cancel
Showing results for 
Search instead for 
Did you mean: 

Ajax does not work second time

SOLVED

Ajax does not work second time

Ajax does not work second time.

I have created a custom module to update custom options.

It works with a button, however it does not work well with Ajax.

 

Screen Shot 2018-04-13 at 10.23.28.png

 

 

Do you have any suggestions for what I can do?

 

My post was removed when I was editing it to make it clear for everyone.

 

Frontend:

require(['jquery',  'Magento_Checkout/js/action/get-payment-information',
'Magento_Checkout/js/model/quote',
'mage/storage'], function($,   getPaymentInformationAction, quote){


 $(document).on( "click", ".product-custom-option", function() {



        $('#loading-mask').show();
       
        var data = $( "#form-validate" ).serialize();

        data.form_key = window.FORM_KEY;
        data.update_cart_action = "update_ajax_options";



            $.ajax({
            type: "POST",
            url: "<?=  $block->getUrl('checkout/cart/updatePost') ?>",
            data: data + "&update_cart_action=update_ajax_options",
            success: function (data) {
              console.log(data.cartcontent);

                var totalsData=data.subtotaldata.totalsData;
                quote.setTotals(totalsData);
                if(data.cartcontent && Number(totalsData.subtotal)>0){
                $('.cart-container form#form-validate').replaceWith(data.cartcontent);
                $('[data-block="minicart"]').trigger('contentLoading');
                $('[data-block="totals"]').trigger('contentLoading');
                $('.cart-sidebar .checkout-methods-items').replaceWith(data.checkout_method);
                
               // $('.item-options').replaceWith(data.item-options);
                $('.cart-sidebar').trigger('contentUpdated');


                    if ($(".messages")[0]){
                    $('.messages').replaceWith(data.page_messages);
                    }/**/
 }    




             $('#loading-mask').hide();
            },
            failure: function (errMsg) {
                console.log(errMsg);
                $('#loading-mask').hide();
            }
            }) 





      });


});

in UpdatePost.php

  public function execute()
    {

        $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->addInfo("execute");
          /** @var \Magento\Framework\Controller\Result\Json $resultJson */
      

        if (!$this->_formKeyValidator->validate($this->getRequest())) {
         //   return $this->resultRedirectFactory->create()->setPath('*/*/');
        }
   
        $updateAction = (string)$this->getRequest()->getParam('update_cart_action');
    
        switch ($updateAction) {
            case 'empty_cart':
                $this->_emptyShoppingCart();
            break;
            case 'update_qty':
                $this->_updateShoppingCart();
            break;
            case 'update_ajax_options':     
            $this->_updateShoppingCart();
            return $this->_getTotalsHtml();
            break;     
            default:
            $this->_updateShoppingCart();
             
        }
        return $this->_goBack();
    }




protected function _getTotalsHtml()
    {

        $response2 = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
        $layout = $response2->addHandle('checkout_cart_index')->getLayout();
        $response['cartcontent'] = $this->_view->getLayout()->getBlock('checkout.cart.form')->toHtml();
        $response['checkout_method'] = $this->_view->getLayout()->getBlock('checkout.cart.methods.bottom')->toHtml();
        $response['page_messages'] = $this->_view->getLayout()->getBlock('checkout.cart.validationmessages')->toHtml();
       // $response['cart_item'] = $this->_view->getLayout()->getBlock('checkout.cart.item')->toHtml();
        $response['content'] = $layout->renderNonCachedElement('checkout.cart.empty');
        $cartQuote= $this->cart->getQuote()->setTotalsCollectedFlag(false)->collectTotals();
        $response['subtotaldata'] = $this->_objectManager->create('Magento\Checkout\Model\DefaultConfigProvider')->getConfig();    
        $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
        $resultJson->setData($response);
        
        
        $this->_checkoutSession->getQuote()->collectTotals()->save();
        
        return $resultJson;

    
}
    protected function  _updateAjaxOptions(){



        $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->addInfo("_updateAjaxOptions");
        $this->_updateShoppingCart();
       
        return;
  


    }

    /**
     * Reload cart to display custom options correctly in AJAX response  
     */
    protected function _reloadCart()
    {

        $currQuoteId = $this->_checkoutSession->getQuoteId(); 
       $this->_checkoutSession->unsetAll();
        $this->_checkoutSession->setQuoteId($currQuoteId);
        $cart = $this->cart;

        if ($cart->getQuote()->getItemsCount()) 
        {
            $cart->save();
        }
    }
