đŸ¤© If you like this project, please support us by starring our GitHub repository đŸ¤©

JavaScript Plugin Example

As an example, let’s recreate the Binding Labels Plugin. It gets the path to some HTML element and prints the value of the slider in it. The content of the element must be constantly updated.

Let’s start with a minimal slider template from here:

/**
 * Required: init ToolCool Range Slider plugins namespace if not defined yet
 */
window.tcRangeSliderPlugins = window.tcRangeSliderPlugins || [];

const ExamplePlugin = () => {
  
  return {
    
    /**
     * Required: unique plugin name
     */
    get name() {
      return 'My Plugin';
    },

    /**
     * Optional: plugin initialization
     */
    init: (
      _$component,
      _requestUpdate,
      _setters,
      _getters
    ) => {
      console.log('plugin initialization');
    },

    /**
     * Optional:
     * this will be called each time
     * range slider perform updates
     */
    update: (data) => {
      console.log(data);
    },

    /**
     * Optional: release resources
     */
    destroy: () => {
      console.log('destroy');
    },
  };
};

/**
 * Required: add current plugin to the plugins list.
 */
window.tcRangeSliderPlugins.push(ExamplePlugin);

The HTML markup should be as follows:

<!-- the slider -->
<tc-range-slider 
  value="50" 
  label="#my-label"></tc-range-slider>

<!-- this label will contain the slider value -->
<div id="my-label"></div>

<script>
  // Here should be the content of our plugin
  // ...
</script>

<!-- the core script -->
<script src="toolcool-range-slider.min.js"></script>

Note: the plugin script should be included BEFORE the core script.

Now let’s get the label attribute that is passed in by the user. We can do this task in the init hook:

const labelPath = _$component?.getAttribute(`label`) ?? '';
const $labelElement = document.querySelector(labelPath);

The label element should be stored in a local variable for future use:

const ExamplePlugin = () => {
  
  let $labelElement;
  
  return {
    
    get name() {
      return 'My Plugin';
    },

    init: (
      _$component,
      _requestUpdate,
      _setters,
      _getters
    ) => {
      const labelPath = _$component?.getAttribute(`label`) ?? '';
      $labelElement = document.querySelector(labelPath);
    },

    update: (data) => {
      console.log(data);
    },

    destroy: () => {
      console.log('destroy');
    },
  };
};

Now let’s use an update hook to change the value of the label each time the slider is updated:

const ExamplePlugin = () => {
  
  let $labelElement;
  
  return {
    
    get name() {
      return 'My Plugin';
    },

    init: (
      _$component,
      _requestUpdate,
      _setters,
      _getters
    ) => {
      const labelPath = _$component?.getAttribute(`label`) ?? '';
      $labelElement = document.querySelector(labelPath);
    },

    update: (data) => {
      if($labelElement){
        $labelElement.textContent = data.values[0];
      }
    },

    destroy: () => {
      console.log('destroy');
    },
  };
};

A complete list of data properties is available here.

Let’s also update the content of the label on page load:

const ExamplePlugin = () => {
  
  let $labelElement;
  
  return {
    
    get name() {
      return 'My Plugin';
    },

    init: (
      _$component,
      _requestUpdate,
      _setters,
      _getters
    ) => {
      const labelPath = _$component?.getAttribute(`label`) ?? '';
      $labelElement = document.querySelector(labelPath);

      if($labelElement){
        $labelElement.textContent = _getters.getValues()[0];
      }
    },

    update: (data) => {
      if($labelElement){
        $labelElement.textContent = data.values[0];
      }
    },

    destroy: () => {
      console.log('destroy');
    },
  };
};

Finally, let’s clear the label when the slider is destroyed:

const ExamplePlugin = () => {
  
  let $labelElement;
  
  return {
    
    get name() {
      return 'My Plugin';
    },

    init: (
      _$component,
      _requestUpdate,
      _setters,
      _getters
    ) => {
      const labelPath = _$component?.getAttribute(`label`) ?? '';
      $labelElement = document.querySelector(labelPath);

      if($labelElement){
        $labelElement.textContent = _getters.getValues()[0];
      }
    },

    update: (data) => {
      if($labelElement){
        $labelElement.textContent = data.values[0];
      }
    },

    destroy: () => {
      if($labelElement){
        $labelElement.textContent = '';
      }
    },
  };
};

You can find the source code for several plugins here.