Как сделать динамический зависимый список ресурсов
Имеется следующая структура:
Медицинские услуги
— Услуга 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`
]]
то есть родителя обрамлять в тег optgroup, а именно услуги.в чанке 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>
html<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>
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.