: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
const useAjax = $element.data( 'choicesjs-use-ajax' ) === 1;
if ( $element.data( 'choicesjs-callback-fn' ) === 'select_pages' ) {
instance = WPForms.Admin.Builder.WPFormsChoicesJS.setup(
app.dropdownField.config.args,
action: 'wpforms_ajax_search_pages_for_dropdown',
nonce: useAjax ? wpforms_builder.nonce : null,
instance = new Choices( $element[ 0 ], app.dropdownField.config.args );
app.dropdownField.helpers.setInstance( $element, instance );
app.dropdownField.helpers.addPlaceholderChoice( $element, instance );
$element.closest( '.choices' ).toggleClass( 'wpforms-hidden', ! instance.config.choices.length );
* Multiple option callback.
* @param {Object} event Event object.
const fieldId = $( this ).closest( '.wpforms-field-option-row-multiple' ).data().fieldId,
$primary = app.dropdownField.helpers.getPrimarySelector( fieldId ),
$optionChoicesItems = $( '#wpforms-field-option-row-' + fieldId + '-choices input.default' ),
$placeholder = $primary.find( '.placeholder' ),
isDynamicChoices = app.dropdownField.helpers.isDynamicChoices( fieldId ),
isMultiple = event.target.checked,
choicesType = isMultiple ? 'checkbox' : 'radio';
// Add/remove a `multiple` attribute.
$primary.prop( 'multiple', isMultiple );
// Change a `Choices` fields type:
// checkbox - needed for multiple selection
// radio - needed for single selection
$optionChoicesItems.prop( 'type', choicesType );
// Dynamic Choices doesn't have default choices (selected options) - make all as unselected.
if ( isDynamicChoices ) {
$primary.find( 'option:selected' ).prop( 'selected', false );
const selectedChoices = $optionChoicesItems.filter( ':checked' );
if ( ! isMultiple && selectedChoices.length ) {
$optionChoicesItems.prop( 'checked', false );
// For single selection, we can choose only one.
$( selectedChoices.get( 0 ) ).prop( 'checked', true );
// Toggle selection for a placeholder option based on a select type.
if ( $placeholder.length ) {
$placeholder.prop( 'selected', ! isMultiple );
// Update a primary field.
app.dropdownField.helpers.update( fieldId, isDynamicChoices );
* Apply a style to <select> - modern or classic.
const $field = $( this ),
fieldId = $field.closest( '.wpforms-field-option-row-style' ).data().fieldId,
if ( 'modern' === fieldVal ) {
app.dropdownField.helpers.convertClassicToModern( fieldId );
app.dropdownField.helpers.convertModernToClassic( fieldId );
* Get Modern select options and prepare them for the Classic <select>.
* @param {string} fieldId Field ID.
convertModernToClassic: ( fieldId ) => {
const $primary = app.dropdownField.helpers.getPrimarySelector( fieldId ),
isDynamicChoices = app.dropdownField.helpers.isDynamicChoices( fieldId ),
instance = app.dropdownField.helpers.getInstance( $primary ),
$sidebarChoices = $( '#wpforms-field-option-row-' + fieldId + '-choices' ),
$sidebarList = $sidebarChoices.find( '.choices-list' ),
elementsCount = $sidebarList.find( 'li' ).length;
if ( instance && typeof instance.destroy === 'function' ) {
// Destroy the instance of Choices.js.
app.dropdownField.helpers.updatePlaceholderChoice( instance, fieldId );
if ( ! isDynamicChoices ) {
app.fieldChoiceUpdate( 'select', fieldId, elementsCount );
* @param {string} fieldId Field ID.
* @return {Object} Choices.
getInitialChoices( fieldId ) {
const $primary = app.dropdownField.helpers.getPrimarySelector( fieldId ),
instance = app.dropdownField.helpers.getInstance( $primary );
return instance.config.choices;
* Convert a Classic to Modern style selector.
* @param {string} fieldId Field ID.
convertClassicToModern( fieldId ) {
const $primary = app.dropdownField.helpers.getPrimarySelector( fieldId ),
isDynamicChoices = app.dropdownField.helpers.isDynamicChoices( fieldId );
if ( ! isDynamicChoices ) {
app.fieldChoiceUpdate( 'select', fieldId );
// Call a Choices.js initialization.
app.dropdownField.events.choicesInit( $primary );
* Update a primary field.
* @param {string} fieldId Field ID.
* @param {boolean} isDynamicChoices True if `Dynamic Choices` is turned on.
update( fieldId, isDynamicChoices ) {
const $primary = app.dropdownField.helpers.getPrimarySelector( fieldId );
if ( app.dropdownField.helpers.isModernSelect( $primary ) ) {
// If we had a `Modern` select before, then we need to make re-init - destroy() + init().
app.dropdownField.helpers.convertModernToClassic( fieldId );
if ( ! isDynamicChoices ) {
app.dropdownField.events.choicesInit( $primary );
} else if ( ! isDynamicChoices ) {
app.fieldChoiceUpdate( 'select', fieldId );
* Add a new choice to behave like a placeholder.
* @param {Object} $jquerySelector jQuery primary selector.
* @param {Object} instance The instance of Choices.js.
* @return {boolean} False if a fake placeholder wasn't added.
addPlaceholderChoice( $jquerySelector, instance ) { // eslint-disable-line complexity
const wpFormsField = $jquerySelector.closest( '.wpforms-field' );
if ( wpFormsField.length <= 0 ) {
const fieldId = wpFormsField.data().fieldId;
let hasDefaults = app.dropdownField.helpers.hasDefaults( fieldId );
if ( app.dropdownField.helpers.isDynamicChoices( fieldId ) ) {
// Already has a placeholder.
if ( false !== app.dropdownField.helpers.searchPlaceholderChoice( instance ) ) {
if ( ! instance.config.choices.length ) {
const placeholder = instance.config.choices[ 0 ].label,
isMultiple = $( instance.passedElement.element ).prop( 'multiple' ),
selected = ! ( isMultiple || hasDefaults );
// Add a new choice as a placeholder.
{ value: '', label: placeholder, selected, placeholder: true },
// Additional case for multiple select.
$( instance.input.element ).prop( 'placeholder', placeholder );
* Search a choice-placeholder item.
* @param {Object} instance The instance of Choices.js.
* @return {boolean|object} False if a field doesn't have a choice-placeholder.
* Otherwise - return choice item.
searchPlaceholderChoice( instance ) {
instance.config.choices.forEach( function( item, i, choices ) { // eslint-disable-line no-unused-vars
if ( 'undefined' !== typeof item.placeholder && true === item.placeholder ) {
* Add/update a placeholder.
* @param {Object} instance The instance of Choices.js.
* @param {string} fieldId Field ID.
updatePlaceholderChoice( instance, fieldId ) {
const $primary = $( instance.passedElement.element ),
placeholderValue = wpf.sanitizeHTML( $( '#wpforms-field-option-' + fieldId + '-placeholder' ).val() ),
placeholderChoice = app.dropdownField.helpers.searchPlaceholderChoice( instance );
let $placeholderOption = {};
// Get an option with placeholder.
// Note: `.placeholder` class is skipped when calling Choices.js destroy() method.
if ( 'object' === typeof placeholderChoice ) {
$placeholderOption = $( $primary.find( 'option' ).get( placeholderChoice.key ) );
// We have a placeholder and need to update the UI with it.
if ( '' !== placeholderValue ) {
if ( ! $.isEmptyObject( $placeholderOption ) && $placeholderOption.length ) {
// Update a placeholder option.
.addClass( 'placeholder' )
.text( placeholderValue );
// Add a placeholder option.
$primary.prepend( '<option value="" class="placeholder">' + placeholderValue + '</option>' );
} else if ( $placeholderOption.length ) {
// Remove the placeholder as it's empty.
$placeholderOption.remove();
* Is it a `Modern` style dropdown field?
* @param {Object} $jquerySelector jQuery primary selector.
* @return {boolean} True if it's a `Modern` style select, false otherwise.
isModernSelect( $jquerySelector ) {
const instance = app.dropdownField.helpers.getInstance( $jquerySelector );
if ( 'object' !== typeof instance ) {
if ( $.isEmptyObject( instance ) ) {
return instance.initialised;
* Save an instance of Choices.js.
* @param {Object} $jquerySelector jQuery primary selector.
* @param {Object} instance The instance of Choices.js.
setInstance( $jquerySelector, instance ) {
$jquerySelector.data( 'choicesjs', instance );
* Retrieve an instance of Choices.js.
* @param {Object} $jquerySelector jQuery primary selector.
* @return {Object} The instance of Choices.js.
getInstance( $jquerySelector ) {
return $jquerySelector.data( 'choicesjs' );
* Get Dynamic Choices option field.
* @param {string|number} fieldId Field ID.
* @return {HTMLElement|boolean} False if a field doesn't have a `Dynamic Choices` option.
* Otherwise - return option field.
getDynamicChoicesOption( fieldId ) {
const $fieldOption = $( '#wpforms-field-option-' + fieldId + '-dynamic_choices' );
if ( ! $fieldOption.length ) {
* Is `Dynamic Choices` used?
* @param {string|number} fieldId Field ID.
* @return {boolean} True if a `Dynamic Choices` active, false otherwise.
isDynamicChoices( fieldId ) {
const $fieldOption = app.dropdownField.helpers.getDynamicChoicesOption( fieldId );
if ( ! $fieldOption.length ) {
return '' !== $fieldOption.val();
* Is `Dynamic Choices` option type is `Modern`?
* @param {string|number} fieldId Field ID.
* @return {boolean} True if a `Dynamic Choices` option type is `Modern`, false otherwise.
isDynamicChoicesOptionModern( fieldId ) {
const $fieldOption = $( '#wpforms-field-option-' + fieldId + '-style' );
if ( ! $fieldOption.length ) {
return $fieldOption.val() === 'modern';
* Get a Dynamic Choices option type.
* @param {string|number} fieldId Field ID.
* @return {string|boolean} False if a field doesn't have a `Dynamic Choices` option.
* Otherwise - return option type.
getDynamicChoicesOptionType( fieldId ) {
const $fieldOption = app.dropdownField.helpers.getDynamicChoicesOption( fieldId );
if ( ! $fieldOption.length ) {
return $fieldOption.val();
* Get a Dynamic Choices option source.
* @param {string|number} fieldId Field ID.
* @return {string|boolean} False if a field doesn't have a `Dynamic Choices` option.
* Otherwise - return option source.
getDynamicChoicesOptionSource( fieldId ) {
const type = app.dropdownField.helpers.getDynamicChoicesOptionType( fieldId );
const $fieldOption = $( '#wpforms-field-option-' + fieldId + '-dynamic_' + type );
if ( ! $fieldOption.length ) {
return $fieldOption.find( 'option:selected' ).text();
* Is a field having default choices?
* @param {string} fieldId Field ID.
* @return {boolean} True if a field has default choices.
const $choicesList = $( '#wpforms-field-option-row-' + fieldId + '-choices .choices-list' );
return !! $choicesList.find( 'input.default:checked' ).length;
* Retrieve a jQuery selector for the Primary field.
* @param {string} fieldId Field ID.
* @return {Object} jQuery primary selector.
getPrimarySelector( fieldId ) {
return $( '#wpforms-field-' + fieldId + ' .primary-input' );
* Add number slider events listeners.
* @param {Object} $builder JQuery object.
numberSliderEvents( $builder ) {
'.wpforms-field-option-row-min_max .wpforms-input-row .wpforms-number-slider-min',
app.fieldNumberSliderUpdateMin
'.wpforms-field-option-row-min_max .wpforms-input-row .wpforms-number-slider-max',
app.fieldNumberSliderUpdateMax
// Change default input value.