Как сделать динамический зависимый список ресурсов
        Имеется следующая структура:
Медицинские услуги
— Услуга 1
— — Врач 1
— — Врач 2
— Услуга 2
— — Врач 3
— — Врач 4
— Услуга 3
— — Врач 5
— — Врач 6
На сайте два выпадающих списка, в первом по умолчанию загружен список медицинских услуг. А как сделать, чтобы при выборе услуги во второй список подгружался список врачей, относящихся к этой услуге?
В данный момент первый список генерируется так:
Код чанка tpl.uslugaItem:
    
    
                                                                                
            Медицинские услуги
— Услуга 1
— — Врач 1
— — Врач 2
— Услуга 2
— — Врач 3
— — Врач 4
— Услуга 3
— — Врач 5
— — Врач 6
На сайте два выпадающих списка, в первом по умолчанию загружен список медицинских услуг. А как сделать, чтобы при выборе услуги во второй список подгружался список врачей, относящихся к этой услуге?
В данный момент первый список генерируется так:
<select name="usluga" class="service-select">
	<option value="" selected>Выберите услугу</option>
	[[!pdoMenu?
		&level=`1`
		&parents=`2`
		&tpl=`tpl.uslugaItem`
	]]
</select>Код чанка tpl.uslugaItem:
<option value="[[+menutitle]]">[[+menutitle]]</option>Комментарии: 16
                так же. только в parents вставь текущий id 
                    &parents=`[[*id]]`
                я так понимаю вам нужно что то подобное? 
в чанке tpl.uslugaItem необходимо использовать сниппет UltimateParent или pdoField в результате должно получится как то так:
где parents=`2` родительский ресурс в котором находятся услуги -> врачи…
                    [[!pdoMenu?
&parents=`2`
&level=`2`
&firstClass=`0`
&lastClass=`0`
&hereClass=`0`
&outerClass=`0`
&tplOuter=`@INLINE [[+wrapper]]`
&tpl=`@INLINE <optgroup label="[[+menutitle]]">[[+wrapper]]</optgroup>`
&tplInner=`@INLINE [[+wrapper]]`
&tplInnerRow=`tpl.uslugaItem`
]]в чанке tpl.uslugaItem необходимо использовать сниппет UltimateParent или pdoField в результате должно получится как то так:
<option [[+id:is=`[[UltimateParent? id=`[[+id]]` &topLevel=`3`]]`:then=`selected`]] value="[[+id]]">[[+menutitle]]</option>где parents=`2` родительский ресурс в котором находятся услуги -> врачи…
                Не совсем. Нужно динамически добавлять список врачей во второй селектбокс, после выбора услуги из первого.
s6221.h6.modhost.pro
                    s6221.h6.modhost.pro
                Реализовать ajax-запрос. Примерно вот так:
1. Вешаем на событие переключения селектора скрипт, который будет выполнять ajax-запрос:
2. Создаем файл (в моем примере assets/ajax/getlist.php), на который ссылается скрипт и который будет возвращать нам результат:
                    1. Вешаем на событие переключения селектора скрипт, который будет выполнять ajax-запрос:
<script>
	var canClick = true;
	$(document).on('change', 'select[name="selector-1"]', function(e) {
		if ($(this).val() != '' && canClick = true) {
    			$.ajax({
    				type: "POST",
    				url: "assets/ajax/getlist.php",
    				data: {
    					action: 'getList', 
    					parent: $("select[name='selector-1']").val()
       		        	},
    			
    				beforeSend: function(){
					canClick = false;
    				},
    			
    				success: function(response) {
    					var data = eval(response);
    
    					switch (data[1]) {
    						case 'success':
							//Если все ок - вставляем результат во второй селектор
							$("select[name='selector-2']").html("<option value='' selected disabled>Выберите значение из списка</option>" + data[0]).val("");
    							break;
    							
    						case 'error':
							//Если не ок - выводим ошибку (используется jGrowl)
    							$.jGrowl(data[0], {theme: 'error', position: 'center'});
    							
    							break;
    						
    					}
					canClick = true;
    				}
    			});
		}
	});
