cancel
Showing results for 
Search instead for 
Did you mean: 

Ajax does not work second time

SOLVED
   Did you know you can see the translated content as per your choice?

Translation is in progress. Please check again after few minutes.

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);
   
        }
    
    }
1 ACCEPTED SOLUTION

Accepted Solutions

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".

View solution in original post

9 REPLIES 9

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. Get Magento insight from
Magento 2 Blogs/Tutorial

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. Get Magento insight from
Magento 2 Blogs/Tutorial

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".

Re: Ajax does not work second time

Can you please explain the solution in detail as I'm also stuck on the same issue, ajax working only one time.