Elementor Widgets are a great way to build your landing pages when using Elementor. Mostly, widgets are done through PHP but if you need some of the functionality on the front end or for the user editing the page, you will need to use JavaScript.

In this tutorial, we will learn about all the methods you can use with their JavaScript widget model and check for examples of the same.

If you want to check the Elementor’s guide of using JavaScript in widgets, you can get it on their site.

Since their guide uses the ES6 classes, we will use that approach as well here. The recommendation is to transpile your code into ES5 to support most browsers using Babel.js or similar.

To enqueue the script, you can use your widget’s construct method in PHP:

<?php class Widget_Class_Name extends Widget_Base { public function __construct($data = [], $args = null) { parent::__construct($data, $args); wp_register_script( 'script-handle', 'path/to/file.js', , '1.0.0', true ); } public function get_script_depends() { return ; } }

That file would contain the transpiled JavaScript file. The file with ES6 would then have a widget that is extending the base class.

class WidgetHandlerClass extends elementorModules.frontend.handlers.Base {}

And to register our own Widget class (in above example WidgetHandlerClass), we do this right below our class definition.

jQuery( window ).on( 'elementor/frontend/init', () => { const addHandler = ( $element ) => { elementorFrontend.elementsHandler.addHandler( WidgetHandlerClass, { $element, } ); }; elementorFrontend.hooks.addAction( 'frontend/element_ready/your-widget-name.default', addHandler ); });

The your-widget-name is the name that your PHP widget class returns in the method get_name() .

Let’s now see what we have in the elementorModules.frontend.handlers.Base on which we extend our own JavaScript class.

Elementor JavaScript Base

To check the whole class (model) on the Elementor github, you can check the base.js.

Here are the methods and attributes that exist in the class:

$element – attribute,

– attribute, editorListeners – attribute,

– attribute, onElementChange – method; null by default,

– method; null by default, onEditSettingsChange – method; null by default,

– method; null by default, onGeneralSettingsChange – method; null by default,

– method; null by default, onPageSettingsChange – method; null by default,

– method; null by default, isEdit – true if we are in the editor,

– true if we are in the editor, findElement – method,

– method, getUniqueHandlerID – method,

– method, initEditorListeners – method,

– method, getEditorListeners – method,

– method, addEditorListeners – method,

– method, removeEditorListeners – method,

– method, getElementType – method,

– method, getWidgetType – method,

– method, getID – method, returns unique ID of the element,

– method, returns unique ID of the element, getModelCID – method, returns unique Client ID,

– method, returns unique Client ID, getElementSettings – method, returns custom defined settings,

– method, returns custom defined settings, getEditSettings – method, returns the editor settings such as panel when clicking on the various control sections,

– method, returns the editor settings such as when clicking on the various control sections, getCurrentDeviceSetting – method,

– method, onDestroy – method, called when we remove the element from the page.

Some of this methods and attributes you can use in your custom defined methods. Let’s go over a few of them, to get an idea of what is going on here.

$element

This attribute is the jQuery wrapper around the widget. You can use jQuery on it to find elements and manipulate the DOM of the widget or elements inside of the widget.

editorListeners

editorListeners attribute is an array of events that will trigger different methods on some changes. The default listeners are:

element:destroy – calls the destroy() method

– calls the method change:your-widget-name – calls onElementChange method

– calls method change:editSettings – calls onEditSettingsChange method

– calls method onPageSettingsChange – calls onPageSettingsChange method

– calls method onGeneralSettingsChange – calls onGeneralSettingsChange method

If some of those methods do not exist, they won’t be called.

findElement

This will find a jQuery element inside of the main $element object.

getUniqueHandlerID

This will get a unique handler for ID which is used for handling events so those don’t get to be called more than once on the specific element (widget instance).

onElementChange

This method is the method you will have to define if you want to make different operations/changes on the widget if a setting has changed.

This method will pass a parameterName which is the registered setting (control) key.

Example of an Elementor Core widget Video

Let’s now go over the Elementor core widget Video.

The Video Widget code can be found here:

The JavaScript handle is registered to video.default because the video is returned by get_name() .

