Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Включить/отключить checkbox при включении нескольких других checkbox (https://javascript.ru/forum/misc/78653-vklyuchit-otklyuchit-checkbox-pri-vklyuchenii-neskolkikh-drugikh-checkbox.html)

Aruta 15.10.2019 11:20

Включить/отключить checkbox при включении нескольких других checkbox
 
Добрый день!
Задача тут встала передо мной на jQuery... часть её решения нашел, но вот над этой частью бьюсь и не получается никак.
Ссылка на вид страницы: http://prntscr.com/pjfpdb

Нужно чтобы:
- чекбокс id="floor" получал галочку, когда хотя бы один из один из дочерних чекбоксов в <div class="floor__item"> имеет галочку и наоборот, если галочки снять со всех дочерних чекбоксов <div class="floor__item">, то и на id="floor" галочка убиралась (но она должна быть пока имеется хоть один включенный флаг).
- если с id="floor" снять галочку, то и со всех дочерних чекбоксов <div class="floor__item"> тоже снималась.
- если ни на одном дочернем чекбоксе <div class="floor__item"> нет, то id="floor" не кликабелен.

Весь код jQuery должен быть написан не от id, а по дочка/родитель, т.к. подобный код в других частях страницы планируется использовать.

ниже код html только с одним из 4-х блоков, которые содержат чекбокс, который нужно прослушивать, т.к. остальные 3 блока отличаются только картинкой и подписью под ней. onclick="event.stopPropagation()" для id="floor" сделан, чтобы при раскрытии дочернего блока id="floor" не отмечался, т.к. блок ниже строки "Choose your floor" открывается по нажатию на родителя id="floor"

<div class="upsale__block__sub-right-wrap">
						<div class="upsale__block__bot-right__title-wrap dflex">
							<div class="upsale__block__bot-right__title dflex">
								<input id="floor" type="checkbox" class="block__check" onclick="event.stopPropagation()"/>								
							</div>							
						</div>
						<div class="upsale__block__bot-right__sub-wrap dnone">
							<div class="montage__content-wrap">
								<span class="montage__text">intro text where we explain </span>
								<div class="montage__floor-wrap montage__comp-wrap dflex">
									<div class="montage__floor dflex">
										<div class="floor__item-wrap">
											<div class="floor__item-inner">
												<div class="floor__item">
													<input id="first_floor" type="checkbox" name="groundfloor" value="groundfloor">
													<div class="floor__item__img">
														<img src="catalog/view/theme/myown/image/floor/groundFloor.svg" alt="">
													</div>
													<span class="floor__item__text"><?php echo $this->language->get('text_floor_0'); ?></span>
												</div>
											</div>
										</div>										
									</div>
								</div>
							</div>			
						</div>			
					</div>


У меня уже есть код, который активирует чекбоксы в блоках <div class="floor__item"> - с ним я справился за 3 часа, т.к. новенький в этом деле:) может пригодится при рассмотрении моего вопроса:)
$('.montage__floor').on('click', '.floor__item-wrap', function() {
	var $input = $(this).children('.floor__item-inner').children('.floor__item').children('input');
	if ($input.prop('checked'))	{
		$input.prop('checked',false); 
		$(this).css('background', 'none');
	}else{
		$input.prop('checked',true);
		$(this).css('background', '#bbd9ff');
	};
	});

ksa 15.10.2019 12:39

Aruta, как вариант...

