Last Updated on December 25, 2020 by Neil Murray
After testing with the same results, adding admin notification after Save can be done with two methods. This notice is added in Visual.saveVisualForm() during successful AJAX cf7sRequest.
1. Using Native Javascript
We need to create a div element with specific id, and add other HTML content into it. Check if Visual is saved previously, delete the div if it exists. Insert the whole HTML before CF7 form element.
let notice = document.getElementById('cf7svisual-notice'); if ( notice ) { notice.remove(); } let cf7form = document.getElementById('wpcf7-admin-form-element'); let div = document.createElement('div') div.id = 'cf7svisual-notice' div.className = 'notice notice-success is-dismissible' div.innerHTML = '<p>Visual saved!</p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>'; let parentDiv = cf7form.parentNode; parentDiv.insertBefore( div, cf7form ); |
2. Using React DOM
With ReactDOM, we need to put empty div container in PHP for rendering.
add_action( 'wpcf7_admin_notices', array( &$this, 'visual_admin_notice' ) ); function visual_admin_notice() { ?><div id="cf7s-visual-notice"></div><?php } |
2.1. With createElement()
const adminNotice = React.createElement( 'div', { className: 'notice notice-success is-dismissible' }, React.createElement( 'p', null, 'Visual saved!' ), React.createElement( 'button', { className: 'notice-dismiss', type: 'button' }, React.createElement( 'span', { className: 'screen-reader-text' }, 'Dismiss this notice.' ) ) ); ReactDOM.render( adminNotice, document.getElementById('cf7s-visual-notice') ); |
2.2. With JSX
const adminNotice = ( <div className="notice notice-success is-dismissible"> <p>Visual saved!</p> <button type="button" className="notice-dismiss"> <span className="screen-reader-text">Dismiss this notice.</span> </button> </div> ); ReactDOM.render( adminNotice, document.getElementById('cf7s-visual-notice') ); |
The best option we have currently is using ReactDOM.render() to render the admin notification and ReactDOM.unmountComponentAtNode(container) for unmounting or destroying the DOM content to dismiss/hide it.
<button type="button" className="notice-dismiss" onClick={ () => ReactDOM.unmountComponentAtNode( document.getElementById('cf7s-visual-notice') ) }> <span className="screen-reader-text">Dismiss this notice.</span> </button> |
NOTES #
Neil:
I’m unsure about us calling ReactDOM.render() from within the Visual component – is this common practice in React?
I see in this instance we are updating ‘cf7s-visual-notice’ which is an area outside the location where the
Also the Visual component in /src/visual/index.js is exported as export default DragDropContext( HTML5Backend )( Visual );
Sastra:
With JSX approach is the best option we have currently. As mentioned in https://reactjs.org/docs/react-dom.html, it is as an escape hatch to get outside of the React model.
They host different container, but they are sharing the same state. The admin notice render is triggered inside main Visual after AJAX request. I think that’s what Flux, Redux or any other listen/trigger module does.
Further reading:
- ReactDOM
- Display Contact form saved notification when use Save Visual (BitBucket Issue)