</script>2. Создаем файл (в моем примере assets/ajax/getlist.php), на который ссылается скрипт и который будет возвращать нам результат:
<?php
	if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest' || empty($_POST['action'])) {
		return;
	}
	define('MODX_API_MODE', true);
	require dirname(dirname(dirname(__FILE__))) . '/index.php';
	
	$modx->getService('error','error.modError');
	$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
	$modx->setLogTarget('FILE');
	
	
	if ($_POST['action'] == "getList" && isset($_POST['parent'])) {
		//Получаем значение для второго селектора
		$snippetParams = array();
		$snippetParams['parents'] = intval($_POST['parent']);
		$snippetParams['tpl'] = '@INLINE <option value="[[+menutitle]]">[[+menutitle]]</option>';
		//Дописать параметры для сниппета получающего результаты по вкусу			
		$snippetResult = $modx->runSnippet('pdoResources', $snippetParams);
		$result = array($snippetResult, 'success');
	}
	else {
		$result = array('Некорректный запрос', 'error');
	}
	
	if (!empty($result)) {
		die(json_encode($result));
	}
                Спасибо, но что-то пока не заводится… s6221.h6.modhost.pro
И ошибку никакую не пишет даже.
                    И ошибку никакую не пишет даже.
                Это потому что у вас parent отправляется не как id родителя, а как «Услуга 1». Замените чанк:
                    <option value="[[+menutitle]]">[[+menutitle]]</option><option value="[[+id]]">[[+menutitle]]</option>
                Заменил. К сожалению, пока тот же результат.            
                    
                Скиньте доступы, если не затруднит.
Ну или проверьте сами, пожалуйста — у вас точно есть данная строка в php-файле:
                    Ну или проверьте сами, пожалуйста — у вас точно есть данная строка в php-файле:
$result = array($snippetResult, 'success');
                Отправил доступы            
                    
                Готово. =)            
                    
                Вижу) спасибо огромное!
Если кому нужно, выкладываю скрипты:
Файл getlist.php
javascript:
Ну и html понятно:
                    Если кому нужно, выкладываю скрипты:
Файл getlist.php
<?php
	if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest' || empty($_POST['action'])) {
		return;
	}
	define('MODX_API_MODE', true);
	require dirname(dirname(dirname(__FILE__))) . '/index.php';
	
	$modx->getService('error','error.modError');
	$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
	$modx->setLogTarget('FILE');
	
	
	if ($_POST['action'] == "getList" && isset($_POST['parent'])) {
		//Получаем значение для второго селектора
		$snippetParams = array();
		$snippetParams['parents'] = intval($_POST['parent']);
		$snippetParams['tpl'] = 'option.item';
		//Дописать параметры для сниппета получающего результаты по вкусу			
		$snippetResult = $modx->runSnippet('pdoResources', $snippetParams);
		$result = array($snippetResult, 'success');
	}
	else {
		$result = array('Некорректный запрос', 'error');
	}
	
	if (!empty($result)) {
		die(json_encode($result));
	}javascript:
<script type="text/javascript">
    	$(document).on('change', 'select[name="selector-1"]', function(e) {
    		if ($(this).val() != '') {
        			$.ajax({
        				type: "POST",
        				url: "assets/ajax/getlist.php",
        				data: {
        				    action: 'getList', 
        				    parent: $("select[name='selector-1']").val()
           		         },
        			success: function(response) {
        				var data = eval(response);
        
        				switch (data[1]) {
        					case 'success':
    						//Если все ок - вставляем результат во второй селектор
    						$("select[name='selector-2']").val("").html("<option value='' selected disabled>Выберите значение из списка</option>" + data[0])
    
        						break;
        							
        					case 'error':
    						//Если не ок - выводим ошибку (используется jGrowl)
        						$.jGrowl(data[0], {theme: 'error', position: 'center'});
        							
        						break;
        						
        					}
        				}
        			});
    		}
    	});
    </script>Ну и html понятно:
<select name="selector-1">
    <option selected disabled>Выберите услугу</option>
    [[!pdoMenu?
    	&level=`1`
    	&parents=`2`
    	&tplOuter=`@INLINE [[+wrapper]]`
    	&tpl=`@INLINE <option value="[[+id]]">[[+menutitle]]</option>`
    ]]
</select>
<select name="selector-2">
    <option value="" selected disabled>Выберите врача</option>
</select>
                Да я, честно говоря, и скопировал свой же код из поста выше — видимо, вы его вставили до моей редакции..)
Ну и содержимое Inline-чанка вынес в полноценный чанк + canClick убрал, вот и все.
                    Ну и содержимое Inline-чанка вынес в полноценный чанк + canClick убрал, вот и все.
                В 4й строке 