/**
     * Update customer's shopping cart
     *
     * @return void
     */
    protected function _updateShoppingCart()
    {

        $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->addInfo("_updateShoppingCart");
  
        try {
            $cartData = $this->getRequest()->getParam('cart');

            $this->_checkoutSession->setMyValue($cartData);

            if (is_array($cartData)) {
                $filter = new \Zend_Filter_LocalizedToNormalized(
                    ['locale' => $this->_objectManager->get(
                        \Magento\Framework\Locale\ResolverInterface::class
                    )->getLocale()]
                );
                foreach ($cartData as $index => $data) {
                    if (isset($data['qty'])) {
                        $cartData[$index]['qty'] = $filter->filter(trim($data['qty']));
                    }
                }
                if (!$this->cart->getCustomerSession()->getCustomerId() && $this->cart->getQuote()->getCustomerId()) {
                    $this->cart->getQuote()->setCustomerId(null);
                }
           
                $cartData = $this->cart->suggestItemsQty($cartData);
                $this->cart->updateItems($cartData)->save();

                $this->_reloadCart();
           
                $this->_checkoutSession->setMyValue($cartData);
                
            }
        } catch (\Magento\Framework\Exception\LocalizedException $e) {
            $this->messageManager->addError(
                $this->_objectManager->get(\Magento\Framework\Escaper::class)->escapeHtml($e->getMessage())
            );

        } catch (\Exception $e) {
            $this->messageManager->addException($e, __('We can\'t update the shopping cart.'));
            $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
   
        }
    
    }

8 REPLIES

Re: Ajax does not work second time

It only gets this error in exception.log. I am not sure if it's related to the problem I have.

 

 main.CRITICAL: Dotmailer connector API endpoint cannot be empty. {"exception":"[object] (Magento\\Framework\\Exception\\LocalizedException(code: 0): Dotmailer connector API endpoint cannot be empty. at /vendor/dotmailer/dotmailer-magento2-extension/Model/Apiconnector/Client.php:118)"} []

Re: Ajax does not work second time

You can just disable Dotmailer Module by app/etc/config.php with

'Dotdigitalgroup_Email' => 0,

remove generated folder from root and check again. If Still not working then enable dotmailer module and issue related to your custom module.

If Issue Solved, Click Kudos/Accept As solutions.

Re: Ajax does not work second time

It still the same. It looks like it's not updating input values ... for instance when there is a checked checkbox and a customer unchecked it, it does not mark as unchecked - stay checked in the backend, but it displayes as unchecked.

 

I can change quantity  on 2nd time, it's just custom options stops working.

 

If refresh the page it works again, I think it's matter of refreshing cart in backend.

 

Re: Ajax does not work second time

You need to create sections.xml file in your module etc/frontend scope,

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="[frontName]/[ActionPath]/[ActionName]">
        <section name="cart"/>
    </action>
</config>

You need to set in above  [frontName]/[ActionPath]/[ActionName] from your module name.

You need to set [frontName]/[ActionPath]/[ActionName] from your module name.

If Issue Solved, Click Kudos/Accept As solutions.

Re: Ajax does not work second time

Maybe it's because I'm using a custom code on Catalog/Product/Options/Type/Select.php.

Any suggestions...?

