Всего 123 782 комментария

Сергей
24 октября 2023, 11:49
0
Увидел, что компонент обновился, может есть надежда еще. Автор огромная просьба выполнить пожелание первого комментария. Было бы максимально полезно, если бы адреса сохранялись автоматически при оформлении товара, а при повторном заказе данные бы подставлялись автоматически, как на крупных маркетплейсах.
Игорь
24 октября 2023, 11:42
0
Нашел другое решение и оно работает. От сюда решение modzone.ru/blog/2015/12/22/ajax-loading-of-content/

Создадим файл, на который будем отправлять AJAX запрос и который будет возвращать контент указанной страницы. Назовем его ajax.php и положим в папку assets.

ajax.php
<?php
// Если запрос не AJAX или не передано действие, выходим
if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest' || empty($_REQUEST['action'])) {exit();}

$action = $_REQUEST['action'];

define('MODX_API_MODE', true);
require_once dirname(dirname(__FILE__)).'/index.php';

$modx->getService('error','error.modError');
$modx->getRequest();
$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
$modx->setLogTarget('FILE');
$modx->error->message = null;

$output = '';
switch ($action) {
    case 'getContent':
        // Если не передан id страницы, тоже выходим
        $id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
        if (empty($id)) {
            exit();
        };

        $object = $modx->getObject('modResource',$id);
        $output = $object->get('content');
        // Парсим теги MODX
        $maxIterations= (integer) $modx->getOption('parser_max_iterations', null, 10);
        $modx->getParser()->processElementTags('', $output, false, false, '[[', ']]', array(), $maxIterations);
        $modx->getParser()->processElementTags('', $output, true, true, '[[', ']]', array(), $maxIterations);
}


@session_write_close();
exit($output);

Создайте JavaScript файл, например script.js, и добавьте в него следующий код:

$(document).on('click', '.read-more', function(e) {
  e.preventDefault();
  var id = $(this).data('id') || 0;
  // Вставляем контент в тело модального окна
  $("#content").load("/assets/ajax.php", {action: "getContent", id: id}, function(response) {
    // Если ответ не пустой, открываем модальное окно
    if (response) {
      $("#mymodal").modal('show');
    }
  });
});
Подключите созданный JavaScript файл на вашем сайте.

<script src="путь/к/вашему/script.js"></script>
Добавление разметки для модального окна:
Добавьте на вашу страницу HTML код для модального окна Bootstrap:
<div class="modal fadeIn" id="mymodal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" aria-label="Close"><span aria-hidden="true">×</span></button>
        <h4 class="modal-title" id="myModalLabel">Модальное окно</h4>
      </div>
      <div id="content" class="modal-body"></div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default btn-close">Закрыть</button>
      </div>
    </div>
  </div>
</div>
Пример ссылки, где 42 это id страницы:

<a href="#" class="read-more" data-id="42">Подробнее</a>
Все, теперь страницы будут открываться без шаблона страницы.
Денис Усманов
23 октября 2023, 17:49
0
Засунуть в файл вряд-ли получится, так не передашь ID… вызывать в шаблоне страницы, где эта функция должна выполняться. Вызывается классом modalTrigger на кнопке необходимой, а выводится вызов в блоке с id modalAjax
Игорь
23 октября 2023, 17:29
0
это засунуть в js файл?
а вызывать как тогда… )
Игорь
23 октября 2023, 16:28
0
так… осталось понять как это применить…
Денис Усманов
23 октября 2023, 16:18
0
Простейший способ решения задачи: сделать запрашиваемый ресурс без шаблона.
Вот у меня скрипт 1 есть, мб поможет как:
$(document).on('click', '.modalTrigger', function(e) {
	e.preventDefault();
	$.ajax({  
	  type: "POST",  
	  url: '[[~ID]]', 
	  data: {parent: '[[*id]]'},
	  success:  function(data) { 
		if (data){
		    $('#modalAjax').html(data);
		}else{
		  AjaxForm.Message.error('Что-то пошло не так, попробуйте позже!');
		}
	  } 
	}); 
});
Игорь
23 октября 2023, 16:12
0
<a data-fancybox data-type="ajax" data-src="[[#42.content]]" href="#">Тест3</a>
контент подгрузил со страницы в моем случае в footer… получается это уже не ajax…

