Dans GMail, l'utilisateur peut cliquer sur une case à cocher dans la liste de diffusion, maintenir la touche Maj enfoncée et sélectionner une deuxième case. Le JavaScript sélectionnera / désélectionnera ensuite les cases à cocher situées entre les deux cases à cocher.
Je suis curieux de savoir comment cela se fait? S'agit-il de JQuery ou d'un JavaScript basique (ou complexe)?
javascript
gmail
Ascalonien
la source
la source
Réponses:
J'ai écrit une démo autonome qui utilise jquery:
$(document).ready(function() { var $chkboxes = $('.chkbox'); var lastChecked = null; $chkboxes.click(function(e) { if (!lastChecked) { lastChecked = this; return; } if (e.shiftKey) { var start = $chkboxes.index(this); var end = $chkboxes.index(lastChecked); $chkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', lastChecked.checked); } lastChecked = this; }); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <html> <head> </head> <body> <input type="checkbox" id="id_chk1" class="chkbox" value="1" />Check 1<br/> <input type="checkbox" id="id_chk2" class="chkbox" value="2" />Check 2<br/> <input type="checkbox" id="id_chk3" class="chkbox" value="3" />Check 3<br/> <input type="checkbox" id="id_chk4" class="chkbox" value="4" />Check 4<br/> <input type="checkbox" id="id_chk5" class="chkbox" value="5" />Check 5<br/> <input type="checkbox" id="id_chk6" class="chkbox" value="6" />Check 6<br/> <input type="checkbox" id="id_chk7" class="chkbox" value="7" />Check 7<br/> </body> </html>
la source
.prop('checked'
, non.attr('checked'
. jsFiddle: jsfiddle.net/dn4jv9a5Cela se fait grâce à un javascript assez simple.
Ils gardent une trace de l'id de la dernière case cochée et lorsqu'une autre case est cochée, ils utilisent l' attribut d'événement shiftKey pour voir si le décalage a été maintenu en cliquant sur la case à cocher. Si tel est le cas, ils définissent la propriété cochée de chaque case à cocher entre les deux sur true.
Pour déterminer quand une case est cochée, ils utilisent probablement un événement onclick sur les cases à cocher
la source
Récemment, j'ai écrit un plugin jQuery qui fournit cette fonctionnalité et plus encore.
Après avoir inclus le plugin, il vous suffit d'initialiser le contexte des cases à cocher avec l'extrait de code suivant:
$('#table4').checkboxes({ range: true });
Voici le lien vers la documentation, la démo et le téléchargement: http://rmariuzzo.github.io/checkboxes.js/
la source
Il semble que chaque réponse que je puisse trouver en ligne dépend entièrement de jQuery pour cela. JQuery ajoute très peu de fonctionnalités. Voici une version rapide qui ne nécessite aucun framework:
function allow_group_select_checkboxes(checkbox_wrapper_id){ var lastChecked = null; var checkboxes = document.querySelectorAll('#'+checkbox_wrapper_id+' input[type="checkbox"]'); //I'm attaching an index attribute because it's easy, but you could do this other ways... for (var i=0;i<checkboxes.length;i++){ checkboxes[i].setAttribute('data-index',i); } for (var i=0;i<checkboxes.length;i++){ checkboxes[i].addEventListener("click",function(e){ if(lastChecked && e.shiftKey) { var i = parseInt(lastChecked.getAttribute('data-index')); var j = parseInt(this.getAttribute('data-index')); var check_or_uncheck = this.checked; var low = i; var high=j; if (i>j){ var low = j; var high=i; } for(var c=0;c<checkboxes.length;c++){ if (low <= c && c <=high){ checkboxes[c].checked = check_or_uncheck; } } } lastChecked = this; }); } }
Et puis initialisez-le chaque fois que vous en avez besoin:
allow_group_select_checkboxes('[id of a wrapper that contains the checkboxes]')
la source
Eh bien, le post est assez ancien mais voici une solution que je viens de trouver: Plug-In jQuery Field
la source
Vous avez cette solution de http://abcoder.com/javascript/jquery/simple-check-uncheck-all-jquery-function/ (maintenant mort) :
Code JavaScript et HTML
var NUM_BOXES = 10; // last checkbox the user clicked var last = -1; function check(event) { // in IE, the event object is a property of the window object // in Mozilla, event object is passed to event handlers as a parameter if (!event) { event = window.event } var num = parseInt(/box\[(\d+)\]/.exec(this.name)[1]); if (event.shiftKey && last != -1) { var di = num > last ? 1 : -1; for (var i = last; i != num; i += di) { document.forms.boxes['box[' + i + ']'].checked = true; } } last = num; } function init() { for (var i = 0; i < NUM_BOXES; i++) { document.forms.boxes['box[' + i + ']'].onclick = check; } }
<body onload="init()"> <form name="boxes"> <input name="box[0]" type="checkbox"> <input name="box[1]" type="checkbox"> <input name="box[2]" type="checkbox"> <input name="box[3]" type="checkbox"> <input name="box[4]" type="checkbox"> <input name="box[5]" type="checkbox"> <input name="box[6]" type="checkbox"> <input name="box[7]" type="checkbox"> <input name="box[8]" type="checkbox"> <input name="box[9]" type="checkbox"> </form> </body>
la source
Inspiré par les bonnes réponses fournies, voici une version JavaScript simple utilisant
Array.prototype
pour forcer les nodelists à utiliser des fonctions de tableau, plutôt que desfor
boucles.(function () { // encapsulating variables with IIFE var lastcheck = null // no checkboxes clicked yet // get desired checkboxes var checkboxes = document.querySelectorAll('div.itemslist input[type=checkbox]') // loop over checkboxes to add event listener Array.prototype.forEach.call(checkboxes, function (cbx, idx) { cbx.addEventListener('click', function (evt) { // test for shift key, not first checkbox, and not same checkbox if ( evt.shiftKey && null !== lastcheck && idx !== lastcheck ) { // get range of checks between last-checkbox and shift-checkbox // Math.min/max does our sorting for us Array.prototype.slice.call(checkboxes, Math.min(lastcheck, idx), Math.max(lastcheck, idx)) // and loop over each .forEach(function (ccbx) { ccbx.checked = true }) } lastcheck = idx // set this checkbox as last-checked for later }) }) }())
<div class="itemslist"> <input type="checkbox" name="one" value="1"> <input type="checkbox" name="two" value="2"> <input type="checkbox" name="three" value="3"> <input type="checkbox" name="four" value="4"> <input type="checkbox" name="five" value="5"> </div>
la source
J'ai vraiment aimé l'exemple de gyo et j'ai ajouté du code pour qu'il fonctionne sur toutes les cases à cocher du même nom.
J'ai également ajouté un MutationObserver afin que les événements soient également gérés sur les cases à cocher nouvellement ajoutées.
$(document).ready(function() { var previouslyClicked = {}; var rangeEventHandler = function(event) { if (event.shiftKey && previouslyClicked[this.name] && this != previouslyClicked[this.name]) { var $checkboxes = $('input[type=checkbox][name='+this.name+']').filter(':visible'); var start = $checkboxes.index( this ); var end = $checkboxes.index( previouslyClicked[this.name] ); // console.log('range', start, end, this, previouslyClicked[this.name]); $checkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', previouslyClicked[this.name].checked); } else { previouslyClicked[this.name] = this; } }; if ("MutationObserver" in window) { // https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/MutationObserver to refresh on new checkboxes var mutationCallback = function(mutationList, observer) { mutationList.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node.nodeName == 'INPUT' && node.type == 'checkbox') { $(node).on('click.selectRange', rangeEventHandler); } }); }); }; var observer = new MutationObserver(mutationCallback); observer.observe(document, { childList: true, attributes: false, // since name is dynamically read subtree: true }); } $('input[type=checkbox][name]').on('click.selectRange', rangeEventHandler); });
<html> <head> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div> First: <input type="checkbox" name="first"> <input type="checkbox" name="first"> <input type="checkbox" name="first"> <input type="checkbox" name="first"> <input type="checkbox" name="first"> </div> <div> Second: <input type="checkbox" name="second"> <input type="checkbox" name="second"> <input type="checkbox" name="second"> <input type="checkbox" name="second"> <input type="checkbox" name="second"> </div> </body> </html>
la source
J'ai pris la version jQuery de @BC. et l'a transformé en une version ES6, car le code résout en fait assez élégamment le problème, au cas où quelqu'un trébucherait encore sur cela ...
function enableGroupSelection( selector ) { let lastChecked = null; const checkboxes = Array.from( document.querySelectorAll( selector ) ); checkboxes.forEach( checkbox => checkbox.addEventListener( 'click', event => { if ( !lastChecked ) { lastChecked = checkbox; return; } if ( event.shiftKey ) { const start = checkboxes.indexOf( checkbox ); const end = checkboxes.indexOf( lastChecked ); checkboxes .slice( Math.min( start, end ), Math.max( start, end ) + 1 ) .forEach( checkbox => checkbox.checked = lastChecked.checked ); } lastChecked = checkbox; } ) ); }
la source
Nous avons trouvé la meilleure solution pour les cases à cocher de sélection et de désélection.
Utilise un noyau javascript et Jquery.
$(document).ready(function() { var $chkboxes = $('.chkbox'); var lastChecked = null; $chkboxes.click(function(e) { if(!lastChecked) { lastChecked = this; return; } if(e.shiftKey) { var start = $chkboxes.index(this); var end = $chkboxes.index(lastChecked); $chkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', e.target.checked); } lastChecked = this; }); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <html> <head> </head> <body> <input type="checkbox" id="id_chk1" class="chkbox" value="1" />Check 1<br/> <input type="checkbox" id="id_chk2" class="chkbox" value="2" />Check 2<br/> <input type="checkbox" id="id_chk3" class="chkbox" value="3" />Check 3<br/> <input type="checkbox" id="id_chk4" class="chkbox" value="4" />Check 4<br/> <input type="checkbox" id="id_chk5" class="chkbox" value="5" />Check 5<br/> <input type="checkbox" id="id_chk6" class="chkbox" value="6" />Check 6<br/> <input type="checkbox" id="id_chk7" class="chkbox" value="7" />Check 7<br/> </body> </html>
la source
Voici également une autre implémentation similaire à la sélection multiple Outlook.
<script type="text/javascript"> function inRange(x, range) { return (x >= range[0] && x <= range[1]); } $(document).ready(function() { var $chkboxes = $('.chkbox'); var firstClick = 1; var lastClick = null; var range = []; $chkboxes.click(function(e) { if(!e.shiftKey && !e.ctrlKey) { $('#index-' + firstClick).prop('checked', false); firstClick = $chkboxes.index(this) + 1; if (firstClick !== null && firstClick !== ($chkboxes.index(this)+1)) { $('#index-' + firstClick).prop('checked', true); } } else if (e.shiftKey) { lastClick = $chkboxes.index(this) + 1; if ((firstClick < lastClick) && !inRange(lastClick, range)) { for (i = firstClick; i < lastClick; i++) { $('#index-' + i).prop('checked', true); } range = [firstClick, lastClick]; } else if ((firstClick > lastClick) && !inRange(lastClick, range)) { for (i = lastClick; i < firstClick; i++) { $('#index-' + i).prop('checked', true); } range = [lastClick, firstClick]; } else if ((firstClick < lastClick) && inRange(lastClick, range)) { for (i = 1; i < 100; i++) { $('#index-' + i).prop('checked', false); } for (i = firstClick; i < lastClick; i++) { $('#index-' + i).prop('checked', true); } range = [firstClick, lastClick]; }else if ((firstClick > lastClick) && inRange(lastClick, range)) { for (i = 1; i < 100; i++) { $('#index-' + i).prop('checked', false); } for (i = lastClick; i < firstClick; i++) { $('#index-' + i).prop('checked', true); } range = [lastClick, firstClick]; } } }); });
la source
C'est la solution jquery que j'ai écrite et utilisée:
chksel
chksel_index
Chacun
checkbox
a également un attribut nommérg
qui contient le même indexvar chksel_last=-1; $('.chksel').click(function(ev){ if(ev.shiftKey){var i=0; if(chksel_last >=0){ if($(this).attr('rg') >= chksel_last){ for(i=chksel_last;i<=$(this).attr('rg');i++){$('.chksel_'+i).attr('checked','true')}} if($(this).attr('rg') <= chksel_last){for(i=$(this).attr('rg');i<=chksel_last;i++){$('.chksel_'+i).attr('checked','true')}} } chksel_last=$(this).attr('rg'); }else{chksel_last=$(this).attr('rg');}
})
la source
cette solution fonctionne pour moi, également basée sur ajax pour DataTables https://jsfiddle.net/6ouhv7bw/4/
<table id="dataTable"> <tbody> <tr> <td><input type="checkbox"></td> </tr> <tr> <td><input type="checkbox"></td> </tr> <tr> <td><input type="checkbox"></td> </tr> <tr> <td><input type="checkbox"></td> </tr> </tbody> </table> <script> $(document).ready(function() { var $chkboxes = $('#dataTable'); var $range = '#dataTable tbody'; var $first = false; var $indexWrapp = 'tr'; var lastChecked = null; var $checkboxes = 'input[type="checkbox"]'; $chkboxes.on('click',$checkboxes,function(e) { if ($first===false) { lastChecked = $(this).closest($indexWrapp).index(); lastCheckedInput = $(this).prop('checked'); $first=true; return; } if (e.shiftKey) { var start = lastChecked; var end = $(this).closest($indexWrapp).index(); $( $range+' '+$indexWrapp).each(function() { $currIndex=$(this).index(); if( $currIndex>=start && $currIndex<=end ){ $(this).find($checkboxes).prop('checked', lastCheckedInput); } }) } lastCheckedInput = $(this).prop('checked'); lastChecked = $(this).closest($indexWrapp).index(); }); </script>
la source