views:

1082

answers:

2

Hello!

I have a dynamically populated (by ajax) select box with resulting options like that:

<select id="destination" name="destination">
<option value="london-paris">London-Paris</option>
<option value="paris-london">Paris-London</option>

<option value="london-newyork">London-New-York</option>
<option value="newyork-london">New-York-London</option>

<option value="london-berlin">London-Berlin</option>
<option value="berlin-london">Berlin-London</option>

<option value="london-helsinki">London-Helsinki</option>
<option value="helsinki-london">Helsinki-London</option>

... there are actually more of them but not the essence

The thing i want is to group each this two option portions by optgroup using Javascript (using Jquery or Mootools maybe) after the list is loaded, so that before each of this group - we add an optgroup tag with label that we get from second option html of the group (actually the word before dash):

<select id="destination" name="destination">
<optgroup label="Paris">
<option value="london-paris">London-Paris</option>
<option value="paris-london">Paris-London</option>
</optgroup>
<optgroup label="New-York">
<option value="london-newyork">London-New-York</option>
<option value="newyork-london">New-York-London</option>
</optgroup>
<optgroup label="Berlin">
<option value="london-berlin">London-Berlin</option>
<option value="berlin-london">Berlin-London</option>
</optgroup>
<optgroup label="Helsinki">
<option value="london-helsinki">London-Helsinki</option>
<option value="helsinki-london">Helsinki-London</option>
</optgroup>
</select>

Though,there are always two destinations in each group.

Please, advice how to implement this Thanks in advance.

+1  A: 

This is not too tricky, you only need to move around your options a bit. Take them out of the document flow, add an optgroup in the place of the two associated options and append the options to that optgroup.

Assuming that the options are actually sequential, as in your example, a possible, good old DOM scripting implementation is as follows:

var destinationSelect = document.getElementById("destination");
var options = destinationSelect.getElementsByTagName("option");

var optgroups = [];

while(options.length > 0) {

  var option1 = options[0];
  var option2 = options[1];
  var optgroup = document.createElement("optgroup");
  var label = option1.innerHTML.replace(/^[^\-]-/, "");
  optgroup.setAttribute("label", label);
  destinationSelect.removeChild(option1);
  destinationSelect.removeChild(option2);
  optgroup.appendChild(option1);
  optgroup.appendChild(option2);

  optgroups.push(optgroup);
}

for(var i = 0; i < optgroups.length; i ++) {
  destinationSelect.appendChild(optgroups[i]);
}

I haven't tested this, but hopefully it should work alright. If not, I bow my head in shame.

Andreas Jansson
Thanks! But it throws an exception error:[Exception... "Node was not found" code: "8" nsresult: "0x80530008 (NS_ERROR_DOM_NOT_FOUND_ERR)I guess because removeChild should remove DOM Element, not the options[i]...
moogeek
haha, yes i do bow my head in shame. fixed now, sorry
Andreas Jansson
hmm.. it just sort's the list now, not adding groups :(Aah my shame.. then i need to add labels... Thanks :)
moogeek
Mootools FTW! var optgroup = new Element('optgroup', {label: option2.get('text').substr(0, option2.get('text').toString().indexOf("-"))});
moogeek
oh, sorry didn't notice the label attribute, edited now. not really on the ball tonight.
Andreas Jansson
+2  A: 

You can do this in place using jQuery:

$(document).ready(function() {
    var select = $('#destination');
    var opt1, opt2;
    $('option', select).each(function(i) {
        if (i % 2 === 0) {
            opt1 = $(this);
        } else {
            opt2 = $(this);
            var label = opt1.text().replace('London-', '');
            var optgroup = $('<optgroup/>');
            optgroup.attr('label', label);
            opt2.add(opt1).wrapAll(optgroup);
        }

    });
});

This code iterates over all the options in the select tag, and wraps every set of two in an optgroup. It also figures out what to label the optgroup as, based on text in the options.

DaveS
Wow big thanks! Nice one! it worked as i wished!
moogeek