Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Обработка чекбоксов, радио-кнопок, и селектов (https://javascript.ru/forum/dom-window/56415-obrabotka-chekboksov-radio-knopok-i-selektov.html)

dpts 15.06.2015 07:51

Обработка чекбоксов, радио-кнопок, и селектов
 
Есть форма, позволяющая указать состав изделия и материалы для каждой детали, условно выглядит так:
<form name="zakaz">
Жилет меховой:&nbsp;<input name="isdel" type="text" size="4" value="3">&nbsp;шт.
<table>
	<tr>
		<td>
			Рукав левый 
				<div style="float: right;width: 20px;">
					<input name="detail" type="checkbox" checked value="1">
				</div>
		</td>
		<td>
			<select name="material">
				<option value="1">Кожа</option>
				<option value="2">Мех</option>
				<option value="3">Ткань</option>
			</select>
		</td>
	</tr>
	<tr>
		<td>
			Рукав правый
				<div style="float: right;width: 20px;">
					<input name="detail" type="checkbox" checked value="2">
				</div>
		</td>
		<td>
			<select name="material">
				<option value="1">Кожа</option>
				<option value="2">Мех</option>
				<option value="3">Ткань</option>
			</select>
		</td>
	</tr>
	<tr>
		<td>
			<b>Застежка молния</b>
				<div style="float: right;width: 20px;">
					<input name="detailmod" type="radio" checked value="4">
				</div>
				<div style="float: right;width: 20px;">
					<input name="detail" type="checkbox" checked value="3">
				</div>
				<table>
					<tr>
						<td>
							Пуговицы
							<div style="float: right;width: 20px;">
								<input name="detailmod" type="radio" checked value="5">
							</div>
						</td>
					</tr>
					<tr>
						<td>
							Кнопки
							<div style="float: right;width: 20px;">
								<input name="detailmod" type="radio" checked value="6">
							</div>
						</td>
					</tr>
				</table>
		</td>
		<td>
			<select name="material">
				<option value="1">Пластик</option>
				<option value="2">Металл</option>
				<option value="3">Дерево</option>
			</select>
		</td>
	</tr>
</table>
<br>
<center><input type="submit" value="Далее"></center>
</form>


Форма позволяет пользователю указать какие части изделия он хочет заказать, в каком варианте (радиокнопки про застежку молнию/пуговицы/кнопки) и из какого материала каждая деталь, а какие он заказывать не хочет. По умолчанию выставлена полная комплектация (чекбоксы включены).

Когда все чекбоксы включены, - форма передает обработчику парные данные: Деталь/Материал (количество переданных обработчику detail равно количеству material), соответственно обработчиком можно посчитать пары и запихать их в массив не особо раздумывая.

Если, допустим, один из чекбоксов отключить, то обработчику передастся на 1 detail меньше чем количество material. Обработчик получит 2 шт. detail и 3 шт. material, соответственно загнать эти данные в массив, простым циклом не получится, без смещения материалов относительно деталей.

В связи с этим вопрос. Раз при отключенном чекбоксе обработчику не передается соответствующий detail, как сделать, чтобы и соответствующий этому detail material тоже не передавался, и кол-во переданных detail всегда равнялось кол-ву переданных material?

dpts 15.06.2015 08:46

upd предыдущего
 
Как вариант, как сделать чтобы если чекбокс включен его value равнялось указанному, а если выключен - его value равнялось нулю?

Sigizmund2012 15.06.2015 08:51

Цитата:

Сообщение от dpts (Сообщение 375106)
Как вариант, как сделать чтобы если чекбокс включен его value равнялось указанному, а если выключен - его value равнялось нулю?

if (!checkbox.checked) {
        checkbox.value = 0;
    }

dpts 15.06.2015 08:55

Цитата:

Сообщение от Sigizmund2012 (Сообщение 375107)
if (!checkbox.checked) {
        checkbox.value = 0;
    }

А можно подробнее? Я практически полный ноль в JS.

Sigizmund2012 15.06.2015 08:59

dpts,
Этот блок кода проверяет, отмечен чекбокс или нет, и если нет, задаёт ему value = 0. Стандартная синтаксическая конструкция для любого языка.

dpts 15.06.2015 09:02

Цитата:

Сообщение от Sigizmund2012 (Сообщение 375110)
dpts,
Этот блок кода проверяет, отмечен чекбокс или нет, и если нет, задаёт ему value = 0. Стандартная синтаксическая конструкция для любого языка.

Это понятно. В какое место его - этот блок кода засадить?
Можно как-то на примере приведенной выше формы?

Sigizmund2012 15.06.2015 10:07

dpts,
Типа того:
var form = document.getElementsByName('zakaz')[0];

form.onsubmit = function (e) {
    var checkboxes = form.querySelectorAll('input[type="checkbox"]');
    for (var i = 0; i < checkboxes.length; i++) {
        if (!checkboxes[i].checked) {
        checkboxes[i].value = '0';
        }
    }
};

У вас сама форма странная какая-то, атрибут name у инпутов должен быть уникальным, исключая радиокнопки.

dpts 15.06.2015 10:20

Цитата:

Сообщение от Sigizmund2012 (Сообщение 375113)
У вас сама форма странная какая-то, атрибут name у инпутов должен быть уникальным, исключая радиокнопки.

уникальным? хм, это может сработать на изделиях у которых одинаковое количество деталей, но когда деталей у каждого изделия разное количество, - проще обрабатывать одинаковые name, мне так кажется.

dpts 15.06.2015 10:22

Добавил перед формой:
<script type="text/javascript">
var form = document.getElementsByName('zakaz')[0];

form.onsubmit = function (e) {
    var checkboxes = form.querySelectorAll('input[type="checkbox"]');
    for (var i = 0; i < checkboxes.length; i++) {
        if (!checkboxes[i].checked) {
        checkboxes[i].value = '0';
        }
    }
};
</script>


Не помогло, также если чекбокс отключаешь, уменьшается количество detail.

Sigizmund2012 15.06.2015 10:31

Цитата:

Сообщение от dpts (Сообщение 375117)
уникальным? хм, это может сработать на изделиях у которых одинаковое количество деталей, но когда деталей у каждого изделия разное количество, - проще обрабатывать одинаковые name, мне так кажется.

Это не вопрос предпочтений или конкретно вашей формы. Так должно быть по стандарту, данные отправляются на сервер в виде name&value. Как серверный скрипт корректно вашу форму обработает, если у вас name одинаковый? http://htmlbook.ru/html/input/name

dpts 15.06.2015 10:38

Цитата:

Сообщение от Sigizmund2012 (Сообщение 375119)
Это не вопрос предпочтений или конкретно вашей формы. Так должно быть по стандарту, данные отправляются на сервер в виде name&value. Как серверный скрипт корректно вашу форму обработает, если у вас name одинаковый? http://htmlbook.ru/html/input/name

Ну вообще-то серверный скрипт (asp+vbscript) спокойно считает количество переданных ему detail-ов и может обратиться к каждому detail, как к элементу массива (тоже самое с material-ами).
По-этому мне и надо, чтобы detail-ов было столькоже, сколько и material-ов.

Sigizmund2012 15.06.2015 10:46

Цитата:

Сообщение от dpts
если чекбокс отключаешь, уменьшается количество detail

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

dpts 15.06.2015 10:50

Цитата:

Сообщение от Sigizmund2012 (Сообщение 375122)
Вот тут ничего конкретного не могу сказать, возможно если чекбокс не отмечен, его значение вообще на сервер не отправляется.

Похоже на то.

вот тогда и вопрос, как если чекбокс отключен, то соответствующий ему material тоже не отправлять на сервер, чтобы на червер приходили одинаковые количества detail и material&

dpts 15.06.2015 10:55

Еще вариант как передавать одинаковое количество
 
Еще, как вариант выхода
к каждому checkbox приделать input type="hidden" value="..."

и в зависимости от состояния соответствующего чекбокса менять value у hidden и на сервере обрабатывать массив hidden-ов.

Вотпрос, как менять value у hidden-ов?

Sigizmund2012 15.06.2015 11:14

Цитата:

Сообщение от dpts
Вотпрос, как менять value у hidden-ов?

Так же как и у не скрытых, например отсеять по querySelectorAll('input[type="hidden"]') и в цикле изменить checkboxes[i].value = 'true';

Sigizmund2012 15.06.2015 11:22

http://www.askdev.ru/question/3943/%...cked-checkbox/

dpts 15.06.2015 12:02

Цитата:

Сообщение от Sigizmund2012 (Сообщение 375126)

Если чекбокс отмечен, - отправляются 2 значения, и из чекбокса и из хиддена.

Мне предложили вроде рабочее решение, выглядит так:
var details = zakaz.detail;
for (var i = 0; i < details.length; i++) {
    details[i].addEventListener('change', function () {
        var td = closest(this, function (el) {
            return el.tagName.toLowerCase() == 'td';
        });
        var material = td.nextElementSibling.querySelector('[name=material]');
        material.disabled = !this.checked;
    }, false);
}

function closest(el, fn) {
    while (el) {
        if (fn(el)) return el;
        el = el.parentNode;
    }
}

Если отключается чекбокс, отключается и material. вроде все хорошо, все работает (чекбокс - не передается, материал - тоже не передается). Но сразу не подумал.
Обработчику же должен передаваться массив из detail-ов, detailmod-ов, material-ов.
Поэтому пришлось к левому и правому рукавам добавить еще input type="hidden" name="detailmod" value="0".

Как надо дописать приведенный JS, чтобы он еще и detailmod не передавал?


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