Но всё равно не работает
                    if ($(this).val() != '' && canClick = true) {if ($(this).val() != '' && canClick == true) {Но всё равно не работает
                сделал по аналогии
файл
элементы неопубликованные и контейнеры, но я вроде бы добавил параметры чтобы они попадали в выборку, да и пробовал публиковать — все равно ничего не дает.
                    файл
if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest' || empty($_POST['action'])) {
		return;
	}
	define('MODX_API_MODE', true);
	require dirname(dirname(dirname(__FILE__))) . '/index.php';
	
	$modx->getService('error','error.modError');
	$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
	$modx->setLogTarget('FILE');
	
	
	if ($_POST['action'] == "getList" && isset($_POST['parent'])) {
		//Получаем значение для второго селектора
		$snippetParams = array();
		$snippetParams['parents'] = intval($_POST['parent']);
		$snippetParams['tpl'] = 'option.item';
		$snippetParams['showUnpublished'] = '1';
		$snippetParams['depth'] = '0';
		//Дописать параметры для сниппета получающего результаты по вкусу			
		$snippetResult = $modx->runSnippet('pdoResources', $snippetParams);
		$result = array($snippetResult, 'success');
	}
	else {
		$result = array('Некорректный запрос', 'error');
	}
	
	if (!empty($result)) {
		die(json_encode($result));
	}<script type="text/javascript">
    	$(document).on('change', 'select[name="vid_vzn"]', function(e) {
    		if ($(this).val() != '') {
        			$.ajax({
        				type: "POST",
        				url: "assets/lk/getlist.php",
        				data: {
        				    action: 'getList', 
        				    parent: $("select[name='vid_vzn']").val()
           		         },
        			success: function(response) {
        				var data = eval(response);
        
        				switch (data[1]) {
        					case 'success':
    						//Если все ок - вставляем результат во второй селектор
    						$("select[name='god']").val("").html("<option value='' selected disabled>Выберите значение из списка</option>" + data[0])
    
        						break;
       							
        						
        					}
        				}
        			});
    		}
    	});
    </script><div class="form-group">
		<label for="vid_vzn" class="col-sm-4 control-label">Вид взноса</label>
		<div class="col-sm-8">
			 <select class="form-control" name="vid_vzn" id="vid_vzn">
			 [[!pdoResources?
			    &parents=`1469`
			    &depth=`0`
			    &limit=`0`
			    &showUnpublished=`1`
			    &tpl=`@INLINE <option value="[[+id]]">[[+pagetitle]]</option>`
			    &sortby=`pagetitle`
			    &sortdir=`ASC`
			]]
			 </select>
		</div>
	</div>
	<div class="form-group">
		<label for="god" class="col-sm-4 control-label">Выберите год</label>
		<div class="col-sm-8">
			<select name="god">
			    <option value="" selected disabled>Год</option>
			</select>
		</div>
	</div>case 'error':
							//Если не ок - выводим ошибку (используется jGrowl)
    							$.jGrowl(data[0], {theme: 'error', position: 'center'});
    							
    							break;элементы неопубликованные и контейнеры, но я вроде бы добавил параметры чтобы они попадали в выборку, да и пробовал публиковать — все равно ничего не дает.
                Самый простой и самый быстрый вариант — выводить полный список и услуг и врачей, а яваскриптом скрывать ненужные пункты. Единственный момент — защита от дурака/хулигана — при сохранении проверять соответствие врача услуге по родителю.            
                    
                Ребята, решение отличное! Поставил работает четко, но нужна ваша помощь по скрипту. Использую данное решение для онлайн калькулятора с плагином jAutoCalc, при использовании функции добавить новую форму расчета он копирует контейнер первого без заполненных полей, так вот, класс контейнера и имена селектов естественно не меняють и при выборе в новой скопированной форме первого селекта, второй селект обновляеться в обоих формах, возможно привязать данное действие передачи информации с первого во второй селект с привязкой действия к родительскому контейнеру каждой формы? При копировании форм код получаеться такой:
                    [[!pdoMenu?
        &level=`1`
        &parents=`2`
        &tplOuter=`@INLINE [[+wrapper]]`
        &tpl=`@INLINE <option value="[[+id]]">[[+menutitle]]</option>`
        &toPlaceholder=`selector-1`
    ]]
<form name="form-calc">
    
Основная форма
    <div class="line_items">
        <select name="selector-1">
            <option selected disabled>Выберите услугу</option>
            [[+selector-1]]
        </select>
        <select name="selector-2">
            <option value="" selected disabled>Выберите врача</option>
        </select>
    </div>
Первая копия
    <div class="line_items">
        <select name="selector-1">
            <option selected disabled>Выберите услугу</option>
            [[+selector-1]]
        </select>
        <select name="selector-2">
            <option value="" selected disabled>Выберите врача</option>
        </select>
    </div>
Вторая копия
    <div class="line_items">
        <select name="selector-1">
            <option selected disabled>Выберите услугу</option>
            [[+selector-1]]
        </select>
        <select name="selector-2">
            <option value="" selected disabled>Выберите врача</option>
        </select>
    </div>
    и т.д.
</form>
                            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                    
            
 
             
                    
                    
                






