Свързани SELECTS

xlebabarov

Registered
Здравейте, как мога да използвам два свързани селекта кода ми е следният:
Код:
<select name="website"><option value="1">Global</option>
<option value="2">Desita</option>
<option value="3">Pro-Sdelka</option>
</select>

Съответно Глобал да отваря този код:
Код:
<select name="product"><option id="1">Първа стока от Global</option>
<option id="2">Втора стока от Global</option>
<option id="3">Трета стока от Global</option>
</select>

Съответно Desita да отваря този код:
Код:
<select name="product"><option id="4">Първа стока от Desita</option>
<option id="5">Втора стока от Desita</option>
<option id="6">Трета стока от Desita</option>
</select>

Съответно Pro-Sdelka да отваря този код:
Код:
<select name="product"><option id="7">Първа стока от Pro-Sdelka</option>
<option id="8">Втора стока от Pro-Sdelka</option>
<option id="9">Трета стока от Pro-Sdelka</option>
</select>
 
Например така.

Код:
<form>

    <select name="website" id="main" onchange="mainChange()">
        <option value="1">Global</option>
        <option value="2">Desita</option>
        <option value="3">Pro-Sdelka</option>
    </select>

    <select name="product" id="sub"></select>

</form>

<script>

    function mainChange() {

        var val = document.getElementById("main").value;
        var sub = document.getElementById("sub");

        if (val === "1") {
            sub.innerHTML =
                "<option id='1'>Първа стока от Global</option>" +
                "<option id='2'>Втора стока от Global</option>" +
                "<option id='2'>Трета стока от Global</option>";
        }

        if (val === "2") {
            sub.innerHTML =
                "<option id='4'>Първа стока от Desita</option>" +
                "<option id='5'>Втора стока от Desita</option>" +
                "<option id='6'>Трета стока от Desita</option>";
        }

        if (val === "3") {
            sub.innerHTML =
                "<option id='7'>Първа стока от Pro-Sdelka</option>" +
                "<option id='8'>Втора стока от Pro-Sdelka</option>" +
                "<option id='9'>Трета стока от Pro-Sdelka</option>";
        }
    }

    if (mainChange() === false) {
        sub.innerHTML =
            "<option id='1'>Първа стока от Global</option>" +
            "<option id='2'>Втора стока от Global</option>" +
            "<option id='2'>Трета стока от Global</option>";
    }

</script>
 
Аз бих препоръчал селектите да живеят в хтмл сорса и показването да се управлява чрез css display: none/block. Option-ите ще имат data-target атрибут, който ще е връзката с id-то на съответстващия субселект. Нямам възможност да пиша код в момента - ако на някого му се занимава, нека имплементира идеята.
 
anonimen каза:
Аз бих препоръчал селектите да живеят в хтмл сорса и показването да се управлява чрез css display: none/block. Option-ите ще имат data-target атрибут, който ще е връзката с id-то на съответстващия субселект. Нямам възможност да пиша код в момента - ако на някого му се занимава, нека имплементира идеята.

Аз бих опитал, обаче не ми е ясен този data-target атрибут. Това не е ли нещо от bootstrap? Също така не е ли по-добре връзката с id-то на съответстващия субселект да са id-та на option-ите? Какво е предимството на този data-target атрибут?
 
teroristd каза:
anonimen каза:
Аз бих препоръчал селектите да живеят в хтмл сорса и показването да се управлява чрез css display: none/block. Option-ите ще имат data-target атрибут, който ще е връзката с id-то на съответстващия субселект. Нямам възможност да пиша код в момента - ако на някого му се занимава, нека имплементира идеята.

Аз бих опитал, обаче не ми е ясен този data-target атрибут. Това не е ли нещо от bootstrap? Също така не е ли по-добре връзката с id-то на съответстващия субселект да са id-та на option-ите? Какво е предимството на този data-target атрибут?

Optionите на главния селект не могат да имат същите id-та като субселектите, защото id-тата в един документ трябва да са уникални. А с класове не е добра идея, защото може по случайност да ползваш същия клас някъде другаде в страницата и да се приложи нежелан стил върху селектите.

А атрибутът data-target е съвсем фиктивен и няма нищо общо с bootstrap, освен че библиотеката използва това име за някакви цели. Data-* атрибутите в html ти дават място да запишеш допълнителна информация за даден елемент, която иначе не би била подходяща за id/class или други стандартни атрибути на съответния елемент.
Google for "html data attributes".
 