in function getValuesHtml();

        $this->setSkipJsReloadPrice(1);
        // Remove inline prototype onclick and onchange events

        if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_DROP_DOWN ||
            $_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_MULTIPLE
        ) {
            $require = $_option->getIsRequire() ? ' required' : '';
            $extraParams = '';
            $select = $this->getLayout()->createBlock(
                \Magento\Framework\View\Element\Html\Select::class
            )->setData(
                [
                    'id' => 'select_' . $_option->getId(),
                    'class' => $require . ' product-custom-option admin__control-select'
                ]
            );
            if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_DROP_DOWN) {
                $select->setName('options[' . $_option->getid() . ']')->addOption('', __('-- Please Select --'));
            } else {
                $select->setName('options[' . $_option->getid() . '][]');
                $select->setClass('multiselect admin__control-multiselect' . $require . ' product-custom-option');
            }
            foreach ($_option->getValues() as $_value) {
                $priceStr = $this->_formatPrice(
                    [
                        'is_percent' => $_value->getPriceType() == 'percent',
                        'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'),
                    ],
                    false
                );
                $select->addOption(
                    $_value->getOptionTypeId(),
                    $_value->getTitle() . ' ' . strip_tags($priceStr) . '',
                    ['price' => $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false)]
                );
            }
            if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_MULTIPLE) {
                $extraParams = ' multiple="multiple"';
            }
            if (!$this->getSkipJsReloadPrice()) {
                $extraParams .= ' onchange="opConfig.reloadPrice()"';
            }
            $extraParams .= ' data-selector="' . $select->getName() . '"';
            $select->setExtraParams($extraParams);

            if ($configValue) {
                $select->setValue($configValue);
            }

            return $select->getHtml();
        }

        if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_RADIO ||
            $_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_CHECKBOX
        ) {

   
            $selectHtml = '<div class="options-list nested" id="options-' . $_option->getId() . '-list">';
            $require = $_option->getIsRequire() ? ' required' : '';
            $arraySign = '';
            switch ($_option->getType()) {
                case \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_RADIO:
                    $type = 'radio';
                    $class = 'radio admin__control-radio';
                    if (!$_option->getIsRequire()) {
                        $selectHtml .= '<div class="field choice admin__field admin__field-option">' .
                            '<input type="radio" id="options_' .$iCurrentItemId.'_'.
                            $_option->getId() .
                            '" class="' .
                            $class .
                            ' product-custom-option" '. 
                         ($this->_request->getFullActionName()=="checkout_cart_index"? 
                            'name="cart['.$iCurrentItemId.'][cart_options][' .$_option->getId() .'] ' 
                            : 'name="options[' .$_option->getId() .']"' ).
                            ' data-selector="options[' . $_option->getId() . ']"' .
                            ($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') .
                            ' value=""'.
                            
                            ($this->_request->getFullActionName()=="checkout_cart_index" ? '' : 'checked="checked"' )
                            
                            
                            .'
                            
                             /><label class="label admin__field-label" for="options_' .
                            $_option->getId() .
                            '"><span>' .
                            __('None') . '</span></label></div>';




$selectHtml .= "";

 

Re: Ajax does not work second time

Thank you,

 

I have created sections.xml and placed this code below, but it remains same:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="checkout/cart/updatepost">
        <section name="cart"/>
    </action>
</config>

Re: Ajax does not work second time

I have created routes.xml and sections.xml. However the problem is still there.

 

routes.xml

<?xml version="1.0"?>
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
    <router id="standard">
        <route id="vender_module" frontName="vender_module">
            <module name="Vender_Module" />
        </route>
    </router>
</config>

sections.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="vender_module/checkout/updatepost">
        <section name="cart"/>
    </action>
</config>

 

Re: Ajax does not work second time

I have fixed the issue. When it's loading layout after ajax call, it was writing a wrong html as there is a condition to see if this is "checkout_cart_index". As this was "checkout_cart_Updatepost", it should load the same code as "checkout_cart_index".