getDefaultElements() { const selectors = this.getSettings( 'selectors' ); return { $imageOverlay: this.$element.find( selectors.imageOverlay, $video: this.$element.find( selectors.video ), $videoIframe: this.$element.find( selectors.videoIframe ), }; }

When the widget is loaded, they will get the default selectors using jQuery. The class/id for each of those elements are defined within the getDefaultSettings method.

getDefaultSettings() { return { selectors: { imageOverlay: '.elementor-custom-embed-image-overlay', video: '.elementor-video', videoIframe: '.elementor-video-iframe', }, }; }

Then, inside of the method playVideo(), we can use the this.elements.$video to get the jQuery object for the video.

The Video JavaScript handler has the method onElementChange defined to listen for changes in the widget settings.

That method then listens for several changes such as:

lightbox_content_animation – it uses indexOf because the settings name will also have a suffix there because it is a responsive control,

– it uses indexOf because the settings name will also have a suffix there because it is a responsive control, checks if the lightbox is enabled and if the setting lightbox changes and we see that the lightbox has been disabled with it, then we hide the modal/popup,

is enabled and if the setting changes and we see that the lightbox has been disabled with it, then we hide the modal/popup, otherwise, if the aspect_ratio setting changed and the lightbox is enabled, it will set the new aspect ratio on the lightbox.

On the lightbox_content_animation , Elementor uses the indexOf because there will be three different settings since it’s a response method. It will append _mobile, _table and _desktop.

The mentioned settings on JavaScript can be found as registered controls in PHP:

Custom Elementor Widget – Working Hours

Now that we have gone through the JavaScript part of Elementor Widgets, let’s create our own. We will create Working Hours widget where we will use JavaScript to reverse the rows when we click the days table head.

If you want to skip the code step and get the complete code, you can get it at the bottom.

Preparing the plugin

Create a new plugin folder elementor-widget (or however you want it). Then inside of it create a file elementor-widget.php , then create a folder src and inc . Inside of the folder src , create a JavaScript file index.js and inside of the inc folder create a file widget.php .

Be sure to have npm installed so that we can use it install @wordpress/scripts.

Then, with the terminal (command prompt) place yourself inside of the plugin folder and execute:

npm install @wordpress/scripts --save-dev

Then inside of the package.json file, if there are no scripts yet add:

"scripts": {"build": "wp-scripts build"}

Now, you can type npm run build and there will be a folder build created with the processed index.js . We can now start creating our widget.

Register our Elementor Widget

Add this to the elementor-widget.php file so we can register our widget.

We are hooking on the action elementor/widgets/widgets_registered that is called once all the core widgets have been registered.

Then we use the Elementor\Widgets_Manager object to register our own Elementor widget with the method register_widget_type() .

Defining Elementor Widget

Let’s now define our My_Elementor_Widget . Put this in the inc/widget.php file.

In the constructor method, we register our script. Then inside of the method get_script_depends we define that this is a dependency for this widget. Then, when this widget is called, it will also enqueue our build/index.js file.

We have also define a custom method here get_days() to get the week days. Now, we need to define all the controls we will have for this widget.

Here we define a new section under which we will register a repeater control.

Afte that, we define three controls; day, start and end. We will then be able to define days and when the work starts and when it ends.

Let’s now render the widget.

We render the widget inside of the render() method. If we have any days defined, we show them with the start and end hours.

Ok, now let’s define our src/index.js file and build it.

JavaScript in our Elementor Widget

Open the src/index.js file and add this code:

That is the frontend handler for our widget. We named it MyElementorHandler .

We bind an event to reverse the rows when we click on the day head column.

Now we also need to hook it onto our widget.

Now in the terminal, while in the folder of the plugin, type npm run build .

If you now add your widget, add some working hours and try clicking on the Day column, you will see the rows being reversed.

Complete Code

If you want to skip all the steps and have the code ready, you can download the complete code here.

This part is available only to the members. If you want to become a member and support my work go to this link and subscribe: Become a Member

Conclusion

Elementor is a really powerful page builder and you can easily build your own widgets. They can be only PHP but you can also enhance the user experience with a little of JavaScript.

Have you tried building your own Elementor Widgets? Let us know in the comment about your experience and link what you have built.