So I'm trying to populate a dropdown with the states, the value for the option should be the two characters value, and the text for the option should be the full state's name, using the code below is returning a value of 0,1,2,3... and returning all the options in the var as the text.
var states = ["Select State","","Alabama","AL","Alaska","AK","Arizona","AZ","Arkansas","AR",...];
$.each(states, function(val, text) {
$('#selector').append( $('<option> </option>').val(val).html(text) )
});
Try this, using an object for states instead of an array. Same results, but it's more clear what's what and you're less likely to have problems if you accidentally skip a name or abbreviation:
var states = {
"Select State":"",
"Alabama":"AL",
"Alaska":"AK",
"Arizona":"AZ",
"Arkansas":"AR"
};
var val, text;
for (text in states) {
val = states[text];
$('<option/>').val(val).text(text).appendTo($('#selector'));
};
http://jsfiddle.net/g59U4/
The problem is that the callback function provided to .each results in val containing the index of the current iteration (e.g. 0, 1, 2 etc.) and text containing the value of that index of the array.
To achieve what you are trying to, you would probably be better off with a normal for loop:
for(var i = 0; i < states.length; i+=2) {
$("#selector").append($('<option> </option>').val(states[i+1]).html(states[i]));
}
You would be even better off caching the jQuery object containing #selector outside of your loop, so it doesn't have to look it up every iteration.
Here's a working example of the above.
Another option would be to use an object instead of an array, using the state name or abbreviation as the keys, and the other as the values. Edit: just like #mblase75 has done
Well you have the jQuery.each function arguments confused. The first is the index of the value in the array, and the second in the value itself. What you need to do is something like:
$.each(states, function(index) {
if(index%2 > 0) {
//continue, basically skip every other one. Although there is probably a better way to do this
return true;
}
$('#selector').append( $('<option> </option>').val(states[index+1]).html(states[index]) )
});
That would be really straightforward if your array had two dimensions. Considering you really need to use the one-dimensional array you presented, you could do this:
var states = ["Select State","","Alabama","AL","Alaska","AK","Arizona","AZ","Arkansas","AR"];
for(var i=1; i<states.length; i+=2) {
$('#selector').append( $('<option value="' + states[i] + '">' + states[i-1] + '</option>').val(val).html(text) )
}
If you changed your array to be an array of objects, you could do something like this -
var states = [{"text":"Select State","val":""},{"text":"Alabama","val":"AL"}]; //etc
$.each(states, function(val, statedata) {
$('#selector').append( $('<option> </option>').val(statedata.val).html(statedata.text) )
});
This change passes a JavaScript object in to the callback each time. The object has text and val properties and is passed in to the callback as the statedata parameter. The val parameter holds the current index position of the array so it is not required to populate the select box.
Demo - http://jsfiddle.net/sR35r/
I have a similar situation populating a select list with a two-dimensional array as the result of an $.ajax callback ....
JSON ...
[["AL","Alabama"],["AK","Alaska"],["AS","American Samoa"],["AZ","Arizona"] ...
var stateOptions = $('#state');
var html ='';
for (var i =1; i<data.length; i++){
html+= '<option value="' +data[i][0]+ '">' +data[i][1]+ '</option>';
}
stateOptions.append(html);
<form name="form" id="form">
<select name="state" id="state">
<option value=''>State</option>
</select>
</form>
Related
I have 2 select boxes, with the second showing a subset of all options based on the category in the first box. The second box contains ids and names, where the option value equals the id. I already filtered out the id's I am interested in and have them in an array. This will change each time and can be different sizes (filtering all users by groups). What I would like to do is take a clone of the complete options and then only show those whos id (or value) is present. So, compare the array of filtered values to the complete set. I did see a couple ways to remove options, but most were for only one value at a time or for fixed values, so it didn't exactly fit what I need and I can't figure out how to do this last step! Looks like the following:
<select id = 'doctor_select' >
<option value = '1' > John Doe </option>
<option value = '2' > Jane Doe </option>
.... etc
edit: solved for now by hiding all and doing a for each loop to enable the ones I need.
I wouldn't do it like this, but you could clone the original combo and simply remove the unnecessary options from the DOM. Something like:
var newDoctorSelect=$("#doctor_select").clone();
$(newDoctorSelect).children("option").each(function() {
if(some condition) $(this).remove();
});
$("#somewhere").append(newDoctorSelect);
But I'd recommend either using AJAX or storing the options in an object and populating the select when needed.
var optionsByCategory={
"1":{"1":"One","3":"Three"},
"2":{"2":"Two"}
};
$("#categorySelect").on("change",function() {
var options=optionsByCategory[$(this).val()];
//OR some AJAX call to retreive the options from the server instead
$("#doctor_select option").remove();
for(var k in options) $("#doctor_select").append($("<option>").val(k).text(options[k]));
});
You could do this:
var options = getElementsByTagName("option"),
elem,
length = options.length;
for (var i = 0; i<length; i++) {
if (!((elem = options[i]).value === IDYouWantToMatch)); elem.parentNode.removeChild(elem);
}
I think you want something like the following using filter()
var $sel = $('#doctor_select'),
$opts = $sel.children();
var $filteredOpts = $opts.clone().filter(function(){
return someArray.indexOf(this.value)>-1;
})
$sel.empty().append($filteredOpts);
The stored $opts can now be re-used for future changes
state.on('change', function(){
city.empty();
$.getJSON("pincodes.JSON", function(pincodes){
var key = state.val();
for (var j= 0; j < pincodes['address'].length; j++) {
if (pincodes['address'][j]['circlename'] == key) {
temp.push(pincodes['address'][j]['regionname']);
}
}
cities = $.unique(temp);
for (var k = 0; k < cities.length; k++) {
city.append('<option>' + cities[k] + '</option>');
}
});
});
In the above state = $('#state') , the above works fine fills the cities on select "state" . But the issue is when a new state is selected the previously filled cities are also there . Even though I tried .empty on every change() .
You don't empty your temp array. So, every time this function is called, you keep appending items to your temp array.
You simply need to add the following line in your code:
state.on('change', function() {
city.empty();
temp = []; // <---
$.getJSON("pincodes.JSON", function(pincodes) {
What about cities = $.unique(temp);, it won't work.
According to jQuery.unique() documentation, this function
Sorts an array of DOM elements, in place, with the duplicates removed. Note that this only works on arrays of DOM elements, not strings or numbers.
So, it is not a correct usage. If you get non-unique values from your JSON, you will need to use another way to get distinct values. There is a good SO article on this topic.
So I've been trying this for a while but no luck so far. What I want to achieve is, after selecting a value from the drop down, that value should be compared with the json multi-dimensional array. If it matches, then there are certain html elements on the webpage whose content needs to be replaced with the corresponding json values.
Here is the what I've been working so far (link)
<select onchange="executeMe(this)" id="selectOpt">
<option value="445">Choose...</option>
<option value="445">Daisy</option>
<option value="446">Romeo</option>
</select>
<br/><br/><br/>
<label id="entity_id">replaceThis</label>
So in the fiddle, if the user chooses "Daisy" from the dropdown, (the first array has Daisy in it) the corresponding value set from the array should be displayed in each of the html element on the webpage.
I can use only javascript for this. Thanks in advance guys...
You've got problems. First, your string you get back from your map function is massive and certainly won't pass an equality check with your option value. Additionally, your anonymous function is going to return the first value and not iterate through your for loop properly. There's no correlation between your select option values/labels and the items in the array. Try this:
function executeMe(select) {
var myselect = document.getElementById("selectOpt");
var selectOption = myselect.options[myselect.selectedIndex].innerHTML;
var i = theArray.length, obj, index, val;
while (i--) {
obj = theArray[i];
for (index in obj) {
val = obj[index];
//following matches on both keys and values, if you only
//want values delete the second part of the check
if (val == selectOption || index == selectOption) {
var string = '', prop;
for (prop in obj) {
string += prop + ': ' + obj[prop].toString() + '<br>';
}
document.getElementById('entity_id').innerHTML = string;
}
}
}
}
If this isn't what you need let me know with a comment.
I have a jquery script which converts the options of a dropdown select box to ul list items using an array. Each option in the dropdown has a numerical option value, e.g.
<option value="12">Size S</option>
<option value="34">Size M</option>
<option value="7">Size L</option>
which get converted to a list like
<ul>
<li class="opt_12">Size S</li>
<li class="opt_34">Size M</li>
<li class="opt_7">Size L</li>
</ul>
In Firefox everything works as expected and the list items appear in the same order as the dropdown options. However IE and Chrome seem to sort the option values of the array automatically by option value in descending order.
So instead of size order S,M,L,XL like in the dropdown, in Chrome & IE I get a list with something like XL,M,S,L.
I noticed one thing: When I use var options = Array; to construct the array, Firefox displays the list elements in the right order and Chrome and IE the wrong one. When I use var options = [];, all three tested browsers display the list in the wrong order.
Below is the relevant code of the script which I use to transform the dropdown into list items:
(function($) {
$.fn.visualAttribute = function(options) {
var defaults = {
useTitle: false,
attrClicked : function(data) {
return true;
},
attrUpdated : function(data) {
}
};
var settings = $.extend(defaults, options);
//loop all attributes
var selectbox_counter = 0;
return this.each(function() {
//use counter for a unique class for each wrapper
selectbox_counter++;
//store reference to attribute selectbox
var selectbox = $(this);
//hide the default dropdown (but keep it in dom for posting the required values)
$(this).css('position', 'absolute').css('left', '-100000px').show();
//insert wrapper for options
var wrapper = $('<ul />')
.attr("class", "la_wrapper")
.attr("id", "la_wrapper_" + selectbox_counter)
.appendTo($(this).parent());
$(this).parent().append('<div style="clear:both"></div>');
if (selectbox.attr("id") != "") {
wrapper.attr("rel", selectbox.attr("id"));
}
//store all values of the dropdown in an array
var options = [];
var option_counter = 0;
var description = '';
selectbox.children('option').each(function() {
option_counter++;
if (option_counter == 1) {
//first option contains the description, e.g. 'please select size'
description = $(this).text();
}
//only use option if has a value
var value = $(this).val();
if (value != '') {
options[value] = ({value : value, text : $(this).text()});
}
});
//loop all stored options and create custom html
if (options.length) {
for (var index in options) {
if (!isNaN(index)) {
var value = index;
var text = options[index].text;
if (!settings.useTitle) {
description = '';
}
wrapper.append('<li title="' + description + '" class="opt_' + value + '">' + text + '</li>');
}
}
}
//set custom options to same value as current selectbox value (only needed in rare cases)
var current_value = selectbox.val();
if (current_value > 0) {
$("#la_wrapper_" + selectbox_counter + ' li.opt_' + current_value + ' a').addClass('selected');
}
//event handler for catching a clicked attribute
$("#la_wrapper_" + selectbox_counter + ' li a').click(function() {
var value = $(this).attr("href").split('#')[1];
//use callback
if (!settings.attrClicked(options[value])) {
return false;
}
//set value and class
selectbox.val(value);
$("#la_wrapper_" + selectbox_counter + ' .selected').removeClass('selected');
$(this).addClass('selected');
//use callback
settings.attrUpdated(options[value]);
return false;
});
});
};
})(jQuery);
How can I prevent IE and Chrome from "autosorting" the array and keep/transfer the original order of the dropdown options in the resulting list?
If the order is important, don't use the value of the option as the array key, just do an append (P.S. use [], not Array—that isn't doing what you think it's doing)
var options = [];
var option_counter = 0;
var description = '';
selectbox.children('option').each(function() {
option_counter++;
//only use option if has a value
var value = $(this).val();
if ( value ) {
options.push({value : value, text : $(this).text()});
}
});
Then, when looping, get rid of the if (options.length) altogether, and use a regular for loop:
for (var i=0; i<options.length; i++) {
var value = options[i].value;
var text = options[i].text;
if (!settings.useTitle) {
description = '';
}
wrapper.append('<li title="' + description +
'" class="opt_' + value +
'"><a href="#' + value + '">' + text +
'</a></li>');
}
When you iterate an array with this:
for (var index in options)
you are not getting a guaranteed order as you are just iterating properties of an object (not array indexes) which by specification have no guaranteed order. You should be using this:
for (var i = 0; i < options.length; i++)
to iterate an array in the array order. The first form iterates properties of an object in no particular order. The latter form iterates array elements in array index order (which gives you the actual array elements in their array order).
In addition, you declare an array with this:
var options = [];
or
var options = new Array();
You should not be using:
var options = Array;
Your problem is that you're using for...in to enumerate the properties.
Enumeration order for properties of an object (including an array) is undefined in ECMAScript so far. There is a proposal for ECMAScript 6 to define the order as follows, more or less: "first all properties whose names look like integers, in numeric order, then all other properties in the order they were added". This is the behavior Chrome and IE implement. The Firefox behavior is somewhat complicated and depends on whether your object is an array or not and if it's an array on which exact property names got used and in what order and what the length of the array is and a few other things.
In any case, if you want to enumerate the values in order, just store them in an array using array.push() and then enumerate the array's indices. So replace options[value] = ... with options.push(...) and replace for (var index in options) with for (var index = 0; index < options.length; ++index) and get the value from options[index].value just like you get the text already.
I have this
var selected = []
$('#SelectBoxContainer .DDLs :selected').each(function (i, selected)
{
alert($(selected).val());
selected[i] = $(selected).val();
});
My alert is telling me that it is going through this loop and getting the select box values. Yet once everything is said and done there is nothing in my "selected" array.
Your callback defines a local variable named selected, which hides the selected variable in the outer scope. The selected in selected[i] = is the selected from function (i, selected), not the selected from var selected.
Rename one of the two variables for this to work.
you are opening and closing array and then doing some magic without result...
it's late, but var selected = [] $('#SelectBoxContainer .DDLs :selected').each <..code....>
has no result really.
try making array and then: selected.put($('#SelectBoxContainer ))
in other words, you don't have ';' after 'var selected = []'
How do you expect to work with two variables named "selected" at the same time? Change the name of your function's second parameter so that it doesn't shadow the array you're trying to write to:
var selected = [];
$('#SelectBoxContainer .DDLs :selected').each(function (i, item)
{
selected[i] = $(item).val();
});
You can also use the array push method instead of bothering with indices:
selected.push( $(item).val() )