Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Чекбокс (переключатель группы чекбоксов) (https://javascript.ru/forum/misc/8095-chekboks-pereklyuchatel-gruppy-chekboksov.html)

DVNSA 07.03.2010 21:25

Чекбокс (переключатель группы чекбоксов)
 
Есть группа из 3-х чекбоксов:

<input name="obl" type="checkbox" id="obl" value="1">ОБЛАСТЬ А<br>
<input name="gorod[]" type="checkbox" id="gorod[]" value="11">город Аа<br>
<input name="gorod[]" type="checkbox" id="gorod[]" value="12">город Аб<br>

Нужно: 1. чекбокс "obl" отмечает и снимает отметку у всех чекбоксов "gorod[]"
2. если отмечаются оба чекбокса "gorod[]" - отмечается автоматом "obl"
3. если снимается отметка хотя бы с одного чекбокса "gorod[]" - снимается отметка с чекбокса "obl"
Спасибо.

DVNSA 07.03.2010 21:43

PS. Естественно, чекбоксов будет значительно больше.

B@rmaley.e><e 07.03.2010 22:02

Цитата:

Сообщение от DVNSA
<input name="gorod[]" type="checkbox" id="gorod[]" value="11">город Аа<br>
<input name="gorod[]" type="checkbox" id="gorod[]" value="12">город Аб<br>

Идентификаторы не могут совпадать.

subzey 08.03.2010 16:00

Обычно я не пишу готовые скрипты в ответах, но этот случай мне почему-то приглянулся. :)

Во-первых, нужно немного изменить код, чтобы обычные и контрольный чекбоксы чем-то разделялись, я предлагаю использовать для этого связку fieldset — legend, ибо семантика. А уж стили на все это натянуть можно любые и при необходимости добавить другие элементы оформления. Главное — fieldset с классом "js-tree-box" (вдруг, в форме будут другие филдсеты) и легенда.

Код можно засунуть в head страницы — он будет послушно ждать, пока на странице появятся чекбоксы и пользователь их кликнет.
<fieldset class="js-tree-box">
	<legend>
		<label><input type="checkbox" name="obl[]" value="61" />Ростовская</label>
	</legend>
	<label><input type="checkbox" name="gorod[]" value="346780">Азов</label>
	<label><input type="checkbox" name="gorod[]" value="346400">Новочеркасск</label>
	<label><input type="checkbox" name="gorod[]" value="344000">Ростов-на-Дону</label>
	<label><input type="checkbox" name="gorod[]" value="347900">Таганрог</label>
</fieldset>
<fieldset class="js-tree-box">
	<legend>
		<label><input type="checkbox" name="obl[]" value="61" />Ростовская</label>
	</legend>
	<label><input type="checkbox" name="gorod[]" value="346780">Азов</label>
	<label><input type="checkbox" name="gorod[]" value="346400">Новочеркасск</label>
	<label><input type="checkbox" name="gorod[]" value="344000">Ростов-на-Дону</label>
	<label><input type="checkbox" name="gorod[]" value="347900">Таганрог</label>
</fieldset>
…и так далее.

<script>
(function(){ // этот кусок кода автономен, выносим в отдельную область данных
	function clicker(e){ // выполняется при любом кликие или изменении
		var legendObject;
		var fieldsetObject;
		var controlCheckbox;
		
		var trigger = e.srcElement||e.target; // кто вызвал событие?
		if (!trigger.tagName || trigger.tagName.toLowerCase() != "input" || trigger.type.toLowerCase() != "checkbox") return; // если это не чекбокс — делать нам тут нечего
		
		// пробегаемся по всем родителям
		var testElement = trigger;
		while (testElement){
			if (!testElement.tagName) return; // неявно — корень дерева, и мы ничего не нашли
			var tagName = testElement.tagName.toLowerCase();
			if (tagName == "legend") { // по пути встретили legend
				legendObject = testElement;
			} else if (tagName == "fieldset" && /(^|\s)+js-tree-box(\s|$)+/.test(testElement.className)) { // или fieldset с нужным классом
				fieldsetObject = testElement;
				break;
			}
			testElement = testElement.parentNode; // выбираем родителя и повторяем итерацию для него
		};
		if (!fieldsetObject) return;
		if (legendObject){ // т.е., чекбокс внутри легенды
			var controlCheckboxValue = trigger.checked;
			var inputs = fieldsetObject.getElementsByTagName("input");
			for(var i=0; i<inputs.length; i++){
				var input = inputs[i];
				if (input.type.toLowerCase() == "checkbox" && input != controlCheckbox){
					input.checked = controlCheckboxValue;
				};
			};
		} else {
			// находим «контрольный» чекбокс
			if (legendObject = fieldsetObject.getElementsByTagName("legend")[0]){
				var inputs = legendObject.getElementsByTagName("input");
				for(var i=0; i<inputs.length; i++){
					var input = inputs[i];
					if (input.type.toLowerCase() == "checkbox"){
						controlCheckbox = input;
						break;
					};
				};
			};
			if (!controlCheckbox) return;
			var controlCheckboxValue = true;
			// пробегаемся по всем чекбоксам
			var inputs = fieldsetObject.getElementsByTagName("input");
			for(var i=0; i<inputs.length; i++){
				var input = inputs[i];
				// есть неотмеченные?
				if (input.type.toLowerCase() == "checkbox" && input != controlCheckbox && !input.checked){
					controlCheckboxValue = false;
				};
			};
			// устанавливаем значение в контрольный
			controlCheckbox.checked = controlCheckboxValue;
		}
	};
	
	// щелчков будет намного меньше, чем элементов — отлавливаем события через bubbling
	if (document.addEventListener){
		document.addEventListener('change', clicker, false);
		document.addEventListener('click', clicker, false);
	} else {
		document.attachEvent('onchange', clicker);
		document.attachEvent('onclick', clicker);
	};
})();
</script>


Главное, господа, разделение кода и представления. А прописывать каждому чекбоксу уникальный id — проще застрелиться. :)

DVNSA 08.03.2010 19:17

Огромное спасибо, subzey! Очень выручили!

Prevergenec 15.08.2011 14:32

Вопрос такого рода:
Есть допустим число "А".
И ниже должны быть от одного до пяти чекбоксов которые будут менять число А. Допустим если нажат первый чекбокс, к числу А прибавляется 100, если нажат второй чекбокс, к числу А прибавляется 200, если нажаты оба чекбоксы, то к числу А прибавляется 300 и чтобы это было не перезагружая страничку.........
За ранее спасибо.

walik 15.08.2011 14:38

Задача понятна, а вот в чем проблема то ?


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