Adding Custom Menu Item & Settings Form at Tools Panel of BB 2.0
I already published this tutorial. But it will not work for BB 2.0 version. Because new mechanism is using there. One of the Beaver user asked me how he will add the custom link with his own settings form at Tools panel of BB 2.0. In this article I am showing the step by step instructions how you will do the custom menu item with shortcuts key and settings form.
I created a class and js file for this functionality. At first I am describing the PHP and JavaScript codes & later sharing the full codes with complete steps.
1. Adding Custom Menu Link with Shortcuts Key
Beaver Builder 2.0 have a filter fl_builder_main_menu for main menu items. So you can add custom menu item(s) as per your requirements. Shortcuts key option is a cool feature of BB 2.0. So you can easily navigate the content with your keyboard keys. For shortcuts there have another filter fl_builder_keyboard_shortcuts. Here is the code and see how I used these two filters
Adding Custom Menu Link with Shortcuts Key
//* Creating the new menu add_filter( 'fl_builder_main_menu', __CLASS__ . '::probb_builder_main_menu' ); //* Adding shortcut key with this menu add_filter( 'fl_builder_keyboard_shortcuts', __CLASS__ . '::probb_bb_main_menu_keyboard_shortcuts' ); /** * Adding new menu "Custom Link" under Tools main menu panel in builder */ static public function probb_builder_main_menu( $views ) { $key_shortcuts = FLBuilder::get_keyboard_shortcuts(); $views['main']['items'][120] = array( 'type' => 'separator', ); //* 45 is the menu order number. You can change the menu position by editng this number $views['main']['items'][130] = array( 'label' => __( 'Custom Link', 'theme-prefix' ), 'type' => 'event', 'eventName' => 'showCustomSettings', 'accessory' => $key_shortcuts['showCustomSettings'] ); return $views; } /** * Creating the shortcut key "m" for menu "Custom Link" * When press the "m" key, settings form will appear */ static public function probb_bb_main_menu_keyboard_shortcuts( $data ) { //* showCustomSettings is the eventName of "Custom Link" menu item $data['showCustomSettings'] = 'm'; return $data; }
2. Registering Settings Form
FLBuilder class have a method register_settings_form. It is registering the new form. This method is taking two parameters: form id as string and fields as an array. This method is triggering via init hook.
Registering Settings Form
//* Registering the custom settings form add_action( 'init', __CLASS__ . '::probb_load_custom_settings_form' ); /** * Registering custom settings form with tabs & fields * * @uses register_settings_form method of FLBuilder class * * @param form id String * @param form fields Array */ static public function probb_load_custom_settings_form() { //* customform is the settings form ID. It is require to populate the submitted data and render into form FLBuilder::register_settings_form('customform', array( 'title' => __( 'Form Title', 'theme-prefix' ), 'tabs' => array( 'general' => array( 'title' => __( 'General', 'theme-prefix' ), 'sections' => array( 'sec_1' => array( 'title' => __('Secction 1 Title', 'theme-prefix'), 'fields' => array( 'textf' => array( 'label' => __('Input Box', 'theme-prefix'), 'type' => 'text', 'help' => __('This is optional. It is tooltip.', 'theme-prefix') ), 'textareaf' => array( 'label' => __('Textarea', 'theme-prefix'), 'type' => 'textarea', 'rows' => 5 ) ) ), 'sec_2' => array( 'title' => __('Secction 2 Title', 'theme-prefix'), 'fields' => array( 'selectf' => array( 'label' => __('Select', 'theme-prefix'), 'type' => 'select', 'default' => 'none', 'options' => array( 'none' => __('None', 'theme-prefix'), 'val-1' => __('Option 1', 'theme-prefix'), 'val-2' => __('Option 2', 'theme-prefix'), 'val-3' => __('Option 3', 'theme-prefix') ) ), 'mselectf' => array( 'label' => __('Multi-Select', 'theme-prefix'), 'type' => 'select', 'multi-select' => true, 'size' => 3, 'default' => 'none', 'options' => array( 'none' => __('None', 'theme-prefix'), 'val-1' => __('Option 1', 'theme-prefix'), 'val-2' => __('Option 2', 'theme-prefix'), 'val-3' => __('Option 3', 'theme-prefix') ) ), 'iconf' => array( 'label' => __('Icon', 'theme-prefix'), 'type' => 'icon', 'show_remove' => true ) ) ) ) ), 'style' => array( 'title' => __( 'Style', 'theme-prefix' ), 'sections' => array( 'sec_3' => array( 'title' => __('Secction 3 Title', 'theme-prefix'), 'fields' => array( 'colorf' => array( 'label' => __('Color', 'theme-prefix'), 'type' => 'color', 'default' => 'eeeeee', 'show_reset' => true ), 'videof' => array( 'label' => __('Video', 'theme-prefix'), 'type' => 'video' ) ) ), 'sec_4' => array( 'title' => __('Secction 4 Title', 'theme-prefix'), 'fields' => array( 'unitf' => array( 'label' => __('Unit', 'theme-prefix'), 'type' => 'unit', 'default' => '2', 'description' => 'px' ), 'timef' => array( 'label' => __('Time', 'theme-prefix'), 'type' => 'time' ) ) ) ) ), 'another_tab' => array( 'title' => __( 'Another Tab', 'theme-prefix' ), 'sections' => array( 'sec_5' => array( 'title' => __('Secction 5 Title', 'theme-prefix'), 'fields' => array() ), 'sec_6' => array( 'title' => __('Secction 6 Title', 'theme-prefix'), 'fields' => array() ) ) ) /** * and more . . . . */ ) )); }
3. Rendering Settings Form
Above settings form is rendering by following JS scripts.
Rendering the Settings Form
FLBuilder.addHook('showCustomSettings', this.showCustomSettings.bind(this)); /** * Helper for render action */ showCustomSettings: function() { CustomForm._customLinkClicked(); FLBuilder.MainMenu.hide(); } /** * Shows the custom settings form lightbox when the * custom link menu item is clicked. */ _customLinkClicked: function() { FLBuilderSettingsForms.render( { id : 'customform', className : 'fl-builder-customform-settings', settings : FLBuilderConfig.customform }, function() { FLBuilder._layoutSettingsInitCSS(); } ); },
_customLinkClicked method is rendering the settings form. Default or save data is passing to form by this PHP snippets.
add_filter( 'fl_builder_ui_js_config', function( $js_config ){ $js_config['customform'] = self::probb_get_customform_settings(); return $js_config; }); /** * Getting the settings data * * you will use this kind of snippet in your theme or plugin file. * See a demo: * $my_form_settings = Probb_BBMainMenu::probb_get_customform_settings(); * echo "Input Box value: " . $my_form_settings->textf; * echo "Select Field Value" . $my_form_settings->selectf; */ static public function probb_get_customform_settings() { if ( null === self::$customform_settings ) { $settings = get_option( '_fl_builder_customform_settings' ); $defaults = FLBuilderModel::get_settings_form_defaults( 'customform' ); if ( ! $settings ) { $settings = array(); } // Merge in defaults and cache settings self::$customform_settings = (object) array_merge( (array) $defaults, (array) $settings ); self::$customform_settings = FLBuilderModel::merge_nested_form_defaults( 'general', 'preset', self::$customform_settings ); } return self::$customform_settings; }
probb_get_customform_settings method is retrieving the submitted form’s data as an object from WordPress options database table. Options key name is _fl_builder_customform_settings and data is storing as serialized way. See the attached screen
4. Saving the Submitted Data
User inputted data is saving into WordPress options table with the Builder AJAX API. AJAX action is adding by FLBuilderAJAX::add_action() method into the queue with wp hook. This method is accepting three parameters: action name, method and arguments
//* Adds callable AJAX actions add_action( 'wp', __CLASS__ . '::probb_add_ajax_actions', 9 ); /** * Adds callable AJAX actions. */ static public function probb_add_ajax_actions() { FLBuilderAJAX::add_action( 'save_customform_settings', 'Probb_BBMainMenu::probb_save_customform_settings', array( 'settings' ) ); }
save_customform_settings action name is stated into JS script. See the _saveButtonClicked function into the custom.form.actions.js file. probb_save_customform_settings method of Probb_BBMainMenu class is saving the user’s submitted data as serialized data into WordPress options table. Options name is _fl_builder_customform_settings.
Saving the data
/** * Saving the form data */ static public function probb_save_customform_settings( $settings = array() ) { $old_settings = self::probb_get_customform_settings(); $new_settings = (object) array_merge( (array) $old_settings, (array) $settings ); FLBuilderModel::delete_asset_cache_for_all_posts(); self::$customform_settings = null; update_option( '_fl_builder_customform_settings', $new_settings ); return self::probb_get_customform_settings(); }
5. Displaying Data at Front-end
You will write the following PHP scripts into your theme’s or plugin’s file.
Echo the data
$my_settings = Probb_BBMainMenu::get_customform_settings(); //* data is returnign as object //* echo the input field data. This case field name is textf echo $my_settings->textf;
For security purposes You will sanitize the data as per your requirement.
Complete code with Full Instructions
Create one class file “class-probb-bb-main-menu.php” and save into theme’s classes folder. You will create this folder if you have not one yet.
Class File
'separator', ); //* 45 is the menu order number. You can change the menu position by editng this number $views['main']['items'][130] = array( 'label' => __( 'Custom Link', 'theme-prefix' ), 'type' => 'event', 'eventName' => 'showCustomSettings', 'accessory' => $key_shortcuts['showCustomSettings'] ); return $views; } /** * Creating the shortcut key "m" for menu "Custom Link" */ static public function probb_bb_main_menu_keyboard_shortcuts( $data ) { //* showCustomSettings is the eventName of "Custom Link" menu item $data['showCustomSettings'] = 'm'; return $data; } /** * Getting the settings data * * you will use this kind of snippet in your theme or plugin file. * See a demo: * $my_form_settings = Probb_BBMainMenu::probb_get_customform_settings(); * echo "Input Box value: " . $my_form_settings->textf; * echo "Select Field Value" . $my_form_settings->selectf; * * @uses FLBuilderModel::get_settings_form_defaults() * @uses FLBuilderModel::merge_nested_form_defaults() */ static public function probb_get_customform_settings() { if ( null === self::$customform_settings ) { $settings = get_option( '_fl_builder_customform_settings' ); $defaults = FLBuilderModel::get_settings_form_defaults( 'customform' ); if ( ! $settings ) { $settings = array(); } // Merge in defaults and cache settings self::$customform_settings = (object) array_merge( (array) $defaults, (array) $settings ); self::$customform_settings = FLBuilderModel::merge_nested_form_defaults( 'general', 'preset', self::$customform_settings ); } return self::$customform_settings; } /** * Registering custom settings form with tabs & fields * * @uses register_settings_form method of FLBuilder class * * @param form id String * @param form fields Array */ static public function probb_load_custom_settings_form() { //* customform is the settings form ID. It is require to populate the submitted data and render into form FLBuilder::register_settings_form('customform', array( 'title' => __( 'Form Title', 'theme-prefix' ), 'tabs' => array( 'general' => array( 'title' => __( 'General', 'theme-prefix' ), 'sections' => array( 'sec_1' => array( 'title' => __('Secction 1 Title', 'theme-prefix'), 'fields' => array( 'textf' => array( 'label' => __('Input Box', 'theme-prefix'), 'type' => 'text', 'help' => __('This is optional. It is tooltip.', 'theme-prefix') ), 'textareaf' => array( 'label' => __('Textarea', 'theme-prefix'), 'type' => 'textarea', 'rows' => 5 ) ) ), 'sec_2' => array( 'title' => __('Secction 2 Title', 'theme-prefix'), 'fields' => array( 'selectf' => array( 'label' => __('Select', 'theme-prefix'), 'type' => 'select', 'default' => 'none', 'options' => array( 'none' => __('None', 'theme-prefix'), 'val-1' => __('Option 1', 'theme-prefix'), 'val-2' => __('Option 2', 'theme-prefix'), 'val-3' => __('Option 3', 'theme-prefix') ) ), 'mselectf' => array( 'label' => __('Multi-Select', 'theme-prefix'), 'type' => 'select', 'multi-select' => true, 'size' => 3, 'default' => 'none', 'options' => array( 'none' => __('None', 'theme-prefix'), 'val-1' => __('Option 1', 'theme-prefix'), 'val-2' => __('Option 2', 'theme-prefix'), 'val-3' => __('Option 3', 'theme-prefix') ) ), 'iconf' => array( 'label' => __('Icon', 'theme-prefix'), 'type' => 'icon', 'show_remove' => true ) ) ) ) ), 'style' => array( 'title' => __( 'Style', 'theme-prefix' ), 'sections' => array( 'sec_3' => array( 'title' => __('Secction 3 Title', 'theme-prefix'), 'fields' => array( 'colorf' => array( 'label' => __('Color', 'theme-prefix'), 'type' => 'color', 'default' => 'eeeeee', 'show_reset' => true ), 'videof' => array( 'label' => __('Video', 'theme-prefix'), 'type' => 'video' ) ) ), 'sec_4' => array( 'title' => __('Secction 4 Title', 'theme-prefix'), 'fields' => array( 'unitf' => array( 'label' => __('Unit', 'theme-prefix'), 'type' => 'unit', 'default' => '2', 'description' => 'px' ), 'timef' => array( 'label' => __('Time', 'theme-prefix'), 'type' => 'time' ) ) ) ) ), 'another_tab' => array( 'title' => __( 'Another Tab', 'theme-prefix' ), 'sections' => array( 'sec_5' => array( 'title' => __('Secction 5 Title', 'theme-prefix'), 'fields' => array() ), 'sec_6' => array( 'title' => __('Secction 6 Title', 'theme-prefix'), 'fields' => array() ) ) ) /** * and more . . . . */ ) )); } /** * Enqueue scripts */ static public function probb_enqueue_scripts() { if ( FLBuilderModel::is_builder_active() ) { wp_enqueue_script('custom-form-actions', get_stylesheet_directory_uri() . '/js/custom.form.actions.js', array(), time(), true ); } } /** * Adds callable AJAX actions. */ static public function probb_add_ajax_actions() { FLBuilderAJAX::add_action( 'save_customform_settings', 'Probb_BBMainMenu::probb_save_customform_settings', array( 'settings' ) ); } /** * Saving the form data */ static public function probb_save_customform_settings( $settings = array() ) { $old_settings = self::probb_get_customform_settings(); $new_settings = (object) array_merge( (array) $old_settings, (array) $settings ); FLBuilderModel::delete_asset_cache_for_all_posts(); self::$customform_settings = null; update_option( '_fl_builder_customform_settings', $new_settings ); return self::probb_get_customform_settings(); } } Probb_BBMainMenu::init();
Create a JS file “custom.form.actions.js” and save into theme’s js (case-sensitive) file. You will create this folder if you have not one yet.
JS File
(function($, FLBuilder) { CustomForm = { init: function() { FLBuilder.addHook( 'didSaveCustomFormSettingsComplete', this.updateOnSaveCustomFormSettings.bind( this ) ); FLBuilder.addHook('showCustomSettings', this.showCustomSettings.bind(this)); CustomForm._bindEvents(); }, _bindEvents: function() { $('body').delegate('.fl-builder-customform-settings .fl-builder-settings-save', 'click', CustomForm._saveButtonClicked); $('body').delegate('.fl-builder-customform-settings .fl-builder-settings-cancel', 'click', FLBuilder._cancelLayoutSettingsClicked); }, /** * Shows the custom settings form lightbox when the * custom link menu item is clicked. */ _customLinkClicked: function() { FLBuilderSettingsForms.render( { id : 'customform', className : 'fl-builder-customform-settings', settings : FLBuilderConfig.customform }, function() { FLBuilder._layoutSettingsInitCSS(); } ); }, /** * Saves the form data when the save button is clicked. */ _saveButtonClicked: function() { var form = $(this).closest('.fl-builder-settings'), valid = form.validate().form(), settings = FLBuilder._getSettings( form ); if(valid) { FLBuilder.showAjaxLoader(); FLBuilder._layoutSettingsCSSCache = null; FLBuilder.ajax({ action: 'save_customform_settings', settings: settings }, CustomForm._saveCustomFormSettingsComplete); FLBuilder._lightbox.close(); } }, _saveCustomFormSettingsComplete: function( response ) { FLBuilderConfig.customform = JSON.parse( response ); FLBuilder.triggerHook( 'didSaveCustomFormSettingsComplete', FLBuilderConfig.customform ); FLBuilder._updateLayout(); }, updateOnSaveCustomFormSettings: function( e, settings ) { this.customform = settings; }, showCustomSettings: function() { CustomForm._customLinkClicked(); FLBuilder.MainMenu.hide(); } } $(function(){ CustomForm.init(); }); })(jQuery, FLBuilder)
Now open the functions.php file of your theme and add this single line of code there
Include the class file
require_once 'classes/class-probb-bb-main-menu.php';
All are done. You will enable the page builder and click on “Custom Link” menu item or press “m” key. Settings form will appear. Fill up the form and click on “Save” button.