Skip to content

Custom scripts

You can use custom scripts to customize the module behaviour.
You can create javascript files in these folders:

  • /js/dynamic (create the dynamic folder if it doesn't exist)
  • /themes/[current theme]/assets/js/dynamic

The file name should be:

  • custom.js (if you want to target all products)
  • customX.js (if you want to only target the product with ID=X)
    For example, if you want to target product #10, you can create a file named custom10.js

Detecting when the module is loaded

Since the module loading is deferred, you need to listen for the dp.load event in order to execute your custom script correctly and avoid errors.

js
document.addEventListener("dp.load", function () {
  // Your code here
});

Updating the properties of a field

You can change a field properties from the custom script, for that you need to use the updateField function.
Code example:

js

window.dp.methods.updateField(field_name, props);

// This example will change the value of the width field as well as the min, max and step properties
window.dp.methods.updateField("width", {
  value: 50,
  min: 10,
  max: 100,
  step: 10
});

The props object can have these items

ts
// The props interface has this shape
export interface IFieldSettings {
  value: string | number;
  value_formatted: string;
  min: number;
  max: number;
  step: number;
  required: number;
  max_size: number;
  min_date: string;
  max_date: string;
  multiselect: boolean;
  display_value_price: number;
  display_secondary_value_price: number;
  display_in_popup: number;
}

Some field types display the value_formatted property, such as the price field.

To update it, you can use this code for example

js
window.dp.methods.updateField("price_field", {
  value: 50,
  value_formatted: '50€'
});

Get a field properties

You can use the getField function to get the properties of a field.

js
window.dp.methods.getField(field_name);
var props = window.dp.methods.getField("width");

The value of props will have this shape

js
{
  active: 1
  common: 0
  description: ""
  dir: "/dynamicproduct/images/field"
  ext: ".jpg"
  favorite: 0
  force_id: false
  id: 66
  id_group: "0"
  id_product: 11
  id_unit: 0
  image_url: null
  init: 0
  label: "Width"
  linked: "0"
  name: "width"
  options: []
  position: "2"
  settings: {
    color: null
    dir: null
    display_in_popup: null
    display_secondary_value_price: null
    display_value_price: null
    ext: ".jpg"
    extensions: null
    extra: null
    force_id: false
    hide_when_empty: 1
    id: null
    id_field: 66
    id_unit: null
    init: null
    max: null
    max_date: null
    max_size: null
    min: null
    min_date: null
    min_height: null
    min_width: null
    multiselect: null
    position: null
    price_unit: null
    required: null
    show_in_summary: 0
    step: 1
    thumb_suffix: "-thumb.jpg"
  }
  thumb_suffix: "-thumb.jpg"
  thumb_url: null
  type: 1
  unit: {
    dir: null
    displayed: 1
    ext: ".jpg"
    force_id: false
    id: null
    name: null
    position: null
    symbol: null
    thumb_suffix: "-thumb.jpg"
  }
  value: ""
}

Detecting a calculation result

You can subscribe to the module stores in order to detect the calculation results.
The module uses Vegemite stores under the hood.

Code example:

js
document.addEventListener('dp.load', function () {
  window.dp.stores.calculator.listen(function (data) {
    console.log(data);
  });
});

The data will have this shape

js
{
  customization_prices: {
    price_ht: 10
    price_ht_nr: 10
    price_ttc: 12
    price_ttc_nr: 12
  }
  debug_messages: null
  final_prices: {
    price_ht: 20
    price_ht_nr: 20
    price_ttc: 24
    price_ttc_nr: 24
  }
  formatted_prices: {
    price_ht: "€20.00"
    price_ht_nr: "€20.00"
    price_ttc: "€24.00"
    price_ttc_nr: "€24.00"
  }
  formatted_unit_prices: {
    price_ht: "€20.00"
    price_ht_nr: "€20.00"
    price_ttc: "€24.00"
    price_ttc_nr: "€24.00"
  }
  input_fields: {
    width: {
      dir: null
      ext: ".jpg"
      field: {
        // information about the field, similar to the value returned by getField
      }
      force_id: false
      id: null
      id_field: 66
      id_input: 0
      id_shop_list: []
      image_url: null
      label: "Width"
      name: "width"
      options: "[]"
      position: null
      secondary_value: "0"
      selected_options: []
      thumb_suffix: "-thumb.jpg"
      thumb_url: null
      type: 1
      value: 0
      value_formatted: 0
      visible: 1
    }
  }
  met_conditions: []
  oos: false
  success: 1
  unit_prices: {
    price_ht: 20, price_ht_nr
  :
    20, price_ttc
  :
    24, price_ttc_nr
  :
    24
  }
  use_tax: true
  visibility: {
    groups: []
  }
  weight: 0
  weight_formatted: "0 kg"
}

Detecting any change on fields

You can subscribe to the fields store to detect any change on the fields.
The result will be an object containing each field Example code

js
document.addEventListener('dp.load', function () {
  window.dp.stores.fields.listen(function (fields) {
    console.log(fields);
  });
});

The fields variable will have this shape

js
{
  width: {
    dir: null
    ext: ".jpg"
    field: {
      // information about the field, similar to the value returned by getField
    }
    force_id: false
    id: null
    id_field: 0
    id_input: 0
    id_shop_list: []
    image_url: null
    label: null
    name: "changed"
    options: ""
    position: null
    secondary_value: "0"
    selected_options: ""
    thumb_suffix: "-thumb.jpg"
    thumb_url: null
    type: 4
    value: "width"
    value_formatted: "width"
    visible: 0
  }
,
  height: {
    // same shape as the width field 
  }
,
  // ...
}

Validating the fields

If you need to validate the fields programmatically, you can use the validateFields function.

Example code:

js
var valid = window.dp.methods.validateFields();
// valid will be either true or contain error messages based on the validity of the fields
// The module will highlight errors and will scroll to the first visible error

Add the customization to cart

If you need to add the customization to cart, then you can use the addToCart function.

Example code

js
window.dp.methods.addToCart().then(function (response) {
  // response is either true or false based on the success of the operation
});

Customizing the module selectors

Since many themes have a different structure than the default one, the module allows you to change the selectors used to target the product page elements and to better position the module within the page.

Here's the default selectors structure:

ts
export type DynamicProductProps = {
  // used to position the module within the page
  hook: (container: HTMLDivElement) => void;
  // used to position the layers container within the preview images
  preview_hook: (layers_container: HTMLDivElement) => void;
  selectors: {
    price: string; // price with discount (if applicable)
    regular_price: string; // price without discount
    qty_input: string; // the quantity input
    form: string; // the product form
  };
};

Here are the default values:

js
window.dp = {
  hook(container) {
    const product_actions = document.querySelector('.js-product-actions');
    product_actions?.prepend(container);
  },
  preview_hook(layers_container) {
    const images_container = document.querySelector('.js-images-container');
    images_container?.prepend(layers_container);
  },
  selectors: {
    price: '.current-price-value',
    regular_price: '.regular-price',
    qty_input: '#quantity_wanted',
    form: '#add-to-cart-or-refresh'
  }
};

To change the hook, you can use this code for example:

js
window.dp.hook = function (container) {
  const product_actions = document.querySelector('.js-product-actions');
  product_actions?.append(container);
};

To change a selector, you can use this code for example:

js
window.dp.selectors.price = '.product-price > span';

TIP

You can also use the custom hook in your theme tpl.

Custom fields

Check how to create custom fields here