Reputation: 873
I'm trying to implement chained ajax selects from this jQuery plugin: http://www.appelsiini.net/projects/chained
I'm using the remote method.
I have a problem where my select boxes show the "default" (blank) value last in the select as seen here:
This is a problem because I have 5 chains, so when the blank value isn't selected by default, it does 5 sequential lookups. It also isn't working like it shows on the demo page where the default value is selected by default instead of a real value.
A JSON request from my server returns this:
{"":"","1":"Test #1","2":"Test #2"}
So as you can see, it's not the order that my JSON is returning.
This is my HTML:
<label class="control-label" for="branch">Branch</label>
<select id="branch" name="branch">
<option value=""></option>
<option value="1">Foo</option>
<option value="2">Bar</option>
</select>
<label class="control-label" for="facility">Facility</label>
<select id="facility" name="facility">
<option value=""></option>
</select>
<script src="/js/chained.js"></script>
<script>
$(document).ready(function() {
$("#facility").remoteChained("#branch", "/src/record.json.php");
} );
</script>
So now I'm lost and since I can't read/write JavaScript very well, I'm hoping someone can see the issue and help me out.
Upvotes: 2
Views: 2703
Reputation: 13421
It happens because,
Chrome and probably Opera sort object properties automatically
So your JSON also is sorted in for
loop.
var json = {"":"","1":"Test #1","2":"Test #2"};
for(var i in json)
console.log(i);
/* Result : 1 2 (null) */
If you change your index as string that will not be sorted.
var json = {"":"","t1":"Test #1","t2":"Test #2"};
for(var i in json)
console.log(i);
/* Result : (null) t1 t2 */
Changing plug-in
Here is the edited plugin code that works with array,
/*
* Remote Chained - jQuery AJAX(J) chained selects plugin
*
* Copyright (c) 2010-2011 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
*/
(function($) {
$.fn.remoteChained = function(parent_selector, url, options) {
return this.each(function() {
/* Save this to self because this changes when scope changes. */
var self = this;
var backup = $(self).clone();
/* Handles maximum two parents now. */
$(parent_selector).each(function() {
$(this).bind("change", function() {
/* Build data array from parents values. */
var data = {};
$(parent_selector).each(function() {
var id = $(this).attr("id");
var value = $(":selected", this).val();
data[id] = value;
});
$.getJSON(url, data, function(json) {
var selectedVal;
/* Clear the select. */
$("option", self).remove();
/* Add new options from json. */
for (var key in json.options) {
var k = json.options[key];
/* This sets the default selected. */
if ("selected" == k.name) {
selectedVal = k.value;
continue;
}
var option = $("<option />").val(k.value).append(k.name);
$(self).append(option);
}
/* Loop option again to set selected. IE needed this... */
$(self).children().each(function() {
if ($(this).val() == selectedVal) {
$(this).attr("selected", "selected");
}
});
/* If we have only the default value disable select. */
if (1 == $("option", self).size() && $(self).val() === "") {
$(self).attr("disabled", "disabled");
} else {
$(self).removeAttr("disabled");
}
/* Force updating the children. */
$(self).trigger("change");
});
});
/* Force updating the children. */
$(this).trigger("change");
});
});
};
/* Alias for those who like to use more English like syntax. */
$.fn.remoteChainedTo = $.fn.remoteChained;
})(jQuery);
To work with this updated plugin, you should use this JSON format,
{
"options" : [
{ "value" : "", "name" : ""},
{ "value" : "1", "name" : "Test #1"},
{ "value" : "2", "name" : "Test #2"},
]
}
If you want to set a default selected item (for example "Test #1" is selected), so you can do that like this,
{
"options" : [
{ "value" : "", "name" : ""},
{ "value" : "1", "name" : "Test #1"},
{ "value" : "2", "name" : "Test #2"},
{ "value" : "1", "name" : "selected"}
]
}
How can I use this edited plugin?
Just clear all the code in /js/chained.js
than paste the new one.
Upvotes: 1
Reputation: 9781
It looks like the JSON returned from the server is wrong.
It should contain a selected
field like this:
{"":"--","3-doors":"3 doors","5-doors":"5 doors","coupe":"Coupe","cabrio":"Cabrio","selected":"coupe"}
That is taken from the examples here:
http://www.appelsiini.net/projects/chained
In your case the server should return:
{"":"","1":"Test #1","2":"Test #2","selected":""}
Upvotes: 0