Vraag Hoe kan ik een HTML-handeling voor meerdere selecties maken, zoals de bedieningsknop die altijd wordt ingedrukt


Ik heb een webtoepassing waar ik aan werk waarvoor een HTML-meerkeuzemenu nodig is, zoals de bedieningstoets te allen tijde wordt ingedrukt. D.w.z. klik op een optie om aan te geven of het geselecteerd is of niet.

Ik heb verschillende Jquery-gebeurtenisbindingen geprobeerd maar het lijkt erop dat het standaard HTML-meervoudige selectiegedrag wordt uitgevoerd voordat de JQuery-gebonden gebeurtenis wordt gestart, waardoor het vrijwel onmogelijk is om de gebeurtenis alleen te onderscheppen en het standaardgedrag aan te passen.

Hoe kan ik zo maken dat met enkele klikken de selectie van een individuele optie kan worden gewijzigd?


13
2017-09-25 15:08


oorsprong


antwoorden:


Probeer dit eens. U kunt de optiewaarden in een object opslaan en de klikactie gebruiken om het object bij te werken en vervolgens de wijzigingen op de selectie toepassen.

demonstratie

http://jsfiddle.net/iambriansreed/BSdxE/

HTML

<select class="select-toggle" multiple="multiple">
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
</select>​

JavaScript

$('.select-toggle').each(function(){    
    var select = $(this), values = {};    
    $('option',select).each(function(i, option){
        values[option.value] = option.selected;        
    }).click(function(event){        
        values[this.value] = !values[this.value];
        $('option',select).each(function(i, option){            
            option.selected = values[option.value];        
        });    
    });
});​

18
2017-09-25 15:22



Misschien wilt u een eenvoudiger oplossing overwegen, zoals het gebruik van een lijst met selectievakjes in een div waarvan de overloopeigenschap is ingesteld om te scrollen. Dat zou beter voor u kunnen uitpakken. Een drop-down krijgen om te doen wat je hebt gevraagd is een beetje betrokken.

Zien deze viool bijvoorbeeld

HTML

<div id="container">
    <label><input type="checkbox" name="test" value="1" />Option 1</label>
    <label><input type="checkbox" name="test" value="2" />Option 2</label>
    <label><input type="checkbox" name="test" value="3" />Option 3</label>
    <label><input type="checkbox" name="test" value="4" />Option 4</label>
    <label><input type="checkbox" name="test" value="5" />Option 5</label>
    <label><input type="checkbox" name="test" value="6" />Option 6</label>
    <label><input type="checkbox" name="test" value="7" />Option 7</label>
    <label><input type="checkbox" name="test" value="8" />Option 8</label>
    <label><input type="checkbox" name="test" value="9" />Option 9</label>
    <label><input type="checkbox" name="test" value="10" />Option 10</label>
    <label><input type="checkbox" name="test" value="11" />Option 11</label>
    <label><input type="checkbox" name="test" value="12" />Option 12</label>
</div>

CSS

label{display:block;}
#container{height:100px;width:200px;overflow:scroll;}

5
2017-09-25 15:22



Moest dit probleem zelf oplossen en merkte het op afgeluisterd gedrag een eenvoudige onderschepping van de mousedown en het instellen van het attribuut zou hebben gedaan, dus een override gemaakt van het select element en het werkt goed.

jsFiddle: http://jsfiddle.net/51p7ocLw/

Notitie: Deze code corrigeert buggedrag door het select element in de DOM te vervangen. Dit is een beetje agressief en zal event handlers breken die je misschien aan het element hebt gekoppeld.

window.onmousedown = function (e) {
    var el = e.target;
    if (el.tagName.toLowerCase() == 'option' && el.parentNode.hasAttribute('multiple')) {
        e.preventDefault();

        // toggle selection
        if (el.hasAttribute('selected')) el.removeAttribute('selected');
        else el.setAttribute('selected', '');

        // hack to correct buggy behavior
        var select = el.parentNode.cloneNode(true);
        el.parentNode.parentNode.replaceChild(select, el.parentNode);
    }
}
<h4>From</h4>

