Scripts for using the platform

Scripts for the Hotlist.biz CMS SaaS platform

Instructions for using scripts

You can copy the path to the script file or its code and insert it into a block/menu on your website. It is recommended to place all scripts in a single block/menu. Such a block/menu can be placed in: «Service tags before the Body tag (Header Meta)», «Site Header», or «Site Footer».

When adding scripts directly via code (not via file path), the optimal way is to use the «Blocks / Menu» tool. Check «JavaScript / CSS style» and select the «JavaScript» mode. You can choose the «JavaScript – defer/async» mode for deferred loading, which further improves your site optimization.

This method ensures that when platform functions are updated or parameter/class names of elements on the site change, the elements will automatically update. Your code will also be correctly converted into a JS file. Since the block/menu immediately creates a JS file, be sure to remove the wrapper «<script type="text/javascript"> </script>».
It is recommended to use the «Design Editor» — «CSS Styles» tab to add CSS. It automatically optimizes the code by removing unnecessary spaces and empty lines.


Example of used scripts and functions
This list is useful for developers. You can modify built-in scripts and specify built-in callback functions.

🛍️ SHOP & PRODUCT SCRIPTS

💬 POPUPS & DIALOGS

🛒 CART & ORDER

📂 MENUS & NAVIGATION

⚙️ SYSTEM & INTERFACE

📰 BLOG

📅 BOOKING


🎨 A set of standard CSS styles.


Default styles loaded by the system. These styles are used in the basic version of the site, with templates applied on top. CSS files include standard styles for buttons, pages, menu items, and other elements.
Text messages for authorization: successful login, activation, errors.


Popup window

Instructions, an example, and automatic popup generation are available here: Popup window generator

[Example of button - popup with video]

Popup window with Forms

Instructions, an example, and automatic popup with forms generation are available here: Popup window with Forms generator

Replacing Variety Selection Text

The message about the need to select a product type is implemented in the dialog box using a CSS element. You can replace labels in CSS styles:
 Code: СSS
html:lang(ru) .hotengine-shop_cart_add_error_wrong_variety:after{ content:"Вы не выбрали разновидность товара."; }
html:lang(en) .hotengine-shop_cart_add_error_wrong_variety:after{ content:"You did not select a complete set of goods."; }
html:lang(uk) .hotengine-shop_cart_add_error_wrong_variety:after{ content:"Вы не обрали різновид товару."; }
html:lang(pl) .hotengine-shop_cart_add_error_wrong_variety:after{ content:"Nie wybrałeś typu produktu."; }


In order to replace the message about an unselected variety, in the product card, you need to add the callback_hotengine_variety_require function code (if the variety is not selected, before calling the message dialog box). The function starts when the variety is not selected.

In the product card, specify the text "Variety title". Depending on the text, the value for the «.hotengine-shop-product-variety-title» class changes. For example, if the text «Select weight:» is specified, then the title class will be «.hotengine-shop-product-variety-title_24». You can check the class when values ​​change by viewing the source code of the page, after specifying the variation header.

Text replacement code:
Code: html
<script type="text/javascript"> 
  <!-- 
  function callback_hotengine_variety_require(){

if($(".hotengine-shop-product-variety-title_24").length > 0){
  $text = "You haven`t chosen the weight!";
  } else if($(".hotengine-shop-product-variety-title_38").length > 0){
  $text = "You have not selected a quantity!";
  } else if($(".hotengine-shop-product-variety-title_26").length > 0){
  $text = "You have not chosen a color!";
  } else {
  $text = "You have not selected a variety!";
  }

$("body").append(`<div id="hotengine-shop_cart_add_error_wrong_variety"><b align="center" style="display:block;">${$text}</b><a class="hotengine-shop_cart_add_error_wrong_variety-btn-close" data-micromodal-close onclick="return false;"></a></div>
`); hotengine_micromodal({ id: "hotengine-shop-cart-add-error-wrong-variety", content: $("#hotengine-shop_cart_add_error_wrong_variety-data").html(), defaultWidth: $(window).width() > 410 ? "410px" : "90%", defaultHeight: "", minWidth: "290px", onCloseRemove: false, unsetContentHeight: true, onCloseEvent: function(){ $("#hotengine-shop-cart-add-error-wrong-variety,#hotengine-shop_cart_add_error_wrong_variety-data").remove(); } }); return false; } --> </script>

The popup will contain the specified text in the $text variable.

A similar function when viewing the list of products, callback_hotengine_variety_require_list($href), is supplemented with a link to the product card, and therefore can be used in the displayed dialog.

Messages after authorization or account activation

In order to create a pop-up window with a message about the authorization or activation status, you need to create the callback_hotengine_authorize_result function


callback_hotengine_authorize_result($result) - function after user authorization($result - execution result: 1-successful, 2-login or password error, 3-account blocked, 4-activation required, 5-Activation was successful, 6-Incorrect Captcha code )

An example of a standard function that will be called in the absence of your own function:
/templates/scripts/hotengine-script-callback_hotengine_authorize_result.js

Text messages loaded with CSS styles:
/templates/styles/css_hotengine_script_callback_hotengine_authorize_result.css

Loading the list of products with «Product Widget» features using JavaScript


Ajax product list loading:
The product block generator can be loaded using GET/POST/AJAX requests. To do this, you need to make a request from your site (your domain) to the page «/ajax_get_list_shop.php». You can specify additional properties in the request for displaying products. You can find a list of all possible values on the page «Shop Products Widget». To correctly display the style of the product list, you need to add an HTML wrapper and parent elements, as well as buttons for scrolling the product list (forward/backward). An example of such a wrapper and script usage is shown below.


An example of creating a basic environment for displaying a list of products

When using this environment to display a product list, you can enable scripts that allow scrolling items forward and backward, changing the display style, and adding extra effects — such as Scroll, Swipe, and more.

Code: JavaScript

<!-- Container for product list -->
<div id="someID">
  <div class="hotengine-shop-products-list-div" 
       data-hotengine-shop-products-list-param=":shop_products_slider:htmlonly:start-0:on_page-20:description:button-cart:auto_width:swipe:scroll-9999x8x0:id-someID" 
       data-product_limits="20" data-swipe="1" data-scroll-width="9999" 
       data-scroll-product-add="8" data-scroll-max-products="0">
    <span class="hotengine-shop-products-list-div-button-left hotengine-shop-products-list-div-button" data-product_limits_start_n="0"></span>
    <div class="hotengine-shop-products-list-content"></div>
    <span class="hotengine-shop-products-list-div-button-right hotengine-shop-products-list-div-button" data-product_limits_start_n="0"></span>
  </div>
</div>

<script>
let $param = `:shop_products_slider:htmlonly:start-0:on_page-20:description:button-cart:auto_width:swipe:scroll-9999x8x0:id-someID`;
let $onpage = 20;

