- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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); } }
Solved! Go to Solution.
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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".
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)"} []
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Magento 2 Blogs/Tutorial
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Magento 2 Blogs/Tutorial
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 .= "";
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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>
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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>
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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".
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.