4

I have two lists one displays cars company and the second one displays all the cars

Here is the first comboxbox ( The first option is ALL)

<select id="company"> <option selected="true" >ALL</option> <option>GM</option> <option>Honda</option> <option>Ford</option> </select> 

here is my second lisbox

<select id="names" multiple="multiple" size="8"> <option>Chevy [GM]</option> <option>Buick [GM]</option> <option>Civic [Honda]</option> <option>Accord [Honda]</option> <option>Focus [Ford]</option> </select> 

Based on the first combox selection , I should display only that car company cars in the second list . Even the second list has the car company name in brackets .. This is fixed format . Again from the the first list if user selects "ALL" I should show all the vehicles .

Could any body give me an idea to implement this or code snippet for this ?

Thanks for your help

Regards

Kiran

7 Answers 7

6

Not all browsers allow you to hide the individual items in a drop-down list, so you need to keep a master list, and then repopulate based on that.

var names = $('#names option').clone(); $('#company').change(function() { var val = $(this).val(); $('#names').empty(); names.filter(function(idx, el) { return val === 'ALL' || $(el).text().indexOf('[' + val + ']') >= 0; }).appendTo('#names'); }); 

Working demo at http://jsfiddle.net/alnitak/WsHvS/

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks @Alnitak for this wonderful solution . I am testing this for around 12oo records and let you know the result
FWIW this could be made faster if necessary by storing the make in a separate field so that .text().indexOf() isn't called for every row each time the list is refreshed. I've also just changed .html() to .text()
Once again thanks . Just tested with 1500 cars and every thing went well .
2

As far as I know, hiding of select options only works on Firefox, so for cross browser compatibility you need to use a bit more trickery (see this SO question and this question among others). This is what I suggest:

For HTML, have a hidden copy of your select as well as the version you currently provide:

<select id="company"> <option selected="true" >ALL</option> <option>GM</option> <option>Honda</option> <option>Ford</option> </select> <br /> <div id="namesDiv"> <select id="names" multiple="multiple" size="8"> <option>Chevy [GM]</option> <option>Buick [GM]</option> <option>Civic [Honda]</option> <option>Accord [Honda]</option> <option>Focus [Ford]</option> </select> </div> <select id="baseNames" multiple="multiple" size="8"> <option>Chevy [GM]</option> <option>Buick [GM]</option> <option>Civic [Honda]</option> <option>Accord [Honda]</option> <option>Focus [Ford]</option> </select> 

Hide basenames with CSS display:none.

Then for your jQuery, you'll be replacing names regularly with a cloned version of baseNames and filtering it.

$(document).ready(function() { $("#company").change(function() { $("#namesDiv").empty(); $("#baseNames").clone().appendTo("#namesDiv").attr("id", "names"); var val = $(this).find("option:selected").val(); if(val !== "ALL") { $("#names option").each(function() { if($(this).val().indexOf(val) < 0) { $(this).remove(); } }); } }); }); 

You can see this in action.

3 Comments

why put two copies of the drop-down list in your HTML when you could trivially clone it on load [per my answer ;-) ]
@Alnitak - I'd gladly admit that your solution is more elegant. Mine merely works.
Thanks a lot @justkt for your kind words
1

EDIT: Works in FF only

Try this:

$(function(){ $("#company").change(function(){ var val = $(this).val(); $("#names option").hide().filter(function(){ var regExp = new RegExp("\\[" + val + "\\]$"); return (val == "ALL") || regExp.test($(this).text()); }).show(); }); }); 

Example: http://jsfiddle.net/Chandu/2Zppp/

3 Comments

AFAIK, hide is only supported on firefox for select options.
Thank a lot for your quick response, But unfortunately this works only on Firefox
@Bujji: Yep, just realized, check @justkt's answer.
0

http://css-tricks.com/dynamic-dropdowns/

This is you wanted try to do with first option using text files or alternative option is JSON.

1 Comment

the code on that website is horrendous - storing arrays within JSON as comma separated text instead of as a JSON array?!
0

Another option is to assign a classname to the options like this:

 <select id="names" multiple="multiple" size="8"> <option class="gm">Chevy [GM]</option> <option class="gm">Buick [GM]</option> <option class="honda">Civic [Honda]</option> <option class="honda">Accord [Honda]</option> <option class="ford">Focus [Ford]</option> </select> 

Then based on the class you can show() and hide() like this:

 $(document).ready(function(){ $("#names>option").hide(); $("#company").change(function(){ $("#names>option").hide(); $("#names>." + $(this).val()).show(); if($(this).val() == "ALL"){ $("#names>option").show(); } }); }); 

3 Comments

Show and hide of options isn't cross browser.
@justkt Could be replaced with addClass and removeClass in that case. Thanks
.show() and .hide() apply CSS to the elements. IE doesn't support display or visibility on <option> elements, so even changing it to .addClass() would still fail.
0

You can each() on the second select's options in change() of the first select, search for substring and set the disabled attribute. (But this solution has a flaw: not every browser supports disabled attribute for option, AFAIK.)

UPDATE

And if you want to hide options completely, you should consider storing items from your second select in some temp storage and re-populate that select from the storage only with items that match your criteria.

UPDATE2

 var temp = new Array(); $(document).ready(function(){ //save in temp $('select#names').children().each(function(){temp.push($(this).val());}); //change handler $('select#company').change(function(){ var pref = $(this).val(); $('select#names').children().remove(); for(i=0;i<temp.length;i++) { if(pref=='ALL' || temp[i].match('.[\\[]'+pref+'[\\]]$') ) $('select#names').append('<option>'+temp[i]+'</option>'); } }); }); 

Comments

0

Edit: Tested and working with IE7 and Firefox 3.6.x

Live Demo

HTML: note the value="" on the ALL option

<select id="company"> <option selected="true" value="">ALL</option> <option>GM</option> <option>Honda</option> <option>Ford</option> </select> <select id="names" multiple="multiple" size="8"> <option>Chevy [GM]</option> <option>Buick [GM]</option> <option>Civic [Honda]</option> <option>Accord [Honda]</option> <option>Focus [Ford]</option> </select> 

jQuery:

$('#company').change(function() { var make = $(this).val(); $('#names').contents().each(function() { if (this.nodeType == 8 && this.nodeValue.length > 0 && this.nodeValue.indexOf(make) != -1) { $(this).before('<option>' + this.nodeValue + '</option>'); $(this).remove(); } else if ($(this).val().indexOf(make) == -1 && $(this).val().length > 0) { $(this).replaceWith('<!--' + $(this).val() + '-->'); } }); }); 

3 Comments

Hide on select options is not cross-browser.
Thanks jnpcl . Yes as justkt told this won't work on IE or on Chrome
@Bujji: Working on an alternate solution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.