<div>
    <select name="sites-list" size="7" multiple>
        <option value="site-1">SITE</option>
        <option value="site-2" selected>SITE</option>
        <option value="site-3">SITE</option>
        <option value="site-4">SITE</option>
        <option value="site-5">SITE</option>
        <option value="site-6" selected>SITE</option>
        <option value="site-7">SITE</option>
        <option value="site-8">SITE</option>
        <option value="site-9">SITE</option>
    </select>
</div>


2
2017-12-20 08:12



De bovenstaande oplossingen hebben allemaal het grootste nadeel van het niet ondersteunen van selecties in het selectievakje, wat eigenlijk de reden is die ik zou gebruiken <select>-boxen over checkbox-ingangen in de eerste plaats. Aanvankelijk bezocht ik deze pagina om een ​​ingebouwde manier te vinden om dit op te lossen, maar gezien de bovenstaande antwoorden, zal ik gewoon mijn eigen code schrijven.

De volgende code heeft ook het voordeel dat het niet wordt bijgewerkt op mouseup in tegenstelling tot het huidige topantwoord van iambriansreed, maar op mousedown, het standaardgedrag in browsers.

Alleen om toekomstige googlers te helpen, mijn code hieronder:

// Copyright (c) 2018 Joeytje50. All rights reserved.
// This code is licenced under GNU GPL3+; see <http://www.gnu.org/licenses/>

// Source code and most recent version:
// https://gist.github.com/Joeytje50/2b73f9ac47010e7fdc5589788b80af77

// select all <options> within `sel` in the range [from,to]
// change their state to the state sel.options[from] is in,
// ie. change it to the current state of the first selected element
function selectRange(sel, from, to) {
  var toState = sel.options[from].selected;
  // make sure from < to:
  if (from > to) {
    var temp = from;
    from = to;
    to = temp;
  }
  if (!(sel instanceof HTMLSelectElement)) {
    throw new TypeError('selectRange requires a single non-jQuery select-element as first parameter');
  }
  // (de)select every element
  for (var i=from; i<=to; i++) {
    sel.options[i].selected = toState;
  }
}

$(function() {
  $('.addSelect').data('select-start', 0); // default selection start
  $('.addSelect').on('mousedown', function(e) {
    $(this).focus();
    // clicking on the edge of the <select> shouldn't do anything special
    if (!$(e.target).is('option')) return;
    // if Ctrl is pressed, just let the built-in functionality take over
    if (e.ctrlKey) return;
    // keep everything selected that's not affected by the range within a shift-click
    if (e.shiftKey) {
      var fromIdx = $(this).data('select-start')
      selectRange(this, $(this).data('select-start'), e.target.index);
      e.preventDefault();
      return false;
    }
    // save the starting <option> and the state to change to
    $(this).data('select-start', e.target.index);
    e.target.selected = !e.target.selected;
    e.preventDefault();
    // save a list of selected elements, to make sure only the selected <options>
    // are added or removed when dragging
    var selected = [];
    for (var i=0;i<this.selectedOptions.length;i++) {
      selected.push(this.selectedOptions[i].index);
    }
    $(this).data('selected', selected);
    $(this).children('option').on('mouseenter', function(e) {
      var sel = this.parentElement;
      // first reset all options to the original state
      for (var i=0;i<sel.options.length;i++) {
        if ($(sel).data('selected').indexOf(i) == -1) {
          sel.options[i].selected = false;
        } else {
          sel.options[i].selected = true;
        }
      }
      // then apply the new range to the elements
      selectRange(sel, $(sel).data('select-start'), e.target.index);
    });
  });
  // clean up events after click event has ended.
  $(window).on('mouseup', function() {
    $('.addSelect').children('option').off('mouseenter'); // remove mouseenter-events
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="addSelect" multiple size="10">
<option value="0">Foo0</option>
<option value="1">Bar1</option>
<option value="2">Baz2</option>
<option value="3">Lol3</option>
<option value="4">Heh4</option>
<option value="5">Hey5</option>
<option value="6">Meh6</option>
<option value="7">Xcq7</option>
<option value="8">Hmm8</option>
<option value="9">End9</option>
</select>

Voel je vrij om deze code te gebruiken door deze eenvoudigweg te kopiëren naar elk project waarop je het wilt gebruiken.


0
2018-01-12 00:04