<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1251' />
<script src='https://code.jquery.com/jquery-latest.js'></script>
<!--
<script src="https://code.angularjs.org/1.3.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.3.9/angular-route.js"></script>
-->
<style type='text/css'>
</style>
<script type='text/javascript'>
$(function(){
	$('.upsale__block__sub-right-wrap :checkbox').click(function(){
		if (this.id=='floor') {
			this.checked=false;
			this.disabled=true;
			$(this).parents('.upsale__block__sub-right-wrap').find('.floor__item :checkbox').prop('checked',false);
			return;
		};
		if (this.name=='groundfloor') {
			if (this.checked) {
				$('#floor').prop({
					'disabled': false,
					'checked': true
				});
				return;
			};
			var o=$(this).parents('.upsale__block__sub-right-wrap').find('.floor__item :checked');
			if (o.length==0) {
				$('#floor').prop({
					'disabled': true,
					'checked': false
				});
			};
		};
	});
});
</script>
</head>
<body>
<div class="upsale__block__sub-right-wrap">
	<div class="upsale__block__bot-right__title-wrap dflex">
		<div class="upsale__block__bot-right__title dflex">
			<input id="floor" type="checkbox" class="block__check" />								
		</div>							
	</div>
	<div class="upsale__block__bot-right__sub-wrap dnone">
		<div class="montage__content-wrap">
			<span class="montage__text">intro text where we explain </span>
			<div class="montage__floor-wrap montage__comp-wrap dflex">
				<div class="montage__floor dflex">
					<div class="floor__item-wrap">
						<div class="floor__item-inner">
							<div class="floor__item">
								<input type="checkbox" name="groundfloor" value="groundfloor">
								<div class="floor__item__img">
									<img src="catalog/view/theme/myown/image/floor/groundFloor.svg" alt="">
								</div>
								<span class="floor__item__text">floor__item__text 0</span>
							</div>
							<div class="floor__item">
								<input type="checkbox" name="groundfloor" value="groundfloor">
								<div class="floor__item__img">
									<img src="catalog/view/theme/myown/image/floor/groundFloor.svg" alt="">
								</div>
								<span class="floor__item__text">floor__item__text 1</span>
							</div>
						</div>
					</div>										
				</div>
			</div>
		</div>			
	</div>			
</div>
</body>
</html>

laimas 15.10.2019 14:06

Цитата:

Сообщение от Aruta
$input = $(this).children('.floor__item-inner').children('.floor__item').children('input') ;

А зачем, что в '.floor__item-inner' тоже могут быть флажки а не только у '.floor__item'?

В событии изменения (change, а не click) для дочерних флажков нужно брать по фильтру выбранные, и значение length таковых указывать в .prop('checked') для общего флажка. Ну а изменение общего флажка это вообще просто, его состояние флажкам ниже.

Aruta 15.10.2019 15:28

ksa,
на форуме работает вроде как-то, но в живой проект когда добавил, то вышло, что при выборе нижних чекбоксов верхний не отмечается - как и сейчас у меня, а если вручную ставить галку верхнему, то при снятии он неактивен становится пока не нажмешь f5.

Нашел где исправить чтобы disabled не был input верхним, но всё же это завязано на id, а не на родителей/дочек...

Aruta 15.10.2019 15:29

laimas, если .floor__item-inner не добавить, то он вообще не ставит галочку - не спускается по dom куда надо

ksa 15.10.2019 15:54

Цитата:

Сообщение от Aruta
в живой проект когда добавил, то вышло, что при выборе нижних чекбоксов верхний не отмечается

Значит ты не такой хтмл тут показал... :)

В моем варианте все завязано на ту структуру которая есть в примере. Если по факту она не такая - можно просто изменить "родительский" селектор. ;)

laimas 15.10.2019 15:54

<div class="upsale__block__sub-right-wrap">
    <div class="upsale__block__bot-right__title-wrap dflex">
        <div class="upsale__block__bot-right__title dflex">
            <input id="floor" type="checkbox" class="block__check" />                            
        </div>                           
    </div>
    <div class="upsale__block__bot-right__sub-wrap dnone">
        <div class="montage__content-wrap">
            <span class="montage__text">intro text where we explain </span>
            <div class="montage__floor-wrap montage__comp-wrap dflex">
                <div class="montage__floor dflex">
                    <div class="floor__item-wrap">
                        <div class="floor__item-inner">
                            <div class="floor__item">
                                <input type="checkbox" name="groundfloor" value="groundfloor">
                                <div class="floor__item__img">
                                    <img src="catalog/view/theme/myown/image/floor/groundFloor.svg" alt="">
                                </div>
                                <span class="floor__item__text">floor__item__text 0</span>
                            </div>
                            <div class="floor__item">
                                <input type="checkbox" name="groundfloor" value="groundfloor">
                                <div class="floor__item__img">
                                    <img src="catalog/view/theme/myown/image/floor/groundFloor.svg" alt="">
                                </div>
                                <span class="floor__item__text">floor__item__text 1</span>
                            </div>
                        </div>
                    </div>                                       
                </div>
            </div>
        </div>           
    </div>           
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$('div.upsale__block__sub-right-wrap').on('change', 'input', function(e) {
    var chk = $(e.delegateTarget).find('input');
    if(chk.eq(0)[0]==this) chk.slice(1).prop('checked', this.checked);
    else chk.eq(0).prop('checked', chk.slice(1).filter(':checked').length);
})
</script>

