{"id":9802,"date":"2019-07-31T16:08:53","date_gmt":"2019-07-31T13:08:53","guid":{"rendered":"https:\/\/developers.elementor.com\/?p=9802"},"modified":"2024-02-26T10:25:38","modified_gmt":"2024-02-26T08:25:38","slug":"building-a-simple-custom-widget-with-javascript","status":"publish","type":"post","link":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/","title":{"rendered":"Building a simple Custom Widget with Javascript"},"content":{"rendered":"\n<p>Are you building a custom Elementor widget, and looking to add some Javascript functionality to it? You\u2019ve come to the right place. Elementor has a best practice for adding Javascript handlers to custom widgets, which we are going to cover in this blog post. We will build a simple, Javascript-powered widget together, explaining every step of the process.<\/p>\n\n\n\n<p>In addition to this blog post, our <a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/developers.elementor.com\/\" target=\"_blank\">Developers site<\/a> also has official documentation on <a href=\"https:\/\/developers.elementor.com\/creating-a-new-widget\/adding-javascript-to-elementor-widgets\/\">adding JS to widgets<\/a>.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h3 class=\"wp-block-heading\">Widget Concept<\/h3>\n\n\n\n<p>Our widget will consist of a button (similar to Elementor\u2019s familiar button widget) and a content area (powered by a WYSIWYG text-editor). The content will load onto the page as hidden (<code>display: none;<\/code>). Clicking the button will make the button fade out and the content fades in to replace it.<\/p>\n\n\n\n<p>We\u2019ll call the widget \u201cContent Toggle Button\u201d.&nbsp;<\/p>\n\n\n\n<p>Here\u2019s a quick demo in my favorite format, GIF:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img fetchpriority=\"high\" decoding=\"async\" width=\"702\" height=\"270\" src=\"https:\/\/developers.elementor.com\/wp-content\/uploads\/2019\/07\/gif.gif\" alt=\"\" class=\"wp-image-9811\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Let\u2019s Start with the Widget\u2019s PHP<\/h3>\n\n\n\n<p>We\u2019ll start by composing a simple PHP class and supplying the basic information for our widget:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\nif ( ! defined( 'ABSPATH' ) ) {\n   exit; \/\/ Exit if accessed directly.\n}\n\n\/**\n* Elementor Content Toggle Button widget.\n*\n* Elementor widget that displays a styled Button. Clicking the button replaces it with WYSIWYG content.\n*\/\nclass Widget_Content_Toggle_Button extends Elementor\\Widget_Base {\n\n   public function get_name() {\n       return 'content-toggle-button';\n   }\n\n   public function get_title() {\n       return __( 'Content Toggle Button', 'your-plugin-textdomain' );\n   }\n\n   public function get_icon() {\n       return 'eicon-dual-button';\n   }\n\n   public function get_keywords() {\n       return &#091; 'button', 'content', 'toggle' ];\n   }\n\n   protected function _register_controls() {}\n\n   protected function render() {}\n}\n<\/code><\/pre>\n\n\n\n<p>For more info about the structure of Widget PHP classes, see the documentation for <a href=\"https:\/\/developers.elementor.com\/creating-a-new-widget\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">creating a new widget<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Widget Controls<\/h4>\n\n\n\n<p>Within the <code>_register_controls()<\/code> method, we\u2019ll add controls for the button text and the hidden widget content:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>protected function _register_controls() {\n\t\/\/ WYSIWYG CONTENT\n\t$this-&gt;start_controls_section(\n\t\t'content_settings',\n\t\t&#091;\n\t\t\t'label' =&gt; __( 'Content', 'your-plugin-textdomain' ),\n\t\t]\n\t);\n\n\t$this-&gt;add_control(\n\t\t'widget_content',\n\t\t&#091;\n\t\t\t'label' =&gt; __( 'Content Box', 'your-plugin-textdomain' ),\n\t\t\t'type' =&gt; \\Elementor\\Controls_Manager::WYSIWYG,\n\t\t\t'default' =&gt; __( 'Widget Content', 'your-plugin-textdomain' ),\n\t\t\t'show_label' =&gt; false,\n\t\t]\n\t);\n\n\t$this-&gt;end_controls_section();\n\n\t\/*\n\t * BUTTON TEXT\n\t *\/\n\t$this-&gt;start_controls_section(\n\t\t'button_settings',\n\t\t&#091;\n\t\t\t'label' =&gt; __( 'Button Settings', 'your-plugin-textdomain' ),\n\t\t]\n\t);\n\n\t$this-&gt;add_control(\n\t\t'button_text',\n\t\t&#091;\n\t\t\t'label' =&gt; __( 'Button Text', 'your-plugin-textdomain' ),\n\t\t\t'type' =&gt; \\Elementor\\Controls_Manager::TEXT,\n\t\t\t'default' =&gt; __( 'Button Text', 'your-plugin-textdomain' ),\n\t\t]\n\t);\n\n\t$this-&gt;add_responsive_control(\n\t\t'button_align',\n\t\t&#091;\n\t\t\t'label' =&gt; __( 'Button Alignment', 'your-plugin-textdomain' ),\n\t\t\t'type' =&gt; \\Elementor\\Controls_Manager::CHOOSE,\n\t\t\t'options' =&gt; &#091;\n\t\t\t\t'left'    =&gt; &#091;\n\t\t\t\t\t'title' =&gt; __( 'Left', 'your-plugin-textdomain' ),\n\t\t\t\t\t'icon' =&gt; 'eicon-text-align-left',\n\t\t\t\t],\n\t\t\t\t'center' =&gt; &#091;\n\t\t\t\t\t'title' =&gt; __( 'Center', 'your-plugin-textdomain' ),\n\t\t\t\t\t'icon' =&gt; 'eicon-text-align-center',\n\t\t\t\t],\n\t\t\t\t'right' =&gt; &#091;\n\t\t\t\t\t'title' =&gt; __( 'Right', 'your-plugin-textdomain' ),\n\t\t\t\t\t'icon' =&gt; 'eicon-text-align-right',\n\t\t\t\t],\n\t\t\t],\n\t\t\t'default' =&gt; 'left',\n\t\t\t'selectors' =&gt; &#091;\n\t\t\t\t'{{WRAPPER}} .elementor-content-toggle-button-wrapper' =&gt; 'text-align: {{VALUE}};'\n\t\t\t],\n\t\t]\n\t);\n\n\t$this-&gt;end_controls_section();\n}<\/code><\/pre>\n\n\n\n<p>Feel free to add some styling controls. For more info on adding controls to widgets, see <a href=\"https:\/\/developers.elementor.com\/add-controls-to-widgets\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">the documentation on adding controls to widgets<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Widget HTML<\/h3>\n\n\n\n<p>Within the <code>render()<\/code> method, we will output our widget\u2019s HTML:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>protected function render() {\n\t$settings = $this-&gt;get_settings_for_display();\n\n\t?&gt;\n\t&lt;div class=\"elementor-content-toggle-button-wrapper\"&gt;\n\t\t&lt;a class=\"elementor-content-toggle-button-btn\" href=\"\"&gt;&lt;?php echo $settings&#091;'button_text']; ?&gt;&lt;\/a&gt;\n\t\t&lt;div class=\"elementor-content-toggle-button-content-box\"&gt;&lt;?php echo $settings&#091;'widget_content']; ?&gt;&lt;\/div&gt;\n\t&lt;\/div&gt;\n\t&lt;?php\n}<\/code><\/pre>\n\n\n\n<p>Notice that the button is an <code>&lt;a&gt;<\/code> tag wrapper by a <code>&lt;div&gt;<\/code>, and the content box is just a simple <code>&lt;div&gt;<\/code>. We said simple, didn\u2019t we?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Widget CSS<\/h3>\n\n\n\n<p>We\u2019ll create a separate CSS file with some basic styling to make the button look like Elementor\u2019s native button widget:&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" width=\"312\" height=\"119\" src=\"https:\/\/developers.elementor.com\/wp-content\/uploads\/2019\/07\/widgetcss.png\" alt=\"\" class=\"wp-image-9812\" srcset=\"https:\/\/developers.elementor.com\/wp-content\/uploads\/2019\/07\/widgetcss.png 312w, https:\/\/developers.elementor.com\/wp-content\/uploads\/2019\/07\/widgetcss-300x114.png 300w\" sizes=\"(max-width: 312px) 100vw, 312px\" \/><\/figure><\/div>\n\n\n\n<p>We\u2019ll call the file <code>content-toggle-button.css<\/code>:<\/p>\n\n\n\n<pre><code class=\"language-css\">.elementor-content-toggle-button-wrapper {\n    text-align: center;\n}\n\n.elementor-content-toggle-button-btn {\n    border-radius: 3px;\n    background-color: #61ce70;\n    color: #ffffff;\n    display: inline-block;\n    font-family: \"Roboto\", Sans-serif;\n    font-size: 15px;\n    font-weight: 500;\n    line-height: 1;\n    padding: 12px 24px;\n}\n\n.elementor-content-toggle-button-content-box {\n    display: none;\n    text-align: initial;\n}\n<\/code><\/pre>\n\n\n\n<p>We will take care of integrating the CSS into our plugin later on.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Finally, the Javascript<\/h3>\n\n\n\n<p>Ah, the moment we\u2019ve all been waiting for. We\u2019ll write a Javascript handler for our Widget, to give it that show\/hide functionality we mentioned at the beginning of the post.<\/p>\n\n\n\n<p>The Javascript handlers for Elementor\u2019s native widgets are written as ES6 classes. The handlers all extend a base class which provides some useful functionality.<\/p>\n\n\n\n<pre><code class=\"language-javascript\">class ContentToggleButton extends elementorModules.frontend.handlers.Base {\n   getDefaultSettings() {}\n\n   getDefaultElements() {}\n\n   bindEvents() {}\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">getDefaultSettings<\/h4>\n\n\n\n<p>This method is used to configure settings to be used by other methods of our handler class. The method should return a settings object. <code>getDefaultSettings<\/code> is most widely used to enter the jQuery selectors of the HTML elements in your widget you would like to target.<\/p>\n\n\n\n<p>In our example, this method would look like this:<\/p>\n\n\n\n&lt;p<pre><code class=\"language-javascript\">getDefaultSettings() {\n   return {\n       selectors: {\n           button: '.elementor-content-toggle-button-btn',\n           content: '.elementor-content-toggle-button-content-box',\n       },\n   };\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">getDefaultElements()<\/h4>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright\"><img decoding=\"async\" width=\"306\" height=\"283\" src=\"https:\/\/developers.elementor.com\/wp-content\/uploads\/2019\/07\/getdefaultelements.png\" alt=\"\" class=\"wp-image-9813\" srcset=\"https:\/\/developers.elementor.com\/wp-content\/uploads\/2019\/07\/getdefaultelements.png 306w, https:\/\/developers.elementor.com\/wp-content\/uploads\/2019\/07\/getdefaultelements-300x277.png 300w\" sizes=\"(max-width: 306px) 100vw, 306px\" \/><\/figure><\/div>\n\n\n\n<p>This method creates jQuery objects from the widget\u2019s targeted HTML elements, and appends them to the class instance object under a property called <code>elements<\/code>. Grabbing the settings object is done by calling the base method <code>this.getSettings()<\/code>, passing in the key for the requested setting as a parameter.&nbsp;<\/p>\n\n\n\n<p>The image on the right shows the handler class instance as it is running in Chrome devtools.<\/p>\n\n\n\n<p>In our case, our method will look like this:<\/p>\n\n\n\n<pre><code class=\"language-javascript\">getDefaultElements() {\n    const selectors = this.getSettings( 'selectors' );\n    return {\n        $button: this.$element.find( selectors.button ),\n        $content: this.$element.find( selectors.content ),\n    };\n}<\/code><\/pre>\n\n\n\n<p>For convenience, we gave the property name for our jQuery objects keys with identical names to the ones in our settings object, only prefixed with a <code>$<\/code> sign.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">bindEvents()<\/h4>\n\n\n\n<p>This method is used to add event listeners for interactions with our widget\u2019s HTML.<\/p>\n\n\n\n<p>Since we want our button to fade away on click, and reveal our content box, we\u2019ll add an \u2018on click\u2019 listener:<\/p>\n\n\n\n<pre><code class=\"language-javascript\">bindEvents() {\n    this.elements.$button.on( 'click', this.onButtonClick.bind( this ) );\n}<\/code><\/pre>\n\n\n\n<p>Notice our callback in this case is another method called <code>onButtonClick<\/code>. We are binding the method to <strong><code>this<\/code><\/strong>, to make sure it does not lose the widget\u2019s context when it runs.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">onButtonClick()<\/h4>\n\n\n\n<p>This custom method will be included in our handler class, and will handle everything that happens when a user clicks the button.<\/p>\n\n\n\n<p>Our <code>onButtonClick<\/code> method will look like this:<\/p>\n\n\n\n<pre><code class=\"language-javascript\">onButtonClick( event ) {\n    event.preventDefault();\n    this.elements.$button.fadeOut().promise().done( () =&gt; {\n        this.elements.$content.fadeIn();\n    } );\n}<\/code><\/pre>\n\n\n\n<p>First, we prevent the default browser response when our button link is clicked. Then, we use jQuery\u2019s <code>fadeOut()<\/code> method to make the button disappear on click. To make sure the content fades in only once the button has finished its fade-out animation, we chain a promise to the method. In the promise\u2019s callback we call jQuery\u2019s <code>fadeIn()<\/code> method on the content box.<\/p>\n\n\n\n<p>For more information about these handler methods, <a href=\"#\">see the official documentation on adding Javascript to custom Elementor widgets<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The complete handler class<\/h3>\n\n\n\n<p>The finished handler class looks like this:<\/p>\n\n\n\n<pre><code class=\"language-javascript\">class ContentToggleButton extends elementorModules.frontend.handlers.Base {\n   getDefaultSettings() {\n       return {\n           selectors: {\n               button: '.elementor-content-toggle-button-btn',\n               content: '.elementor-content-toggle-button-content-box',\n           },\n       };\n   }\n\n   getDefaultElements() {\n       const selectors = this.getSettings( 'selectors' );\n       return {\n           $button: this.$element.find( selectors.button ),\n           $content: this.$element.find( selectors.content ),\n       };\n   }\n\n   bindEvents() {\n       this.elements.$button.on( 'click', this.onButtonClick.bind( this ) );\n   }\n\n   onButtonClick( event ) {\n       event.preventDefault();\n\n       this.elements.$button.fadeOut().promise().done( () =&gt; {\n           this.elements.$content.fadeIn();\n       } );\n   }\n}<\/code><\/pre>\n\n\n\n<p>For wider browser support, it is recommended to transpile your class into ES5 syntax (using a tool like Babel.js) before deploying it in production.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Registering the Widget Handler with Elementor<\/h3>\n\n\n\n<p>Finally, we need to make sure the widget handler integrates properly with Elementor and is called at the right time.<\/p>\n\n\n\n<p>This is done by listening to Elementor\u2019s<strong> <code>elementor\/frontend\/init<\/code><\/strong> event. In the listener\u2019s callback, we attach our handler registration function (<strong><code>elementorFrontend.elementsHandler.<\/code><\/strong><code>addHandler<\/code>) to a hook that runs only once our widget\u2019s instance is rendered on the page\/in our editor preview.<\/p>\n\n\n\n<pre><code class=\"language-javascript\">jQuery( window ).on( 'elementor\/frontend\/init', () =&gt; {\n   const addHandler = ( $element ) =&gt; {\n       elementorFrontend.elementsHandler.addHandler( ContentToggleButton, {\n           $element,\n       } );\n   };\n\n   elementorFrontend.hooks.addAction( 'frontend\/element_ready\/content-toggle-button.default', addHandler );\n} );<\/code><\/pre>\n\n\n\n<p>For more information on registering widget handlers, <a href=\"#\">see the documentation<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Enqueuing the handler script<\/h3>\n\n\n\n<p>To get our handler script to load when our custom widget is used, we have to go back to our widget\u2019s PHP.&nbsp;<\/p>\n\n\n\n<p>Since our widget\u2019s class does not utilize a constructor method, we create one:&nbsp;<\/p>\n\n\n\n<pre><code>class Widget_Class_Name extends Widget_Base {\n\n    public function __construct($data = [], $args = null) {\n       parent::__construct($data, $args);\n\n       wp_register_script( 'ctb-script', '\/path\/to\/content-toggle-button.js', [ 'elementor-frontend' ], '1.0.0', true );\n       wp_register_style( 'ctb-stylesheet', '\/path\/to\/content-toggle-button.css' );\n    }\n\n    public function get_script_depends() {\n      return [ 'ctb-script' ];\n    }\n\n    public function get_style_depends() {\n      return [ 'ctb-stylesheet' ];\n    }\n}<\/code><\/pre>\n\n\n\n<p>We register our script using WordPress\u2019 native wp_register_script function and we do the same for our stylesheet using WordPress&#8217; native wp_register_style function inside our constructor. <\/p>\n\n\n\n<p>To make sure our registered script and style are enqueued, we add two more methods to our Widget\u2019s PHP class, the first is called&nbsp; <code>get_script_depends()<\/code> which returns an array with our script handle. The second is called <code>get_style_depends()<\/code> which returns an array with our style handle (see above). This makes sure our scripts and styles are enqueued at the right time and only when the widget is in use.<\/p>\n\n\n\n<p>That\u2019s it!* Enjoy creating your very own JavaScript-powered custom widgets!<\/p>\n\n\n\n<small>* Once your widget class is ready and complete, make sure you do everything else required for an Elementor add-on plugin to work properly, such as registering the widget with Elementor\u2019s widgets_manager. For more info, check out the documentation on <a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/developers.elementor.com\/creating-an-extension-for-elementor\/\" target=\"_blank\">extending Elementor<\/a>.<\/small>\n","protected":false},"excerpt":{"rendered":"<p>Are you building a custom Elementor widget, and looking to add some Javascript functionality to it? You\u2019ve come to the right place. Elementor has a best practice for adding Javascript handlers to custom widgets, which we are going to cover in this blog post. We will build a simple, Javascript-powered widget together, explaining every step [&hellip;]<\/p>\n","protected":false},"author":2024245,"featured_media":14447,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34],"tags":[],"marketing_persona":[],"marketing_intent":[],"class_list":["post-9802","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-features"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Building a simple Custom Widget with Javascript - Developers<\/title>\n<meta name=\"description\" content=\"Are you building a custom Elementor widget, and looking to add some Javascript functionality to it? You\u2019ve come to the right place. Elementor has a best\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a simple Custom Widget with Javascript - Developers\" \/>\n<meta property=\"og:description\" content=\"Are you building a custom Elementor widget, and looking to add some Javascript functionality to it? You\u2019ve come to the right place. Elementor has a best\" \/>\n<meta property=\"og:url\" content=\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/\" \/>\n<meta property=\"og:site_name\" content=\"Developers\" \/>\n<meta property=\"article:published_time\" content=\"2019-07-31T13:08:53+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-02-26T08:25:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/developers.elementor.com\/wp-content\/uploads\/2021\/12\/cover-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Ohad Raz\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ohad Raz\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/\"},\"author\":{\"name\":\"Ohad Raz\",\"@id\":\"https:\/\/developers.elementor.com\/#\/schema\/person\/319490ffddcf03867aafd4e69276084a\"},\"headline\":\"Building a simple Custom Widget with Javascript\",\"datePublished\":\"2019-07-31T13:08:53+00:00\",\"dateModified\":\"2024-02-26T08:25:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/\"},\"wordCount\":1021,\"commentCount\":7,\"image\":{\"@id\":\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/developers.elementor.com\/wp-content\/uploads\/2021\/12\/cover-1.png\",\"articleSection\":[\"Features\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/\",\"url\":\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/\",\"name\":\"Building a simple Custom Widget with Javascript - Developers\",\"isPartOf\":{\"@id\":\"https:\/\/developers.elementor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/developers.elementor.com\/wp-content\/uploads\/2021\/12\/cover-1.png\",\"datePublished\":\"2019-07-31T13:08:53+00:00\",\"dateModified\":\"2024-02-26T08:25:38+00:00\",\"author\":{\"@id\":\"https:\/\/developers.elementor.com\/#\/schema\/person\/319490ffddcf03867aafd4e69276084a\"},\"description\":\"Are you building a custom Elementor widget, and looking to add some Javascript functionality to it? You\u2019ve come to the right place. Elementor has a best\",\"breadcrumb\":{\"@id\":\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#primaryimage\",\"url\":\"https:\/\/developers.elementor.com\/wp-content\/uploads\/2021\/12\/cover-1.png\",\"contentUrl\":\"https:\/\/developers.elementor.com\/wp-content\/uploads\/2021\/12\/cover-1.png\",\"width\":1200,\"height\":630,\"caption\":\"Cover image\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Developers\",\"item\":\"https:\/\/developers.elementor.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building a simple Custom Widget with Javascript\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/developers.elementor.com\/#website\",\"url\":\"https:\/\/developers.elementor.com\/\",\"name\":\"Developers\",\"description\":\"Official Elementor Developer Resources\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/developers.elementor.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/developers.elementor.com\/#\/schema\/person\/319490ffddcf03867aafd4e69276084a\",\"name\":\"Ohad Raz\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/developers.elementor.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/4457665d392755ad51548d0bb0b6e22a5c4fcefaf7b10d581189314ce6b0ea89?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/4457665d392755ad51548d0bb0b6e22a5c4fcefaf7b10d581189314ce6b0ea89?s=96&d=mm&r=g\",\"caption\":\"Ohad Raz\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Building a simple Custom Widget with Javascript - Developers","description":"Are you building a custom Elementor widget, and looking to add some Javascript functionality to it? You\u2019ve come to the right place. Elementor has a best","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/","og_locale":"en_US","og_type":"article","og_title":"Building a simple Custom Widget with Javascript - Developers","og_description":"Are you building a custom Elementor widget, and looking to add some Javascript functionality to it? You\u2019ve come to the right place. Elementor has a best","og_url":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/","og_site_name":"Developers","article_published_time":"2019-07-31T13:08:53+00:00","article_modified_time":"2024-02-26T08:25:38+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/developers.elementor.com\/wp-content\/uploads\/2021\/12\/cover-1.png","type":"image\/png"}],"author":"Ohad Raz","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Ohad Raz","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#article","isPartOf":{"@id":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/"},"author":{"name":"Ohad Raz","@id":"https:\/\/developers.elementor.com\/#\/schema\/person\/319490ffddcf03867aafd4e69276084a"},"headline":"Building a simple Custom Widget with Javascript","datePublished":"2019-07-31T13:08:53+00:00","dateModified":"2024-02-26T08:25:38+00:00","mainEntityOfPage":{"@id":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/"},"wordCount":1021,"commentCount":7,"image":{"@id":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#primaryimage"},"thumbnailUrl":"https:\/\/developers.elementor.com\/wp-content\/uploads\/2021\/12\/cover-1.png","articleSection":["Features"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/","url":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/","name":"Building a simple Custom Widget with Javascript - Developers","isPartOf":{"@id":"https:\/\/developers.elementor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#primaryimage"},"image":{"@id":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#primaryimage"},"thumbnailUrl":"https:\/\/developers.elementor.com\/wp-content\/uploads\/2021\/12\/cover-1.png","datePublished":"2019-07-31T13:08:53+00:00","dateModified":"2024-02-26T08:25:38+00:00","author":{"@id":"https:\/\/developers.elementor.com\/#\/schema\/person\/319490ffddcf03867aafd4e69276084a"},"description":"Are you building a custom Elementor widget, and looking to add some Javascript functionality to it? You\u2019ve come to the right place. Elementor has a best","breadcrumb":{"@id":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#primaryimage","url":"https:\/\/developers.elementor.com\/wp-content\/uploads\/2021\/12\/cover-1.png","contentUrl":"https:\/\/developers.elementor.com\/wp-content\/uploads\/2021\/12\/cover-1.png","width":1200,"height":630,"caption":"Cover image"},{"@type":"BreadcrumbList","@id":"https:\/\/developers.elementor.com\/building-a-simple-custom-widget-with-javascript\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Developers","item":"https:\/\/developers.elementor.com\/"},{"@type":"ListItem","position":2,"name":"Building a simple Custom Widget with Javascript"}]},{"@type":"WebSite","@id":"https:\/\/developers.elementor.com\/#website","url":"https:\/\/developers.elementor.com\/","name":"Developers","description":"Official Elementor Developer Resources","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/developers.elementor.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/developers.elementor.com\/#\/schema\/person\/319490ffddcf03867aafd4e69276084a","name":"Ohad Raz","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/developers.elementor.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/4457665d392755ad51548d0bb0b6e22a5c4fcefaf7b10d581189314ce6b0ea89?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4457665d392755ad51548d0bb0b6e22a5c4fcefaf7b10d581189314ce6b0ea89?s=96&d=mm&r=g","caption":"Ohad Raz"}}]}},"_links":{"self":[{"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/posts\/9802","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/users\/2024245"}],"replies":[{"embeddable":true,"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/comments?post=9802"}],"version-history":[{"count":0,"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/posts\/9802\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/media\/14447"}],"wp:attachment":[{"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/media?parent=9802"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/categories?post=9802"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/tags?post=9802"},{"taxonomy":"marketing_persona","embeddable":true,"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/marketing_persona?post=9802"},{"taxonomy":"marketing_intent","embeddable":true,"href":"https:\/\/developers.elementor.com\/wp-json\/wp\/v2\/marketing_intent?post=9802"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}