WordPress.org

Make WordPress Core

Changeset 32012


Ignore:
Timestamp:
04/04/2015 04:33:24 PM (5 years ago)
Author:
ocean90
Message:

Customize Widgets: Improve sync logic for select[multiple] inputs.

The current logic doesn't account for the special case of select[multiple] inputs which lack a single value to synchronize: The value to synchronize is an array of zero or more values.
This change replaces _getInputStatePropertyName() with _getInputState(), which returns the state for an input depending on its type, and _setInputState(), which updates an input's state based on its type.

props westonruter.
fixes #31885.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/js/customize-widgets.js

    r31985 r32012  
    928928
    929929        /**
    930          * Get the property that represents the state of an input.
    931          *
    932          * @param {jQuery|DOMElement} input
    933          * @returns {string}
     930         * Get the state for an input depending on its type.
     931         *
     932         * @param {jQuery|Element} input
     933         * @returns {string|boolean|array|*}
    934934         * @private
    935935         */
    936         _getInputStatePropertyName: function( input ) {
    937             var $input = $( input );
    938 
    939             if ( $input.is( ':radio, :checkbox' ) ) {
    940                 return 'checked';
     936        _getInputState: function( input ) {
     937            input = $( input );
     938            if ( input.is( ':radio, :checkbox' ) ) {
     939                return input.prop( 'checked' );
     940            } else if ( input.is( 'select[multiple]' ) ) {
     941                return input.find( 'option:selected' ).map( function () {
     942                    return $( this ).val();
     943                } ).get();
    941944            } else {
    942                 return 'value';
     945                return input.val();
     946            }
     947        },
     948
     949        /**
     950         * Update an input's state based on its type.
     951         *
     952         * @param {jQuery|Element} input
     953         * @param {string|boolean|array|*} state
     954         * @private
     955         */
     956        _setInputState: function ( input, state ) {
     957            input = $( input );
     958            if ( input.is( ':radio, :checkbox' ) ) {
     959                input.prop( 'checked', state );
     960            } else if ( input.is( 'select[multiple]' ) ) {
     961                if ( ! $.isArray( state ) ) {
     962                    state = [];
     963                } else {
     964                    // Make sure all state items are strings since the DOM value is a string
     965                    state = _.map( state, function ( value ) {
     966                        return String( value );
     967                    } );
     968                }
     969                input.find( 'option' ).each( function () {
     970                    $( this ).prop( 'selected', -1 !== _.indexOf( state, String( this.value ) ) );
     971                } );
     972            } else {
     973                input.val( state );
    943974            }
    944975        },
     
    10171048            // then we do not need to touch the UI and mess up the user's ongoing editing.
    10181049            $inputs.each( function() {
    1019                 var input = $( this ),
    1020                     property = self._getInputStatePropertyName( this );
    1021                 input.data( 'state' + updateNumber, input.prop( property ) );
     1050                $( this ).data( 'state' + updateNumber, self._getInputState( this ) );
    10221051            } );
    10231052
     
    10721101                            var $input = $( this ),
    10731102                                $sanitizedInput = $( $sanitizedInputs[i] ),
    1074                                 property = self._getInputStatePropertyName( this ),
    10751103                                submittedState, sanitizedState, canUpdateState;
    10761104
    10771105                            submittedState = $input.data( 'state' + updateNumber );
    1078                             sanitizedState = $sanitizedInput.prop( property );
     1106                            sanitizedState = self._getInputState( $sanitizedInput );
    10791107                            $input.data( 'sanitized', sanitizedState );
    10801108
    1081                             canUpdateState = ( submittedState !== sanitizedState && ( args.ignoreActiveElement || ! $input.is( document.activeElement ) )   );
     1109                            canUpdateState = ( ! _.isEqual( submittedState, sanitizedState ) && ( args.ignoreActiveElement || ! $input.is( document.activeElement ) ) );
    10821110                            if ( canUpdateState ) {
    1083                                 $input.prop( property, sanitizedState );
     1111                                self._setInputState( $input, sanitizedState );
    10841112                            }
    10851113                        } );
Note: See TracChangeset for help on using the changeset viewer.