Максим Кузнецов

Максим Кузнецов

Был в сети 04 августа 2021, 21:51
Заказы принимаю
Реализовать 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));
	}
Есть пользователь, он может загружать какие-то товары на сайт.
ms2form или самописный сниппет добавления товаров.

При переходе на профиль этого пользователя отображаются все товары, которые он загрузил.
На странице пользователя (написать кастомную маршрутизацию для реализации подобных страниц или создавать их через плагин на событие OnUserActivate):
[[!msProduct?
	...
	&where=`{"createdby": "айди_пользователя"}
]]
Конкретно для вашей задачи, из серии «красивого», я бы сделал так (используется fenom):

1.На нужной странице (допустим, «Управление товарами») ставим селектор секций:
<select class="changeGet" data-key="category">
	<option value="" disabled selected>Выберите тип товара</option>
	<!--Сниппет для вызова подходящих секций-->
	{$_modx->runSnippet('!pdoResources', [
		'depth' => 1,
		'parents' => айди_контейнера_с_секциями,
		'limit' => 0,
		'tpl' => 'section.option.item'
	])}
</select>

Чанк section.option.item:
<option value="{$id}" {if $id == $.get.category} selected{/if}>{$pagetitle}</option>

2. На событие переключения селектора пишем скрипт, выставляющий в адресную строку соответствующий гет-параметр:
<script type="text/javascript">
	function changeGet (param, value) {
		var currentURL = window.location.href+'&';
		var change = new RegExp('('+param+')=(.*)&', 'g');
		var newURL = currentURL.replace(change, '$1='+value+'&');

		if (getURLParameter(param) !== null) {
			try {
				window.history.replaceState('', '', newURL.slice(0, - 1) );
			}
			catch (e) {
				console.log(e);
			}
		}
		else {
			var currURL = window.location.href;
			
			if (currURL.indexOf("?") !== -1){
				window.history.replaceState('', '', currentURL.slice(0, - 1) + '&' + param + '=' + value);
			}
			else {
				window.history.replaceState('', '', currentURL.slice(0, - 1) + '?' + param + '=' + value);
			}
		}
	}

	$('.changeGet').on('change', function () {
		changeGet($(this).attr("data-key"), $(this).val());
		
		location.reload();
	});
</script>

Что мы имеем: селектор, который при переключении прописывает в адресную строку гет-параметр вида
?category=айди_выбранной_категории
и перезагружает страницу. Нам осталось только перехватывать значение этого гет-параметра и в зависимости от него выставлять соответствующую форму:

{var $category_id = $.get.category}

{if $category_id|length > 0}
	{switch $category_id}
		<!--Параметры сниппета TicketForm для категории с id = 1-->
		{case 1}
			{var $params = '
				&allowFiles=`1` 
				&requiredFields=`pagetitle,content` 
				&allowedFields=`pagetitle,introtext,content`
				&tplFormCreate=`category1.form.create`
				&tplFormUpdate=`category1.form..update`
			'}
		
		<!--Параметры сниппета TicketForm для категории с id = 2-->
		{case 2}
			{var $params = '
				&allowFiles=`0` 
				&requiredFields=`pagetitle` 
				&allowedFields=`pagetitle,content`
				&tplFormCreate=`category2.form.create`
				&tplFormUpdate=`category2.form..update`
			'}
	{/switch}
	
	{if $params|length > 0}
		[[!ticketform? {$params}]]
	{else}
		Указана некорректная категория.
	{/if}
{else}
	Выберите категорию.
	<!--Здесь можно прописать общий вызов TicketForm, если категория не указана-->
{/if}
Видимо, не все политики выставил. Как минимум проверяй наличие прав miniShopManagerPolicy для mgr-контекста у группы менеджеров.

Ну и заодно можешь посмотреть читаемый текст ошибки следующим способом:
— открываешь консоль (f12 в хроме)
— переходишь в закладку Network
— переходишь на страницу редактирования товара
— внизу закладки Network выбираешь запрос, возвращающий ошибку и в появившейся правой области переходишь на закладку Preview
Дело в том, что по логике html атрибут id считается уникальным. Исходя из этого, например, поиск значений через айди будет быстрее, чем через классы:
//первое условие выполнится быстрее, т.к. после первого нахождения подходящего элемента, скрипт прекратит работу
$("#id").css("display", "block");
//а эта функция будет искать до конца html-разметки
$(".class").css("display", "block);

В твоем случае решение очень простое — подключай визуальный редактор через идентификатор класса.
Вариант 1 (менее надежный — пользователь может отредактировать значение через консоль браузера):
//также нужно указать параметр template в списке допустимых и обязательных полей (в настройках сниппета TicketForm)
<input type="hidden" name="template" value="айди_шаблона" />

Вариант 2 (через плагин):
<?php
	if ($modx->event->name == 'OnDocFormSave' && $mode == 'new') {
		if (любым условием при помощи входящих POST-данных фильтруешь нужную форму ) {
			$resource->set('template', 'айди_шаблона');
			$resource->save();
		}
	}
1. Comparison (490 р)
2. mSearch2 (1990 р)
3. см. пункт 2
4. mspRobokassa (490 р)
5. CitySelect (бесплатно) + плагин для доступных доставок
6. встроенный функционал minishop2 (бесплатно)
7. встроенный функционал minishop2 (бесплатно)
8. Плагин + js
9. Плагин
10. php + cron
11. руками и/или импорт
12. CallBack или Formit (390 р или бесплатно)
13. готового решения не припоминаю, чаще реализуют через форму обратной связи Formit (бесплатно)

— если надумаете делать своими силами.

Как по мне (брать заказ не планирую) — 250 тысяч, если дизайн и общая верстка готова, это, конечно, перебор, но 150 — вполне (если хотите, чтобы все работало быстро и надежно).