<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Форум ReadyScript &mdash; Редактирование полей заказа из AJAX контроллера]]></title>
	<link rel="self" href="http://forum.readyscript.ru/feed/atom/topic/542/" />
	<updated>2015-12-10T15:38:18Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.readyscript.ru/topic/542/redaktirovanie-polei-zakaza-iz-ajax-kontrollera/</id>
		<entry>
			<title type="html"><![CDATA[Re: Редактирование полей заказа из AJAX контроллера]]></title>
			<link rel="alternate" href="http://forum.readyscript.ru/post/2321/#p2321" />
			<content type="html"><![CDATA[<p>Хорошо. Ждём решения. Если нужна помощь и с административной частью, то мы поможем:) Обращайтесь.</p>]]></content>
			<author>
				<name><![CDATA[Закусило Александр]]></name>
				<uri>http://forum.readyscript.ru/user/20/</uri>
			</author>
			<updated>2015-12-10T15:38:18Z</updated>
			<id>http://forum.readyscript.ru/post/2321/#p2321</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Редактирование полей заказа из AJAX контроллера]]></title>
			<link rel="alternate" href="http://forum.readyscript.ru/post/2320/#p2320" />
			<content type="html"><![CDATA[<p>Спасибо, за разъяснения. Буду пробовать. Правда переделывать много придется, так как в ожидании ответа я уже еще одну реализацию написал (я отлавливал AJAX в методе getAddittionalHtml): <br /></p><div class="codebox"><pre><code>function getAddittionalHtml(\Shop\Model\Orm\Delivery $delivery, \Shop\Model\Orm\Order $order = null)
    {
        //return var_dump($this);
        $request = \RS\Http\Request::commonInstance();
        if (!$order) {
            $order = \Shop\Model\Orm\Order::currentOrder();
        }
        $extra = $order-&gt;getExtraInfo();
        $imlData = $extra[&#039;iml_data&#039;][&#039;data&#039;];

        $view = new \RS\View\Engine();
        $view-&gt;assign(array(
            &#039;region_id_to&#039;       =&gt; $imlData[&#039;region_id_to&#039;],       //Регион куда
            &#039;region_id_from&#039;     =&gt; $this-&gt;getOption(&#039;region_id_from&#039;),     //Регион откуда
            &#039;service_ids&#039;        =&gt; json_encode($this-&gt;getActiveServices()),             //Услуги этогй доставки
            &#039;delivery_cost_json&#039; =&gt; json_encode($this-&gt;getImlCost($order)),         //Текущий объект цены доставки
            &#039;delivery_cost&#039;      =&gt; $this-&gt;getImlCost($order),         //Текущий объект цены доставки
            &#039;order&#039;              =&gt; $order,                                 //Текущий недоофрмленный заказ
            &#039;delivery&#039;           =&gt; $delivery,                              //Текущий объект доставки
            &#039;user&#039;               =&gt; \RS\Application\Auth::getCurrentUser(), //Текущий объект пользователя
        ) + \RS\Module\Item::getResourceFolders($this)); 

        if ($request-&gt;isAjax() &amp;&amp; $this-&gt;getOption(&#039;show_map&#039;) == 1) {
            $action = $request-&gt;request(&#039;action&#039;, TYPE_STRING, &#039;&#039;);
            $params = $request-&gt;request(&#039;params&#039;, TYPE_ARRAY, &#039;&#039;);

            switch ($action) {

                case &#039;loadMap&#039;:
                    return $view-&gt;fetch(&#039;%imldelivery%/delivery/iml/map.tpl&#039;);;
                    break;

                default:
                    $output = $this-&gt;$action($params);
                    $view-&gt;assign(array(
                        &#039;output&#039; =&gt; json_encode($output),
                        &#039;action&#039; =&gt; $action
                    ));
                    return $view-&gt;fetch(&#039;%imldelivery%/delivery/iml/ajax_data.tpl&#039;);
                    break;

            }
        }

        if ($this-&gt;getOption(&#039;show_map&#039;) == 1) {
            return $view-&gt;fetch(&#039;%imldelivery%/delivery/iml/widget.tpl&#039;);
        }
        
    }</code></pre></div><p>Только не ругайте, сейчас я это сотру, все по уму сделаю и отпишусь как вышло.</p>]]></content>
			<author>
				<name><![CDATA[Денис]]></name>
				<uri>http://forum.readyscript.ru/user/194/</uri>
			</author>
			<updated>2015-12-10T14:51:12Z</updated>
			<id>http://forum.readyscript.ru/post/2320/#p2320</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Редактирование полей заказа из AJAX контроллера]]></title>
			<link rel="alternate" href="http://forum.readyscript.ru/post/2308/#p2308" />
			<content type="html"><![CDATA[<p>Отпишитесь если нужна помощь пожалуйста.</p>]]></content>
			<author>
				<name><![CDATA[Закусило Александр]]></name>
				<uri>http://forum.readyscript.ru/user/20/</uri>
			</author>
			<updated>2015-12-08T15:56:29Z</updated>
			<id>http://forum.readyscript.ru/post/2308/#p2308</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Редактирование полей заказа из AJAX контроллера]]></title>
			<link rel="alternate" href="http://forum.readyscript.ru/post/2303/#p2303" />
			<content type="html"><![CDATA[<p>Всё гораздо проще чем Вы думаете. Никакого контроллера делать не нужно у нас всё для этого предусмотрено.<br />Вам надо отловить событие когда пользователь меняет пункт выдачи. После чего сделать запрос на фронт контроллер:</p><p><strong>/shop/controller/front/checkout.inc.php</strong> он же в качестве маршрута <strong>shop-front-checkout</strong> (смотрите файл <strong>handlers.inc.php</strong> в модуле <strong>shop</strong>)<br />Соответственно url для обращения будет /checkout/useract/</p><p>Там есть метод <strong>actionUserAct</strong>. Он позволяет вызвать пользовательский метод из Вашего класса доставки или оплаты. В Вашем случае доставки.</p><p>Он принимает несколько параметров:<br />1. module - Имя модуля (По умолчанию Shop, у Вам соответственно Ваше название папки модуля)<br />2. typeObj - (0 или 1)&nbsp; 0 - доставка (DeliveryType), 1 - оплата (PaymentType)<br />3. typeId - id доставки или оплаты<br />4. class - Класс для обращения, т.е. класс который будет вызван.<br />5. userAct - Статический метод который нужно вызвать<br />6. params - Дополнительные параметры для передачи в метод<br />Описание типов переменных и, то что они принимают можно посмотреть в самом файле я думаю проблем не возникнет.</p><p>Соответственно мы можем сформировать запрос через AJAX, вот пример кода для доставки axiomus:<br /></p><div class="codebox"><pre><code>var $_this = $(this);
$.ajax({
                url  : $_this.data(&#039;url&#039;),
                type : &#039;POST&#039;,    
                dataType : &#039;json&#039;,    
                data : {
                    module  : &#039;Axiomus&#039;,
                    typeObj : 0, //Доставка
                    typeId  : $_this.data(&#039;delivery-id&#039;),
                    &#039;class&#039; : &#039;Axiomus&#039;,
                    userAct : &#039;getChangedDelivery&#039;,
                    params  : {
                        order : { //Объект заказа
                            way   : $_this.data(&#039;way&#039;),
                            key   : $_this.data(&#039;key&#039;),
                            value : office
                        }
                    }
                },
                success : function(response){
                   if (response.success){
                       $(data.options.axiomusCostId + $_this.data(&#039;delivery-id&#039;)).html(response.data);
                   } 
                }
            });</code></pre></div><p>Мы в шаблоне добавляем там свой js который обслуживает обработку этих событий и следит за выбором пользователя.<br /></p><div class="codebox"><pre><code>{addjs file=&quot;%axiomus%/delivery/axiomus_widjet.js&quot;}</code></pre></div><p>Поэтому я дополнительно скину код javascript самого модуля доставки Axiomus. Он не решит Ваших всех проблем, но там можно подсмотреть реализацию.<br /></p><div class="codebox"><pre><code>(function( $ ){
   $.AxiomusWidjetCreator = function( method ) {
        //Найдём ближайший input c выбором
        var closestRadio = $(&#039;input[name=&quot;delivery&quot;]:eq(0)&#039;);        
        var form         = closestRadio.closest(&#039;form&#039;); //найдем форму
       
        var defaults = {            
           axiomusDiv      : &#039;.axiomusDeliveryBlock&#039;, //Контейнер куда будет вставлятся информация Axiomus
           axiomusAdress   : &#039;.axiomusAdress&#039;, //Куда вставляется адрес
           axiomusSchedule : &#039;.axiomusSchedule&#039;, //Блок с расписанием работы
           axiomusCostId   : &#039;#scost_&#039; //Идентификатор блока с ценой за доставку
        },
        
        $this = form,
        data  = $this.data(&#039;axiomusInfo&#039;);
        
        if (!$this.length) return;
        if (!data) { //Инициализация
            data = { options: defaults };
            $this.data(&#039;axiomusInfo&#039;, data);
        }
        
        //public
        var methods = {
            /**
            * Инициализация плагина
            * 
            * @param initoptions - введённые пераметра для записи или перезаписи
            */
            init: function(initoptions) 
            {
                data.options = $.extend(data.options, initoptions);
                
                //Навесим все события
                presetAxiomusRadioEvents();
                
                //Если контент обновился (для заказа на одной странице)
                $(&#039;body&#039;).on(&#039;new-content&#039;,function(){
                    //Навесим события на переключатели
                    presetAxiomusRadioEvents();
                    
                    //Проверим выбор sheepla и если она выбрана, то вызовем соответсвующий метод
                    var selectedCheckbox = $(&#039;input[name=&quot;delivery&quot;]:checked&#039;);
                    if (typeof(selectedCheckbox.data(&#039;axiomus-div-id&#039;))!=&#039;undefined&#039;){ 
                    //  setOrClearAxiomusInfo(null, selectedCheckbox); 
                    }
                });
            },
            
            /**
            * Открывает доступность Axiomus для выбора
            * 
            * @param checkBoxObj  - объект с функциями Axiomus
            */
            showAxiomus : function (checkBoxObj)
            {       
                var parent   = checkBoxObj.data(&#039;axiomus-div-id&#039;);
                $(&quot;select&quot;,$(parent)).prop(&#039;disabled&#039;,false).change();
            },
            
            /**
            * Убирает доступность Axiomus для выбора из всех вариантов
            * и скрывает поля
            * 
            */
            clearAxiomus : function ()
            {       
               $(data.options.axiomusDiv+&quot; select&quot;).prop(&#039;disabled&#039;,true); 
            }
        }
        
        //private
        
        /**
        * Срабатывает при нажатии на выбранную доставку.
        * Если у этой доставки есть признак что если есть признак, что это Axiomus,
        * то ничего не делаем. Если нет признака, что подгружалось, 
        * 
        */
        var setOrClearAxiomusInfo = function (Event, item) 
        {
            if (Event === null){ //Если вызвали программно
                var $_this = item;
            }else{ //Если событие
                var $_this = $(this);
            }
            
            var dataAxiomusDiv = $_this.data(&#039;axiomus-div-id&#039;);
            if ( typeof(dataAxiomusDiv) != &#039;undefined&#039; ) { //Если это радиокнопка Axiomus
               methods.showAxiomus($_this);  //Стартуем            
            }else{
               methods.clearAxiomus();  //Очищаем    
            }
        },
        
        /**
        * Устанавливает события для обработки
        */
        presetAxiomusRadioEvents = function()
        {
            //Смена адреса доставки в выпадающем списке
            $(data.options.axiomusDiv+&quot; select&quot;,$this).off(&#039;change.axiomus&#039;).on(&#039;change.axiomus&#039;, changeAxiomusAdress);
            $(data.options.axiomusDiv+&quot; input[type=&#039;radio&#039;]&quot;, $this).off(&#039;change.axiomusradio&#039;).on(&#039;change.axiomusradio&#039;, changeAxiomusRadio);
            
            //Пройдёмся по контейнерам СДЕК
            $(data.options.axiomusDiv,$this).each(function(i){
                 //Найдём и отметим подходящие радиокнопки, которые относятся к СДЕК  
                 var deliveryId = $(this).data(&#039;delivery-id&#039;);
                 var radio      = $(&#039;input[name=&quot;delivery&quot;][value=&quot;&#039;+deliveryId+&#039;&quot;]&#039;);
                 //Перенесём данные к выборанной радио кнопке, чтобы можно было манипулировать
                 radio.data(&#039;axiomus-div-id&#039;,&quot;#&quot;+$(this).attr(&#039;id&#039;));
                 if (radio.prop(&#039;checked&#039;)){
                     $(&quot;select&quot;, $(radio.data(&#039;axiomus-div-id&#039;))).prop(&#039;disabled&#039;,false).change();
                 }
            });

            //Получим все радио кнопки
            var radioboxes = $(&#039;input[type=&quot;radio&quot;][name=&quot;delivery&quot;]&#039;,$this); //найдем radio
            
            //Навесим переключение радиокнопок 
            radioboxes.each(function(){
                $(this).off(&#039;click.axiomus&#039;).on(&#039;click.axiomus&#039;, setOrClearAxiomusInfo);
            });
            $(data.options.axiomusDiv+&quot; input[type=&#039;radio&#039;]:checked&quot;, $this).trigger(&#039;change.axiomusradio&#039;);
        },
        
        
        /**
        * Смена адреса доставки в выпадающем списке
        * 
        */
        changeAxiomusAdress = function()
        {
            var parent = $(this).closest(data.options.axiomusDiv);
            var info   = $(&quot;option:selected&quot;,$(this)).data(&#039;info&#039;);
            
            if (typeof(info.address)!=&#039;undefined&#039;){
                $(data.options.axiomusAdress, $(parent)).html(&quot;Адрес: &quot;+info.address); 
            }
            if (typeof(info.schedule)!=&#039;undefined&#039;){
                $(data.options.axiomusSchedule, $(parent)).html(info.schedule);
            }
            
            var office = $(this).val();
            var $_this = $(this);
            $.ajax({
                url  : $_this.data(&#039;url&#039;),
                type : &#039;POST&#039;,    
                dataType : &#039;json&#039;,    
                data : {
                    module  : &#039;Axiomus&#039;,
                    typeObj : 0,
                    typeId  : $_this.data(&#039;delivery-id&#039;),
                    &#039;class&#039; : &#039;Axiomus&#039;,
                    userAct : &#039;getChangedDelivery&#039;,
                    params  : {
                        order : { //Объект заказа
                            way   : $_this.data(&#039;way&#039;),
                            key   : $_this.data(&#039;key&#039;),
                            value : office
                        }
                    }
                },
                success : function(response){
                   if (response.success){
                       $(data.options.axiomusCostId + $_this.data(&#039;delivery-id&#039;)).html(response.data);
                   } 
                }
            })
        },
        
        /**
        * Смена переключателя типа забора для DPD
        * 
        */
        changeAxiomusRadio = function ()
        {
            var parent = $(this).closest(data.options.axiomusDiv);
            var val    = $(this).val();
            
            if (val==&quot;1&quot;){
               $(&quot;select&quot;, parent).prop(&#039;disabled&#039;, false); 
            }else{
               $(&quot;select&quot;, parent).prop(&#039;disabled&#039;, true);  
            }
        } 
        
       
        if ( methods[method] ) {
            methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === &#039;object&#039; || ! method ) {
            return methods.init.apply( this, arguments );
        }
   }     
})( jQuery );

$(document).ready(function(){
    $.AxiomusWidjetCreator();
});</code></pre></div><p>Послав запрос система сделает обращение к публичному статическому метод (<strong>public static function</strong>) Вашей доставки. В который передадутся несколько параметров. Например для случая с Axiomus и методом <strong>getChangedDelivery</strong>:</p><p>\Axiomus\Model\Deliverytype\Axiomus::getChangedDelivery($order - объект заказа, $delivery_id - id доставки, $params - Ваши дополнительные параметры, которые Вы передадите)</p><p>Теперь, что касается заказа. Заказ во время его оформления находится в сессии постоянно, поэтому Вы можете в него записывать &quot;на лету&quot; сразу и данные сохранятся, просто присвоив нужные значения не вызывая при этом insert или update. Эти методы системе понадобятся только один раз при создании самого заказа, когда пользователь подтвердил его создание.<br />Мы для записи данных рекомендуем использовать метод addExtraKeyPair у объекта заказа.<br /></p><div class="codebox"><pre><code>$order-&gt;addExtraKeyPair(&#039;ключ по которому можно достать данные&#039;, &#039;Значение для записи можно массив&#039;);</code></pre></div><p>А потом доставать данные с помощью:<br /></p><div class="codebox"><pre><code>$order-&gt;getExtraKeyPair(&#039;ключ по которому можно достать данные&#039;);</code></pre></div><p>Т.к. в таком случае эти данные можно будет достать и после физической записи заказа.</p><p>У заказа также есть метод addExtraInfoLine он позволит не только записать данные в заказ, но и инфомация будет доступна для отображения в админке при редактировании товара.</p>]]></content>
			<author>
				<name><![CDATA[Закусило Александр]]></name>
				<uri>http://forum.readyscript.ru/user/20/</uri>
			</author>
			<updated>2015-12-08T08:38:11Z</updated>
			<id>http://forum.readyscript.ru/post/2303/#p2303</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Редактирование полей заказа из AJAX контроллера]]></title>
			<link rel="alternate" href="http://forum.readyscript.ru/post/2282/#p2282" />
			<content type="html"><![CDATA[<p>Здравствуйте, я занимаюсь разработкой модуля доставки. Класс типа доставки почти готов, но неожиданно столкнулся с проблемой. <br />Дело в том, что модуль использует виджет карты, который выводится через метод getAddittionalHtml(). И далее, в нем реализовано изменение экстра-параметров заказа через AJAX. Обработчик AJAX запросов я разместил в отдельном фронт-контроллере. <br />Так вот в чем беда: когда я обращаюсь через AJAX к тем же функциям, что и через HTTP - система говорит мне, что я вызываю $this не из того контекста. В принципе ничего удивительного, только я никак не могу придумать как ее обмануть (написать правильно). В областях видимости совсем запутался. <br />Подскажите пожалуйста как это слелать.<br />Вот front-controller:<br /></p><div class="codebox"><pre><code>&lt;?php
namespace Imldelivery\Controller\Front;

/**
* Фронт контроллер
*/
class AjaxCtrl extends \RS\Controller\Front
{
    public
        $order,
        $iml;

    function init()
    {
        //$this-&gt;order = \Shop\Model\Orm\Order::currentOrder();
        $this-&gt;iml = new \Imldelivery\Model\DeliveryType\Iml();
    }   

    function actionIndex()
    {
        if ($this-&gt;url-&gt;isAjax()) {
            $action = $this-&gt;url-&gt;request(&#039;action&#039;, TYPE_STRING, &#039;&#039;);
            $params = $this-&gt;url-&gt;request(&#039;params&#039;, TYPE_ARRAY, &#039;&#039;);
            $output = $this-&gt;iml-&gt;$action($params);
            //$this-&gt;result-&gt;addSection(&#039;params&#039;, $params);
            return $this-&gt;result-&gt;addSection($action, $output);
        }
    }
}
?&gt;</code></pre></div><p>Вот AJAX:<br /></p><div class="codebox"><pre><code>function updatePrice () {
    var url = $(&#039;#selectRegionCombo&#039;).attr(&#039;data-ajax-action&#039;);
    $.ajax({
        url: url,
        type: &#039;POST&#039;,
        dataType: &#039;json&#039;,
        data: {action: &#039;getDeliveryCostAjax&#039;},
    })
    .done(function(data) {
        console.log(data.getDeliveryCostAjax);
    })
    .fail(function() {
        console.log(&quot;error&quot;);
    })
    .always(function() {
        console.log(&quot;complete&quot;);
    });  
}</code></pre></div><p>Вот функция из модели:<br /></p><div class="codebox"><pre><code>public function getDeliveryCostAjax()
    {
        $order = \Shop\Model\Orm\Order::currentOrder();
        $address = $order-&gt;getAddress();
        return $this-&gt;getDeliveryCost($order, $address);
    }
/**
    * Возвращает стоимость доставки для заданного заказа. Только число.
    * 
    * @param \Shop\Model\Orm\Order $order
    * @param \Shop\Model\Orm\Address $address - Адрес доставки
    * @return double
    */
    function getDeliveryCost(\Shop\Model\Orm\Order $order, \Shop\Model\Orm\Address $address = null, $use_currency = true)
    {
        //return &#039;&#039;;
        if(!$address) { 
            $address = $order-&gt;getAddress();
        }
        $delivery = $order-&gt;getDelivery(); 
        $cost = $this-&gt;getCost($order, $address);
        if (isset($cost[&#039;Price&#039;])) {
            return $cost[&#039;Price&#039;];
        } else {
            foreach ($cost as $error) {
                //$this-&gt;addError(t(&#039;Ошибка &#039;.$error.&#039;. &#039;.$error));
            }
            return $cost;
        }
    }
/**
     * Запрос базовой стоимости заказа у IML
     * 
     * @param  array|null $filters
     * @return array
     */
    function getCost(\Shop\Model\Orm\Order $order, \Shop\Model\Orm\Address $address = null)
    {
        $extra = $order-&gt;getExtraInfo();

        $content = array(
            &#039;Job&#039; =&gt; $this-&gt;getOption(&#039;service_id&#039;),            // услуга
            &#039;RegionFrom&#039; =&gt; $this-&gt;getOption(&#039;region_id_from&#039;), // регион отправки
            &#039;RegionTo&#039; =&gt; $extra[&#039;iml_region_to&#039;][&#039;value&#039;],   // регион получения
            &#039;Volume&#039; =&gt; &#039;1&#039;,            // кол-во мест  
            &#039;Weigth&#039; =&gt; $order-&gt;getWeight() ? $order-&gt;getWeight() : &#039;1&#039;,            // вес(кг)
            &#039;SpecialCode&#039; =&gt; $extra[&#039;iml_request_code&#039;][&#039;value&#039;]      // код пункта самовывоза(см. справочник пунктов самовывоза)
        );

        return $this-&gt;postApiRequest(self::URL_API_GETPRICE, self::API_LOGIN, self::API_PASS, $content);
    }</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Денис]]></name>
				<uri>http://forum.readyscript.ru/user/194/</uri>
			</author>
			<updated>2015-12-01T16:58:24Z</updated>
			<id>http://forum.readyscript.ru/post/2282/#p2282</id>
		</entry>
</feed>
