2016-05-12 2 views
1

Я имею вопрос пытается получить ниспадающее меню для переключения к следующему варианту, который имеет данные завершенной = ложныйСледующая выбрать вариант, соответствующий фильтр

<select id="selectionChamp"> 
<optgroup label="1"> 
    <option data-completed=true selected>Text 1</option> 
</optgroup> 
<optgroup label="2"> 
    <option data-completed=true>Text 2</option> 
</optgroup> 
<optgroup label="3"> 
    <option data-completed=true>Text 3</option> 
</optgroup> 
<optgroup label="45"> 
    <option data-completed=false>Text 4</option> 
    <option data-completed=false>Text 5</option> 
</optgroup> 
</select> 

<input type="button" id="fieldNext" value="Next"> 

Javascript:

$("#fieldNext").click(function() { 
    var $selected = $("option:selected"); 
    var filter = "[data-completed!=true]"; 
    $selected.attr("data-completed", true).prop("selected", false); 
    var $next = $selected.next("option"+ filter); 
    if ($next.length === 0) { 
     $next = $selected.parent("optgroup").next("optgroup:has(option"+ filter+")").find("option"+ filter+":first"); 
    } 
    $next.prop("selected", true); 
}); 

См: http://jsfiddle.net/w9kcd/105/

Я получил это работает, когда filter = "";, но не тогда, когда filter = "[data-completed!=true]";

Он должен начинаться с 1 и перейти к 4, затем 5, пропуская 2 и 3.

ответ

1

Метод next просто выбирает следующего непосредственного родственника элемента. Если вы передадите ему фильтр, он будет выбирать следующий ближайший родной брат только и только в том случае, если он соответствует указанному селектору. Он не работает, пока не найдет соответствующий элемент. Альтернативным методом является nextAll, который делает это, но следующие целевые элементы не являются братьями и сестрами исходного элемента. Вы могли бы начать с родителя выбранного элемента, а затем использовать селектор :has для нахождения optgroup S, которые имеют ожидаемые дети, но лучше/более эффективный вариант:

var $options = $("#selectionChamp option"); 

$("#fieldNext").click(function() { 
    var $selected = $("option:selected").attr("data-completed", 'true'); 
    // get the index of the current selected element 
    var i = $options.index($selected); 
    // find the first next matching element 
    // you can also pass a string to the filter method: `[data-completed!="true"]` 
    var $next = $options.slice(i /* + 1 */).filter(function() { 
     return this.getAttribute('data-completed') !== "true"; 
    }).eq(0).prop("selected", true); 
}); 

Here вы можете найти демо на jsfiddle. сеть.

Смежные вопросы