Фрилансер У.
248 повідомлень
#16 років тому
Я хочу сделать три селекта, зависимые друг от друга, то есть выбрал что-то в первом, поменялись два других.

<script type="text/javascript">
selectors = new Array('ctlArtist','ctlAlbum','ctlSong');

var generateList = function(j) {
var options = '';
for (var i = 0; i < j.options.length; i++) {
options += '<option value="' + j.options.optionValue + '">' + j.options.optionDisplay + '</option>';
}
$("select#"+selectors).html(options);
}

$(document).ready(function(){


$("select#ctlArtist").change(function(){


$.getJSON("select.php",{id: $(this).val(), level: 1}, generateList);


$("select#ctlAlbum").trigger("change");
});

$("select#ctlAlbum").change(function(){


$.getJSON("select.php",{id: $(this).val(), level: 2}, generateList);
});
});
</script>

Три селекта ctlArtist,ctlAlbum,ctlSong. Значения подгружаются из select.php. Когда выбираю что-нибудь в первом, во втором селекте должно произойти заполнение опциями второго селекта, а затем вызывается событие change для него, но он(второй селект) считает, что значения у него не поменялись! Меняются они судя по всему после функции-колбека, а нужно в самой функции.

Как это можно исправить?
Фрилансер У.
248 повідомлень
#16 років тому
Сразу говорю, у меня select'ы уже присутствуют на странице.
Вот я ужал код, чтобы было проще

<script type="text/javascript">
selectors = new Array('ctlArtist','ctlAlbum','ctlSong');
var generateList = function(j) {
var options = '';
for (var i = 0; i < j.options.length; i++) {
options += '<option value="' + j.options.optionValue + '">' + j.options.optionDisplay + '</option>';
}
$("select#"+selectors).html(options);
console.log(1+"\n"+$("select#"+selectors).html());
}
$(document).ready(function(){
$("select#ctlArtist").change(function(){


$.getJSON("select.php",{id: $(this).val(), level: 1}, generateList);


console.log(2+"\n"+$("select#ctlAlbum").html());
});
});
</script>

В консоли Firebug'а показывает вначале данные из второго console.log и только затем из первого.
Александр Подопригора
13 повідомлень
#16 років тому
Лови компонент и не парься


(function($) {

$.fn.buildSelect = function(opt) {
opt = $.extend({listen_type:true, opt_default:{title:" -- Выберите ", val:-1}},opt);
this.each(function(){
var Elem = $(this);
$(this).preloader(true);
$.ajax({
type:"POST",
dataType:"json",
url:opt.url,
success:function(res) {
if(res.is_error) {
alert(res.error_alert);
} else {
Elem.preloader(false, opt.opt_default);
var options = createOptions(res, opt.selected);
for(var i = 0; i < options.length; i++) {
Elem.get(0).options.add(options);
}
}
}
});
});

function createOptions(res, selected) {
var newOptions = ;
for(var i = 0; i < res.length; i++) {
var title = res.name;
if(res.type != undefined && opt.listen_type == true) {
var value = res.type + "_" + res.id;
} else {
var value = res.id;
}
if(selected == res.id) {
newOptions.push( new Option(title, value, false, true) )
} else {
newOptions.push( new Option(title, value) );
}
}
return newOptions;
};
};

$.fn.preloader = function(flag, opt) {
this.each(function(){
$(this).get(0).options.length = 0;
if(flag) {
$(this).get(0).disabled = true;
var option = new Option("Загрузка ... ", -1);
} else {
$(this).get(0).disabled = false;
var option = new Option(opt.title, opt.val);
}
$(this).get(0).options.add(option);
});
};

})(jQuery);
Александр Подопригора
13 повідомлень
#16 років тому

$("#select1").change(function(){
$("#selet2").buildSelect(url:"getData.php");
));
Николай М.
1895 повідомлень
#16 років тому
Вызывайте событие когда оно требуется если оно не происходит, OnGhange вызивается по идее когда юзер что то выбирал в боксе, а не когда чтото менялось в списке, это 2 кардинальные разницы.
Фрилансер У.
248 повідомлень
#16 років тому
MMM_Corp
Тут не в событии дело, а в том, что функция-коллбек выполняется асинхронно и запаздывает по сравнению с кодом, который идет после вызова getJSON.
Фрилансер У.
248 повідомлень
#16 років тому
php_developer
Спасибо, посмотрю. Но я все-таки хотел разобраться, чтобы затем такого рода проблем не возникало.
Николай М.
1895 повідомлень
#16 років тому
Цитата ("werewolf"):
MMM_Corp
Тут не в событии дело, а в том, что функция-коллбек выполняется асинхронно и запаздывает по сравнению с кодом, который идет после вызова getJSON.

В таких случаях поможет манипуляция переменныим, как напр. это можно поискать в гугле прим. "асинхронное выполнение запросов" примерно так
Фрилансер У.
248 повідомлень
#16 років тому
setTimeout('$("select#ctlAlbum").trigger("change")', 1);

Помогло, гарантировано вызывается после коллбека.