Last Updated on July 25, 2018 by Neil Murray
Strategies we are following with React + jQuery + PHP in development of CF7 Skins Visual plugin.
RST VERSION
Refer:
Working with CF7 Skins AJAX API
Check data exchange between CF7 Skins & Contact Form 7 (BitBucket Issue)
Data Exchange between WP & React (BitBucket Issue)
ALPHA VERSION
1. Global Variables
We need a unique global variable – we use cf7svisual
Reasons:
a. To have a common data container.
b. All the web technologies we are using in the plugin (react, jQuery, php) can access the data anytime.
c. Need to use global variable to initiate CF7 Skins Visual Form Tab (can use Hidden button after 1st interaction)
Notes:
* use the global variable as little as possible
* global variable should only be used for temporary transient data exchange
* global variable should not be persistent if possible
* need to make sure old/previous values of global variable are not used (this has already caused problems)
Reasons:
a. Global Variables can get corrupted in WordPress by other plugins etc.
b. It’s very hard to know when this has happened
c. This can create errors that really annoy customers
d. These errors are often hard to find & fix
e. You can minimize the problems by limiting use of global variable
cf7svisual – is a JSON object, used to transfer data between React & WordPress via jQuery which contains:
- cf7svisual.items – Contains current field items with user setting. This item will be sent back to WordPress to save and update CF7 form.
- cf7svisual.template – [ no longer used ] We use use visual.php for each template that contains template items in JSON format.
- cf7svisual.ajaxurl – WordPress AJAX call URL for saving/updating Visual. See https://codex.wordpress.org/AJAX_in_Plugins
- cf7svisual.update – Action name for doing AJAX with admin-ajax.php. This is for update process in WordPress admin interface.
- cf7svisual.l10n – Contains translation strings. All static text in React should use this to allow translations.
- cf7svisual.title – [ no longer used ] Current form title
- cf7svisual.nonce – Generated using wp_create_nonce for security checking while doing AJAX.
The global variable is printed at CF7 edit page using WordPress wp_localize_script function right before init.js file. For new created form, cf7svisual.items is empty/null.
Need to make default Visual items for new created form, perhaps by following CF7 Skins Contact Template structure.
Enqueue init.js:
wp_enqueue_script( 'visual-init', CF7SKINSVISUAL_URL . 'js/init.js', array( 'jquery' ), CF7SKINSVISUAL_VERSION, true );
Setting up JavaScript global variable:
wp_localize_script( 'visual-init', 'cf7svisual', array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce( CF7SKINSVISUAL_OPTIONS ), // generate a nonce for security checking
'update' => 'cf7skins_visual_update', // post action for saving
'l10n' => array(
'save' => __( 'Save', CF7SKINSVISUAL_TEXTDOMAIN ),
'done' => __( 'Done', CF7SKINSVISUAL_TEXTDOMAIN ),
'error' => __( 'Error', CF7SKINSVISUAL_TEXTDOMAIN ),
),
'title' => $cf7->title(),
'items' => $items
));
2. Hidden Buttons
To save user Visual items into database using CF7 save button, we need to put one input hidden inside the CF7 < form > tag.
<input type="hidden" id="cf7s-visual" name="cf7s-visual" value="serialized visual item" />
We create and append it into CF7 form (#wpcf7-admin-form-element) using this code:
$('#wpcf7-admin-form-element').append( $('<input />').
attr('type', 'hidden').
attr('id', 'cf7s-visual').
attr('name', 'cf7s-visual').
attr('value', '')
);
[ Add details of all Hidden Buttons in all CF7 Skins plugins here ]
cf7s-visual – [ Add description ] – Contact Form 7 Skins Visual
Code to implement Hidden Buttons is at cf7skins-visual\js\jquery.admin.js
// Append hidden input inside CF7 <form>
$('#wpcf7-admin-form-element').append( $('<input />').
attr('type', 'hidden').
attr('id', 'cf7s-visual').
attr('name', 'cf7s-visual').
attr('value', '')
);
There is also a hidden button kept in the Visual interface – this is commented but is used for testing.
[ Add details of this Hidden Button here ]
Reasons:
a. To let the front-end React know that the data is changed by the any other plugin or add-ons.
b. To let the front-end React know that some event has been done on the other plugin or add-ons that can have effect on the Visual plugin.
c. Allows for exchange of data between React & WordPress without need to refresh page
Notes:
The two plugins will communicate through two hidden buttons (visibility: ‘hidden’ added as a style on those buttons). Lite Plugin Hidden button will be clicked using JQuery from Pro plugin to communicate and it remains same from the opposite side.
Need a div with an id where React will load the Pro plugin. In the later stages we will take the id into the lite plugin, so that the pro plugin mounts inside the lite plugin (our desired output).
3. Pass data through JQuery
Pass data to the CF7 Skins Visual Form Tab from the Template or Style tab or other CF7 Skins Add-ons
Reasons:
a. To see the live changes of the CF7 Skins Visual Form Tab after an event on the other plugins or CF7 Skins Add-ons.
b. We want to control React via WP (and the other way as well).
c. We need to supply the data from WP to React (and the other way as well).
Whenever we need any action to happen in React by an event or any changes on WP, we need to change the data source and trigger an action in React and tell that some action happened on WP and here is the data.
Selected Method: Make jQuery function call on every change on the Form Tab and communicate with any js function on other projects that needs the updated value.
We can use pub-sub strategy here. After every change React can trigger a jQuery call with changed data from the Form Tab and and we can keep a listener function in any other plugin to grab the data.
In React we do this after every change:
$(".react-to-wp").trigger("click", data);
In other JS projects we can do this:
jQuery(".react-to-wp").click(function(e, data){
e.preventDefault();
console.log(‘we have updated data from react’, data);
});
Note: We should used jQuery(“…”) instead of $(“…”) in all code we write and in examples given here [ FIX any code examples that do not do this (Rafi) ].
After every change we also update the global variable “cf7svisual.items = updated items”.
Example: Selecting a Template on the template tab should make the form in the CF7 Skins Visual form tab change without any refresh or reload – see Bitbucket Issue #40.
This can be done by using a function on React and calling that function from anywhere using jQuery. We followed this approach for Issue #40.
In React here is function waiting for trigger:
jQuery(".hidden-button").click(function(e, data){
e.preventDefault();
// console.log(e);
// console.log(JSON.parse(data));
Cf7sAction.loadTemplate(JSON.parse(data));
});
It might also be done by adding a hidden button on React.
Here is a way to call it from WP (using Ajax):
$.post( ajaxurl, {
action: 'visual_select_template',
template: json.template,
nonce: cf7svisual.nonce,
post: json.post
}, function( data ) {
$(".hidden-button").trigger("click", data); // triggered from here
});
Note: We want to avoid ajax calls as much as we can [ as this is not a good practice – EXPLAIN WHY ].
4. Send Data outside the Form Tab
The actions after which we need to send the data outside the Form Tab are:
* Dropping a CF7s tags, items or anything on the Form.
* Sorting all items on the Form.
* Editing a single Item on the Form tab
* Deleting an Item.
5. Form field item properties
Both WP & React handle all the props/data of each individual form field.
We add all the field item properties to each form-item HTML as follows:
<div class="cf7s-form-form-item"> <div class="form-item-input" data-id="1474240647431" data-cf7name="acceptance-626" data-cf7slabel="Indicate your acceptance" data-options="" data-required="true" data-defaultvalue="Default value" data-classattribute="Class Attribute" data-idattribute="Id attribute">
Refer:
Share JS data between lite.js & pro.js so Lite & Pro plugins work simultaneously
Add code here