$("#someID .hotengine-shop-products-list-content").load(
  `/ajax_get_list_shop.php?n=0&onpage=${$onpage}${(window.location.search.includes("cacheclear")) ? "&cacheclear" : ""}&param=${encodeURIComponent($param)}`,
  function () {
    // After loading execute callback functions
    if(typeof(callback_hotengine_shop_products_list_div_button) === "function"){ callback_hotengine_shop_products_list_div_button(); }
    if(typeof(callback_hotengine_ajax_load_products_list) === "function"){ callback_hotengine_ajax_load_products_list(); }

    
if ($(`.hotengine-shop-products-list-div[data-append-replace]`).length) {
    if (typeof $hotengine_shop_product_base_append_replace == "undefined") {
        $.getScript("/templates/scripts/hotengine-script-shop-products-list-append-replace.js?v32")
            .fail(function(jqxhr, settings, exception) {
                console.error("Failed to load script: ", exception);
            });
    } else if (typeof ProductWidgetAppendReplace === "function") {
        ProductWidgetAppendReplace();
    }
};

    if ($(".hotengine-shop-products-list-div .hotengine-shop-products-list-auto_width").length) {
      if(typeof $hotengine_shop_product_base_slider_auto_width === "undefined") {
        $.getScript("/templates/scripts/hotengine-script-shop-products-list-base-slider-autowidth.js?v32")
          .fail(function(){ console.error("Failed to reload auto-width script."); });
      } else if(typeof ProductWidgetAutoWidth === "function") {
        ProductWidgetAutoWidth();
      }
    }
    
    if ($(".hotengine-shop-products-add-count-spinner").length) {
      if (typeof $hotengine_shop_product_count_spinner === "undefined") {
        $.getScript("/templates/scripts/hotengine-script-shop-product-count-spinner.js?v32")
          .fail(function(jqxhr, settings, exception){ console.error("Failed to load script: ", exception); });
      } else if (typeof(callback_hotengine_add_count_spinner) === "function") {
        callback_hotengine_add_count_spinner();
      }
    }

    if($(`.hotengine-shop-products-list-div[data-swipe="1"]`).length) {
      if(typeof $hotengine_shop_product_base_slider_touch === "undefined") {
        $.getScript("/templates/scripts/hotengine-script-shop-products-list-base-slider-swipe.js?v32")
          .fail(function(jqxhr, settings, exception){ console.error("Failed to load script: ", exception); });
      } else if(typeof ProductWidgetSwipe === "function") {
        ProductWidgetSwipe();
      }
    }

    if($(".hotengine-shop-products-list-div[data-scroll-width]").length) {
      if(typeof $hotengine_shop_product_base_slider_scroll === "undefined") {
        $.getScript("/templates/scripts/hotengine-script-shop-products-list-base-slider-scroll.js?v32")
          .fail(function(jqxhr, settings, exception){ console.error("Failed to load script: ", exception); });
      } else if(typeof ProductWidgetScrollProcessBlocks === "function") {
        ProductWidgetScrollProcessBlocks();
      }
    }
  }
);
</script>
    


Scrolling and visual effects are implemented using a JavaScript script — hotengine-script-shop-products-list-base-slider.js.






Code for loading the product list + applying Widget parameters (styling and additional functions):


/templates/scripts/hotengine-scripts-additional/hotengine-shop-products-list-generated.js


Script creates an area for displaying a product list with the ability to enable product widget features: product scrolling, effects, and styling. This script includes a wide range of customizable parameters — you can modify the product list, category, display mode, and other settings. All parameters are defined in the same way as in the «Product widget», so you can easily extend the list if needed.

How to install the script?


You can either copy the full script and edit the parameters directly (they are explained in the inline comments and also described on the «Product widget» page), or — recommended — define the parameters separately and load the file via $.getScript:
Code: JavaScript
<script type="text/javascript">

// ============================
// CONFIGURATION (edit values)
// ============================
// This file defines all the parameters that will be
// used when generating the product block.
// This file is loaded BEFORE the main script
// hotengine-shop-products-list-generated.js
// via $.getScript() to pass variables.
// =============================

// targetInsertSelector: jQuery selector (id/class/tag) AFTER which the product block will be inserted.
// Example: "#product-details" or ".product-page .right-col" or "body" (appends at end).
var targetInsertSelector = "#hotengine-header";

// insertMode: "after" = insert after element (default), "replace" = replace element
var insertMode = "after";

// targetBlockId: ID or Class for the generated product block container.
// Example: "hotengine-shop-products-list-generated"
var targetBlockId = "hotengine-shop-products-list-generated";

// shop_cat_page_id: ID of the current product to SKIP (exclude from results).
var shop_cat_page_id = "";

// products_id: Optional. Comma-separated product IDs or SKUs to SHOW.
// Example: "482626,482624" or "" to omit.
var products_id = "";

// site: Optional numeric site ID. Use if the script is used outside your main site.
// Leave 0 or "" to omit.
var site = 0;

// favorite: 1 => add ":favorite-icon", 0 => do not add.
var favorite = 0;

// variety: 1 => add ":variety", 0 => no.
var variety = 0;

// variety_crop: integer >0 — only sent if >0 (trim variety names length).
var variety_crop = 0;

// lazy_load: 0 = enabled (adds ":lazy-0"), 1 = disabled (no lazy param).
var lazy_load = 0;

// cart_add_count: 0 none, 1 counter block, 2/4 spinner behavior.
var cart_add_count = 2;

// compare_pos: position for "Add to compare" (real values from design).
// 1=icon block; 0=after cart; 4=before cart; 2=after title; 3=bottom
var compare_pos = 1;

// favorite_pos: position for "Add to favorites" (same code meanings).
var favorite_pos = 1;

// onpage: default number of products to request / display.
// Note: if auto_width === 1 it is recommended to set onpage = 1.
var onpage = 3;

// stock: availability filter
// ""=all; 0=in stock; 1=in stock+preorder+check; 2=in stock; 3=preorder; 4=check avail
var stock = 1;

// scroll: whole scroll parameter or empty string.
// Example: "scroll-9999x8x64x3,3" or "" to disable.
var scroll_param = "scroll-9999x8x64x3,3";

// widget_style: 0 = append (default), 1 = list, 2 = swipe
var widget_style = 2;

// auto_width: 1 = enable auto width (recommended onpage=1), 0 = disable
var auto_width = 1;

// lang: optional language code (e.g. "ru","ua","en","pl"). If empty, :lang not added.
var lang = "ru";

// pers_cat_id: optional personal category id (keeps original logic)
var pers_cat_id = 0;


$(document).ready(function(){
  $.getScript("/templates/scripts/hotengine-scripts-additional/hotengine-shop-products-list-generated.js")
    .fail(function(){ console.error("Failed to load main generator script"); });
});

</script>


It is recommended to add this script through the «Blocks / Menu» tool, enabling the «JavaScript / CSS style» checkbox and selecting the mode «JavaScript – defer». This method ensures that when parameter names or classes are changed, the elements will be automatically updated, and your code will be correctly converted into a JS file. Since such a menu block immediately generates a JS file, make sure to remove the <script type="text/javascript"> </script> wrapper.

Show related products in the cart (Frequently Bought Together)

Based on the script Loading product list with «Product Widget» functions using JavaScript, you can load a list of products that will include a «Frequently Bought Together» list.
Note: Before connecting the scripts, you can define the following settings:
  • window.auto_width = 1; — enable auto width.
  • window.onpage = 8; — number of products loaded initially.
  • window.widget_style = 2; — widget loading style.
  • window.lang = "en"; — language of displayed products (others will be skipped; leave empty to disable language filtering).
If no parameters are specified, the script will automatically use default values.
The full list of parameters is available in the hotengine-shop-products-list-generated.js instructions above.

When viewing the cart:

When viewing the cart, a microdata element is created that contains the «Frequently Bought Together» list. The list of such products can be displayed in a popup window or as a product block.
Place the code to display the product list on the page «cart_send» - «Functional Page» - «Cart».

