: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
/* global wpforms_builder, WPFormsBuilder, WPFormsUtils */
* @param wpforms_builder.field_cannot_be_reordered
// noinspection ES6ConvertVarToLetConst
* Form Builder Fields Drag-n-Drop module.
var WPForms = window.WPForms || {}; // eslint-disable-line no-var
WPForms.Admin = WPForms.Admin || {};
WPForms.Admin.Builder = WPForms.Admin.Builder || {};
WPForms.Admin.Builder.DragFields = WPForms.Admin.Builder.DragFields || ( function( document, window, $ ) {
* Layout field functions wrapper.
let fieldLayout; // eslint-disable-line prefer-const
* Public functions and properties.
app.initSortableFields();
* Setup. Prepare some variables.
$builder: $( '#wpforms-builder' ),
$sortableFieldsWrap: $( '#wpforms-panel-fields .wpforms-field-wrap' ),
$addFieldsButtons: $( '.wpforms-add-fields-button' ).not( '.not-draggable' ).not( '.warning-modal' ).not( '.education-modal' ),
.on( 'wpformsFieldDragToggle', app.fieldDragToggleEvent );
* @since 1.7.7 Moved from admin-builder.js.
el.$addFieldsButtons.filter( '.ui-draggable' ).draggable( 'disable' );
el.$sortableFieldsWrap.sortable( 'disable' );
el.$sortableFieldsWrap.find( '.wpforms-layout-column.ui-sortable' ).sortable( 'disable' );
* @since 1.7.7 Moved from admin-builder.js.
el.$addFieldsButtons.filter( '.ui-draggable' ).draggable( 'enable' );
el.$sortableFieldsWrap.sortable( 'enable' );
el.$sortableFieldsWrap.find( '.wpforms-layout-column.ui-sortable' ).sortable( 'enable' );
* Show popup in case if field is not draggable, and cancel moving.
* @since 1.7.7 Moved from admin-builder.js.
* @param {jQuery} $field A field or list of fields.
* @param {boolean} showPopUp Whether the pop-up should be displayed on dragging attempt.
fieldDragDisable( $field, showPopUp = true ) {
if ( $field.hasClass( 'ui-draggable-disabled' ) ) {
// noinspection JSUnresolvedReference
$field.draggable( 'enable' );
// noinspection JSUnresolvedReference
startTopPosition = ui.position.top;
if ( Math.abs( ui.position.top ) - Math.abs( startTopPosition ) > 15 ) {
app.youCantReorderFieldPopup();
* @since 1.7.7 Moved from admin-builder.js.
* @param {jQuery} $field A field or list of fields.
fieldDragEnable( $field ) {
if ( $field.hasClass( 'ui-draggable' ) ) {
// noinspection JSUnresolvedReference
$field.draggable( 'disable' );
* Show the error message in the popup that you cannot reorder the field.
* @since 1.7.7 Moved from admin-builder.js.
youCantReorderFieldPopup() {
title: wpforms_builder.heads_up,
content: wpforms_builder.field_cannot_be_reordered,
icon: 'fa fa-exclamation-circle',
text: wpforms_builder.ok,
* Event handler for `wpformsFieldDragToggle` event.
* @param {Object} e Event object.
* @param {number|string} id Field ID.
fieldDragToggleEvent( e, id ) {
const $field = $( `#wpforms-field-${ id }` );
$field.hasClass( 'wpforms-field-not-draggable' ) ||
$field.hasClass( 'wpforms-field-stick' )
app.fieldDragDisable( $field );
app.fieldDragEnable( $field );
* Initialize sortable fields in the builder form preview area.
app.initSortableContainer( el.$sortableFieldsWrap );
el.$builder.find( '.wpforms-layout-column' ).each( function() {
app.initSortableContainer( $( this ) );
app.fieldDragDisable( $( '.wpforms-field-not-draggable, .wpforms-field-stick' ) );
app.initDraggableFields();
* Initialize sortable container with fields.
* @param {jQuery} $sortable Container to make sortable.
initSortableContainer( $sortable ) { // eslint-disable-line max-lines-per-function
const $fieldOptions = $( '#wpforms-field-options' );
const $scrollContainer = $( '#wpforms-panel-fields .wpforms-panel-content-wrap' );
currentlyScrolling = false;
// noinspection JSUnresolvedReference
items: '> .wpforms-field:not(.wpforms-field-stick):not(.no-fields-preview)',
connectWith: '.wpforms-field-wrap, .wpforms-layout-column',
cancel: '.wpforms-field-not-draggable',
placeholder: 'wpforms-field-drag-placeholder',
appendTo: '#wpforms-panel-fields',
fieldId = ui.item.data( 'field-id' );
fieldType = ui.item.data( 'field-type' );
isNewField = typeof fieldId === 'undefined';
$fieldOption = $( '#wpforms-field-option-' + fieldId );
vars.fieldReceived = false;
vars.fieldRejected = false;
vars.$sortableStart = $sortable;
vars.startPosition = ui.item.first().index();
el.$builder.trigger( 'wpformsFieldDragStart', [ fieldId ] );
if ( ! vars.glitchChange ) {
// Before processing in the `stop` method, we need to perform the last check.
if ( ! fieldLayout.isFieldAllowedInColum( fieldType, ui.item.first().parent() ) ) {
vars.fieldRejected = true;
stop( e, ui ) { // eslint-disable-line complexity
const $field = ui.item.first();
ui.placeholder.removeClass( 'wpforms-field-drag-not-allowed' );
$field.removeClass( 'wpforms-field-drag-not-allowed' );
// Reject not allowed fields.
if ( vars.fieldRejected ) {
const $targetColumn = isNewField ? $sortable : $field.parent();
app.revertMoveFieldToColumn( $field );
el.$builder.trigger( 'wpformsFieldMoveRejected', [ $field, ui, $targetColumn ] );
prevFieldId = $field.prev( '.wpforms-field, .wpforms-alert' ).data( 'field-id' );
$prevFieldOption = $( `#wpforms-field-option-${ prevFieldId }` );
if ( $prevFieldOption.length > 0 ) {
$prevFieldOption.after( $fieldOption );
$fieldOptions.prepend( $fieldOption );
// In the case of changing fields' order inside the same column,
// we just need to change the position of the field.
if ( ! isNewField && $field.closest( '.wpforms-layout-column' ).is( $sortable ) ) {
fieldLayout.positionFieldInColumn(
const $layoutField = $field.closest( '.wpforms-field-layout, .wpforms-field-repeater' );
fieldLayout.fieldOptionsUpdate( null, fieldId );
fieldLayout.reorderLayoutFieldsOptions( $layoutField );
.removeClass( 'wpforms-field-dragging' )
.removeClass( 'wpforms-field-drag-over' );
$field.attr( 'style', '' );
el.$builder.trigger( 'wpformsFieldMove', ui );
vars.fieldReceived = false;
over( e, ui ) { // eslint-disable-line complexity
const $field = ui.item.first(),
$placeholder = $target.find( '.wpforms-field-drag-placeholder' ),
isColumn = $target.hasClass( 'wpforms-layout-column' ),
width: $target.outerWidth(),
height: $field.outerHeight(),
let targetClass = isColumn ? ' wpforms-field-drag-to-column' : '';
const columnSize = $target.attr( 'class' ).match( /wpforms-layout-column-(\d+)/ )[ 1 ];
targetClass += ` wpforms-field-drag-to-column-${ columnSize }`;
fieldId = $field.data( 'field-id' );
fieldType = $field.data( 'field-type' ) || vars.fieldType;
isNewField = typeof fieldId === 'undefined';
// Adjust helper size according to the placeholder size.
.addClass( 'wpforms-field-dragging' + targetClass );
if ( ! isColumn || ! fieldLayout.isLayoutBasedField( fieldType ) ) {
width: isColumn ? helper.width - 5 : helper.width,
const placeholderHeight = isColumn ? 90 : helper.height;
// Adjust placeholder height according to the height of the helper.
.removeClass( 'wpforms-field-drag-not-allowed' )
height: isNewField ? placeholderHeight + 18 : helper.height,
// Drop to this place is not allowed.
if ( isColumn && ! fieldLayout.isFieldAllowedInColum( fieldType, $target ) ) {
$placeholder.addClass( 'wpforms-field-drag-not-allowed' );
$field.addClass( 'wpforms-field-drag-not-allowed' );
el.$builder.trigger( 'wpformsFieldDragOver', [ fieldId, $target ] );
// Skip if it is the existing field.
.addClass( 'wpforms-field-drag-over' )
.removeClass( 'wpforms-field-drag-out' );
const $field = ui.item.first(),
// eslint-disable-next-line no-shadow
fieldId = $field.data( 'field-id' ),
// eslint-disable-next-line no-shadow
isNewField = typeof fieldId === 'undefined';
.removeClass( 'wpforms-field-drag-not-allowed' )
.removeClass( function( index, className ) {
// Remove all classes starting with `wpforms-field-drag-to-column`.
return ( className.match( /wpforms-field-drag-to-column(-\d+|)/g ) || [] ).join( ' ' );
if ( vars.fieldReceived ) {
$field.attr( 'style', '' );
// Skip if it is the existing field.
// Remove extra class from the parent layout field.
// Fixes disappearing of duplicate/delete field icons
// after moving the field outside the layout field.
.closest( '.wpforms-field-layout, .wpforms-field-repeater' )
.removeClass( 'wpforms-field-child-hovered' );
.addClass( 'wpforms-field-drag-out' )
.removeClass( 'wpforms-field-drag-over' );
receive( e, ui ) { // eslint-disable-line complexity
const $field = $( ui.helper || ui.item );
fieldId = $field.data( 'field-id' );
fieldType = $field.data( 'field-type' ) || vars.fieldType;
// eslint-disable-next-line no-shadow
const isNewField = typeof fieldId === 'undefined',
isColumn = $sortable.hasClass( 'wpforms-layout-column' );
// Drop to this place is not allowed.
! fieldLayout.isFieldAllowedInColum( fieldType, $sortable )
vars.fieldRejected = true;
vars.fieldReceived = true;
$field.removeClass( 'wpforms-field-drag-over' );
fieldLayout.receiveFieldToColumn(
const position = $sortable.data( 'ui-sortable' ).currentItem.index();
.addClass( 'wpforms-field-drag-over wpforms-field-drag-pending' )
.removeClass( 'wpforms-field-drag-out' )
.append( WPFormsBuilder.settings.spinnerInline )
el.$builder.find( '.no-fields-preview' ).remove();
position: isColumn ? position - 1 : position,