[[#42.content]] - грузит содержимое без шаблона. но не ajax..
Денис Усманов
23 октября 2023, 15:58
0
Попробуйте не [[~ID]], а [[#ID.content]]
perfkirill
23 октября 2023, 11:16
0
Вопрос пр msie2
Если мы импортируем новые товары и в столбце parent указываем строковый путь
«Каталог товаров|категория1|категория2»

И при этом «категория2» не создана, то модуль при импорте пропускает такие товары с ошибкой «Для импортируемого товара не указан родитель, действие отклонено.»

При этом в первой версии он сам создавал категории.

Как сделать так, чтобы он сам создавал категории?
Денис Усманов
23 октября 2023, 07:06
0
Может плагин какой реагирует на поле какое этого шаблона, мб поле какое от компонента какое то особенное, может смайлики где… много факторов.
Роман Л.
22 октября 2023, 16:07
0
Добрый день!
Подскажите как обычно решается проблема дублирования реальных и виртуальных URL при подключении категорий в связку seoFilter+mFilter2?
Допустим в каталоге есть категория1 с алисом category1 которая формирует URL site.ru/сatalog/сategory1.
Подключаем seoFilter+mFilter2 и добавляем туда фильтр по parent:categories.
При формировании полей и сео-правил появляются виртуальные URL site.ru/сatalog/сategory1 которые соответствено дублируют уже существующие адреса категорий.
Реальный URL при обновлении страницы перебивает виртуальный сформированный seoFilter и не подгружаются шаблоны от seoFilter.
С одной стороны простым решением будет категориям давать какие нибудь другие алиасы чтобы они не совпадали с виртуальнымы от seoFilter но их нужно будет прятать в sitemap и следить чтобы ссылки на них в сайте нигде не вылезли. Либо вообще отказаться от категорий и все товары закидывать в корень каталога, и убрать фильтр по категориям?
YanaShine
22 октября 2023, 15:04
0
Мое решение с исправлениями номера телефона, разделением суммы и проверкой на пустые формы

<?php
if($modx->event->name != 'msOnCreateOrder') return;

$token = $modx->getOption('mstelegram_token', null, false);

$recipients = explode(',', $modx->getOption('mstelegram_recipients', null, ''));
$contacts = $msOrder->Address;
$_products = $msOrder->getMany('Products');
$delivery = $msOrder->getOne('Delivery');
$payment = $msOrder->getOne('Payment');

// Преобразование суммы с разделением тысяч
$formattedCost = number_format($msOrder->cost, 0, '.', ' ');

// Проверка и преобразование телефона
$phone = $contacts->phone;
if (!empty($phone) && !preg_match('/^\+7/', $phone)) {
    // Заменяем "8" на "+7"
    $phone = str_replace("8", "+7", $phone);
}

// Список товаров в заказе
$i = 0;
$products = '';
foreach ($_products as $product) {
    if (!empty($product->count)) { // Проверка, что количество товара не пустое
        $i++;
        if ($i > 1) {
            $products .= "\n"; // Добавляем разделитель только после первого товара
        }
        $products .= "{$i}. {$product->name} ({$product->count} шт.)";
    }
}

// Текст сообщения
$message = "
Новый заказ #{$msOrder->num}
на сумму {$formattedCost} ₽.
Оплата: {$payment->name}
Доставка: {$delivery->name}
- - - - - - -
{$products}
- - - - - - -
Имя: {$contacts->receiver}
";
if (!empty($phone)) { // Добавляем телефон только если он не пустой
    $message .= "Телефон: {$phone}\n";
}
if (!empty($contacts->email)) { // Добавляем Email только если он не пустой
    $message .= "Email: {$contacts->email}\n";
}
if (!empty($contacts->street)) { // Добавляем Улица только если он не пустой
    $message .= "Улица: {$contacts->street}\n";
}
if (!empty($contacts->building)) { // Добавляем Дом только если он не пустой
    $message .= "Дом: {$contacts->building}\n";
}
if (!empty($contacts->room)) { // Добавляем Квартиру только если она не пуста
    $message .= "Квартира: {$contacts->room}\n";
}
if (!empty($contacts->comment)) { // Добавляем Комментарий только если он не пустой
    $message .= "Комментарий: {$contacts->comment}";
}

$message = urlencode($message);
foreach($recipients as $id){
    $id = trim($id);
    if(!$id) continue;
    $url = "https://api.telegram.org/bot{$token}/sendMessage?chat_id={$id}&text={$message}";
    $ch = curl_init();
    curl_setopt_array($ch, array(CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true));
    $result = curl_exec($ch);
    curl_close($ch);
}
YanaShine
22 октября 2023, 14:20
0
Решился вопрос

$contacts = $modx->getObject('msOrderAddress', array('id'=> $msOrder->address));
на следующий код
$contacts = $msOrder->Address;
YanaShine
22 октября 2023, 13:09
0
В Телеграм приходят сообщения в таком виде (без адреса и контактных данных) и все попытки тщетны

Новый заказ #2310/22
на сумму 24650 ₽.
Оплата: Оплата наличными
Доставка: Доставка до подъезда

1. Кровать Рондо (1 шт.)

Имя:
Телефон:
Email:
Улица:
Дом:
Квартира:
Комментарий:
Плагин настроен так:
<?php
if($modx->event->name != 'msOnCreateOrder') return;

$token = $modx->getOption('mstelegram_token', null, false);
$recipients = explode(',', $modx->getOption('mstelegram_recipients', null, ''));

$contacts = $modx->getObject('msOrderAddress', array('id'=> $msOrder->address));
$_products = $msOrder->getMany('Products');
$delivery = $msOrder->getOne('Delivery');
$payment = $msOrder->getOne('Payment');

// Список товаров в заказе
$i = 0;
$products = '';
foreach ($_products as $product) {
    $i++;
    $products .= "{$i}. {$product->name} ({$product->count} шт.)";
}

// Текст сообщения
$message = "
Новый заказ #{$msOrder->num}
на сумму {$msOrder->cost} ₽.
Оплата: {$payment->name}
Доставка: {$delivery->name}
- - - - - - -
{$products}
- - - - - - -
Имя: {$contacts->receiver}
Телефон: {$contacts->phone}
Email: {$contacts->email}
Улица: {$contacts->street}
Дом: {$contacts->building}
Квартира: {$contacts->room}
Комментарий: {$contacts->comment}
";

$message = urlencode($message);
foreach($recipients as $id){
	$id = trim($id);
	if(!$id) continue;
    $url = "https://api.telegram.org/bot{$token}/sendMessage?chat_id={$id}&text={$message}";
    $ch = curl_init();
    curl_setopt_array($ch, array(CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true));
    $result = curl_exec($ch);
    curl_close($ch);
}
Чанк tpl.msOrder.custom
<form class="ms2_form" id="msOrder" method="post">
    <div class="row">
        <div class="col-12 col-md-6">
            <h4>{'ms2_frontend_credentials' | lexicon}:</h4>
            {foreach ['email','receiver','phone'] as $field}
                <div class="form-group row input-parent">
                    <label class="col-md-4 col-form-label" for="{$field}">
                        {('ms2_frontend_' ~ $field) | lexicon} <span class="required-star">*</span>
                    </label>
                    <div class="col-md-8">
                        <input type="text" id="{$field}" placeholder="{('ms2_frontend_' ~ $field) | lexicon}" name="{$field}" value="{$form[$field]}" class="form-control{($field in list $errors) ? ' error' : ''}">
                    </div>
                </div>
            {/foreach}
            <div class="form-group row input-parent">
                <label class="col-md-4 col-form-label" for="comment">
                    {'ms2_frontend_comment' | lexicon} <span class="required-star">*</span>
                </label>
                <div class="col-md-8">
                    <textarea name="comment" id="comment" placeholder="{'ms2_frontend_comment' | lexicon}"
                        class="form-control{('comment' in list $errors) ? ' error' : ''}">{$form.comment}</textarea>
                </div>
            </div>
        </div>
        <div class="col-12 col-md-6" id="payments">
            <h4>{'ms2_frontend_payments' | lexicon}:</h4>
            <div class="form-group row">
                <div class="col-12">
                    {foreach $payments as $payment index=$index}
                        {var $checked = !($order.payment in keys $payments) && $index == 0 || $payment.id == $order.payment}
                        <div class="checkbox">
                            <label class="col-form-label payment input-parent">
                                <input type="radio" name="payment" value="{$payment.id}" id="payment_{$payment.id}"{$checked ? 'checked' : ''}>
                                {if $payment.logo?}
                                    <img src="{$payment.logo}" alt="{$payment.name}" title="{$payment.name}" class="mw-100"/>
                                {else}
                                    {$payment.name}
                                {/if}
                                {if $payment.description?}
                                    <p class="small">{$payment.description}</p>
                                {/if}
                            </label>
                        </div>
                    {/foreach}
                </div>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-12 col-md-6" id="deliveries">
            <h4>{'ms2_frontend_deliveries' | lexicon}:</h4>
            <div class="form-group row">
                <div class="col-12">
                    {foreach $deliveries as $delivery index=$index}
                        {var $checked = !($order.delivery in keys $deliveries) && $index == 0 || $delivery.id == $order.delivery}
                        <div class="checkbox">
                            <label class="col-form-label delivery input-parent">
                                <input type="radio" name="delivery" value="{$delivery.id}" id="delivery_{$delivery.id}"
                                    data-payments="{$delivery.payments | json_encode}"
                                    {$checked ? 'checked' : ''}>
                                {if $delivery.logo?}
                                    <img src="{$delivery.logo}" alt="{$delivery.name}" title="{$delivery.name}"/>
                                {else}
                                    {$delivery.name}
                                {/if}
                                {if $delivery.description?}
                                    <p class="small">
                                        {$delivery.description}
                                    </p>
                                {/if}
                            </label>
                        </div>
                    {/foreach}
                </div>
            </div>
        </div>
        <div class="col-12 col-md-6">
            <h4>{'ms2_frontend_address' | lexicon}:</h4>
            {foreach ['index','region','city', 'street', 'building', 'entrance','floor', 'room'] as $field}
                <div class="form-group row input-parent">
                    <label class="col-md-4 col-form-label" for="{$field}">
                        {('ms2_frontend_' ~ $field) | lexicon} <span class="required-star">*</span>
                    </label>
                    <div class="col-md-8">
                        <input type="text" id="{$field}" placeholder="{('ms2_frontend_' ~ $field) | lexicon}"
                            name="{$field}" value="{$form[$field]}"
                            class="form-control{($field in list $errors) ? ' error' : ''}">
                    </div>
                </div>
            {/foreach}
            <div class="form-group row input-parent">
                <label class="col-md-4 col-form-label" for="text_address">
                    {'ms2_frontend_text_address' | lexicon} <span class="required-star">*</span>
                </label>
                <div class="col-md-8">
                    <textarea name="text_address" id="text_address" placeholder="{'ms2_frontend_text_address' | lexicon}"
                        class="form-control{('text_address' in list $errors) ? ' error' : ''}">{$form.text_address}</textarea>
                </div>
            </div>
        </div>
    </div>
    <button type="button" name="ms2_action" value="order/clean" class="btn btn-danger ms2_link">{'ms2_frontend_order_cancel' | lexicon} </button>
    <hr class="mt-4 mb-4"/>
    <div class="d-flex flex-column flex-md-row align-items-center justify-content-center justify-content-md-end mb-5">
        <h4 class="mb-md-0">{'ms2_frontend_order_cost' | lexicon}:</h4>
        <h3 class="mb-md-0 ml-md-2">
            <span id="ms2_order_cart_cost">{$order.cart_cost ?: 0}</span> {'ms2_frontend_currency' | lexicon} +
            <span id="ms2_order_delivery_cost">{$order.delivery_cost ?: 0}</span> {'ms2_frontend_currency' | lexicon} =
            <span id="ms2_order_cost">{$order.cost ?: 0}</span> {'ms2_frontend_currency' | lexicon}
        </h3>
        <button type="submit" name="ms2_action" value="order/submit" class="btn btn-lg btn-primary ml-md-2 ms2_link">
            {'ms2_frontend_order_submit' | lexicon}
        </button>
    </div>
</form>
Станислав
20 октября 2023, 10:37
0
Нужно использовать в разметке переменную MIGX_id, как в разметке полей, так и в разметке колонок
Игорь
20 октября 2023, 10:23
0
Здравствуйте.
Как можно сделать множественный список ресурсов?
Стандартный вариант (добавить в поле «Список (множественный выбор)» запрос mysql или сниппет) здесь не срабатывает…
@EVAL return $modx->runSnippet('pdoResources', array(
	'parents' => 3,
	'limit' => 0,
	'tpl' => '@INLINE {$pagetitle}=={$id}',
	'outputSeparator' => '||',
	'sortby' => '{"menuindex":"ASC"}'
  ));
Сергей Карпович
19 октября 2023, 12:22
0
Подскажите нет ли проблем с Вьетнамским языком у компонента.
У себя на сайте введены настройки соответствия языка браузера с локализацией, по всем языкам работает.кроме вьетнамского.
В настройке polylang_geo_language_country, прописано «vn»:«vn»

{"ab":"ru","az":"ru","ay":"en","sq":"en","am":"en","en":"en","ar":"ru","hy":"en","as":"en","aa":"en","af":"en","eu":"en","ba":"en","bn":"en","my":"en","bi":"en","bh":"en","bg":"en","br":"en","dz":"en","cy":"en","wa":"en","hu":"en","vo":"en","wo":"en","vi":"en","gl":"en","kl":"en","el":"en","ka":"en","gn":"en","gu":"en","gd":"en","gv":"en","da":"en","he":"en","zu":"en","yi":"en","ia":"en","ie":"en","iu":"en","ik":"en","ga":"en","is":"en","es":"es","it":"en","yo":"en","kk":"ru","km":"en","kn":"en","ca":"en","ks":"en","qu":"en","rw":"en","ky":"en","rn":"en","zh":"en","zh":"en","ko":"en","co":"en","xh":"en","ku":"en","lo":"en","lv":"en","la":"en","li":"en","ln":"en","lt":"en","mk":"en","mg":"en","ms":"en","ml":"en","mt":"en","mi":"en","mr":"en","mo":"en","mn":"en","na":"en","ne":"en","nl":"en","no":"en","oc":"en","or":"en","om":"en","pa":"en","pl":"en","pt":"pt","ps":"en","rm":"en","ro":"en","ru":"ru","sm":"en","sg":"en","sa":"en","ss":"en","sh":"en","sr":"en","st":"en","si":"en","sd":"en","sk":"en","sl":"en","so":"en","sw":"en","su":"en","tl":"en","tg":"en","th":"en","ta":"en","tt":"en","te":"en","bo":"en","ti":"en","to":"en","tn":"en","ts":"en","tk":"en","uz":"en","ug":"en","uk":"ru","ur":"en","fo":"en","fa":"en","fj":"en","fi":"en","fr":"fr","fy":"en","ha":"en","hi":"en","hr":"en","tw":"en","cs":"en","sv":"en","sn":"en","eo":"en","et":"en","jv":"en","ja":"en","de":"de","at":"de","be":"de","vn":"vn"}
Определение по IP не используем
Сергей Карпович
19 октября 2023, 08:54
0
Тоже интересует вопрос, как созданные поля перемещать по форме ресурса…
И также вопрос как отключать созданные поля для отдельных шаблонов?
Олег Захаров
18 октября 2023, 22:43
0
Автор компонента ни в личку не отвечает, ни тут. Печаль…