Успях да скалъпя някакъв код с data-target атрибут който работи, само че не не сменям css-a a направо класовете, но то е същото :).

Код:
<style>
    .sub-1 {
        display: none;
    }

    .sub-1-active {
        display: block;
    }

    .sub-2 {
        display: none;
    }

    .sub-2-active {
        display: block;
    }

    .sub-3 {
        display: none;
    }

    .sub-3-active {
        display: block;
    }
</style>

<form>

    <select name="website" id="main" onchange="mainChange()">
        <option data-target="sub-1">Global</option>
        <option data-target="sub-2">Desita</option>
        <option data-target="sub-3">Pro-Sdelka</option>
    </select>

    <select name="product" class="sub-1">
        <option>Първа стока от Global</option>
        <option>Втора стока от Global</option>
        <option>Трета стока от Global</option>
    </select>

    <select name="product" class="sub-2">
        <option>Първа стока от Desita</option>
        <option>Втора стока от Desita</option>
        <option>Трета стока от Desita</option>
    </select>

    <select name="product" class="sub-3">
        <option>Първа стока от Pro-Sdelka</option>
        <option>Втора стока от Pro-Sdelka</option>
        <option>Трета стока от Pro-Sdelka</option>
    </select>

</form>

<script>

$('.sub-1').removeClass('sub-1').addClass('sub-1-active');

function mainChange() {

    var element = $('#main').find('option:selected');
    var data = element.attr("data-target");

    if (data == 'sub-1') {
        $('.sub-1').removeClass('sub-1').addClass('sub-1-active');
    }
    else {
        $('.sub-1-active').removeClass('sub-1-active').addClass('sub-1');
    }

    if (data == 'sub-2') {
        $('.sub-2').removeClass('sub-2').addClass('sub-2-active');
    }
    else {
        $('.sub-2-active').removeClass('sub-2-active').addClass('sub-2');
    }

    if (data == 'sub-3') {
        $('.sub-3').removeClass('sub-3').addClass('sub-3-active');
    }
    else {
        $('.sub-3-active').removeClass('sub-3-active').addClass('sub-3');
    }

}

</script>
 
Не си ми разбрал идеята поначало :)

В момента, както и в първия код, който даде, ръчно описваш всички селекти. Ако първият селект има 10 опции, то ще трябва да копираш проверката 10 пъти. Ако искаш да направиш 2-3 под-групи, става 10^3=1000 случая. И ти искаш да ги опишеш всичките :D

Вместо това, използвай htmlа, за да запишеш връзката межди селектите. Както си започнал - всяка опция държи в себе си връзка към селекта, който трябва да се активира. И вместо да изброяваш случаи, директно показваш (class=active примерно) селекта, до който води връзката.

Т.е. ако в дата-таргет записваш id, ще активираш селекта със съответното id. Динамично, без да изреждаш случаи.
 
anonimen каза:
Вместо това, използвай htmlа, за да запишеш връзката межди селектите. Както си започнал - всяка опция държи в себе си връзка към селекта, който трябва да се активира. И вместо да изброяваш случаи, директно показваш (class=active примерно) селекта, до който води връзката.

Т.е. ако в дата-таргет записваш id, ще активираш селекта със съответното id. Динамично, без да изреждаш случаи.

Честно казано не разбрах и сега какво имаш предвид :D. Ще трябва да дадеш примерен код.
 
Вместо да проверяваш всички възможности за data-target, директно извикай .show() върху елемента, съответстващ на data-targetа. Решението мога да дам веднага, но ще е по-продуктивно сам да се сетиш.
[js]
if (data == 'sub-1') {
$('.sub-1').removeClass('sub-1').addClass('sub-1-active');
}
else {
$('.sub-1-active').removeClass('sub-1-active').addClass('sub-1');
}

if (data == 'sub-2') {
$('.sub-2').removeClass('sub-2').addClass('sub-2-active');
}
else {
$('.sub-2-active').removeClass('sub-2-active').addClass('sub-2');
} [/js]

Не ти ли правят впечатление всичките повторения? И не ти ли прави впечатление, че сравнява data със стойност, която след това използваш точно 6 пъти? Нали е променлива, защо изписваш всичко на ръка - използвай директно променливата.
 
Това ли имаш предвид?