Code to add the list when viewing the cart (under the «Continue Shopping» button):




The list will only display if related products exist. For styling, the block is surrounded as a standard block/menu.

Example CSS style:
Code: CSS
.menu_bought_with_generated #menu_c .headm:before{ content:"Frequently bought with selected products:"; display:block; text-align:center; line-height:30px;}
.menu_bought_with_generated {margin-top:50px;} .menu_bought_with_generated #menu_c .headm b{display:none;}



Code for popup window with «Frequently Bought Together» list when viewing the cart:


The list of such products can be displayed in a popup window.
Place the code to display the product list on the page «cart_send» - «Functional Page» - «Cart».
Code: JavaScript
<script type="text/javascript" src="/templates/scripts/hotengine-scripts-additional/hotengine-script-additional-bought-with-popup.js"></script>



The window will only pop up when related products are found.

.hotengine-bought_with-window-btn-close - define the style for the window close button (displayed under the product list in the popup).

Example CSS style:
Code: CSS
.hotengine-bought_with-window-btn-close:before{ content:"Close";}
.hotengine-bought_with-window-btn-close {
  display:block;
  background:none;
  width:110px;
  line-height:38px;
  height: auto;
  padding: 0px 0px;
  white-space:nowrap;
  background: #4f86b1;
  cursor: pointer;
  transition-delay: 0;
  transition-duration: 0.2s;
  transition-property: all;
  transition-timing-function: cubic-bezier(0, 0, 1, 1);
  border:none; box-shadow: 0 1px 3px rgba(0,0,0,0.12);
  -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px;
  text-shadow:1px 1px 1px rgba(1, 39, 106, 1);
  color: #fff!important;
  text-decoration: none;
  margin:-10px auto 0px auto;
  text-align: center;
}
.hotengine-bought_with-window-btn-close:hover { background:#24689E; opacity: 1; -moz-opacity: 1; -khtml-opacity: 1; filter: alpha(opacity=100);  }


The «Frequently Bought Together» list is also displayed on the product page. If you need a popup or a product list displayed only in the cart, use the «Product list for mailing». In this case, replace «data-hotengine-marking-boughtwith» with «data-hotengine-marking-boughtwith-email»


Frequently Bought Together - Popup after adding product to cart


Based on the script Loading product list with «Product Widget» functions using JavaScript, you can load a list of products that will include a «Frequently Bought Together» list.
After adding products to the cart, the callback function «callback_hotengine_cart_plus_after_boughtwith» is executed, which contains the «Frequently Bought Together» list. The list of such products can be displayed in a popup window or as a product block.
The callback_hotengine_cart_plus_after_boughtwith function can be replaced with callback_hotengine_cart_plus_after_boughtwith_email to display the same list for email mailing (E-mail newsletter of other products).

The window will only pop up when related products are found.

.hotengine-bought_with-window-btn-close - define the style for the window close button (displayed under the product list in the popup).
Create a «Block/Menu», place it in the «Footer» or in the «Service Tags» section, and set it to display on all pages or only on pages where a product with an «Add to Cart» button exists.

Example CSS style:
Code: CSS
.hotengine-bought_with-window-btn-close:before{ content:"Close";}
.hotengine-bought_with-window-btn-close {
  display:block;
  background:none;
  width:110px;
  line-height:38px;
  height: auto;
  padding: 0px 0px;
  white-space:nowrap;
  background: #4f86b1;
  cursor: pointer;
  transition-delay: 0;
  transition-duration: 0.2s;
  transition-property: all;
  transition-timing-function: cubic-bezier(0, 0, 1, 1);
  border:none; box-shadow: 0 1px 3px rgba(0,0,0,0.12);
  -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px;
  text-shadow:1px 1px 1px rgba(1, 39, 106, 1);
  color: #fff!important;
  text-decoration: none;
  margin:-10px auto 0px auto;
  text-align: center;
}
.hotengine-bought_with-window-btn-close:hover { background:#24689E; opacity: 1; -moz-opacity: 1; -khtml-opacity: 1; filter: alpha(opacity=100);  }


Function after adding product to cart. Notify about buyer discount amount


The callback_hotengine_cart_plus_after function is called after adding a product to the cart. In this example, it implements notification about the buyer's discount, if any. The data is taken from the microdata attribute data-hotengine-cart-discount in the cart.

Code: html
<script type="text/javascript">
  <!--
  function callback_hotengine_cart_plus_after() {
  const $stick_cart = $(".hotengine-shop-cart-sticker-cart-cart");
  if ($stick_cart.length > 0) {
  const $your_discount = $stick_cart.attr("data-hotengine-cart-discount");
  if ($your_discount !== "" && $your_discount !== undefined) {
  $("#cart").after(`<span class="hotengine-your_discount">${$your_discount}</span>`);
  }
  }
  }
$(function() {
  callback_hotengine_cart_plus_after();
  });
  -->
  </script>

To trigger the notification not only after adding a product to the cart, duplicate the script that checks for the discount microdata. In the example, this is done by an additional call to the callback_hotengine_cart_plus_after(); function without adding a product to the cart.

Example CSS style:
Code: CSS
.hotengine-your_discount  { 
    white-space: nowrap;
    position: absolute;
    margin-top: -32px;
    right: 47px;
    background: #f00;
    color: #fff;
    border-radius: 50px 50px 0px 50px;
    line-height: 30px;
    width: 50px;
    opacity: 0.9;
    text-align: center;
  }


Load article list using Javascript


Ajax loading article list:
Block generator with articles can be downloaded using a GET/POST/AJAX request. To do this, you need to make a request from your site (your domain) to the «/ajax_get_list_blog.php» page. You can specify additional properties for displaying articles in the request. You can find a list of all possible values ​​on the page «Articles widget». For correct display of articles, you need to add HTML wrapper and parent elements, as well as buttons for rewinding/continuing the list of articles (scrolling forward/backward). An example of such a wrapper is shown in the script below.


Code: html
<div class="blog-page-list-AJAXLOAD">
</div>
<script type="text/javascript">
  <!--
  $(function() {
  const $blog_marking = $(`.hotengine-marking[data-hotengine-marking-type="blog_catalog_page"]`);
  if ($blog_marking.length > 0) {
 const $site_id = "XXXX";
  const $blog_cat_id = $blog_marking.attr("data-hotengine-marking-blog_cat_page_catid");
 const $onpage = "4";
  const $param = `:blog_page_slider:htmlonly:cat_id-${$blog_cat_id}:site-${$site_id}:start-0:on_page-${$onpage}:description:append:id-hotengine-blog-page-list-AJAXLOAD`;
 $(".blog-page-list-AJAXLOAD").html(`
  <div id="hotengine-blog-page-list-AJAXLOAD" style="display:none;">
  <div class="hotengine-blog-page-list-div hotengine-blog-page-list-div-append" data-hotengine-blog-page-list-param="${$param}" data-blog_limits="${$onpage}">
  <span class="hotengine-blog-page-list-div-button-left hotengine-blog-page-list-div-button hotengine-blog-page-list-append" data-site-id="${$site_id}" data-blog_limits_start_n="0"></span>
  <span class="hotengine-blog-page-list-content"></span>
  <span class="hotengine-blog-page-list-div-button-right hotengine-blog-page-list-div-button hotengine-blog-page-list-append" data-site-id="${$site_id}" data-blog_limits_start_n="0"></span>
      </div>
  </div>
  `);
 $("#hotengine-blog-page-list-AJAXLOAD .hotengine-blog-page-list-content").load(`/ajax_get_list_blog.php?c=${$site_id}&n=0&onpage=${$onpage}&param=${$param}`, function() {
  $(".hotengine-blog-page-list-content-loading").hide("fast", function() {
  $(".hotengine-blog-page-list-content-loading").remove();
  });
 if ($("#hotengine-blog-page-list-AJAXLOAD .hotengine-blog-page-list-content").not(":empty").length > 0 &&
  $("#hotengine-blog-page-list-AJAXLOAD .hotengine-blog-product-list-block-empty").length === 0) {
  $("#hotengine-blog-page-list-AJAXLOAD").show();
  }
  });
  }
  });
  -->
  </script>

This code loads articles as with the "Block/Menu Generator, Articles Slider". In this script, loading occurs with the replacement of the parent category of the list of articles, which is defined using micro-markup.
XXXX - Site ID.
$onpage - the number of articles on one page (slide)
$blog_cat_id - directory categories, which in the example is indicated using micro-markup from this open article.
.blog-page-list-AJAXLOAD - Block into which articles are loaded.


Loading an article using Javascript in JSON format

Script for loading an article in JSON format

These articles are available upon request /ajax.php?json&blog_cat_p=XX

  • XX - Article ID

The request only works if you specify your domain, for example http://example.com/ajax.php?json&blog_cat_p=0


Code: JavaScript
<script type="text/javascript">
function decodeHtml(str)
  {
  let map =
  {
  '&amp;': '&',
  '&lt;': '<',
  '&gt;': '>',
  '&quot;': '"',
  '&amp;#039;': "'"
  };
  return str.replace(/&amp;|&lt;|&gt;|&quot;|&#039;/g, function(m) {return map[m];});
  }
$(function(){
  $.getJSON("/ajax.php?json&blog_cat_p=14674", function(blog){
   if(Object.keys(blog).length > 0){ 
    // full parameters console.log(blog);
    console.log(decodeHtml(blog.blog_cat_page_title_inpage));
    console.log(decodeHtml(blog.blog_cat_page_description));
    console.log(decodeHtml(blog.blog_cat_page_text));
    console.log(decodeHtml(blog.blog_cat_page_datestamp));
   } 
  });
});
</script>


Styling the search filter (hiding the list of values ​​when clicked)

If you need to hide/reveal the values ​​of the search filter, then you can use the script from the example below. The script writes the ID of the block with a list of values ​​in Cookies and displays/hides it according to the option selected by the user.
Attention! To use a search filter, first create a «Product Type» and provide values ​​for the characteristic type. This script is recommended to be used for «Multiple value».



Code: html
<script><!--
  /*FILTER STYLE*/
  $(function(){
$("#shop_catalog_product_types_id_ajax .shop_catalog_product_types_block").each(function(){
 if ($.cookie("scptbt"+$(this).attr("data-id"))){ 
  $(this).find(".shop_catalog_product_types_block_title").addClass("scptbt_ishidden");
  $(this).find(".shop_catalog_product_types_block_value").css({"max-height":"0px"});
  }
  })

$(document).on("click","#shop_catalog_product_types_id_ajax .shop_catalog_product_types_block_title",function(){
  let thise = $(this);
  let sptelem = $(this).next(".shop_catalog_product_types_block_value");
  if(sptelem.outerHeight() < 1){
  sptelem.css({"max-height":"unset"});
  thise.removeClass("scptbt_ishidden");
  if ($.cookie("scptbt"+thise.parent().attr("data-id"))){ $.cookie('scptbt' + thise.parent().attr("data-id"), null, {expires: null, path: '/'});	}
  } else {
  sptelem.css({"max-height":"0px"}); 
  thise.addClass("scptbt_ishidden");
  $.cookie('scptbt' + thise.parent().attr("data-id"), true, {expires: null, path: '/'}); 
  }
  
  
  })

})
  /*FILTER STYLE*/
  --></script>


Css style for header (icon):

Code: CSS

#search_smart_hotengine-search_form_block .shop_catalog_product_types_block_title:after{

position: relative;
    content: "";
    display: inline-block;
    top: -2px;
    left: 10px;
    width: 8px;
    height: 5px;

background: url(/templates/styles/menu_arrow/arrow-down.svg) no-repeat center center; background-size: 15px; opacity: 0.3;
}
.scptbt_ishidden:after{
 transform: rotate(270deg);
}



Creating your own sorting of the product list


If you need to create your own product sorting form, you can do this by passing GET variables. Below you will find instructions on how to save the selected sorting in COOKIES, as well as an example on how to implement sorting. To quickly create sorting you can use a «Functional Menu» - «Sorting goods». A search form will be inserted into the menu, as well as basic sorting fields.


The following GET parameters are available for custom sorting:
«order_by»:
  • 0 - by product id
  • 1 - by the date the product was added
  • 2 - by product price
  • 4 - by product name
  • 5 - by product priority

«sort_by»:
  • 0 - Descending (DESC)
  • 1 - Ascending (ASC)

«sort_instock_priority»: (sorted by priority, goods in stock are higher than goods out of stock)

  • 0 - ignore parameter
  • 1 - first, goods are in stock and on order, then those that are not in stock. Further, the sorting parameters specified above are taken into account.
  • 2 - initially out of stock.

«Price_from» - price from
«Price_to» - price up to
«Producer» - manufacturer (id or name of the manufacturer)
«Collection» - collection (id or collection name)
«Search» - search query
«Smart_search» - search query data from the search filter

In addition, the values ​​that are taken into account if a non-empty value is specified (for example, «1»):
«Shop_sale» - promotional,
«Shop_new_goods» - new items,
«Shop_bestsellers» - bestsellers,
«Shop_discount» - discount,
«Shop_reduced_price» - Reduced price,
«Order_by_param» - an additional parameter with an arbitrary value, for creating your own list, sorting by name or value.

When a GET variable «sort_by»is found in the address of the open page, the sorting data will be set accordingly to these values. If a page with a list of products is opened, the values ​​will be filled from the link of the «.hotengine-pagination-current» element. In addition, upon opening a sorted page, COOKIEs will be generated to remember the user-selected options. The script that performs this function, which is also installed when creating the functional sorting menu, is located at /templates/scripts/hotengine-script-sort-shop-products.js.


Combined product sorting (functional menu).


The combined sorting version allows you to combine multiple criteria, such as sorting by price, new arrivals, or promotions. This is convenient if you want to consider several parameters simultaneously when displaying products.
Example of a combined sorting menu:

  • Price sorting: you can choose ascending or descending.
  • Additional parameters: new arrivals, sales, discounted items, reduced prices, bestsellers.
  • "In stock first" flag: when enabled, products available in stock are shown first.

To use this sorting, create the Functional Menu «Combo Product Sorting» in the «My Blocks/Menus» section.

Consider an example of creating a sort with your own values.

This can be done using the additional parameter «order_by_param», when selected, the values ​​of the fields «order_by», «sort_by» and others will be changed.
Set one field (#order_by_param) with a choice of options , and also leave the number of products displayed.


Create "Block/Menu", location "at the top".
Block Name/Menu: hotengine_sort_products
Block Header/Menu: hotengine_sort_products
Block Position/Menu: Top
Show Block/Menu on pages: everywhere
Enter characters to display Block/Menu when found: (No spaces)
/pers_shop/ /producer/ /collection/ /shop/

Enter characters to not display Block / Menu when found: (No spaces)
.htm
Menu text:
Code: JavaScript
<form id="hotengine-sort-products-generated" name="hotengine-sort-products-generated" method="get" action="">
 <span>

<label>
<select name="order_by_param" id="order_by_param">
<option value="none">Sort</option>
<option value="lowtohight">Cheap to expensive</option>
<option value="highttolow">From expensive to cheap</option>
<option value="new">New</option>
<option value="sales">Promotional</option>
<option value="date">By date</option>
</select>
</label>

<div class="hidden">
<select name="shop_new_goods" id="shop_new_goods"><option value=""><option value="1"></select>
<select name="shop_sale" id="shop_sale"><option value=""><option value="1"></select>

 <label>
 <select name="sort_by" id="sort_by"> 
 <option value="ASC">Sort:</option>
 <option value="ASC">Ascending</option>
 <option value="DESC">Descending</option>
 </select>
 </label>
<label>
 <select name="order_by" id="order_by"> 
 <option value="5">Sort:</option>
 <option value="0">By item ID</option>
 <option value="4">By Name</option>
 <option value="1">By date</option>
 <option value="2">By price</option>
 </select>
 </label>
</div>
<label>
 <select name="NUM_ONPAGE" id="NUM_ONPAGE" onchange="this.form.submit()"> 
 <option value="10">10</option>
 <option value="20">20</option>
 <option value="30">30</option>
 <option value="50">50</option> 
 </select>
 </label>
 <input class="smart_search" name="smart_search" type="hidden" value="">
 <input class="search" name="search" type="hidden" value="">
 </span>
 </form> 
 
 
<script>
  $(function() {
  $(document).on("change", "#order_by_param", function() {
  const $sortForm = $("#hotengine-sort-products-generated");
  const $orderBySelect = $sortForm.find(`select[name="order_by"]`);
  const $sortBySelect = $sortForm.find(`select[name="sort_by"]`);
  const $shopNewGoodsSelect = $sortForm.find(`select[name="shop_new_goods"]`);
  const $shopSaleSelect = $sortForm.find(`select[name="shop_sale"]`);
  
  const selectedValue = $(this).val();
  
  let orderByValue = "5";
  let sortByValue = "ASC";
  let shopNewGoodsValue = "";
  let shopSaleValue = "";
 switch (selectedValue) {
  case "lowtohight":
  orderByValue = "2";
  sortByValue = "ASC";
  break;
  case "highttolow":
  orderByValue = "2";
  sortByValue = "DESC";
  break;
  case "date":
  orderByValue = "1";
  sortByValue = "DESC";
  break;
  case "sales":
  orderByValue = "1";
  sortByValue = "DESC";
  shopSaleValue = "1";
  break;
  case "new":
  orderByValue = "1";
  sortByValue = "DESC";
  shopNewGoodsValue = "1";
  break;
  case "none":
  orderByValue = "5";
  sortByValue = "ASC";
  break;
  }
  
  $orderBySelect.val(orderByValue).prop("selected", true);
  $sortBySelect.val(sortByValue).prop("selected", true);
  $shopNewGoodsSelect.val(shopNewGoodsValue).prop("selected", true);
  $shopSaleSelect.val(shopSaleValue).prop("selected", true);
  $(this).closest("form").submit();
  });
  });
  </script>

 <script type="text/javascript" src="/templates/scripts/hotengine-script-sort-shop-products.js"></script>


CSS style for sorting (add CSS styles in the design editor):
Code: CSS
.menu_position_top_000000 #menu_c .headm{ display:none; }
.menu_position_top_000000 #menu_c { border: none; background: none; text-align: right;}
.menu_position_top_000000 #menu_c select { 
 background: transparent; 
 padding: 5px 8px 5px 5px; 
 font-size: 12px;
 line-height: 1;
 border-radius: 2px;
 height: 24px;
 -webkit-appearance: none;
 overflow: hidden;
 background: url(/templates/styles/menu_arrow/arrow-down.svg) no-repeat 95%; background-size: 16px;

 }
 .menu_position_top_000000 #menu_c select[name="NUM_ONPAGE"] { background:none;}
 .menu_position_top_000000 #menu_c span:before{ content:"Sort:"; display:inline-block; padding: 5px; font-size: 12px; }
 
 @-moz-document url-prefix(){ 
 .menu_position_top_000000 #menu_c select {
  padding:0px!important;
  background:none!important;

 }

}

Where 000000 needs to be replaced with the ID of the created menu with the sorting code.



Changing the «order_by_param» field will change the sort values and submit the form. Sorting fields have been added to the Form, including «New items» и «Promotion». The fields are hidden, since only a separate list «order_by_param» and the number of displayed products will be used visually. After submitting the form, the Values will be saved in a COOKIE.

Loading the basket on hover


If you need to display the contents of the cart on hover over the trash icon, you can enable the « Content on hover» option in the «Settings», in the tab «Store» - «Making the basket». Or perform a GET call to the address «/ajax.php?cart&load_cart_ajax»
JavaScript displaying the contents of the cart:

Code: JavaScript
<script type="text/javascript" src="/templates/scripts/hotengine-script-cart-hover-block.js"></script>


CSS style:
Code: JavaScript
/*CART HOVER BLOCK*/
#hotengine-cart_menu-hover-block{position:absolute; z-index:99; background:#fff; color:#444; border:1px solid #C7C7C7; padding:20px; display:block; width:50%; display:none; text-align:left;}
#hotengine-cart_menu-hover-block:before{ content:""; height:15px; width:100%; display:block; position:absolute; top:-10px; left:0px; z-index:99999;  }
#hotengine-cart_menu:hover + #hotengine-cart_menu-hover-block{ display:block; }
#hotengine-cart_menu-hover-block:hover{display:block; }
#hotengine-cart_menu-hover-block .hotengine-cart_menu-hover-block-close:after {
    content: "x";
    background: rgb(255,255,255);
    background: radial-gradient(circle,rgba(255,255,255,0) 0%,rgba(182,182,182,1) 100%);
    oveflow: hidden;
    border-radius: 50%;
    -moz-border-radius: 50%;
    -webkit-border-radius: 50%;
    width: 15px;
    height: 15px;
    position: absolute;
    right: 5px;
    top: 5px;
    line-height: 14px;
    text-align: center;
    color: #656565;
    cursor: pointer;
    opacity: 0.8;
    font-size: 9px;
}
/*CART HOVER BLOCK*/