Aruta 15.10.2019 15:59

laimas,
да вроде тот.

Вот вообще весь код без обрезания:)

<div class="upsale__block__sub-right-wrap">
						<div class="upsale__block__bot-right__title-wrap dflex">
							<div class="upsale__block__bot-right__title dflex">
								<input id="floor" type="checkbox" class="block__check" onclick="event.stopPropagation()"/>					
								<span>
									<img class="arrow arrow_down" src="http://test.vhost78896.cpsite.ru/catalog/view/theme/myown/image/arrowselect.png" alt="arrow_down"/>
									Choose your floor
								</span>
							</div>
							<div class="col-title__price-wrap dflex">
								<div class="col-title__quantity-header col-width">Aantal</div>
								<div class="col-title__price col-width" style="white-space:nowrap;">Prijs</div>
								<div class="col-title__total col-title__totalheader col-width">Totaal</div>
							</div>
						</div>
						<div class="upsale__block__bot-right__sub-wrap dnone">
							<div class="montage__content-wrap">
								<span class="montage__text">intro text where we explain</span>
								<div class="montage__floor-wrap montage__comp-wrap dflex">
									<div class="montage__floor dflex">
										<div class="floor__item-wrap">
											<div class="floor__item-inner">
												<div class="floor__item">
													<input id="first_floor" type="checkbox" name="groundfloor" value="groundfloor">
													<div class="floor__item__img">
														<img src="catalog/view/theme/myown/image/floor/groundFloor.svg" alt="">
													</div>
													<span class="floor__item__text"><?php echo $this->language->get('text_floor_1'); ?></span>
												</div>
											</div>
										</div>
										<div class="floor__item-wrap">
											<div class="floor__item-inner">
												<div class="floor__item">
														<input id="sec_floor" type="checkbox" name="middlefloor" value="middlefloor">
													<div class="floor__item__img">
														<img src="catalog/view/theme/myown/image/floor/middleFloor.svg" alt="">
													</div>
													<span class="floor__item__text"><?php echo $this->language->get('text_floor_2'); ?></span>
												</div>
											</div>
										</div>	
										<div class="floor__item-wrap">
											<div class="floor__item-inner">
												<div class="floor__item">
													<input id="third_floor" type="checkbox" name="topfloor" value="topfloor">
													<div class="floor__item__img">
														<img src="catalog/view/theme/myown/image/floor/topFloor.svg" alt="">
													</div>
													<span class="floor__item__text"><?php echo $this->language->get('text_floor_3'); ?></span>
												</div>
											</div>
										</div>
										<div class="floor__item-wrap">
											<div class="floor__item-inner">
												<div class="floor__item">
														<input id="all_floor" type="checkbox" name="apartment" value="apartment">
													<div class="floor__item__img">
														<img src="catalog/view/theme/myown/image/floor/apartmentBuilding.svg" alt="">
													</div>
													<span class="floor__item__text"><?php echo $this->language->get('text_floor_build'); ?></span>
												</div>
											</div>
										</div>
									</div>
								</div>
							</div>			
						</div>			
					</div>

Aruta 15.10.2019 16:04

laimas,
как тут добавить исполняемый код как у вас в посте? Я закину в него всё - css, js, html, чтобы можно было видеть как это всё работает сейчас

laimas 15.10.2019 16:04

Цитата:

Сообщение от Aruta
Вот вообще весь код без обрезания

Не важно, обработка делегируется общему родителю. Вот только с disabled не понятно, добавляйте сами, для него значением будет инверсия chk.slice(1).filter(':checked').length, а по умолчанию <input id="floor" type="checkbox" class="block__check" disabled /> коли не разрешено пока не выбрано что-то, а по уму при загрузке ничего и не выбрано, если только не было запоминания предыдущих выборов.
Странно, если его сделать недоступным, то выбрать все им можно только в случае когда хотя бы "один из" был выбран. Что так и должно быть?


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