New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
馃悶 elementorModules.frontend.tools
is undefined when creating a JS Handler for a Custom widget
#19709
Comments
Hi @MarleyPlant Can you share your code here? |
Handler.js (function ($) {
class ImageSliderHandler extends elementorModules.frontend.handlers.Base {
currentSlide = 0;
dotActiveClass = "image-slider__dot--active";
getDefaultSettings() {
return {
selectors: {
prevButton: ".image-slider__controls__prev",
nextButton: ".image-slider__controls__next",
dots: ".image-slider__dot",
slides: ".image-slider__img",
},
};
}
getDefaultElements() {
const selectors = this.getSettings("selectors");
return {
$nextButton: this.$element.find(selectors.nextButton),
$prevButton: this.$element.find(selectors.prevButton),
$slides: this.$element.find(selectors.slides),
$dots: this.$element.find(selectors.dots),
};
}
bindEvents() {
this.elements.$nextButton.on("click", this.nextSlide.bind(this));
this.elements.$prevButton.on("click", this.prevSlide.bind(this));
this.elements.$dots.on("click", this.onDotClick.bind(this));
}
nextSlide() {
this.resetSlides();
this.currentSlide++;
if (this.currentSlide > slides.length) {
this.currentSlide = 1;
}
dots[this.currentSlide - 1].classList.add(this.dotActiveClass);
this.showSlide(this.currentSlide - 1);
}
showSlide() {
this.elememts.$slides[slide].style.display = "block";
}
resetSlides() {
this.elements.$dots.removeClass(this.dotActiveClass);
this.elements.$slides.css("display", "none");
}
prevSlide() {
this.resetSlides();
if (this.currentSlide > 0) {
this.currentSlide--;
} else if (this.currentSlide == 0) {
this.currentSlide = this.elements.$slides.length - 1;
}
if (this.currentSlide > 0) {
this.elements.$dots[this.currentSlide - 1].classList.add(
this.dotActiveClass
);
} else {
this.elements.$dots[slides.length - 1].classList.add(
this.dotActiveClass
);
}
this.showSlide(this.currentSlide);
}
onDotClick(event) {
this.resetSlides();
this.currentSlide = $(event.target).index();
this.showSlide(this.currentSlide);
event.target.classList.add(this.dotActiveClass);
}
}
$(window).on("elementor/frontend/init", () => {
elementorFrontend.elementsHandler.attachHandler(
"image-slider",
ImageSliderHandler
);
});
})(jQuery); Widget.php <?php
/**
* Marleyplant Widgets Library
* php version 7.3.1
*
* @category Scripts
* @package MarleyPlant
* @subpackage Scripts
* @author Marley Plant <marley@marleyplant.com>
* @license Apache http://www.apache.org/licenses/
* @link https://marleyplant.com
* @since 1.0
*/
use Elementor\Widget_Base;
use Elementor\Controls_Manager;
if (!defined('ABSPATH')) {
exit; // Exit if accessed directly
}
/**
* Elementor Image Comparison Widget
*
* This class defines the Image Slider Widget
*
* @category Scripts
* @package MarleyPlant
* @subpackage Scripts
* @author Marley Plant <marley@marleyplant.com>
* @license Apache http://www.apache.org/licenses/
* @link https://marleyplant.com
* @since 1.0
*/
class ImageSlider extends \Elementor\Widget_Base
{
/**
* Retrieve the widget name.
*
* @since 1.0.0
*
* @access public
*
* @return string Widget name.
*/
public function get_name()
{
return 'image-slider';
}
/**
* Retrieve the widget title.
*
* @since 1.0.0
*
* @access public
*
* @return string Widget title.
*/
public function get_title()
{
return __('Image Slider', 'marleyplant_widgets');
}
/**
* Retrieve the widget icon.
*
* @since 1.0.0
*
* @access public
*
* @return string Widget icon.
*/
public function get_icon()
{
return 'eicon-slider-full-screen';
}
/**
* Retrieve the list of categories the widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* Note that currently Elementor supports only one category.
* When multiple categories passed, Elementor uses the first one.
*
* @since 1.0.0
*
* @access public
*
* @return array Widget categories.
*/
public function get_categories()
{
return ['general'];
}
/**
* Get custom help URL.
*
* Retrieve a URL where the user can get more information about the widget.
*
* @since 1.0.0
* @access public
* @return string Widget help URL.
*/
public function get_custom_help_url()
{
return 'https://developers.elementor.com/docs/widgets/';
}
/**
* Get widget keywords.
*
* Retrieve the list of keywords the oEmbed widget belongs to.
*
* @since 1.0.0
* @access public
* @return array Widget keywords.
*/
public function get_keywords()
{
return ['plantek'];
}
/**
* Retrieve the list of scripts the widget depended on.
*
* Used to set scripts dependencies required to run the widget.
*
* @since 1.0.0
*
* @access public
*
* @return array Widget scripts dependencies.
*/
public function get_script_depends()
{
return ['image-slider-js'];
}
/**
* Register the widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 1.0.0
*
* @access protected
* @return null
*/
protected function register_controls()
{
$this->start_controls_section(
'content_section',
[
'label' => __('Content', 'plugin-name'),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]
);
$repeater = new \Elementor\Repeater();
$repeater->add_control(
'heading',
[
'label' => esc_html__('Title', 'plugin-name'),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => esc_html__('Title', 'plugin-name'),
'label_block' => true,
]
);
$repeater->add_control(
'image',
[
'label' => esc_html__('Choose Image', 'plugin-name'),
'type' => \Elementor\Controls_Manager::MEDIA,
'default' => [
'url' => \Elementor\Utils::get_placeholder_image_src(),
],
]
);
$this->add_control(
'slides',
[
'label' => esc_html__('Slides List', 'plugin-name'),
'type' => \Elementor\Controls_Manager::REPEATER,
'fields' => $repeater->get_controls()
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style',
[
'label' => __('Style', 'marleyplant_widgets'),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'color_slider',
[
'label' => esc_html__('Primary Color', 'plugin-name'),
'type' => \Elementor\Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .title' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'sliderWidth',
[
'label' => __('Width', 'plugin-domain'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['%', 'em', 'px'],
'range' => [
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'unit' => '%',
'size' => 100,
],
'selectors' => [
'{{WRAPPER}} .image-slider' => 'width: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'sliderHeight',
[
'label' => __('Height', 'plugin-domain'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['%', 'em', 'px'],
'range' => [
'%' => [
'min' => 0,
'max' => 100,
],
"em" => [
'min' => 0,
'max' => 100
]
],
'default' => [
'unit' => '%',
'size' => 100,
],
'selectors' => [
'{{WRAPPER}} .image-slider' => 'height: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .image-slider__img' => 'height: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'objectFit',
[
'label' => esc_html__('Object Fit', 'plugin-name'),
'type' => \Elementor\Controls_Manager::SELECT,
'default' => 'cover',
'options' => [
'cover' => esc_html__('Cover', 'plugin-name'),
'fill' => esc_html__('Fill', 'plugin-name'),
'contain' => esc_html__('Contain', 'plugin-name'),
'scale-down' => esc_html__('Scale Down', 'plugin-name'),
],
]
);
$this->add_control(
'show_controls',
[
'label' => esc_html__('Show Controls?', 'plugin-name'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => esc_html__('Show', 'your-plugin'),
'label_off' => esc_html__('Hide', 'your-plugin'),
'return_value' => 'yes',
'default' => 'yes',
]
);
$this->add_control(
'show_dots',
[
'label' => esc_html__('Show Dots?', 'plugin-name'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => esc_html__('Show', 'your-plugin'),
'label_off' => esc_html__('Hide', 'your-plugin'),
'return_value' => 'yes',
'default' => 'yes',
]
);
$this->end_controls_section();
}
/**
* Render the widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
*
* @access protected
* @return null
*/
protected function render()
{
include __DIR__ . '/template.php';
}
} |
Would love to know the reason why this isn't working. |
Hi @MarleyPlant Sounds like a similar problem I had when trying to use the At the bottom of the page you'll notice that the code needs to be transpiled:
However, you can create the My issue/post has info on how to transpile it if you want to do it that way: #19858 |
I have the same problem. This bug only appears on the Twenty Twenty-Two and Twenty Twenty-Three themes (WP 6.1, Elementor 3.8.0, clean themes, no other plugins). The console error:
My code:
My Script:
Moreover, here in the documentation - https://developers.elementor.com/docs/scripts-styles/widget-scripts/ - there is no 'elementor-frontend' in the dependencies, but then the error is like this:
But here - https://developers.elementor.com/add-javascript-to-elementor-widgets/#Registering_the_Widget_Handler_with_Elementor - 'elementor-frontend' is in the dependencies - and this solution works in all but these two themes. I would appreciate any help! |
elementorModules.frontend.tools
is undefined when creating a JS Handler for a Custom widget
Same problem here since a year i think. I noticed that this happens for logged in users, however i think i found a temporary workaround for this as the error reported by this bug report shows up even if you enqueue a blank js and this let me think that maybe is a priority issue. It seems that the scripts are loaded before 'elementor-frontend' is actually loaded, so my solution is to add an high priority to the reccomended code as showed below: This seems the only thing that works for now. |
Yes, this issue occurs till latest update of elementor |
I found this - the problem occurs on block themes: |
This also occurs with the MasterStudy LMS theme. |
Guys, this bug is still relevant - my custom widget is still causing this error on block themes. Any progress in this area? |
Hi, i think at this point that they did not want to solve this bug. As a solution, created a function in wich i register and localize all my scripts and then enqueue them on init. So i have a function like this: public function register_dependencies() {
$dbp_js_ver = date("ymd-Gis", filemtime( brainless_elements()->plugin_path . '/assets/js/db-post.js' ));
wp_register_script( 'db-post-scripts', brainless_elements()->assets_url .'/js/db-post.js', [ 'elementor-frontend' ], $dbp_js_ver, true );
wp_localize_script( 'db-post-scripts', 'db_post_ajax', array( 'ajaxurl' => admin_url('admin-ajax.php'), 'check_nonce' => wp_create_nonce('db-nonce')) );
} and then in init i do this: add_action( 'wp_enqueue_scripts', [ $this, 'register_dependencies' ], 9999 ); shortly after registering my widgets and controls. I also noticed that elementor do not load all my registered files, but only the ones the widget depends on where the widget is loaded, using the public function get_script_depends() {
return [ 'db-post-scripts' ];
} Hope it helps 馃 |
Hi @nicoblg! This solution continues to cause an error on block themes. I enqueued the script in the high priority way you suggested above and it works on block themes, but some users are having the problem when using some caching plugins. I'm not 100% sure this is where the problem lies as I haven't had access to the problem sites, but theoretically the possibility is there. Ok, too bad we can't influence this..... |
elementorModules.frontend.tools
is undefined when creating a JS Handler for a Custom widgetelementorModules.frontend.tools
is undefined when creating a JS Handler for a Custom widget
Prerequisites
Description
When creating a JS Handler for a custom widget I am receiving the following error in the web browser.
the error seems to be caused when creating my handler class and using
extends elementorModules.frontend.handlers.Base
this handler is registered as a script depend for my widget in the widget class and also has "elementor-frontend" as a dependency when registering the script with WordPressI can't seem to figure out the reason for this happening, I have followed the documentation exactly
Steps to reproduce
extends elementorModules.frontend.handlers.Base
Isolating the problem
System Info
Click to reveal
The text was updated successfully, but these errors were encountered: