I'm creating a custom slider element for the WPBakery Page Builder plugin, as the built in carousels are not suitable for my purpose.
Everything works just fine except when I update the element settings, the slider disappears because the element is re-created in the DOM by removing the old HTML.
Here's the element code:
<?php
class WPBakery_Custom_Slider {
/**
* Setup class
*/
public function __construct() {
// Actions.
add_action( 'vc_before_init', array( $this, 'custom_mapping' ) );
// Shortcodes.
add_shortcode( 'wpbakery_custom_slider', array( $this, 'shortcode' ) );
}
/**
* Custom Mapping
*/
public function custom_mapping() {
vc_map( array(
'name' => __( 'Custom Slider', 'text-domain' ),
'base' => 'wpbakery_custom_slider',
'description' => __( 'The Custom Slider.', 'text-domain' ),
'category' => __( 'Content', 'text-domain' ),
'icon' => 'icon-wpb-carousel',
'front_enqueue_js' => get_theme_file_uri( 'assets/js/wpbakery-page-builder.js' ),
'params' => array(
...
),
) );
}
/**
* The element HTML
*
* @param array $atts Shortcode attributes.
* @return string
*/
public function shortcode( $atts ) {
// Params extraction.
...
ob_start();
?>
<div class="text-domain-wpb-custom-slider-wrapper">
<div class="text-domain-wpb-custom-slider">
...
</div>
</div>
<?php
$html = ob_get_clean();
return $html;
}
}
And here's the wpbakery-page-builder.js
file:
vc.events.on( 'shortcodes:wpbakery_custom_slider:update', function ( model ) {
jQuery( document ).find( '.text-domain-wpb-custom-slider' ).customSlider();
} );
But when the event runs, it seems like the .text-domain-wpb-custom-slider
does not exist. The variants I tried are:
vc.events.on( 'shortcodes:wpbakery_custom_slider:update', function ( model ) {
jQuery( '.text-domain-wpb-custom-slider', document ).customSlider();
} );
And
vc.events.on( 'shortcodes:wpbakery_custom_slider:update', function ( model ) {
setTimeout( function () {
jQuery( '.text-domain-wpb-custom-slider', document ).customSlider();
}, 1000 );
} );
All the above, when saving the settings of the element results in:
Uncaught TypeError: jQuery(...).customSlider is not a function
Because jQuery( '.text-domain-wpb-custom-slider', document ).length
is zero even though there's a .text-domain-wpb-custom-slider
in the DOM.
Any ideas of how to properly update a custom JavaScript-based element for WPBakery Page Builder/Visual Composer?
The problem is the scope of the document
variable. It refers to the Builder edit page, not the page that needs to be edited (called model
by WPBakery).
So here's the solution, use model.view.el
instead of document
to refer to the page:
vc.events.on( 'shortcodes:wpbakery_custom_slider:update', function ( model ) {
setTimeout( function () {
jQuery( model.view.el ).find( '.text-domain-wpb-custom-slider' ).customSlider();
}, 1000 );
} );