0

I'm trying to update the options of ALL select lists on a page and implemented a solution found on Get list of all `input` objects using JavaScript, without accessing a `form` object and other pages.

This works to an extent but only the select lists which occur AFTER the one which is triggering the javascript are updated whereas I need them ALL done, regardless of their position relative to the triggering select.

Here's a simplified version of what I have:

function chooseBon(id, value) {

var bonbonsAmount  = 12;
    var bonbonsCurrent = 0;
    var bonbonsCount   = 4;

    var inputs, index;


    // get all the select lists
    inputs = document.getElementsByTagName('select');

// loop through all the lists
    for (index = 0; index < inputs.length; ++index) {

// First disable all options
for (j = 0; j<=bonbonsAmount; ++j) {
    inputs[index].options[j].disabled="disabled";
}

    // Then re-enable the ones we still need
    for (j = 0; j<=(bonbonsAmount - bonbonsCurrent); ++j) {
    inputs[index].options[j].disabled="";
}

// add up the no of chocs selected so we know how many options to re-enabled above
bonbonsCurrent += inputs[index].selectedIndex;

}

I'm an admitted newbie and am adapting a script from one ecommerce platform for another so am hamstrung in certain areas so feel free to make other suggestions.

Community
  • 1
  • 1
  • Hi there, yeah I have between five and twenty select lists, each starting with options from 1-12. Each option is for a chocolate and they are allowed to choose a max total of twelve but in any combination - so if they pick 4 from one select list, all the other select lists should update to only have options 1-8 enabled. If they pick 2 from the next list then each list would be limited to 1-6 and so on. The script above works fine but only updates the select lists AFTER the one which has the option picked, the ones before it on the page aren't updated. – Simon Logan Aug 02 '12 at 17:49

1 Answers1

0

here is one of possible solutions and the fiddle:

function chooseBon() {
    var bonbonsAmount = 12;
    var bonbonsCurrent = 0;
    var bonbonsRemaining; //max. is bonbonsAmount
    var inputs, i, j;
    inputs = document.getElementsByTagName('select');
    for (i = 0; i < inputs.length; i++) {
        bonbonsCurrent += parseInt(inputs[i].value, 10);
    }
    bonbonsRemaining = bonbonsAmount - bonbonsCurrent;
    for (i = 0; i < inputs.length; i++) {
        for (j = 0; j <= bonbonsAmount; j++) {
            inputs[i].options[j].disabled = (j < bonbonsRemaining + parseInt(inputs[i].value, 10) + 1) ? false : true;
        }
    }
}
Stano
  • 8,749
  • 6
  • 30
  • 44
  • Thanks so much Stano it's *almost* there. The one change I need to make is that due to the way the ecommerce system works the select list option values aren't the same as the value that is shown in the list (ie the option text are 1,2,3 etc but the values are, for example, 2234, 2245, 2246, 2247). The values are required by the system so we can't change these so we need to read the text content from the select list not the actual value. Is there a way to do that? – Simon Logan Aug 03 '12 at 12:14
  • Hi, yes, it's easy modification. I updated [the fiddle](http://jsfiddle.net/lalatino/hBf2t/), so now it counts with the `selectedIndex`, so the `value` attribute now can be anything. Another possible solution is to use [HTML 5 data- Attributes](http://ejohn.org/blog/html-5-data-attributes/). – Stano Aug 03 '12 at 12:20
  • Got it - changed the bonbonsCurrent to pull .selectedIndex rather than .value and that seems to do it. Now I just need to take it out of this testing page and see if it still works whilst implemented in the actual site! Big props to you. – Simon Logan Aug 03 '12 at 12:39
  • Just realised we must have tripped over posts and I'd found that solution before noticing your reply, however thanks a lot anyway, much appreciated. – Simon Logan Aug 03 '12 at 13:44
  • A LITTLE? Stano you saved my SANITY! :) – Simon Logan Aug 03 '12 at 14:36
  • Really? So I am glad it helped :-) I suppose, people only missed your question, but it is not as difficult as it seemed, is it? So have a nice day amigo! :) – Stano Aug 03 '12 at 14:45
  • Thanks again, working well. Now I just need to filter the list to skip running the updating on certain lists as described on this other post http://stackoverflow.com/questions/11831964/filter-getelementsbytagname-list-by-option-values. – Simon Logan Aug 06 '12 at 23:45
  • I suppose it's not so big problem. Either put the list into some `#container` div and use `document.getElementById('container').getElementsByTagName('select');` -> this will select only selects from that container - [look at this fiddle](http://jsfiddle.net/lalatino/hBf2t/20/), or differ your selects via unique identifiers, like `id="choco1"` `id="choco2"` ... etc. and filter them in loop with regexp or substring like `inputs[i].options[j].id.indexOf('choco')==0` , or assign them some common class like `class="choco"` and use `getElementsByClassName` selector instead of `getElementsByTagName`. – Stano Aug 07 '12 at 10:47
  • Hi Stano, yeah I managed to get it working using a similar filter - because of the ecommerce system I could't wrap in a div or tailor the ID names so I filtered based on the first item in the list's text (ie the chocs all have a first value of "1" whereas other options have values which are colours etc. – Simon Logan Aug 08 '12 at 16:30