The script displays an additional block in case of detection of goods in the basket and hovering the mouse cursor over «#hotengine-cart_menu» (cart in the block/menu).




Product card child images

Loading a list of product images

For each product card, you can get a list of embedded images in JSON format. To do this, you need to make a request to the page «/ajax.php?get_shop_images=PATH», where PATH is the path to any product image or product ID.

Upload product image list in Colorbox popup gallery:

To add an icon that, when clicked, will pop up the colorbox gallery, scrolling through all the images available in the product, Add the following script to the Block/Menu:
Code: JavaScript
<script type="text/javascript" defer src="/templates/scripts/hotengine-script-shop-load-images-product.js"></script>


Icon CSS style:
Code: JavaScript
/*CHILD IMAGES SHOW POPUP IN SHOP LIST*/
.hotengine-shop-product-img-load-list {
    background: url(/templates/styles/mobile/search.png) no-repeat center center;
    width: 18px;
    height: 18px;
    position: relative;
    z-index: 5;
    background-size: contain;
}
/*CHILD IMAGES SHOW POPUP IN SHOP LIST END*/

Display child images in product list with image list scroll buttons:

If you need to display child images in the product list, then enable the option «Installed images in the product list»; in the store settings, in the «Product View / Tabs / Variety» tab. Add the following script to the Block/Menu:
Code: JavaScript
<script type="text/javascript" defer src="/templates/scripts/hotengine-script-shop-images-child-in-list.js"></script>


