Файловый менеджер - Редактировать - /home/avadvi5/public_html/fcolliver.com/wp-content/plugins/wpforms/assets/pro/js/admin/builder/conditional-logic-core.js
Ðазад
/* global wpf, wpforms_builder */ // noinspection ES6ConvertVarToLetConst var WPFormsConditionals = window.WPFormsConditionals || ( function( document, window, $ ) { // eslint-disable-line no-var /** * Helper methods. * * @since 1.6.0.2 */ const helpers = { /** * Splits an array to chunks of n elements. * * @since 1.6.0.2 * * @param {Array} array Array to split. * @param {number} n Number of elements in each chunk. * * @return {Array} Array. */ arraySplitIntoChunks( array, n ) { if ( ! array.length ) { return []; } return [ array.slice( 0, n ) ] .concat( helpers.arraySplitIntoChunks( array.slice( n ), n ) ); }, }; /** * Conditional rules updating methods. * * @since 1.6.0.2 */ const updater = { /** * All form fields. * * @since 1.6.0.2 */ allFields: {}, /** * Conditional rule rows. * * @since 1.6.0.2 */ $ruleRows: {}, /** * Form fields supporting conditional logic. * * @since 1.6.0.2 */ conditionalFields: {}, /** * HTML template containing a list of <option> elements representing available conditional fields. * * @since 1.6.0.2 */ fieldsListTemplate: '', /** * HTML templates containing a list of <option> elements representing values of every conditional field. * * @since 1.6.0.2 */ fieldValuesListTemplates: {}, /** * Cache all form fields. * * @since 1.6.0.2 * * @param {Array} allFields List of all fields. */ cacheAllFields( allFields ) { updater.allFields = allFields; }, /** * Cache all rule rows. * * @since 1.6.0.2 * * @param {jQuery} $rows Collection of all conditional rule rows. */ cacheRuleRows( $rows ) { updater.$ruleRows = $rows || $( '.wpforms-conditional-row' ); }, /** * Cache allowed form fields supporting conditional logic. * * @since 1.6.0.2 */ setConditionalFields() { updater.conditionalFields = updater.removeUnsupportedFields(); }, /** * Remove field types that are not allowed and whitelisted. * * @since 1.6.0.2 * * @return {Object} Filtered list of fields. */ removeUnsupportedFields() { const allowed = wpforms_builder.cl_fields_supported; let fields = { ...updater.allFields }; /** * Filter the fields list before removing unsupported field types. * * @since 1.8.9 * * @param {Object} fields Fields data. * * @return {Object} Filtered fields data. */ fields = wp.hooks.applyFilters( 'wpforms.ConditionalLogicCore.BeforeRemoveUnsupportedFields', fields ); Object.keys( fields ).forEach( ( key ) => { if ( ! allowed.includes( fields[ key ].type ) || fields[ key ].dynamic_choices ) { delete fields[ key ]; } } ); return fields; }, /** * Set up all HTML templates. * * @since 1.6.0.2 */ setTemplates() { updater.setFieldsListTemplate(); // Reset cached field values templates before processing. updater.fieldValuesListTemplates = {}; }, /** * Return an HTML template for a select with all the field names. * * Doing a jQuery-DOM and copying the underlying HTML makes rendering * twice as fast. * * @since 1.6.0.2 */ setFieldsListTemplate() { // language=HTML const $fieldsListTemplate = $( '<select>' ) .append( $( '<option>', { value: '', text: wpforms_builder.select_field } ) ); for ( const key in updater.conditionalFields ) { const field = updater.conditionalFields[ key ]; let label; if ( typeof field.label !== 'undefined' && field.label.toString().trim() !== '' ) { label = wpf.sanitizeHTML( field.label.toString().trim() ); } else { label = wpforms_builder.field + ' #' + field.id; } $fieldsListTemplate.append( $( '<option>', { value: field.id, text : label, id : 'option-' + field.id, } ) ); } updater.fieldsListTemplate = $fieldsListTemplate.html(); }, /** * Return an HTML with a list of options from a given field. * * @since 1.6.0.2 * * @param {Array} fields Array of fields. * @param {number} fieldSelected ID of selected field. * * @return {string} HTML template. */ getFieldValuesListTemplate( fields, fieldSelected ) { // Return the cached template if possible. if ( updater.fieldValuesListTemplates[ fieldSelected ] ) { return updater.fieldValuesListTemplates[ fieldSelected ]; } /* * Trigger to allow rewrite value field options. * * @since 1.9.8.6 * * @param {Object} fieldSelected Rule field value. * @param {Object} fields Field object. */ const customValuesHTML = $( '#wpforms-builder' ).triggerHandler( 'wpformsConditionalRuleRowValue', [ { fieldSelected, fields } ] ); if ( typeof customValuesHTML === 'string' ) { return updater.fieldValuesListTemplates[ fieldSelected ] = customValuesHTML; } const items = wpf.orders.choices[ 'field_' + fieldSelected ], // language=HTML $select = $( '<select>' ), field = Object.values( wpf.getFields() ).find( ( el ) => el.id.toString() === fieldSelected.toString() ); for ( const key in items ) { const choiceKey = items[ key ]; const choice = ( field.choices || {} )[ choiceKey ] || {}; // Exclude the "Other" option from conditional value select. if ( choice.other ) { continue; } const label = typeof choice.label !== 'undefined' && choice.label.toString().trim() !== '' ? wpf.sanitizeHTML( choice.label.toString().trim() ) : wpforms_builder.choice_empty_label_tpl.replace( '{number}', choiceKey ); $select.append( $( '<option>', { value: choiceKey, text: label, id: 'choice-' + choiceKey } ) ); } // Cache the template for future use and return the HTML. return updater.fieldValuesListTemplates[ fieldSelected ] = $select.html(); }, /** * Form fields supporting conditional logic. * * @since 1.6.0.2 */ updateConditionalRuleRows() { /** * Split all the rows in sets of at most 20 elements. * * The set of 20 rows would then be processed as soon as possible, but without blocking * the main thread (thanks to setTimeout). * * When all the groups are processed, the function finalize is called. * * @since 1.6.0.2 */ helpers.arraySplitIntoChunks( updater.$ruleRows, 20 ).map( function( elements ) { setTimeout( function() { for ( let i = 0; i < elements.length; ++i ) { updater.updateConditionalRuleRow( elements[ i ] ); } }, 0 ); return elements; } ); }, /** * Redraw the conditional rule in the builder. * * @since 1.6.0.2 * * @param {Object} row Element container. */ updateConditionalRuleRow( row ) { const $row = $( row ), fieldID = $row.attr( 'data-field-id' ), $fields = $row.find( '.wpforms-conditional-field' ), fieldSelected = $fields.val(); // Clone template $fields[ 0 ].innerHTML = updater.fieldsListTemplate; // Remove the current item $fields.find( '#option-' + fieldID ).remove(); /** * Trigger to allow addons to add custom fields to rule. * * @since 1.9.8.6 * * @param {Object} $row Row container. * @param {Object} $fields Field object. * @param {string} fieldSelected Field selected value. * @param {Object} fieldID Field ID. */ $( '#wpforms-builder' ).trigger( 'wpformsConditionalRuleRowField', [ $row, $fields, fieldID, fieldSelected ] ); if ( ! fieldSelected ) { // Remove all id properties. // Querying the DOM by ID is much faster. It is safe to remove the IDs now. $fields.find( 'option' ).removeAttr( 'id' ); return; } const $value = $row.find( '.wpforms-conditional-value' ); // Check if the previous selected field exists in the new options added. if ( $fields.find( '#option-' + fieldSelected ).length ) { updater.restorePreviousRuleRowSelection( $row, $fields, fieldSelected, $value ); } else { updater.removeRuleRow( $row ); } // Remove all id properties. // Querying the DOM by ID is much faster. It is safe to remove the IDs now. $fields.find( 'option' ).removeAttr( 'id' ); $value.find( 'option' ).removeAttr( 'id' ); }, /** * Update delete confirmation alert message. * * @since 1.6.7 * * @param {Object} fieldData Field Data object. */ fieldDeleteConfirmAlert( fieldData ) { let alert = wpforms_builder.conditionals_change + '<br>', updateAlert; $( '.wpforms-conditional-field' ).each( function() { if ( fieldData.id === Number( $( this ).val() ) ) { if ( fieldData.choiceId && fieldData.choiceId !== Number( $( this ).closest( '.wpforms-conditional-row' ).find( '.wpforms-conditional-value' ).val() ) ) { return; } alert += updater.getChangedFieldNameForAlert( updater.getReferenceName( this ) ); updateAlert = true; fieldData.trigger = true; } } ); if ( updateAlert ) { fieldData.message = '<strong>' + fieldData.message + '</strong>' + '<br><br>' + alert; } }, /** * Retrieves the reference name based on the provided conditional field context. * The reference name is determined by the closest provider or conditional group associated with the field. * * @since 1.9.6 * * @param {HTMLElement} conditionalField The conditional field element for which the reference name needs to be determined. * * @return {string} The determined reference name. */ getReferenceName( conditionalField ) { const $conditionalField = $( conditionalField ); // Fetch only Marketing provider name. const providerName = $conditionalField.closest( '.wpforms-builder-provider' ).data( 'provider-name' ); if ( ! providerName ) { return $conditionalField.closest( '.wpforms-conditional-group' ).data( 'reference' ); } return wpforms_builder.cl_reference.replace( '{integration}', providerName ); }, /** * Restore the rule row selection before conditional rules update. * * @since 1.6.0.2 * * @param {Object} $row Row container. * @param {Object} $fields Field object. * @param {string} fieldSelected Field selected value. * @param {Object} $value Field Value. */ restorePreviousRuleRowSelection( $row, $fields, fieldSelected, $value ) { let valueSelected = ''; // Exists, so restore the previous selected value $fields.find( '#option-' + fieldSelected ).prop( 'selected', true ); if ( ! $value.length || ! $value.is( 'select' ) ) { return; } // Since the field exists and was selected, now we must proceed to update the field values. // Luckily, we only have to do this for fields that leverage a select element. // Grab the currently selected value to restore later valueSelected = $value.val(); $value[ 0 ].innerHTML = updater.getFieldValuesListTemplate( updater.conditionalFields, fieldSelected ); // Check if the previous selected value exists in the new options added if ( $value.find( '#choice-' + valueSelected ).length ) { $value.find( '#choice-' + valueSelected ).prop( 'selected', true ); } }, /** * Check if the previous selected field exists in the new options added. * * @since 1.6.0.2 * * @param {Object} $row Row container. */ removeRuleRow( $row ) { // Since the previously selected field no longer exists, this // means this rule is now invalid. So the rule gets // deleted as long as it isn't the only rule remaining. const $group = $row.closest( '.wpforms-conditional-group' ); if ( $group.find( 'table >tbody >tr' ).length === 1 ) { const $groups = $row.closest( '.wpforms-conditional-groups' ); if ( $groups.find( '.wpforms-conditional-group' ).length > 1 ) { $group.remove(); } else { $row.find( '.wpforms-conditional-value' ).remove(); $row.find( '.value' ).append( '<select>' ); } } else { $row.remove(); } }, /** * Return HTML with an error message. * * @since 1.6.0.2 * * @param {string|number} field Field ID or field name. * * @return {string} HTML message. */ getChangedFieldNameForAlert( field ) { if ( ! wpf.isNumber( field ) ) { // Panel return '<br>' + field; } const formData = wpf.formObject( '#wpforms-field-options' ); if ( ( ( formData.fields[ field ] || {} ).label || '' ).length ) { return '<br/>' + wpf.sanitizeHTML( formData.fields[ field ].label ) + ' (' + wpforms_builder.field + ' #' + field + ')'; } return '<br>' + wpforms_builder.field + ' #' + field; }, }; const app = { /** * Start the engine. * * @since 1.0.0 */ init() { // Document ready $( WPFormsConditionals.ready ); }, /** * Document ready. * * @since 1.0.0 */ ready() { WPFormsConditionals.bindUIActions(); }, /** * Get layout fields to exclude. * * @since 1.9.0 * * @param {Object} $element Element to get layout fields to exclude. * * @return {Object} Layout fields to exclude. */ getLayoutFieldsToExclude( $element ) { const layoutID = $element.parents( '.wpforms-field-option' ).find( '.wpforms-field-option-hidden-id' ).val(); const formData = wpf.formObject( '#wpforms-field-options' ); const layoutFieldData = layoutID && formData?.fields?.[ layoutID ] ? formData.fields[ layoutID ] : []; const fieldsToExclude = {}; Object.values( layoutFieldData[ 'columns-json' ] ?? {} ).forEach( ( column ) => { Object.values( column?.fields ?? [] ).forEach( ( field ) => { if ( ! formData.fields[ field ] ) { return; } fieldsToExclude[ field ] = formData.fields[ field ]; } ); } ); return fieldsToExclude; }, /** * Element bindings. * * @since 1.0.0 */ bindUIActions() { const $builder = $( '#wpforms-builder' ); // Conditional support toggle. $builder.on( 'change', '.wpforms-conditionals-enable-toggle input[type=checkbox]', function( e ) { WPFormsConditionals.conditionalToggle( this, e ); } ); $builder.on( 'click', '.wpforms-field-option-group-conditionals', function() { const $this = $( this ); const isAllowedLayoutFields = $this.parents( '.wpforms-field-option' ).find( '.wpforms-field-option-hidden-type' ).val() !== 'layout'; if ( isAllowedLayoutFields ) { return; } const $block = $this.find( '.wpforms-conditional-block' ); const fields = wpf.getFields( false, true, false, app.getLayoutFieldsToExclude( $this ) ); WPFormsConditionals.conditionalUpdateOptions( false, fields, $block.find( '.wpforms-conditional-row' ) ); } ); // Conditional process field selects. $builder.on( 'change', '.wpforms-conditional-field', function( e ) { WPFormsConditionals.conditionalField( this, e ); } ); // Conditional process operator select. $builder.on( 'change', '.wpforms-conditional-operator', function( e ) { WPFormsConditionals.conditionalOperator( this, e ); } ); // Conditional add new rule. $builder.on( 'click', '.wpforms-conditional-rule-add', function( e ) { WPFormsConditionals.conditionalRuleAdd( this, e ); } ); // Conditional delete rule. $builder.on( 'click', '.wpforms-conditional-rule-delete', function( e ) { WPFormsConditionals.conditionalRuleDelete( this, e ); } ); // Conditional add new group. $builder.on( 'click', '.wpforms-conditional-groups-add', function( e ) { WPFormsConditionals.conditionalGroupAdd( this, e ); } ); // Conditional logic update/refresh. $( document ).on( 'wpformsFieldUpdate', WPFormsConditionals.conditionalUpdateOptions ); $builder.on( 'wpformsBeforeFieldDeleteAlert', function( e, fieldData ) { updater.fieldDeleteConfirmAlert( fieldData ); } ); }, /** * Update/refresh the conditional logic fields and associated options. * * @since 1.0.0 * * @param {Object} e Event object. * @param {Array} allFields All fields in the form. * @param {jQuery} $rows Conditional rule rows. */ conditionalUpdateOptions( e, allFields, $rows ) { if ( wpf.empty( allFields ) ) { return; } updater.cacheAllFields( allFields ); updater.cacheRuleRows( $rows ); updater.setConditionalFields(); updater.setTemplates(); updater.updateConditionalRuleRows(); }, /** * Toggle conditional support. * * @since 1.0.0 * @since 1.7.5 Added `wpformsRemoveConditionalLogicRules` trigger. * * @param {Object} el Conditional Logic input (toggle). * @param {Object} e Event object. */ conditionalToggle( el, e ) { e.preventDefault(); const $this = $( el ), $block = $this.closest( '.wpforms-conditional-block' ), logicBlock = wp.template( 'wpforms-conditional-block' ), data = { fieldID : $this.closest( '.wpforms-field-option-row' ).data( 'field-id' ), fieldName : $this.data( 'name' ), actions : $this.data( 'actions' ), actionDesc : $this.data( 'action-desc' ), reference : $this.data( 'reference' ), }; if ( $this.is( ':checked' ) ) { // Add conditional logic rules. $block.append( logicBlock( data ) ); // Update fields in the added rule. const fields = wpf.getFields( false, true, false, app.getLayoutFieldsToExclude( $this ) ); WPFormsConditionals.conditionalUpdateOptions( false, fields, $block.find( '.wpforms-conditional-row' ) ); } else { // Remove conditional logic rules. $.confirm( { title: false, content: wpforms_builder.conditionals_disable, backgroundDismiss: false, icon: 'fa fa-exclamation-circle', type: 'orange', buttons: { confirm: { text: wpforms_builder.ok, btnClass: 'btn-confirm', keys: [ 'enter' ], action() { // Prompt $block.find( '.wpforms-conditional-groups' ).remove(); $( document ).trigger( 'wpformsRemoveConditionalLogicRules', [ $this ] ); }, }, cancel: { text: wpforms_builder.cancel, action() { $this.prop( 'checked', true ); }, }, }, } ); } }, /** * Process conditional field. * * @since 1.0.0 * * @param {Object} el Conditional Logic input (toggle). * @param {Object} e Event object. */ conditionalField( el, e ) { // eslint-disable-line complexity e.preventDefault(); const $this = $( el ), $rule = $this.parent().parent(), $operator = $rule.find( '.wpforms-conditional-operator' ), operator = $operator.find( 'option:selected' ).val(), data = WPFormsConditionals.conditionalData( $this ), name = data.inputName + '[' + data.groupID + '][' + data.ruleID + '][value]'; let $element; if ( ! data.field ) { // Placeholder has been selected. // language=HTML $element = $( '<select>' ); } else if ( data.field.type === 'select' || data.field.type === 'radio' || data.field.type === 'checkbox' || data.field.type === 'payment-multiple' || data.field.type === 'payment-checkbox' || data.field.type === 'payment-select' ) { // Selector type fields use select elements. // language=HTML $element = $( '<select>' ).attr( { name, class: 'wpforms-conditional-value' } ); // jshint ignore:line $element.append( $( '<option>', { value: '', text : wpforms_builder.select_choice } ) ); const order = data.field.choices ? wpf.orders.choices[ 'field_' + data.field.id ] : []; for ( const key in order ) { const choiceKey = order[ key ], choice = data.field.choices[ choiceKey ] || {}, label = typeof choice.label !== 'undefined' && choice.label.toString().trim() !== '' ? wpf.sanitizeHTML( choice.label.toString().trim() ) : wpforms_builder.choice_empty_label_tpl.replace( '{number}', choiceKey ); // Exclude the "Other" option from conditional value select. if ( choice.other ) { continue; } $element.append( $( '<option>', { value: choiceKey, text: wpf.sanitizeHTML( label ) } ) ); } $operator.find( 'option' ).prop( 'disabled', false ); $operator.find( "option:not([value='=='],[value='!='],[value='e'],[value='!e'])" ).prop( 'disabled', true ).prop( 'selected', false ); // jshint ignore:line } else { // Text type fields (everything else) use text inputs. // Determine an input type. let inputType = 'text'; if ( 'rating' === data.field.type || 'net_promoter_score' === data.field.type || 'number-slider' === data.field.type ) { inputType = 'number'; } // language=HTML $element = $( '<input>' ).attr( { type: inputType, name, class: 'wpforms-conditional-value' } ); // jshint ignore:line $operator.find( 'option' ).prop( 'disabled', false ); } if ( operator === 'e' || operator === '!e' ) { // Empty/not empty doesn't use input, so we disable it. $element.prop( 'disabled', true ); } $rule.find( '.value' ).empty().append( $element ); /* * Trigger to allow addons to modify operator options and the value element. * * @since 1.9.8.6 * * @param {jQuery} $this The conditional field element. * @param {jQuery} $rule The conditional rule element. * @param {string} $operator The conditional operator element. * @param {Object} data The conditional data object. * @param {jQuery} $element The conditional value element. */ $( '#wpforms-builder' ).trigger( 'wpformsConditionalRuleRowOperator', [ $this, $rule, $operator, data, $element ] ); }, /** * Process conditional field. * * @since 1.2.0 * * @param {HTMLElement} el Conditional Logic input (toggle). * @param {Object} e Event object. */ conditionalOperator( el, e ) { e.preventDefault(); const $this = $( el ), $rule = $this.parent().parent(), $value = $rule.find( '.wpforms-conditional-value' ), operator = $this.find( 'option:selected' ).val(); if ( operator === 'e' || operator === '!e' ) { $value.prop( 'disabled', true ); if ( $value.is( 'select' ) ) { $value.find( 'option:selected' ).prop( 'selected', false ); } else { $value.val( '' ); } } else { $value.prop( 'disabled', false ); } }, /** * Add new conditional rule. * * @since 1.0.0 * * @param {HTMLElement} el Conditional Logic input (toggle). * @param {Object} e Event object. */ conditionalRuleAdd( el, e ) { e.preventDefault(); const $this = $( el ), $group = $this.closest( '.wpforms-conditional-group' ), $rule = $group.find( 'tr' ).last(), $newRule = $rule.clone(), $field = $newRule.find( '.wpforms-conditional-field' ), $operator = $newRule.find( '.wpforms-conditional-operator' ), data = WPFormsConditionals.conditionalData( $field ), ruleID = Number( data.ruleID ) + 1, name = data.inputName + '[' + data.groupID + '][' + ruleID + ']'; $newRule.find( 'option:selected' ).prop( 'selected', false ); // language=HTML $newRule.find( '.value' ).empty().append( $( '<select>' ) ); $field.attr( 'name', name + '[field]' ).attr( 'data-ruleid', ruleID ); $operator.attr( 'name', name + '[operator]' ); $rule.after( $newRule ); }, /** * Delete conditional rule. * If the only rule in a group, then a group will also be removed. * * @since 1.0.0 * * @param {HTMLElement} el Conditional Logic input (toggle). * @param {Object} e Event object. */ conditionalRuleDelete( el, e ) { e.preventDefault(); const $this = $( el ), $group = $this.closest( '.wpforms-conditional-group' ), $rows = $group.find( 'table >tbody >tr' ); if ( $rows && $rows.length === 1 ) { const $groups = $this.closest( '.wpforms-conditional-groups' ); if ( $groups.find( '.wpforms-conditional-group' ).length > 1 ) { $group.remove(); } else { $rows.find( '.wpforms-conditional-operator' ).val( '==' ).trigger( 'change' ); $rows.find( '.wpforms-conditional-value' ).val( '' ).trigger( 'change' ); $rows.find( '.wpforms-conditional-field' ).val( '' ).trigger( 'change' ); } } else { $this.parent().parent().remove(); } }, /** * Add a new conditional group. * * @since 1.0.0 * * @param {HTMLElement} el Conditional Logic input (toggle). * @param {Object} e Event object. */ conditionalGroupAdd( el, e ) { e.preventDefault(); const $this = $( el ), $groupLast = $this.parent().find( '.wpforms-conditional-group' ).last(), $newGroup = $groupLast.clone(); $newGroup.find( 'tr' ).slice( 1 ).remove(); const $field = $newGroup.find( '.wpforms-conditional-field' ), $operator = $newGroup.find( '.wpforms-conditional-operator' ), data = WPFormsConditionals.conditionalData( $field ), groupID = Number( data.groupID ) + 1, ruleID = 0, name = data.inputName + '[' + groupID + '][' + ruleID + ']'; $newGroup.find( 'option:selected' ).prop( 'selected', false ); // language=HTML $newGroup.find( '.value' ).empty().append( $( '<select>' ) ); $field.attr( 'name', name + '[field]' ).attr( 'data-ruleid', ruleID ).attr( 'data-groupid', groupID ); $operator.attr( 'name', name + '[operator]' ); $this.before( $newGroup ); }, //--------------------------------------------------------------------// // Helper functions //--------------------------------------------------------------------// /** * Return various data for the conditional field. * * @since 1.0.0 * * @param {HTMLElement} el Conditional Logic input (toggle). * * @return {Object} Data object containing fields, inputBase, fieldID, ruleID, groupID, selectedID and field. */ conditionalData( el ) { const $this = $( el ); const data = { fields : wpf.getFields( false, true ), inputBase : $this.closest( '.wpforms-conditional-row' ).attr( 'data-input-name' ), fieldID : $this.closest( '.wpforms-conditional-row' ).attr( 'data-field-id' ), ruleID : $this.attr( 'data-ruleid' ), groupID : $this.attr( 'data-groupid' ), selectedID : $this.find( ':selected' ).val(), }; data.inputName = data.inputBase + '[conditionals]'; if ( data.selectedID.length ) { data.field = wpf.getField( data.selectedID ); } else { data.field = false; } return data; }, }; return app; }( document, window, jQuery ) ); WPFormsConditionals.init();
| ver. 1.1 | |
.
| PHP 8.3.30 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0.02 |
proxy
|
phpinfo
|
ÐаÑтройка