File: /home/globfdxw/www/wp-content/plugins/wpforms-pdf/assets/js/modules/notifications.js
/* global wpf, WPForms, wpforms_builder */
/**
* @param wpforms_builder.pdf.settings.notifications_no_choices
* @param wpforms_builder.pdf.settings.notifications_no_results
* @param choicesInstance.setChoiceByValue
*/
// noinspection JSUnusedGlobalSymbols, JSUnusedLocalSymbols
/**
* WPForms PDF: Notifications module.
*
* @since 1.0.0
*
* @param {Object} document Document object.
* @param {Object} window Window object.
* @param {jQuery} $ jQuery object.
*
* @return {Object} Public functions and properties.
*/
export default function( document, window, $ ) { // eslint-disable-line no-unused-vars, max-lines-per-function
/**
* Elements holder.
*
* @since 1.0.0
*
* @type {Object}
*/
const el = {};
/**
* Public functions and properties.
*
* @since 1.0.0
*/
const app = {
/**
* Start the engine.
*
* @since 1.0.0
*/
init() {
app.ready();
},
/**
* Start the engine.
*
* @since 1.0.0
*/
ready() {
app.setup();
app.bindEvents();
app.initExistingNotificationDropdowns();
},
/**
* Setup. Prepare some variables.
*
* @since 1.0.0
*/
setup() {
// Cache DOM elements.
el.$builder = $( '#wpforms-builder' );
app.notifications = app.getAllNotifications();
},
/**
* Bind events.
*
* @since 1.0.0
*/
bindEvents() {
el.$builder
.on( 'wpformsPanelSectionSwitch', app.panelSectionSwitch )
.on( 'wpformsPanelSwitch', app.panelSwitch )
.on( 'wpformsSettingsBlockAdded', app.pdfAdded )
.on( 'wpformsSettingsBlockCloned', app.pdfCloned )
.on( 'wpformsUndoRedoRun', app.undoRedoRun )
.on( 'change', '.wpforms-pdf-notifications select', function() {
app.changeNotificationsValue( $( this ) );
} );
},
/**
* The PDF block was added.
*
* @since 1.0.0
*
* @param {Event} e The event object.
* @param {jQuery} $block The block element.
*/
pdfAdded( e, $block ) {
if ( $block.data( 'block-type' ) !== 'pdf' ) {
return;
}
WPForms.Admin.Builder.UndoRedo?.preventRecord( true );
app.initNotificationDropdownsForBlock( $block );
app.refreshNotificationDropdown( $block.find( '.wpforms-pdf-notifications select' ) );
app.setDefaultValue( $block );
WPForms.Admin.Builder.UndoRedo?.preventRecord( 'continue' );
},
/**
* The PDF block was added.
*
* @since 1.0.0
*
* @param {Event} e The event object.
* @param {jQuery} $block The block element.
* @param {string} clonedPdfId The cloned PDF block ID.
*/
pdfCloned( e, $block, clonedPdfId ) {
if ( $block.data( 'block-type' ) !== 'pdf' ) {
return;
}
WPForms.Admin.Builder.UndoRedo?.preventRecord( true );
app.initNotificationDropdownsForClonedBlock( $block, clonedPdfId );
WPForms.Admin.Builder.UndoRedo?.preventRecord( 'continue' );
},
/**
* The undo/redo action was run.
*
* @since 1.2.0
*
* @param {Event} e The event object.
* @param {string} commandType The command type.
* @param {Object} command The command object.
*/
undoRedoRun( e, commandType, command ) {
if ( ! app.shouldProcessUndoRedoEvent( command.args?.event ?? '' ) ) {
return;
}
app.initExistingNotificationDropdowns();
},
/**
* Whether the undo/redo event should be processed.
*
* @since 1.2.0
*
* @param {string} event Event name.
*
* @return {boolean} True when the event should be processed.
*/
shouldProcessUndoRedoEvent( event ) {
const events = [
'wpformsSettingsBlockCloned',
'wpformsSettingsBlockAdded',
'wpformsSettingsBlockDeleted',
];
return events.includes( event );
},
/**
* Initialize existing notification dropdowns for all elements on the page.
*
* @since 1.0.0
*/
initExistingNotificationDropdowns() {
// Return if Choices.js is not available.
if ( typeof window.Choices !== 'function' ) {
return;
}
// Initialize existing notification dropdowns
el.$builder.find( '.wpforms-pdf-notifications select' ).each( function() {
app.initializeChoicesForSelect( $( this ) );
} );
},
/**
* Initialize notification dropdown for a specific block.
*
* @since 1.0.0
*
* @param {jQuery} $block The block element.
*/
initNotificationDropdownsForBlock( $block ) {
// Return if Choices.js is not available.
if ( typeof window.Choices !== 'function' ) {
return;
}
// Initialize notification dropdowns this block.
const $select = $block.find( '.wpforms-pdf-notifications select' );
app.initializeChoicesForSelect( $select );
},
/**
* Re-initialize notification dropdown for a cloned block.
*
* @since 1.0.0
*
* @param {jQuery} $block The block element.
* @param {string} clonedPdfId The cloned PDF block ID.
*/
initNotificationDropdownsForClonedBlock( $block, clonedPdfId ) {
const pdfId = $block.data( 'block-id' );
const $originSelect = $( `#wpforms-panel-field-pdfs-${ clonedPdfId }-notifications` );
const originValue = $originSelect.last().data( 'choicesjs' )?.getValue();
// language=HTML
const $newSelect = $( '<select multiple></select>' )
.attr( 'id', `wpforms-panel-field-pdfs-${ pdfId }-notifications` )
.attr( 'name', `settings[pdfs][${ pdfId }][notifications]` );
let selectedValues = originValue ? wpf.listPluck( originValue, 'value' ) : $originSelect.val();
selectedValues = Array.isArray( selectedValues ) ? selectedValues : [ selectedValues ];
app.notifications.forEach( function( item ) {
// language=HTML
const $option = $( '<option></option>' )
.val( item.id )
.prop( 'selected', selectedValues.includes( item.id ) )
.text( item.name );
$newSelect.append( $option );
} );
// Remove existing choices.
const $choices = $block.find( '.wpforms-pdf-notifications .choices' );
$choices.after( $newSelect );
$choices.remove();
app.initNotificationDropdownsForBlock( $block );
},
/**
* Initialize Choices.js for a select element.
*
* @since 1.0.0
*
* @param {jQuery} $select The select element.
*/
initializeChoicesForSelect( $select ) {
// Initialize Choices.js if not already initialized.
if ( $select.data( 'choicesjs' ) ) {
return;
}
app.notifications = app.getAllNotifications();
WPForms.Admin.Builder.WPFormsChoicesJS.setup(
$select[ 0 ],
{
removeItemButton: true,
noChoicesText: wpforms_builder.pdf.settings.notifications_no_choices,
noResultsText: wpforms_builder.pdf.settings.notifications_no_results,
},
{}
);
// Save the form state after initialization if it's the initial save.
if ( wpf && wpf.initialSave === true ) {
wpf._updateFormState();
}
},
/**
* Set the default Notification.
*
* @since 1.0.0
*
* @param {jQuery} $block The block element.
*/
setDefaultValue( $block ) {
const $select = $block.find( '.wpforms-pdf-notifications select' );
const choicesInstance = $select.data( 'choicesjs' );
// Skip if no Choices.js instance found.
if ( ! choicesInstance ) {
return;
}
// By default, we should use the first available Notification.
const defaultValue = app.notifications[ 0 ]?.id ?? '1';
choicesInstance.setChoiceByValue( defaultValue );
app.changeNotificationsValue( $select );
},
/**
* Change notifications value.
*
* @since 1.0.0
*
* @param {jQuery} $select The select element.
*/
changeNotificationsValue( $select ) {
// Return if no select element provided.
if ( ! $select.length ) {
return;
}
// Find the JSON field associated with this select.
const $jsonField = $select.closest( '.wpforms-builder-settings-block-content' )
.find( '.wpforms-panel-field-pdf-notifications-json' );
// Update the JSON field value if found.
if ( $jsonField.length ) {
$jsonField.val( JSON.stringify( $select.val() ) );
}
},
/**
* Handle panel switch event.
*
* @since 1.0.0
*
* @param {Object} event Event object.
* @param {string} panelName Name of the panel.
*/
panelSwitch( event, panelName ) {
// Check if switching to the settings panel.
if ( panelName === 'settings' ) {
const section = $( '#wpforms-panel-settings .wpforms-panel-sidebar' )
.find( '.wpforms-panel-sidebar-section.active' )
.data( 'section' );
// If the PDF section is active, refresh all PDF notification dropdowns.
if ( section === 'pdf' ) {
app.refreshAllPDFNotificationDropdowns();
}
}
},
/**
* Handle panel section switch event.
*
* @since 1.0.0
*
* @param {Object} event Event object.
* @param {string} sectionName Name of the section.
*/
panelSectionSwitch( event, sectionName ) {
// If switching to the PDF section, refresh all PDF notification dropdowns.
if ( sectionName === 'pdf' ) {
app.refreshAllPDFNotificationDropdowns();
}
},
/**
* Refresh PDF notification dropdown.
*
* @since 1.0.0
*
* @param {jQuery} $select The select element.
*/
refreshNotificationDropdown( $select ) {
const choicesInstance = $select.data( 'choicesjs' );
// Skip if no Choices.js instance found.
if ( ! choicesInstance ) {
return;
}
// Get current selected values.
const currentValues = choicesInstance.getValue();
const selectedValues = currentValues?.map( ( item ) => item.value ) ?? [];
// Format notifications for Choices.js.
const choicesData = app.notifications.map( ( notification ) => ( {
value: notification.id,
label: notification.name,
} ) );
// Clear and reset choices.
choicesInstance.clearStore();
choicesInstance.setChoices( choicesData, 'value', 'label', true );
// Restore previously selected values if they still exist.
for ( let i = 0; i < selectedValues.length; i++ ) {
if ( app.notifications.some( ( notification ) => notification.id === selectedValues[ i ] ) ) {
choicesInstance.setChoiceByValue( selectedValues[ i ] );
}
}
// Update the JSON field.
app.changeNotificationsValue( $select );
},
/**
* Refresh all PDF notification dropdowns.
*
* @since 1.0.0
*/
refreshAllPDFNotificationDropdowns() {
// Get all notifications from the form.
app.notifications = app.getAllNotifications();
// Refresh each PDF notification dropdown.
$( '.wpforms-pdf-notifications select' ).each( function() {
app.refreshNotificationDropdown( $( this ) );
} );
},
/**
* Get all notifications from the form.
*
* @since 1.0.0
*
* @return {Array} Array of notification objects.
*/
getAllNotifications() {
const notifications = [];
// Get all notification blocks.
$( '.wpforms-panel-content-section-notifications .wpforms-notification' ).each( function() {
const $notification = $( this );
const id = $notification.data( 'block-id' ).toString();
const name = $notification.find( '.wpforms-builder-settings-block-name' ).text().trim();
// Add to a notification array if both ID and name are present.
if ( id && name ) {
notifications.push( {
id,
name,
} );
}
} );
return notifications;
},
};
// Return the public-facing methods.
return app;
}