dodo254
dodo254

Reputation: 519

Elementor live preview for custom (non-elementor) widgets/components

I have a theme that has a header component. That header is not an Elementor widget, but just a normal HTML/PHP component. Just like an Elementor widget it has some properties, e.g. transparent, overlayed...

I have added those properties to the Elementor Page Settings section via hook:

add_action('elementor/element/wp-page/document_settings/before_section_start', 'page_settings' );

function page_settings($controlStack){
    $controlStack->start_controls_section(
            'page_settings',
            [
                'label' => _x('Page Settings', 'elementor', 'theme'),
                'tab' => \Elementor\Controls_Manager::TAB_SETTINGS,
            ]
        );

        $controlStack->add_control(
            'header_overlayed',
            [
                'type' => \Elementor\Controls_Manager::SWITCHER,
                'label' => _x('Header Overlayed', 'elementor', 'theme'),
                'label_on' => __('True', 'theme'),
                'label_off' => __('False', 'theme'),
                'return_value' => true,
                'default' => false,
            ]
        );

        $controlStack->add_control(
            'header_transparent',
            [
                'type' => \Elementor\Controls_Manager::SWITCHER,
                'label' => _x('Header Transparent', 'elementor', 'theme'),
                'label_on' => __('True', 'theme'),
                'label_off' => __('False', 'theme'),
                'return_value' => true,
                'default' => false,
            ]
        );

        $controlStack->end_controls_section();
}

Now the issue is that I want to see the changes in the preview of Elementor when I change any of the settings.

I tried hooking into elementor/editor/after_enqueue_scripts (any many other hooks) to execute custom JS and simulate preview. Unfortunately, I had no luck.

JavaScript code looked something like this:

var headerTransparency = function( newValue ){
        if( newValue == 'true' ){
            $('.header').addClass('header--transparent');
        }else{
            $('.header').removeClass('header--transparent');
        }
    }
elementor.settings.page.addChangeCallback( 'header_transparent', headerTransparency );

Is there any way to do it?

Upvotes: 2

Views: 1618

Answers (1)

Insomnia88
Insomnia88

Reputation: 368

Because you are doing just a styling change you could also use selectors option.

$controlStack->add_control(
    'header_overlayed',
    [
        'type' => \Elementor\Controls_Manager::SWITCHER,
        'label' => _x('Header Overlayed', 'elementor', 'theme'),
        'label_on' => __('True', 'theme'),
        'label_off' => __('False', 'theme'),
        'return_value' => true,
        'default' => false,
        'selectors' => [
            '{{WRAPPER}} .your-target-selector' => 'background-color: #f00 !important;' //{{VALUE}} for the field value
        ],
    ]
);

But your JS method is also possible. I guess your mistake is that your hook isn't triggered because of a missing event. This should be the content of your js file:

jQuery(document).ready(function(){
    elementor.settings.page.addChangeCallback( 'header_transparent', headerTransparency );
});

function headerTransparency ( newValue ) {
    if( newValue == 'true' ){
        jQuery('.header').addClass('header--transparent');
    }else{
        jQuery('.header').removeClass('header--transparent');
    }
}

In case you might have some errors with your injections - you can inject scripts/styles like this:

add_action('elementor/editor/before_enqueue_scripts', function() {
    wp_enqueue_script( 'js-test-inject', get_template_directory_uri() . '/assets/js/test-inject.js', array( 'jquery' ), null, true );
}, 10, 3);

I tested your scenario at my site and it works for me ;)

Upvotes: 0

Related Questions