CSS style:
Code: JavaScript
/*CHILD IMAGES SHOW IN SHOP LIST*/
.hotengine-imgchenge { position:absolute; z-index:2; padding:15px; font-size:20px; display:inline-block;  background: #858585;
    color: #fff;
    border-radius: 50%;
    height: auto;
    width: auto; line-height:20px; top: 50%; cursor:pointer; margin:-30px 5px 5px 5px; opacity:0;}
.hotengine-imgchenge::after{ 
    position: absolute;
    left: 50%;
    top: 50%;
    width: 30px;
    height: 30px;
    font-size: 30px;
    line-height: 23px;
    text-align: center;
    transform: translate(-50%, -50%);
    pointer-events: none;
}
.hotengine-imgchenge-left {left:0px;} 
.hotengine-imgchenge-left::after {
    content: "\2039";
}
.hotengine-imgchenge-right {right:0px;} 
.hotengine-imgchenge-right:after{content:"\203A";}
.hotengine-shop-product-list-block:hover .hotengine-imgchenge{ opacity:1; -webkit-transition: opacity 1s ease-in-out;
  -moz-transition: opacity 1s ease-in-out;
  -ms-transition: opacity 1s ease-in-out;
  -o-transition: opacity 1s ease-in-out;
  transition: opacity 1s ease-in-out;}
/*CHILD IMAGES SHOW IN SHOP LIST END*/

If the product contains child images, then the script displays buttons for scrolling them, forward and backward.

Show child images in product list: Image replacement on hover:

If you need to display a child image on hover in the product list, then enable the option "Installed images in the product list"; in the store settings, in the product list»; in the store settings, in the «Product View / Tabs / Variety» tab. Add the following script to the Block/Menu:

Code: JavaScript
<script type="text/javascript" defer src="/templates/scripts/hotengine-script-shop-images-child-in-list-hover.js"></script>


Dropdown menu script

Dropdown menu script (default)

By default, you can customize how the child items of the Main Menu are displayed. This can be done in the "Design Editor", in the «Main Menu» tab, or when changing the main menu items in the «My Blocks/Menu» section.

When changing parameters, to the element «id="hotengine-mainmenu"» appropriate classes will be added.

  • «.hotengine-mainmenu-dropdown-default» - dropdowns by default
  • «.hotengine-mainmenu-categories-popup» - popup window with menu items full width of the page
  • «.hotengine-mainmenu-categories-column» – drop-down window with menu items on the entire width of the page
For the correct use of scripts, the list elements containing subitems are assigned the class «.hotengine-mainmenu-dropdown».
By disabling these scripts in the Main Menu Options or removing the above classes, you can set your own event code or CSS styles on hover.

The following are examples of scripts that activate these dropdown sub-items for the main menu, and are built in by default.
Default drop down menu
Code: JavaScript
<script type="text/javascript">
$(function(){
if(!$(".hotengine-mainmenu-categories-popup").length && !$(".hotengine-mainmenu-categories-column").length && $(".hotengine-mainmenu-dropdown-default").length && $("#hotengine-mainmenu .hotengine-mainmenu-dropdown").length){ 
if(typeof $hotengine_mainmenu_categories_dropdown == "undefined"){
$.getScript("/templates/scripts/hotengine-script-mainmenu-categories-dropdown.js"); 
}
}
});
</script>

Pop-up window
Code: JavaScript
<script type="text/javascript">
$(function(){
if($(".hotengine-mainmenu-categories-popup").length && $("#hotengine-mainmenu .hotengine-mainmenu-dropdown").length){
if(typeof $hotengine_mainmenu_categories_popup == "undefined"){
$.getScript("/templates/scripts/hotengine-script-mainmenu-categories-popup.js");
}
}
});
</script>

Dropping window
Code: JavaScript
<script type="text/javascript">
$(function(){
if($(".hotengine-mainmenu-categories-column").length && $("#hotengine-mainmenu .hotengine-mainmenu-dropdown").length){ 
if(typeof $hotengine_mainmenu_categories_popup_column == "undefined"){
$.getScript("/templates/scripts/hotengine-script-mainmenu-categories-popup-column.js"); 
}
}
});
</script>

Script after loading Automatic descriptions

Script for adding the "Buy" button after loading Automatic descriptions in the product card

If you are using auto descriptions in short form, after clicking "Read More" you can add a "Buy" button, as well as a price.
After loading the text, the callback function "callback_hotengine_shop_autodescription_readmore" will be executed.

Code: JavaScript
<script type="text/javascript">
function callback_hotengine_shop_autodescription_readmore($id, $job) { 
if ($job === "load") {
let clone = $(".hotengine-shop-product-offerdetails .hotengine-shop-product-cart_icon").clone();
let priceblock = $(".hotengine-shop-product-offerdetails .hotengine-shop-product-price_box").clone();
$(`.hotengine-store-autodescription-block .hotengine-store-autodescription-list-block[data-hotengine-marking-id="${$id}"] .hotengine-store-autodescription-fulltext`).append([priceblock, clone]);
}
}
</script>

JSON loading goods

Script for loading a product card in JSON format

Product card data available upon request /ajax.php?json&shop_products

When unloading goods, you can specify sorting and filtering options by the following parameters:
  • id - product card ID (one or more values, separated by commas).
  • pers_shop_cat_page_catid - store category ID (one or more values, separated by commas)
  • producer - producer (one or more values, separated by commas)
  • collection - collection (one or more values, separated by commas)
  • sort_by - sorting
  • order_by - sorting
  • sort_instock_priority - sorting priority
  • price_from - price from
  • price_to - price to
  • stock - availability

The request only works with your domain, for example http://example.com/ajax.php?json&shop_products&id=0


