Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Не выбирается нужный option в select (https://javascript.ru/forum/misc/72845-ne-vybiraetsya-nuzhnyjj-option-v-select.html)

the_little 02.03.2018 14:25

Не выбирается нужный option в select
 
Здравствуйте.

Что-то я совсем не пойму как должна выглядеть структура скрипта в плане объявления функций...

У меня идет
$(document).ready(function() {

Потом я объявляю основные переменные с которыми буду работать
var amount 				= $('select[name=amount]').val();
	var srochnost 		= $('select[name=srochnost]').val(); 			// 1 - срочный, 2 - с проживанием
	var rejim 				= $('select[name=rejim]').val();					// 1 - дневной, 2 - ночной, 3 - суточный
	var skolko_chasov = $('select[name=skolko_chasov]').val();
	var skolko_dnej 	= $('select[name=skolko_dnej]').val();
	var mesto 				= $('select[name=mesto]').val();					// 1 - стационар, 2 - на дому
	var samoobsluj		= $('select[name=samoobsluj]').val();			// 1 - сам, 2 - частично, 3 - полностью
	var fiz_active 		= $('select[name=fiz_active]').val();			// 1 - ходит, 2 - сидит, 3 - лежит
	var ves 					= $('select[name=ves]').val();


Потом идет функция которая должна убирать несколько вариантов из селекта №3 в зависимости от того что выбрано Селекте №2.

$("#srochnost").bind("keyup change", function() {
		var srochnost 		= $('select[name=srochnost]').val(); 			// 1 - срочный, 2 - с проживанием
		var rejim 				= $('select[name=rejim]').val();					// 1 - дневной, 2 - ночной, 3 - суточный


		// Прописываем условия по которым часть опций скрывается либо проставляется автоматически

			if ( srochnost == 2 ) {
				$('#rejim-opt-null').fadeOut();
				$('#rejim-opt-day').fadeOut();
				$('#rejim-opt-night').fadeOut();
				$("#rejim [value='3']").attr("selected", "selected");
				rejim = 3;
			} else {
				$('#rejim-opt-null').fadeIn();
				$('#rejim-opt-day').fadeIn();
				$('#rejim-opt-night').fadeIn();
				$("#rejim [value='0']").attr("selected", "selected");
				rejim = 0;
			}

Тут приходится снова объявлять те переменные что были объявлены в самом начале...

В одну сторону все работает. А вот когда в селекте 2 значение меняется на отличное от 2, то в селекте 3 остается активным пункт 3. В чем проблема?

laimas 02.03.2018 14:50

selected - это не атрибут, это свойство, то что задать выбор опции указав этот атрибут, не делает его атрибутом в полной мере.

$("#rejim [value='3']").prop("selected", true или 1 или что угодно что вернет булево значение true, хоть такое "qwerty");

Цитата:

Сообщение от the_little
Тут приходится снова объявлять те переменные что были объявлены в самом начале...

Зачем?

the_little 02.03.2018 14:57

Цитата:

Сообщение от laimas (Сообщение 479570)
Зачем?

Ну получается внутри это функции
$("#srochnost").bind("keyup change", function() {

она не понимает что такое переменные есть
srochnost
и rejim

т.е. если я их оттуда удаляю, то ничего не работает...

the_little 02.03.2018 15:03

Сделал так.
if ( srochnost == 2 ) {
				$('#rejim-opt-null').fadeOut();
				$('#rejim-opt-day').fadeOut();
				$('#rejim-opt-night').fadeOut();
				$("#rejim [value='3']").prop("selected", "true");				
			} else {
				$('#rejim-opt-null').fadeIn();
				$('#rejim-opt-day').fadeIn();
				$('#rejim-opt-night').fadeIn();
				$("#rejim [value='0']").prop("selected", "true");
			}


работает, но через шаг...
Т.е. когда srochnost == 2 выбирает нужный пункт, делает его активным, но значение остается = 0.
А когда я переключаю первый селектор на 1, то сбрасывается во втором селект, как и должен, но значение как раз устанавливается 3.

Проверяю я это через
console.log("Количество " + amount + "\n" +
								"Срочность " + srochnost + "\n" +
								"Режим " + rejim + "\n" +
								"Часов " + skolko_chasov + "\n" +
								"Дней " + skolko_dnej + "\n" +
								"Место " + mesto + "\n" +
								"Самообслуживание " + samoobsluj + "\n" +
								"Физактив. " + fiz_active + "\n" +
								"Вес " + ves);

laimas 02.03.2018 15:06

Что такое #srochnost? Если это список, то какой смысл в keyup?

Цитата:

Сообщение от the_little
она не понимает что такое переменные есть
srochnost
и rejim

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(function() {
    var a = 1, b = 2;
    $('select').on('change', function() {
        alert(a)
    })
});
</script>
<select>
    <option value="1">aaa</option>
    <option value="2">bbb</option>
</select>


Естественно в обработчике будут доступны и а, и b, ибо они глобальные. Чего-то вы не досказываете.

laimas 02.03.2018 15:12

Цитата:

Сообщение от the_little
$("#rejim [value='3']").prop("selected", "true"); 

$("#rejim [value='3']").prop("selected", true); - это булево значение, а не строковое.

Механика происходящего здесь prop("selected", true):

prop("selected", Boolean(указанное значение)), и не пустая строка конечно вернет true.

the_little 02.03.2018 15:27

<script>$(document).ready(function() {

	// Объявляем переменные по первому шагу формы

	var amount 				= $('select[name=amount]').val();
	var srochnost 		= $('select[name=srochnost]').val(); 			// 1 - срочный, 2 - с проживанием
	var rejim 				= $('select[name=rejim]').val();					// 1 - дневной, 2 - ночной, 3 - суточный
	var skolko_chasov = $('select[name=skolko_chasov]').val();
	var skolko_dnej 	= $('select[name=skolko_dnej]').val();
	var mesto 				= $('select[name=mesto]').val();					// 1 - стационар, 2 - на дому
	var samoobsluj		= $('select[name=samoobsluj]').val();			// 1 - сам, 2 - частично, 3 - полностью
	var fiz_active 		= $('select[name=fiz_active]').val();			// 1 - ходит, 2 - сидит, 3 - лежит
	var ves 					= $('select[name=ves]').val();


	$("#srochnost").bind("keyup change", function() {

		var srochnost 		= $('select[name=srochnost]').val(); 			// 1 - срочный, 2 - с проживанием
		var rejim 				= $('select[name=rejim]').val();					// 1 - дневной, 2 - ночной, 3 - суточный

		// Прописываем условия по которым часть опций скрывается либо проставляется автоматически

			if ( srochnost == 2 ) {
				$('#rejim-opt-null').fadeOut();
				$('#rejim-opt-day').fadeOut();
				$('#rejim-opt-night').fadeOut();
				$("#rejim [value='3']").prop("selected", "3");
			} else {
				$('#rejim-opt-null').fadeIn();
				$('#rejim-opt-day').fadeIn();
				$('#rejim-opt-night').fadeIn();
				$("#rejim [value='0']").prop("selected", "0");
			}


		console.log("Количество " + amount + "\n" +
								"Срочность " + srochnost + "\n" +
								"Режим " + rejim + "\n" +
								"Часов " + skolko_chasov + "\n" +
								"Дней " + skolko_dnej + "\n" +
								"Место " + mesto + "\n" +
								"Самообслуживание " + samoobsluj + "\n" +
								"Физактив. " + fiz_active + "\n" +
								"Вес " + ves);
	});

});</script>

                        <select class="form-control" name="srochnost" id="srochnost">
                          <option value="0">Выбрать...</option>
                          <option value="1">Срочный</option>
                          <option value="2">С проживанием</option>
                        </select>

                        <select class="form-control" name="rejim" id="rejim">
                          <option id="rejim-opt-null" value="0">Выбрать...</option>
                          <option id="rejim-opt-day" value="1">Дневной</option>
                          <option id="rejim-opt-night"value="2">Ночной</option>
                          <option id="rejim-opt-sutki" value="3">Суточный</option>
                        </select>

laimas 02.03.2018 15:32

Это

$("#srochnost").bind("keyup change", function() {
var srochnost = $('select[name=srochnost]').val();

мягко выражаясь глупость - в обработчике обращаться к самому себе через свое имя.

$("#srochnost").on("keyup change", function() {
alert(this.value); //а не $('select[name=srochnost]').val();

the_little 02.03.2018 15:40

И так не отрабатывает. Значение в 3-ем селекте просто не меняется и все.
$(function() {

	var amount 				= $('select[name=amount]').val();
	var srochnost 		= $('select[name=srochnost]').val(); 			// 1 - срочный, 2 - с проживанием
	var rejim 				= $('select[name=rejim]').val();					// 1 - дневной, 2 - ночной, 3 - суточный

	$("#srochnost").on("change", function() {

			if ( srochnost == 2 ) {
				$('#rejim-opt-null').fadeOut();
				$('#rejim-opt-day').fadeOut();
				$('#rejim-opt-night').fadeOut();
				$("#rejim [value='3']").prop("selected", "3");
			} else {
				$('#rejim-opt-null').fadeIn();
				$('#rejim-opt-day').fadeIn();
				$('#rejim-opt-night').fadeIn();
				$("#rejim [value='0']").prop("selected", "0");
			}


		console.log("Количество " + amount + "\n" +
								"Срочность " + srochnost + "\n" +
								"Режим " + rejim + "\n" +
								"Часов " + skolko_chasov + "\n" +
								"Дней " + skolko_dnej + "\n" +
								"Место " + mesto + "\n" +
								"Самообслуживание " + samoobsluj + "\n" +
								"Физактив. " + fiz_active + "\n" +
								"Вес " + ves);
	});

});

laimas 02.03.2018 15:43

Цитата:

Сообщение от the_little
Значение в 3-ем селекте просто не меняется и все.

В каком третьем ? Чего вообще нужно сделать, словами опишите.

Это что-ли $("#rejim [value='3']").prop("selected", "3"); 3-й селект?

Это глупость, сколько раз можно говорить?

the_little 02.03.2018 15:43

Если я внутри
$("#srochnost").on("change", function() {

напишу
alert(srochnost);
то он сработает.
А вот IF отработает, только если я снова задам переменные... Те же, что уже заданы.

the_little 02.03.2018 15:46

конкретно сейчас решается следующая задача.
Есть внешняя функция, в которой объявлены переменные (чекбоксы и селекты)
Есть внутренняя функция, которая говорит следующее
Если в первом селекте выбрана опция №2, то во втором селекте может быть только опция №3 доступна.

the_little 02.03.2018 15:48

$(function() {
	var srochnost 		= $('select[name=srochnost]').val(); 			// 1 - срочный, 2 - с проживанием
	var rejim 				= $('select[name=rejim]').val();					// 1 - дневной, 2 - ночной, 3 - суточный

	$("#srochnost").on("change", function() {

			if ( srochnost == 2 ) {
				$('#rejim-opt-null').fadeOut();
				$('#rejim-opt-day').fadeOut();
				$('#rejim-opt-night').fadeOut();
				$("#rejim [value='3']").prop("selected", "3");
			} else {
				$('#rejim-opt-null').fadeIn();
				$('#rejim-opt-day').fadeIn();
				$('#rejim-opt-night').fadeIn();
				$("#rejim [value='0']").prop("selected", "0");
			}
	});
});

laimas 02.03.2018 15:56

Может проще:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(function() {
    $('#srochnost').on('change', function() {
        if(!this.value) return;
        $('#rejim option').slice(0, -1)
                          .prop('disabled', this.value==2)
                          .end()
                          .eq(3)
                          .prop('selected', this.value==2)
    })
});
</script>

<select class="form-control" name="srochnost" id="srochnost">
    <option value="" disabled>Выбрать...</option>
    <option value="1">Срочный</option>
    <option value="2">С проживанием</option>
</select>
 
<select class="form-control" name="rejim" id="rejim">
    <option id="rejim-opt-null" value="">Выбрать...</option>
    <option id="rejim-opt-day" value="1">Дневной</option>
    <option id="rejim-opt-night"value="2">Ночной</option>
    <option id="rejim-opt-sutki" value="3">Суточный</option>
</select>

the_little 02.03.2018 16:17

Визуально - работает.
Но при попытке алертом выдать значения двух этих селектов - выдает 0 и 0 при любом раскладе.

$(function() {

	var srochnost 		= $('select[name=srochnost]').val(); 		
	var rejim 			= $('select[name=rejim]').val();					

	$('#srochnost').on('change', function() {
	        if(!this.value) return;
	        $('#rejim option').slice(0, -1)
	                          .prop('disabled', this.value==2)
	                          .end()
	                          .eq(3)
	                          .prop('selected', this.value==2)
				
alert(srochnost + " " + rejim)

	});

});

laimas 02.03.2018 16:19

Каким алертом, чего и зачем?

PS. Зачем вообще это нужно?

var srochnost = $('select[name=srochnost]').val();
var rejim = $('select[name=rejim]').val();

И почему тогда не

var srochnost = $('#srochnost').val();
var rejim = $('#rejim').val();

?

А "при любом раскладе" потому, что эти значения были получены до изменения состояния списков, и их никто не изменял.

the_little 02.03.2018 17:11

что-то я не догоняю.

Есть селект. При выборе опции ему присваивается значение определенное.
Мне нужно с этими селектами работать дальше. Нужны их значения.

Я объявляю переменную и получаю значение нужного селекта. И это всегда работает без проблем. 20 селектов - я спокойно получаю 20 значений и делаю с ними дальше то что мне нужно.

А как только появляется эта функция, которая отвечает за скрытие и открытие не нужных опций - то я уже не получаю их значения...

точнее получаю нули в обоих списках. Как с ними дальше то работать.

Объявлена переменная
var srochnost = $('select[name=srochnost]').val();

потом проходят манипуляции со списками.

и я получаю всегда значение var srochnost = 0. Алерт я объявляю после того как прошли все изменения, а все равно ноль выводит.

j0hnik 02.03.2018 17:14

val надо получать каждый раз внутри функции с обработчиком change, а не один раз при загрузке

the_little 02.03.2018 17:16

Спасибо!
с переменными разобрался. все сводится к тому чтобы их по новой прописывать внутри каждой функции.

laimas 02.03.2018 17:17

the_little,
j0hnik, уже написал, но учтите, что изменение состояние списка не обязательно произойдет, поэтому в вашей задаче, может лучше опрашивать сами списки, получая их значения?

PS. И запомните и .prop("selected", "3"), и .prop("selected", "0") выберет указанную опцию, ибо и "3", и "0" вернет true, так как это строковое значение и не пустое.

the_little 02.03.2018 17:28

Цитата:

Сообщение от laimas (Сообщение 479611)
the_little,
j0hnik, уже написал, но учтите, что изменение состояние списка не обязательно произойдет, поэтому в вашей задаче, может лучше опрашивать сами списки, получая их значения?

т.е. мне нужно местами поменять все.

Сначала пойдут функции которые будут отвечать за поведение списков.

И уже после всех этих функций, я задаю переменные и получаю значения списков. Так?

А по коду подскажите еще
$('#srochnost').on('change', function() {
	        if(!this.value) return;
	        $('#rejim option').slice(0, -1)
	                          .prop('disabled', this.value==2)
	                          .end()
	                          .eq(3)
	                          .prop('selected', this.value==2)
					
});


Тут мы для опции 2 в первом списке подставляли опцию 3 во втором списке.

Если немного изменить задачу.

При выборе опции 2 в первом списке во втором нужно оставить например опции с value равным 5, 6, 7, 9, 13.
При выборе опции 3 в первом списке во втором нужно оставить например опции с value равным 1,2,3,8,12.

При этом опцию во втором списке подставлять и выбирать по умолчанию не нужно.

laimas 02.03.2018 17:49

Цитата:

Сообщение от the_little
А по коду подскажите еще

А что по нему подсказать? Здесь согласно условию вами описанному становятся доступными/недоступными для выбора соответствующие списки. Ведь то, что у вас

$('#rejim-opt-null').fadeOut();
$('#rejim-opt-day').fadeOut();
$('#rejim-opt-night').fadeOut();

и что можно написать проще:

$('#rejim-opt-null,#rejim-opt-day,#rejim-opt-night').fadeOut();

лишено смысла, так как всех этих эффектов пользователь все равно не увидит. Тогда уж просто css({dispalay: 'none/block'}).

Что касается каких-то сложных условий, как то при выборе второго списка скрыть 5, 6, 7, 9, 13, а третьего 1,2,3,8,12, то лучше эти параметры задать через атрибут. При выборе получать эти значения и скрывать указанные опции.

PS. Например так:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(function() {
    $('#a').on('change', function() {
        var o = $(this).children(':selected').data('mod');
        $('#b').val('')
               .find('option')
               .show()
               .filter('[value='+o.join('],[value=')+']')
               .hide()
    })
});
</script>

<select id="a">
    <option value="" selected disabled>Select...</option>
    <option data-mod="[2,5,7,9]" value="1">Option 1</option>
    <option data-mod="[3,4,6,8,9]" value="2">Option 2</option>
</select>
 
<select id="b">
    <option value="">Select...</option>
    <option value="1">Option 1</option>
    <option value="2">Option 2</option>
    <option value="3">Option 3</option>
    <option value="4">Option 4</option>
    <option value="5">Option 5</option>
    <option value="6">Option 6</option>
    <option value="7">Option 7</option>
    <option value="8">Option 8</option>
    <option value="9">Option 9</option>
</select>

the_little 02.03.2018 21:25

Цитата:

Сообщение от laimas (Сообщение 479620)

Что касается каких-то сложных условий, как то при выборе второго списка скрыть 5, 6, 7, 9, 13, а третьего 1,2,3,8,12, то лучше эти параметры задать через атрибут. При выборе получать эти значения и скрывать указанные опции.

PS. Например так:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(function() {
    $('#a').on('change', function() {
        var o = $(this).children(':selected').data('mod');
        $('#b').val('')
               .find('option')
               .show()
               .filter('[value='+o.join('],[value=')+']')
               .hide()
    })
});
</script>

<select id="a">
    <option value="" selected disabled>Select...</option>
    <option data-mod="[2,5,7,9]" value="1">Option 1</option>
    <option data-mod="[3,4,6,8,9]" value="2">Option 2</option>
</select>
 
<select id="b">
    <option value="">Select...</option>
    <option value="1">Option 1</option>
    <option value="2">Option 2</option>
    <option value="3">Option 3</option>
    <option value="4">Option 4</option>
    <option value="5">Option 5</option>
    <option value="6">Option 6</option>
    <option value="7">Option 7</option>
    <option value="8">Option 8</option>
    <option value="9">Option 9</option>
</select>

То что нужно! Только у меня не работает... В смысле тут не работает.

laimas 03.03.2018 01:58

Цитата:

Сообщение от the_little
В смысле тут не работает.

Код по запуску кнопкой "Просмотреть"? Он и в цитировании (чего не надо делать) работает. Нет в нем чего-то, что вызывало бы проблемы.

Фильтр лучше бы было задать так:

.filter(function() {
     return ~o.indexOf(+this.value)
     //или если с поддержкой IE8, то можно средствами JQ
     //return ~$.inArray(+this.value, o)
})


Часовой пояс GMT +3, время: 01:17.