[js]
function mainChange() {
var element = $('#main').find('option:selected');
var data = element.attr("data-target");
$('.' + data).removeClass(data).addClass(data + '-active');
}
[/js][/php]
 
Сега разбираш ли защо :D

Сведе 25 реда функция до 3 :)

А сега и css-a изчисти. Имаш 6 класа за 3 опции. Про 10 опции ще трябва да поддържаш 20 класа.
 
Така обаче има два проблема :). Първият е че един път показан селекта не може да се скрие. Вторият е че няма дефаултов. Един вид главният селект стои на първата опция, а за да покажеш съответстващият му подселект, трябва първо да изберш някоя друга и пак да се върнеш на първата.

П.П.

Само xlebabarov нищо не казва по темата :D.
 
И двата проблема се решават супер лесно.

За първия - изключваш класа от единствения елемент, който го притежава. След това добавяш класа към избрания селект. Така винаги ще поддържаш само един включен.

За втория - в самия html задаваш "включено" за селекта, който искаш да се показва по дефолт.
 
anonimen каза:
И двата проблема се решават супер лесно.

За първия - изключваш класа от единствения елемент, който го притежава. След това добавяш класа към избрания селект. Така винаги ще поддържаш само един включен.

За втория - в самия html задаваш "включено" за селекта, който искаш да се показва по дефолт.

Без проверките които бях направил не открих решение на проблема.
 
1. При смяна на опцията, първо скриваш стария субселект:

[js]$('.subselect.active').removeClass('active');
[/js]
2. След това показваш новия:

[js]$('.subselect.' + data).addClass('active');
[/js]
3. На дефолтовия субселект слагаш active клас по default:

HTML:
<select class="subselect active">

Толкоз :wink:
 
Бях на бачкане и сега се върнах.. изглежда добре! Само където пробвах първия код и нещо нищо не изкарва подопциите въобще при смяна. Някъкви идеи? :cry:
 
Мда сега чатнах :D.
Не ми беше хрумнало класа да е разделен на повече нива (не знам как се нарича) този тип "subselect sub-1 active".
До сега при мен беше class="sub-1" и го сменях на class="sub-1-active" но така съм се ограничавал откъм опции.
 
Няма нужда от sub-1, sub-2, sub-3. Сложих някакъв .subselect клас за удобство, иначе може да минем само с .active.

Достатъчно е да групираш субселектите по някакъв удобен начин, за да можеш лесно да ги идентифицираш, примерно да ги сложи в някакъв елемент:

HTML:
<div id="subselect-container">


</div>

И сега можеш така:
[js]$('.subselect.active') -> $('#subselect-container .active')

$('.subselect.' + data) -> $('#subselect-container .' + data) [/js]

Така е малко по-ефективно, защото не преравяш цялата страница за субселектите, а търсиш направо там, където са.
 
xlebabarov каза:
Бях на бачкане и сега се върнах.. изглежда добре! Само където пробвах първия код и нещо нищо не изкарва подопциите въобще при смяна. Някъкви идеи? :cry:

Остави го първият код. Ето ти новият. Само трябва да си сложиш едно jQuery. Също ако искаш можеш да си го преправиш с div както е показал @anonimen.

Код:
<style>
        .subselect.active {
            display: block;
        }

        .subselect {
            display: none;
        }
</style>

Код:
<form>

    <select name="website" id="main" onchange="mainChange()">
        <option data-target="sub-1">Global</option>
        <option data-target="sub-2">Desita</option>
        <option data-target="sub-3">Pro-Sdelka</option>
    </select>

    <select name="product" class="subselect sub-1 active">
        <option>Първа стока от Global</option>
        <option>Втора стока от Global</option>
        <option>Трета стока от Global</option>
    </select>

    <select name="product" class="subselect sub-2">
        <option>Първа стока от Desita</option>
        <option>Втора стока от Desita</option>
        <option>Трета стока от Desita</option>
    </select>

    <select name="product" class="subselect sub-3">
        <option>Първа стока от Pro-Sdelka</option>
        <option>Втора стока от Pro-Sdelka</option>
        <option>Трета стока от Pro-Sdelka</option>
    </select>

</form>

Код:
<script>

    function mainChange() {

        var element = $('#main').find('option:selected');
        var data = element.attr("data-target");

        $('.subselect.active').removeClass('active');
        $('.subselect.' + data).addClass('active');

    }

</script>
 

Горе