Code: JavaScript
<script type="text/javascript">
function decodeHtml(str)
  {
  let map =
  {
  '&amp;': '&',
  '&lt;': '<',
  '&gt;': '>',
  '&quot;': '"',
  '&amp;#039;': "'"
  };
  return str.replace(/&amp;|&lt;|&gt;|&quot;|&#039;/g, function(m) {return map[m];});
  }
$(function(){
  $.getJSON("/ajax.php?json&shop_products&id=12345,12346", function(offers){
   if(Object.keys(offers).length > 0){ 
    // full parameters console.log(offers);
    $.each( offers.offers, function(z, items){ 
      $.each(items, function(i, item){ 
        console.log(decodeHtml(item.description)); //show description with htmldecode
        console.log(decodeHtml(item.text)); //show text with htmldecode
      });
    });
   } 
  });
});
</script>

Hiding/Showing characteristics in the product description

Hiding/Showing characteristics in the product description

In the product card, the display of Characteristics is available. The block can contain a long list, so you can use a script to hide some of the characteristics. To do this, create a Block/Menu and paste the following script:
Code: JavaScript
<script type="text/javascript" defer src="/templates/scripts/hotengine-script-hide-properties.js"></script>

Script can be changed by specifying the number of fields to display by default. To do this, copy the Script from the file and paste it into the Block/Menu.

Button css style:
Code: JavaScript
/*SHOW/HIDE PROPERTIES*/
.shop_catalog_product_properties_block_showblock{text-align:left; margin-bottom:40px;}
.shop_catalog_product_properties_block_showblock:before{
    content: "Show all characteristics"!important;
    white-space: nowrap;
    cursor: pointer;
    white-space: nowrap;
    text-align: center;
    height: auto;
    border-radius:0px;
    margin: 5px auto 5px auto;
    font-size: 15px;
    padding: 4px 4px;
    border-bottom: 1px dashed #666666;
    margin-left:19px;
    display: inline-block;
}
html:lang(en) .shop_catalog_product_properties_block_showblock:before{
    content: "Show all characteristics"!important;
}
html:lang(ru) .shop_catalog_product_properties_block_showblock:before{
    content: "Показать все характеристики"!important;
}
html:lang(uk) .shop_catalog_product_properties_block_showblock:before{
    content: "Показати всі характеристики"!important;
}
html:lang(pl) .shop_catalog_product_properties_block_showblock:before{
    content: "Pokaż wszystkie cechy"!important;
}

html:lang(en) .shop_catalog_product_properties_block_showblock.visible:before{
    content: "Hide"!important;
}
html:lang(ru) .shop_catalog_product_properties_block_showblock.visible:before{
    content: "Скрыть"!important;
}
html:lang(uk) .shop_catalog_product_properties_block_showblock.visible:before{
    content: "Приховати"!important;
}
html:lang(pl) .shop_catalog_product_properties_block_showblock.visible:before{
    content: "Ukrywać"!important;
}

.shop_catalog_product_properties_block_showblock:hover:before{
    color:#008fc3;
    border-color: #008fc3;
}
/*SHOW/HIDE PROPERTIES END*/


Adding Delivery Information to Product Card via Ajax


The recommended method for adding delivery information is to load the information via Ajax from a previously created page. This mechanism helps avoid indexing repetitive text on all product card pages. To start, create a page, for example, named «delivery_info». This can be done in the "My Pages" section. Now, let's consider the options for loading this page into the product card.

Adding Delivery Information to a Tab

Tabs are available for display in the product card. To create a custom tab and display delivery information when switching to that tab, you need to create a script. For this, create a Block/Menu and insert the following script:
Code: JavaScript
$(document).ready(function () {
$('.hotengine-shop-content-tabs-block').before(`<input type="radio" id="button_tabs-8" name="button_tab"><label for="button_tabs-8">Delivery</label>`);

 let $l = $("meta[http-equiv='content-language']").attr("content");
  const languageMap = {
  "uk": "ua",
  };
  $l = languageMap[$l] || $l;

 $('.hotengine-shop-content-tabs-block').append('<div id="tabs-8"></div>');
  $('#button_tabs-8, label[for="button_tabs-8"]').on('click change', function () {
  if ($('#button_tabs-8').is(':checked')) {
  let $href = "/"+$l+"/delivery_info.htm";
  let $content_block = '#tabs-8';
  if($($content_block).html()==""){
  $($content_block).html('<div class="loading" align="center"><span class="loading-spin"></span></div>');
 $.ajax({ 
  type: "GET",
  dataType: "html",
  url: "/ajax.php",
  data: { p: $href },
  timeout: 20000,
  beforeSend: function() {
  $(".loading").show(400);
  },
  success: function(data) {
  $(".loading").fadeOut(300, function() {
  $(".loading").remove();
  $($content_block).html(data);
  });
  }
 });
  }
  }
  });
  });

Before saving the Block/Menu, make sure to check the box - JavaScript. Show Block/Menu on pages: «Only on Shop Pages». Enter the characters, upon detection of which the Block/Menu will be displayed: «.htm». This script will create a tab, and when clicked, it will load data from the previously created page. The language of the loaded page corresponds to the language in which the product card is being viewed.


Adding Delivery Information via Button in a Popup Window.

Similarly, using a script, you can set an event to create a button. When clicked, it will load the page created earlier.
Code: JavaScript
$(document).ready(function () {
  let $l = $("meta[http-equiv='content-language']").attr("content");
 const languageMap = {
  "uk": "ua",
  };
 $l = languageMap[$l] || $l;
 
 const deliveryTextMap = {
  ru: "Доставка",
  pl: "Dostawa",
  en: "Delivery",
  ua: "Доставка",
  fr: "Livraison",
  de: "Lieferung",
  es: "Entrega"
  };
 const deliveryText = deliveryTextMap[$l] || "Delivery";
 
 let $href = "/" + $l + "/delivery_info.htm";
 
 $(".hotengine-shop-product-offerdetails").after(
  `<a class="delivery_button hotengine-script-popup" 
  target="_blank" 
  data-remove-on-close="1" 
  data-iframe="14" 
  href="${$href}" 
  data-title="${deliveryText}" 
  data-header-fix="1" 
  data-auto-width="320" 
  data-auto-height="320" 
  data-max-width="800" 
  data-max-height="800" 
  data-mobile-width="320" 
  data-unset-height="1">${deliveryText}</a>`
  );
  });



Dynamic price update during booking


Adding tips during booking

Here is an example of adding tips when making a booking.

  1. In the booking form (form builder), add two fields:
      - form_tips — select dropdown for choosing a tip. Option text can be 5%, 10%, 20%, with values 5, 10, 20.
      - form_price_no_tip — hidden field to store the base price without tips.
  2. The form_price_no_tip field should be hidden so the user does not see it, but the script can use it for calculations.
  3. Next, create a menu/block with your script callback_hotengine_booking_form that will handle tip changes and recalculate the total price.
  4. Place this block on all pages where the booking form is present so that dynamic price calculation works correctly everywhere.

Script to calculate the total price.

Create a block/menu and insert the following script:
Code: JavaScript
function callback_hotengine_booking_form(value) {
  if (value === 9) {
  var $form = $("#dialog-booking-modal-content form");
 if ($form.length === 0) {
  console.log("no form found");
  return;
  }
 // Get current booking_data
  const bookingDataText = $(`textarea[name="booking_data"]`).val();
  let bookingData = {};
 if (bookingDataText) {
  try {
  bookingData = JSON.parse(bookingDataText);
  } catch (e) {
  console.error("JSON parse error: ", e);
  return;
  }
  }
 // --- 1. Save initial prices if not already stored ---
  if (!bookingData.bookingData?.selectedFormPrice_BEFORE) {
  bookingData.bookingData.selectedFormPrice_BEFORE = bookingData.bookingData?.selectedFormPrice || "-";
  }
  if (!bookingData.bookingData?.form_price_BEFORE) {
  bookingData.bookingData.form_price_BEFORE = bookingData.bookingData?.form_price || "-";
  }
 // --- 2. Use reserved values as the base ---
  let baseTotalPrice = bookingData.bookingData.form_price_BEFORE;
 // --- 3. Set the initial price in #form_price_no_tip ---
  $("#form_price_no_tip").val(baseTotalPrice);
 // --- 4. Handle tip changes ---
  $(`#form_tips`).change(function () {
  const tipValue = $(this).val();
 // If tip is "-", 0, or negative → revert to base values
  if (tipValue === "-" || tipValue === "0" || parseInt(tipValue, 10) <= 0) {
  const baseFormPrice = bookingData.bookingData.selectedFormPrice_BEFORE;
  const baseTotalPrice = bookingData.bookingData.form_price_BEFORE;
 const updatedBookingDataArray = {
  ...bookingData.bookingData,
  selectedFormPrice: baseFormPrice,
  form_price: baseTotalPrice
  };
 const updatedBookingData = { bookingData: updatedBookingDataArray };
  const updatedBookingDataJSON = JSON.stringify(updatedBookingData);
 // Update hidden field and displayed price
  $(`textarea[name="booking_data"]`).remove();
  $form.append(`<textarea name="booking_data" class="hidden">${updatedBookingDataJSON}</textarea>`);
  $(".booking-text-form-price span").text(baseTotalPrice);
  return;
  }
 const tipPercentage = parseInt(tipValue, 10);
 // Get reserved prices
  let baseFormPrice = bookingData.bookingData.selectedFormPrice_BEFORE;
  let baseTotalPrice = bookingData.bookingData.form_price_BEFORE;
 // --- 5. Extract numeric value and currency ---
  let priceMatch = baseFormPrice.match(/^([\d.]+)\s?(\D+)?$/);
  let totalMatch = baseTotalPrice.match(/^([\d.]+)\s?(\D+)?$/);
 if (!priceMatch || !totalMatch) {
  console.error("Failed to extract price values");
  return;
  }
 let baseFormPriceValue = parseFloat(priceMatch[1]);
  let baseTotalPriceValue = parseFloat(totalMatch[1]);
  let currency = priceMatch[2] || "$";
 // --- 6. Calculate new prices with tip percentage ---
  let newFormPrice = (baseFormPriceValue * (1 + tipPercentage / 100)).toFixed(2) + "" + currency;
  let newTotalPrice = (baseTotalPriceValue * (1 + tipPercentage / 100)).toFixed(2) + "" + currency;
 // --- 7. Update JSON data ---
  const updatedBookingDataArray = {
  ...bookingData.bookingData,
  selectedFormPrice: newFormPrice,
  form_price: newTotalPrice
  };
 const updatedBookingData = { bookingData: updatedBookingDataArray };
  const updatedBookingDataJSON = JSON.stringify(updatedBookingData);
 // --- 8. Update hidden field and displayed price ---
  $(`textarea[name="booking_data"]`).remove();
  $form.append(`<textarea name="booking_data" class="hidden">${updatedBookingDataJSON}</textarea>`);
  $(".booking-text-form-price span").text(newTotalPrice);
  });
  }
  }


The script modifies the JSON data containing the total price of the selected booking slot.

Dynamic price adjustment when placing an order


Adding an amount to the total order price in the cart

You can use the hidden field «form_price_append» to add a specific amount to the total in the cart. For example, if 5 items cost $100 and you want to add another $50, specify this value in «form_price_append».

The field can be created in two ways:
  • through the form editor in the store settings, on the "Checkout" tab in the "Add fields to order form" section;
  • or programmatically using scripts that dynamically change its value.
This allows you to account for tips, additional services, exclusive products, or any other surcharges, while ensuring the total price is displayed correctly in the cart.

Script for adding the «form_price_append» field and additional surcharge

Create a functional page «Cart» and add the following code in the content:
Code: JavaScript
<script>
$(document).ready(function() {
  const $form = $("#hotengine-shop-cart-form");
  if (!$form.length) return;
 // --- Add hidden append field if missing ---
  if ($form.find(`input[name="form_price_append"]`).length === 0) {
  $form.append(`<input type="hidden" name="form_price_append" value="0">`);
  }
  const $appendField = $form.find(`input[name="form_price_append"]`);
 // --- Add temporary element for calculations ---
  if ($form.find(`.hotengine-shop-product-price_before_append`).length === 0) {
  $form.append(`<span class="hotengine-shop-product-price_before_append" style="display:none;"></span>`);
  }
  const $tempPrice = $form.find(`.hotengine-shop-product-price_before_append`);
 // --- Add block for storing data via attributes ---
  if ($form.find(`.hotengine-shop-cart-cart_order_price_append`).length === 0) {
  $(`.hotengine-shop-cart-cart_order_price`)
  .after(`<div class="hotengine-shop-cart-cart_order_price_append"></div>`);
  }
  const $infoAppend = $(`.hotengine-shop-cart-cart_order_price_append`);
 // --- Save base price if not already ---
  const $priceNumber = $(`.hotengine-shop-cart-cart_order_price .hotengine-shop-product-price_number`);
  if (!$priceNumber.data(`base-price`)) {
  $priceNumber.data(`base-price`, parseFloat($priceNumber.text()) || 0);
  }
 // --- Price formatting function ---
  const formatPrice = (price) => Number.isInteger(price) ? price : price.toFixed(2);
 // --- Main update function ---
  const updateCartPriceAppend = () => {
  const appendVal = $appendField.val().trim();
  const basePrice = $priceNumber.data(`base-price`);
  let newPrice = basePrice;
 if (appendVal && appendVal !== "0") {
  // Handle percentage
  if (appendVal.indexOf("%") > -1) {
  const percent = parseFloat(appendVal.replace("%",""));
  if (!isNaN(percent)) newPrice = basePrice * (1 + percent / 100);
  } else {
  const fixed = parseFloat(appendVal);
  if (!isNaN(fixed)) newPrice = basePrice + fixed;
  }
  }
 // Update temporary element
  $tempPrice.text(formatPrice(newPrice));
 // Update price in cart
  $priceNumber.text(formatPrice(newPrice));
 // Update data attributes only
  $infoAppend.attr({
  "data-base": formatPrice(basePrice),
  "data-append": appendVal || 0,
  "data-new": formatPrice(newPrice)
  });
  };
 // --- Event: recalc on change and page load ---
  $appendField.on("input change", updateCartPriceAppend);
 // --- Example: set additional +1000 on page load ---
  $appendField.val("1000").trigger("change"); // additional price for example
  });
</script>

For example, an amount of 1000 has been added.

Displaying the latest wholesale price in the product list


If you need to display the latest wholesale price (i.e., the minimum) when displaying the product list, you can use the following CSS style:
Code: CSS
.hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block .hotengine-shop-product-price_bulk, .hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block .hotengine-shop-product-price_bulk_moq { display: none; }
.hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block .hotengine-shop-product-price_bulk:nth-last-of-type(2) { display: inline-block; }

.hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block:hover{border-color:#f96013;}
.hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block:hover .hotengine-shop-product-price_bulk { color:#f96013;}
.hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block:hover {color:#f96013; }

Similarly, to show only the first price (maximum):
Code: CSS
.hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block .hotengine-shop-product-price_bulk, .hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block .hotengine-shop-product-price_bulk_moq { display: none; }
.hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block .hotengine-shop-product-price_bulk:first-child, .hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block .hotengine-shop-product-price_bulk_moq:first-child {display:inline-block;}

.hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block:hover{border-color:#f96013;}
.hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block:hover .hotengine-shop-product-price_bulk { color:#f96013;}
.hotengine-shop-product-list-block .hotengine-shop-product-price_bulk_block:hover {color:#f96013; }