mati7716 Posted December 27, 2023 Share Posted December 27, 2023 I created a module that displays to the customer the amount required for free delivery. The module displays the missing values correctly, the problem is that when the customer increases the number of products in the basket, the module does not update in real time, only after restarting the page Free shipping is over $50. 1. The customer adds a product to the cart for $20 and then goes to it 2. The customer is in the cart and a message is displayed that $30 is missing for free delivery. 3. The customer adds a second product to the cart while still in it (clicks the + button) 4. The module does not immediately change the value that the customer is missing $10, this is visible after refreshing the page (F5) What should I do to make the module update in real time and not after refreshing the page? Module code: <?php if (!defined('_PS_VERSION_')) { exit; } class FreeDeliveryIndicator extends Module { public function __construct() { $this->name = 'freedeliveryindicator'; $this->tab = 'shipping_logistics'; $this->version = '1.0.0'; $this->author = 'Name'; $this->need_instance = 0; $this->ps_versions_compliancy = ['min' => '1.7', 'max' => _PS_VERSION_]; $this->bootstrap = true; parent::__construct(); $this->displayName = $this->l('Wskaźnik Darmowej Dostawy'); $this->description = $this->l('Pokazuje klientom, ile brakuje do darmowej dostawy.'); $this->confirmUninstall = $this->l('Czy na pewno chcesz odinstalować?'); } public function install() { return parent::install() && $this->registerHook('displayShoppingCartFooter') && $this->registerHook('displayHeader') && Configuration::updateValue('FREESHIPPINGLIMIT', 80); } public function uninstall() { Configuration::deleteByName('FREESHIPPINGLIMIT'); return parent::uninstall(); } public function getContent() { $output = null; if (Tools::isSubmit('submit'.$this->name)) { $freeShippingLimit = (float)Tools::getValue('FREESHIPPINGLIMIT'); if (!$freeShippingLimit || empty($freeShippingLimit) || !Validate::isFloat($freeShippingLimit)) { $output .= $this->displayError($this->l('Invalid Configuration value')); } else { Configuration::updateValue('FREESHIPPINGLIMIT', $freeShippingLimit); $output .= $this->displayConfirmation($this->l('Settings updated')); } } return $output.$this->displayForm(); } private function displayForm() { // Get default configuration value $default_limit = (float)Configuration::get('FREESHIPPINGLIMIT'); // Build form $fields_form[0]['form'] = [ 'legend' => [ 'title' => $this->l('Settings'), ], 'input' => [ [ 'type' => 'text', 'label' => $this->l('Free shipping limit'), 'name' => 'FREESHIPPINGLIMIT', 'size' => 7, 'required' => true, 'desc' => $this->l('Set the total amount for free shipping.'), ], ], 'submit' => [ 'title' => $this->l('Save'), 'class' => 'btn btn-default pull-right' ] ]; $helper = new HelperForm(); $helper->module = $this; $helper->name_controller = $this->name; $helper->token = Tools::getAdminTokenLite('AdminModules'); $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name; $helper->title = $this->displayName; $helper->submit_action = 'submit'.$this->name; $helper->fields_value['FREESHIPPINGLIMIT'] = $default_limit; return $helper->generateForm($fields_form); } public function hookDisplayHeader() { $this->context->controller->addCSS($this->_path.'views/css/progress-bar.css'); $this->context->controller->addJS($this->_path.'views/js/front.js'); } public function hookDisplayShoppingCartFooter($params) { $cart = $params['cart']; $total = $cart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING); $freeShippingLimit = (float)Configuration::get('FREESHIPPINGLIMIT'); $amountLeftForFreeShipping = max(0, $freeShippingLimit - $total); $progressPercentage = $total / $freeShippingLimit * 100; $progressPercentage = min(100, max(0, $progressPercentage)); $this->context->smarty->assign([ 'amountLeftForFreeShipping' => $amountLeftForFreeShipping, 'progressPercentage' => $progressPercentage, ]); return $this->display(__FILE__, 'views/templates/hook/indicator.tpl'); } } Link to comment Share on other sites More sharing options...
ps8modules Posted December 28, 2023 Share Posted December 28, 2023 (edited) Hi. Unfortunately, I can't see the TPL file and I don't know the id of the element for ajax update, so in short. Module (update): public function hookDisplayHeader() { if ($this->context->controller->php_self == 'cart') { $this->context->controller->addCSS($this->_path.'views/css/progress-bar.css'); $this->context->controller->addJS($this->_path.'views/js/front.js'); $ajax = $this->context->shop->getBaseURL(true).'modules/'.$this->name.'/ajax/ajax.php?token='.Tools::encrypt($this->name.'/ajax.php'); $jsDef = [ 'freedeliveryindicator_ajaxcart' => $ajax, ]; Media::addJsDef($jsDef); } } public function hookDisplayShoppingCartFooter() { $cart = new Cart($this->context->cart->id); $total = $cart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING); $freeShippingLimit = (float)Configuration::get('FREESHIPPINGLIMIT'); $amountLeftForFreeShipping = max(0, $freeShippingLimit - $total); $progressPercentage = $total / $freeShippingLimit * 100; $progressPercentage = min(100, max(0, $progressPercentage)); $this->context->smarty->assign([ 'amountLeftForFreeShipping' => $amountLeftForFreeShipping, 'progressPercentage' => $progressPercentage, ]); return $this->display(__FILE__, 'views/templates/hook/indicator.tpl'); } AJAX PHP ($this->_path.'ajax/ajax.php'): <?php header("Access-Control-Allow-Origin: *"); include('../../../config/config.inc.php'); include('../../../init.php'); $module_name = 'freedeliveryindicator'; $token = pSQL(Tools::encrypt($module_name.'/ajax.php')); $token_url = pSQL(Tools::getValue('token')); $context = Context::getContext(); $module = Module::getInstanceByName($module_name); $db = Db::getInstance(); if ($token != $token_url || !Module::isInstalled($module_name)) { echo($module->l('AJAX error')); } if ($module->active && Tools::getValue('action') == 'updateDisplayShoppingCartFooter') { $cart = new Cart($context->cart->id); $total = $cart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING); $freeShippingLimit = (float)Configuration::get('FREESHIPPINGLIMIT'); $amountLeftForFreeShipping = max(0, $freeShippingLimit - $total); $progressPercentage = $total / $freeShippingLimit * 100; $progressPercentage = min(100, max(0, $progressPercentage)); $returnParams = array(); $returnParams['amountLeftForFreeShipping'] = $amountLeftForFreeShipping; $returnParams['progressPercentage'] = $progressPercentage; echo json_encode($returnParams); } front.js (update): $(document).ajaxStart(function() { if(typeof prestashop !== 'undefined') { prestashop.on( 'updateCart', function (event) { if (event && event.reason && typeof event.resp !== 'undefined' && !event.resp.hasError) { updateDisplayShoppingCartFooter(); } } ); } }); function updateDisplayShoppingCartFooter() { // call ajax function $.ajax({ type: "POST", url: freedeliveryindicator_ajaxcart, // defined in module.php data: { action: 'updateDisplayShoppingCartFooter', // call action ajax.php }, async: false, cache: false, dataType: 'json', success: function(data) { if (data !== '') { if (data['amountLeftForFreeShipping'] !== '' && data['progressPercentage'] !== '') { // here update values in TPL file with element id or name ... $('#amountLeftForFreeShipping').text(data['amountLeftForFreeShipping']); $('#progressPercentage').attr('style', 'width:'+data['progressPercentage']+'%'); if (data['progressPercentage'] < 100) { $('#freedeliveryindicator').show(); } else { $('#freedeliveryindicator').hide(); } } } } }); } Indicator.tpl (update): <div id="freedeliveryindicator" style="{if $progressPercentage < 100}display:block;{else}display:none;{/if}"> {if $amountLeftForFreeShipping > 0} <div class="free-delivery-info"> {l s='Still missing' mod='freedeliveryindicator'} <span id="amountLeftForFreeShipping">{Tools::displayPrice($amountLeftForFreeShipping)}</span> {l s='for free delivery' mod='freedeliveryindicator'} </div> <div class="progress-bar-container"> <div id="progressPercentage" class="progress-bar" style="width: {$progressPercentage}%;"></div> </div> {/if} </div> Edited December 29, 2023 by ps8moduly.cz added indicator.tpl (see edit history) Link to comment Share on other sites More sharing options...
mati7716 Posted December 28, 2023 Author Share Posted December 28, 2023 I updated the code according to your instructions, and the shopping cart does not work. indicator.tpl -> {if $amountLeftForFreeShipping > 0} <div class="free-delivery-info"> Brakuje jeszcze {$amountLeftForFreeShipping} zł do darmowej dostawy </div> <div class="progress-bar-container"> <div class="progress-bar" style="width: {$progressPercentage}%;"> </div> </div> {/if} Link to comment Share on other sites More sharing options...
mati7716 Posted December 28, 2023 Author Share Posted December 28, 2023 I have added the entire file in the attachment. I've tried everything and the module still doesn't listen to the cart in real time. Could you tell me what I'm doing wrong? freedeliveryindicator.rar Link to comment Share on other sites More sharing options...
ps8modules Posted December 28, 2023 Share Posted December 28, 2023 (edited) Hi. When I look in your module, none of the changes I gave you here exist. There is no ajax.php file, no front.js, no modified hookDisplayHeader and more. I also don't see a treatment for carriers where shipping will be free. It only calculates and displays the number remaining until free shipping. This must be stored in the delivery configuration. Edited December 28, 2023 by ps8moduly.cz (see edit history) Link to comment Share on other sites More sharing options...
mati7716 Posted December 28, 2023 Author Share Posted December 28, 2023 I am uploading the corrected module with your code. First I want to focus on how the module works in real time, this is a problem for me because it doesn't work Frontend dead after adding a module with your code freedeliveryindicator.rar Link to comment Share on other sites More sharing options...
mati7716 Posted December 28, 2023 Author Share Posted December 28, 2023 I think I'm entering the wrong selectors for tracking. I'm uploading the module, could you take a look at it and tell me what I'm doing wrong. freedeliveryindicator.rar Link to comment Share on other sites More sharing options...
ps8modules Posted December 28, 2023 Share Posted December 28, 2023 It is necessary to understand that in the TPL you do not have the id of the elements that JavaScript should overwrite for you, and the values from the basket are not loaded correctly. Here you have a module that does what you want, including translation and for different currencies (the default price in the e-shop is taken). freedeliveryindicator.zip Install the module normally and you will be amazed 😄 Don't forget to clear the cache, otherwise javascript won't load correctly. Link to comment Share on other sites More sharing options...
mati7716 Posted December 28, 2023 Author Share Posted December 28, 2023 Thank you very much, could you tell me again what I did wrong that made AJAX not work? Link to comment Share on other sites More sharing options...
ps8modules Posted December 28, 2023 Share Posted December 28, 2023 (edited) It's easy, compare your files and mine 😏 You need to learn and look for your own mistakes. Then you'll remember it. You can like by clicking on the gray heart below my posts. Edited December 28, 2023 by ps8moduly.cz (see edit history) 2 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now