File: /home/globfdxw/www/wp-content/plugins/wpforms-pdf/assets/js/modules/access-restrictions.js
/* global wpforms_builder, wpf, WPForms */
/**
* WPForms PDF: Access Restrictions 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}
*/
let el = {};
/**
* Public functions and properties.
*
* @since 1.0.0
*/
const app = {
/**
* Start the engine.
*
* @since 1.0.0
*/
init() {
app.ready();
},
/**
* DOM is fully loaded.
*
* @since 1.0.0
*/
ready() {
app.setup();
app.events();
},
/**
* Setup. Prepare some variables.
*
* @since 1.0.0
*/
setup() {
// Cache DOM elements.
el = {
$builder: $( '#wpforms-builder' ),
};
},
/**
* Add handlers on events.
*
* @since 1.0.0
*/
events() {
el.$builder
.on( 'change', '.wpforms-pdf-access-restrictions input[type=checkbox]', app.accessRestrictionsOptionHandler )
.on( 'change', '.wpforms-pdf-password-restrictions input[type=checkbox]', app.passwordRestrictionsOptionHandler )
.on( 'change', '.wpforms-pdf-user-restrictions select', app.userRestrictionsOptionHandler )
.on( 'keyup focus', '.wpforms-pdf-password-input', app.cleanPasswordButtonHandler )
.on( 'keyup', '.wpforms-pdf-password-input', app.checkPasswordMatch )
.on( 'keyup', '.wpforms-pdf-password-confirm-input', app.checkPasswordMatch )
.on( 'change', '.wpforms-pdf-password-input', app.sanitizePasswordValue )
.on( 'click', '.wpforms-pdf-password-clean', app.cleanPasswordInput )
.on( 'wpformsBeforeSave', app.checkPasswordMatchBeforeSave )
.on( 'wpformsBuilderReady', app.initUserRestrictionsSelects );
},
/**
* Initialize user restrictions selects with ChoicesJS.
*
* @since 1.0.0
*/
initUserRestrictionsSelects() {
$( '.wpforms-pdf-user-roles-select select' ).each( function() {
app.initChoicesJS( $( this )[ 0 ], {}, wpforms_builder.pdf.access_restrictions.all_user_roles_selected );
} );
$( '.wpforms-pdf-user-names-select select' ).each( function() {
app.initUserNamesSelect( $( this )[ 0 ] );
} );
},
/**
* Initialize usernames select with AJAX search.
*
* @since 1.0.0
*
* @param {HTMLElement} select The select element to initialize.
*/
initUserNamesSelect( select ) {
const ajaxArgs = {
action: 'wpforms_ajax_search_user_names',
nonce: wpforms_builder.nonce,
};
// From select, strip all options that have no value attribute set.
const options = $( select ).find( 'option' );
options.each( function() {
if ( ! $( this ).attr( 'value' ) ) {
$( this ).remove();
}
} );
app.initChoicesJS( select, ajaxArgs );
},
/**
* Initialize ChoicesJS for the given select element.
*
* @since 1.0.0
*
* @param {HTMLElement} select The select element to initialize ChoicesJS on.
* @param {Object} ajaxArgs Optional. Arguments for AJAX requests.
* @param {string} noChoicesText Optional. Text to display when there are no choices.
*/
initChoicesJS( select, ajaxArgs = {}, noChoicesText = '' ) { // eslint-disable-line complexity
if (
! select ||
typeof WPForms.Admin.Builder.WPFormsChoicesJS === 'undefined' ||
! select.nodeName ||
select.nodeName.toLowerCase() !== 'select'
) {
return;
}
if ( ! document.body.contains( select ) ) {
return;
}
const choicesJS = WPForms.Admin.Builder.WPFormsChoicesJS.setup(
select,
{
removeItemButton: true,
noChoicesText,
callbackOnInit() {
if ( typeof wpf !== 'undefined' && typeof wpf.showMoreButtonForChoices === 'function' ) {
wpf.showMoreButtonForChoices( this.containerOuter.element );
}
},
},
ajaxArgs
);
app.setChoicesJSInitialValue( choicesJS, select );
app.addChoicesJSEventListeners( choicesJS );
},
/**
* Set initial value for ChoicesJS select.
*
* @since 1.0.0
*
* @param {Object} choicesJS The ChoicesJS instance.
* @param {HTMLElement} select The select element.
*/
setChoicesJSInitialValue( choicesJS, select ) {
const fieldId = $( select ).data( 'field-id' ),
fieldName = $( select ).data( 'field-name' );
const values = app.getHiddenValues( fieldId, fieldName );
// For user roles, always ensure administrator is selected
if (
fieldName === 'user_roles_restrictions' &&
( ! values || ! values.length || ! values.includes( 'administrator' ) )
) {
choicesJS.setChoiceByValue( [ 'administrator' ] );
} else {
choicesJS.setChoiceByValue( values );
}
},
/**
* Add event listeners for ChoicesJS select.
*
* @since 1.0.0
*
* @param {Object} choicesJS The ChoicesJS instance.
*/
addChoicesJSEventListeners( choicesJS ) {
const updateHiddenField = () => {
const fieldId = $( choicesJS.passedElement.element ).data( 'field-id' );
const fieldName = $( choicesJS.passedElement.element ).data( 'field-name' );
const values = choicesJS.getValue( true ); // Get array of selected values
const $hiddenField = $( `#settings-pdfs-${ fieldId }-${ fieldName }-options` );
if ( $hiddenField.length ) {
$hiddenField.val( JSON.stringify( values ) );
}
};
choicesJS.passedElement.element.addEventListener( 'removeItem', function( event ) {
// Set the selected value to 'administrator' if it is removed.
if ( event.detail.value === 'administrator' ) {
choicesJS.setChoiceByValue( 'administrator' );
}
if ( event.target.classList.contains( 'wpforms-pdf-user-names-select' ) ) {
choicesJS.clearChoices();
}
// Update hidden field
setTimeout( updateHiddenField, 10 );
} );
choicesJS.passedElement.element.addEventListener( 'addItem', function( event ) {
if ( event.target.classList.contains( 'wpforms-pdf-user-names-select' ) ) {
choicesJS.hideDropdown();
choicesJS.clearChoices();
}
// Update hidden field
setTimeout( updateHiddenField, 10 );
} );
},
/**
* Get selected values from a hidden JSON field.
*
* @since 1.0.0
*
* @param {number} fieldId The ID of the field.
* @param {string} fieldName The name of the field.
*
* @return {Array} The selected values.
*/
getHiddenValues( fieldId, fieldName ) {
const $hiddenField = $( `#settings-pdfs-${ fieldId }-${ fieldName }-options` );
const value = $hiddenField.val();
if ( ! $hiddenField.length || ! value ) {
return [];
}
let selected;
try {
selected = JSON.parse( value );
} catch ( e ) {
selected = {};
}
// Convert to an array of values and ensure they are strings.
selected = Object.values( selected );
return selected.map( function( item ) {
return item.toString();
} );
},
/**
* Handle access restrictions option change.
*
* @since 1.0.0
*
* @param {Object} event The event object.
*/
accessRestrictionsOptionHandler( event ) {
const $toggle = $( event.target ),
$pdfBlock = $toggle.closest( '.wpforms-builder-settings-block' ),
$restrictionSettings = $pdfBlock.find( '.wpforms-pdf-restriction-settings' ),
isChecked = $toggle.is( ':checked' );
if ( isChecked ) {
$restrictionSettings.show();
} else {
$restrictionSettings.hide();
$pdfBlock.find( '.wpforms-pdf-password-restrictions input[type=checkbox]' ).prop( 'checked', false ).trigger( 'change' );
$pdfBlock.find( '.wpforms-pdf-user-restrictions select' ).val( 'none' ).trigger( 'change' );
}
},
/**
* Handle password restrictions option change.
*
* @since 1.0.0
*
* @param {Object} event The event object.
*/
passwordRestrictionsOptionHandler( event ) {
const $toggle = $( event.target ),
$pdfBlock = $toggle.closest( '.wpforms-builder-settings-block' ),
$passwordFields = $pdfBlock.find( '.wpforms-pdf-password-fields-wrap' ),
isChecked = $toggle.is( ':checked' );
if ( isChecked ) {
$passwordFields.show();
} else {
$passwordFields.hide();
$pdfBlock.find( '.wpforms-pdf-password-field input' ).val( '' );
$pdfBlock.find( '.wpforms-pdf-password-error' ).hide();
}
},
/**
* Handle user restrictions option change.
*
* @since 1.0.0
*
* @param {Object} event The event object.
*/
userRestrictionsOptionHandler( event ) {
const $select = $( event.target ),
$pdfBlock = $select.closest( '.wpforms-builder-settings-block' ),
$userRolesWrap = $pdfBlock.find( '.wpforms-pdf-user-roles-restrictions-wrap' ),
$userNamesWrap = $pdfBlock.find( '.wpforms-pdf-user-names-restrictions-wrap' ),
value = $select.val();
if ( value === 'none' ) {
$userRolesWrap.hide();
$userNamesWrap.hide();
return;
}
$userRolesWrap.show();
$userNamesWrap.show();
// Initialize ChoicesJS for the select fields in this block if not already initialized
const $userRolesSelect = $pdfBlock.find( '.wpforms-pdf-user-roles-select select' );
const $userNamesSelect = $pdfBlock.find( '.wpforms-pdf-user-names-select select' );
if ( $userRolesSelect.length && ! $userRolesSelect.hasClass( 'choices__input' ) ) {
app.initChoicesJS( $userRolesSelect[ 0 ], {}, wpforms_builder.pdf.access_restrictions.no_user_roles_selected );
}
if ( $userNamesSelect.length && ! $userNamesSelect.hasClass( 'choices__input' ) ) {
app.initUserNamesSelect( $userNamesSelect[ 0 ] );
}
},
/**
* Handle clean password button visibility.
*
* @since 1.0.0
*
* @param {Object} event The event object.
*/
cleanPasswordButtonHandler( event ) {
const $input = $( event.target ),
$passwordField = $input.closest( '.wpforms-pdf-password-field' ),
$button = $passwordField.find( '.wpforms-pdf-password-clean' );
if ( $input.val() ) {
$button.show();
} else {
$button.hide();
}
},
/**
* Clean password input.
*
* @since 1.0.0
*
* @param {Object} event The event object.
*/
cleanPasswordInput( event ) {
const $button = $( event.target ).closest( '.wpforms-pdf-password-clean' ),
$passwordField = $button.closest( '.wpforms-pdf-password-fields-wrap' ).find( '.wpforms-pdf-password-field' );
$passwordField.each( function() {
const $input = $( this ).find( 'input' );
$input.val( '' ).trigger( 'focus' );
} );
$button.hide();
},
/**
* Check if passwords match.
*
* @since 1.0.0
*
* @param {Object} event The event object.
*/
checkPasswordMatch( event ) {
const $confirmInput = $( event.target ),
$pdfBlock = $confirmInput.closest( '.wpforms-builder-settings-block' ),
$passwordInput = $confirmInput.hasClass( 'wpforms-pdf-password-input' ) ? $pdfBlock.find( '.wpforms-pdf-password-confirm-input' ) : $pdfBlock.find( '.wpforms-pdf-password-input' ),
$error = $pdfBlock.find( '.wpforms-pdf-password-error' );
if ( $confirmInput.val() !== $passwordInput.val() ) {
$error.show();
return;
}
$error.hide();
},
/**
* Sanitize password value.
*
* @since 1.0.0
*
* @param {Object} event The event object.
*/
sanitizePasswordValue( event ) {
const $input = $( event.target ),
value = $input.val(),
sanitized = value.replace( /\s+/g, '' );
if ( value !== sanitized ) {
$input.val( sanitized );
}
},
/**
* Check if passwords match before save.
*
* @since 1.0.0
*
* @param {Object} event The event object.
*/
checkPasswordMatchBeforeSave( event ) { // eslint-disable-line complexity
const $form = $( event.target ),
$pdfBlocks = $form.find( '.wpforms-builder-settings-block.wpforms-pdf' );
let hasErrors = false,
isPasswordEmpty = false,
$errors,
$passwordInput;
$pdfBlocks.each( function() {
const $pdfBlock = $( this );
// Return early if password toggle is off.
if ( ! $pdfBlock.find( '.wpforms-pdf-password-restrictions input[type=checkbox]' ).is( ':checked' ) ) {
return;
}
$passwordInput = $pdfBlock.find( '.wpforms-pdf-password-input' );
const $confirmInput = $pdfBlock.find( '.wpforms-pdf-password-confirm-input' );
// If password or confirm password is empty, show error.
if (
( $passwordInput.val() && ! $confirmInput.val() ) ||
( ! $passwordInput.val() && $confirmInput.val() )
) {
$pdfBlocks.find( '.wpforms-pdf-password-error' ).show();
}
$errors = $pdfBlocks.find( '.wpforms-pdf-password-error:visible' );
hasErrors = hasErrors || $errors.length > 0;
isPasswordEmpty = isPasswordEmpty || ! $passwordInput.val();
} );
if ( hasErrors ) {
event.preventDefault();
$.alert( {
icon: 'fa fa-exclamation-triangle',
type: 'red',
title: wpforms_builder.pdf.access_restrictions.password_match_error_title,
content: wpforms_builder.pdf.access_restrictions.password_match_error_text,
buttons: {
confirm: {
text: wpforms_builder.close,
btnClass: 'btn-confirm',
action: () => {
setTimeout( function() {
$errors.first().closest( '.wpforms-pdf-password-confirm' ).find( 'input' ).trigger( 'focus' );
}, 400 );
},
},
},
} );
}
if ( isPasswordEmpty ) {
event.preventDefault();
$.alert( {
icon: 'fa fa-exclamation-triangle',
type: 'red',
title: wpforms_builder.pdf.access_restrictions.password_empty_error_title,
content: wpforms_builder.pdf.access_restrictions.password_empty_error_text,
buttons: {
confirm: {
text: wpforms_builder.close,
btnClass: 'btn-confirm',
},
},
} );
}
},
};
// Provide access to public functions/properties.
return app;
}