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. git-svn-id: https://develop.svn.wordpress.org/trunk@32012 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
58ee5beced
commit
9be177ec95
|
@ -927,19 +927,50 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the property that represents the state of an input.
|
* Get the state for an input depending on its type.
|
||||||
*
|
*
|
||||||
* @param {jQuery|DOMElement} input
|
* @param {jQuery|Element} input
|
||||||
* @returns {string}
|
* @returns {string|boolean|array|*}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_getInputStatePropertyName: function( input ) {
|
_getInputState: function( input ) {
|
||||||
var $input = $( input );
|
input = $( input );
|
||||||
|
if ( input.is( ':radio, :checkbox' ) ) {
|
||||||
if ( $input.is( ':radio, :checkbox' ) ) {
|
return input.prop( 'checked' );
|
||||||
return 'checked';
|
} else if ( input.is( 'select[multiple]' ) ) {
|
||||||
|
return input.find( 'option:selected' ).map( function () {
|
||||||
|
return $( this ).val();
|
||||||
|
} ).get();
|
||||||
} else {
|
} else {
|
||||||
return 'value';
|
return input.val();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update an input's state based on its type.
|
||||||
|
*
|
||||||
|
* @param {jQuery|Element} input
|
||||||
|
* @param {string|boolean|array|*} state
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_setInputState: function ( input, state ) {
|
||||||
|
input = $( input );
|
||||||
|
if ( input.is( ':radio, :checkbox' ) ) {
|
||||||
|
input.prop( 'checked', state );
|
||||||
|
} else if ( input.is( 'select[multiple]' ) ) {
|
||||||
|
if ( ! $.isArray( state ) ) {
|
||||||
|
state = [];
|
||||||
|
} else {
|
||||||
|
// Make sure all state items are strings since the DOM value is a string
|
||||||
|
state = _.map( state, function ( value ) {
|
||||||
|
return String( value );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
input.find( 'option' ).each( function () {
|
||||||
|
$( this ).prop( 'selected', -1 !== _.indexOf( state, String( this.value ) ) );
|
||||||
|
} );
|
||||||
|
} else {
|
||||||
|
input.val( state );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1016,9 +1047,7 @@
|
||||||
// we know if it got sanitized; if there is no difference in the sanitized value,
|
// we know if it got sanitized; if there is no difference in the sanitized value,
|
||||||
// then we do not need to touch the UI and mess up the user's ongoing editing.
|
// then we do not need to touch the UI and mess up the user's ongoing editing.
|
||||||
$inputs.each( function() {
|
$inputs.each( function() {
|
||||||
var input = $( this ),
|
$( this ).data( 'state' + updateNumber, self._getInputState( this ) );
|
||||||
property = self._getInputStatePropertyName( this );
|
|
||||||
input.data( 'state' + updateNumber, input.prop( property ) );
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if ( instanceOverride ) {
|
if ( instanceOverride ) {
|
||||||
|
@ -1071,16 +1100,15 @@
|
||||||
$inputs.each( function( i ) {
|
$inputs.each( function( i ) {
|
||||||
var $input = $( this ),
|
var $input = $( this ),
|
||||||
$sanitizedInput = $( $sanitizedInputs[i] ),
|
$sanitizedInput = $( $sanitizedInputs[i] ),
|
||||||
property = self._getInputStatePropertyName( this ),
|
|
||||||
submittedState, sanitizedState, canUpdateState;
|
submittedState, sanitizedState, canUpdateState;
|
||||||
|
|
||||||
submittedState = $input.data( 'state' + updateNumber );
|
submittedState = $input.data( 'state' + updateNumber );
|
||||||
sanitizedState = $sanitizedInput.prop( property );
|
sanitizedState = self._getInputState( $sanitizedInput );
|
||||||
$input.data( 'sanitized', sanitizedState );
|
$input.data( 'sanitized', sanitizedState );
|
||||||
|
|
||||||
canUpdateState = ( submittedState !== sanitizedState && ( args.ignoreActiveElement || ! $input.is( document.activeElement ) ) );
|
canUpdateState = ( ! _.isEqual( submittedState, sanitizedState ) && ( args.ignoreActiveElement || ! $input.is( document.activeElement ) ) );
|
||||||
if ( canUpdateState ) {
|
if ( canUpdateState ) {
|
||||||
$input.prop( property, sanitizedState );
|
self._setInputState( $input, sanitizedState );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue