Как сделать динамический зависимый список ресурсов Новый


Имеется следующая структура:

Медицинские услуги
— Услуга 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>
08 августа 2016, 09:46    Александр   G+  
3    704 0

Комментарии (14)

  1. Владислав 08 августа 2016, 10:13 # 0
    так же. только в parents вставь текущий id
    &parents=`[[*id]]`
    1. Дмитрий Середюк 08 августа 2016, 10:14 # 0
      я так понимаю вам нужно что то подобное?
      [[!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`
      ]]
      
      то есть родителя обрамлять в тег optgroup, а именно услуги.

      в чанке tpl.uslugaItem необходимо использовать сниппет UltimateParent или pdoField в результате должно получится как то так:

      <option [[+id:is=`[[UltimateParent? id=`[[+id]]` &topLevel=`3`]]`:then=`selected`]] value="[[+id]]">[[+menutitle]]</option>

      где parents=`2` родительский ресурс в котором находятся услуги -> врачи…
      1. Александр 08 августа 2016, 10:35 # 0
        Не совсем. Нужно динамически добавлять список врачей во второй селектбокс, после выбора услуги из первого.

        s6221.h6.modhost.pro
      2. Максим Кузнецов 08 августа 2016, 10:34 # +3
        Реализовать ajax-запрос. Примерно вот так:

        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));
        	}
        
        1. Александр 08 августа 2016, 10:55 # 0
          Спасибо, но что-то пока не заводится… s6221.h6.modhost.pro
          И ошибку никакую не пишет даже.
          1. Максим Кузнецов 08 августа 2016, 10:58 # 0
            Это потому что у вас parent отправляется не как id родителя, а как «Услуга 1». Замените чанк:
            <option value="[[+menutitle]]">[[+menutitle]]</option>
            на такой:
            <option value="[[+id]]">[[+menutitle]]</option>
            1. Александр 08 августа 2016, 11:11 # 0
              Заменил. К сожалению, пока тот же результат.
              1. Максим Кузнецов 08 августа 2016, 11:12 # 0
                Скиньте доступы, если не затруднит.

                Ну или проверьте сами, пожалуйста — у вас точно есть данная строка в php-файле:
                $result = array($snippetResult, 'success');
                1. Александр 08 августа 2016, 11:20 # 0
                  Отправил доступы
                  1. Максим Кузнецов 08 августа 2016, 11:24 # 0
                    Готово. =)
                    1. Александр 08 августа 2016, 11:29 # 0
                      Вижу) спасибо огромное!
                      Если кому нужно, выкладываю скрипты:

                      Файл 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>
                      
                      1. Максим Кузнецов 08 августа 2016, 11:31 # +1
                        Да я, честно говоря, и скопировал свой же код из поста выше — видимо, вы его вставили до моей редакции..)

                        Ну и содержимое Inline-чанка вынес в полноценный чанк + canClick убрал, вот и все.
          2. Александр 08 августа 2016, 10:57 # 0
            В 4й строке
            if ($(this).val() != '' && canClick = true) {
            пришлось поменять на
            if ($(this).val() != '' && canClick == true) {
            ругался браузер.

            Но всё равно не работает
          3. Сергей Шлоков 08 августа 2016, 11:05 # 0
            Самый простой и самый быстрый вариант — выводить полный список и услуг и врачей, а яваскриптом скрывать ненужные пункты. Единственный момент — защита от дурака/хулигана — при сохранении проверять соответствие врача услуге по родителю.
            Вы должны авторизоваться, чтобы оставлять комментарии.