Widget: Allow setting individual properties of deep options. Fixes #7035 - Widget: Extend .option() to set partial nested options.

This commit is contained in:
Scott González 2011-03-24 09:21:53 -04:00
parent a2015497fc
commit 6fc98deef0
2 changed files with 42 additions and 3 deletions

View File

@ -441,6 +441,30 @@ test( ".option() - delegate to ._setOption()", function() {
], "_setOption called with multiple options" );
});
test( ".option() - deep option setter", function() {
$.widget( "ui.testWidget", {} );
var div = $( "<div>" ).testWidget();
function deepOption( from, to, msg ) {
div.data( "testWidget" ).options.foo = from;
$.ui.testWidget.prototype._setOption = function( key, value ) {
same( key, "foo", msg + ": key" );
same( value, to, msg + ": value" );
};
}
deepOption( { bar: "baz" }, { bar: "qux" }, "one deep" );
div.testWidget( "option", "foo.bar", "qux" );
deepOption( null, { bar: "baz" }, "null" );
div.testWidget( "option", "foo.bar", "baz" );
deepOption(
{ bar: "baz", qux: { quux: "quuux" } },
{ bar: "baz", qux: { quux: "quuux", newOpt: "newVal" } },
"add property" );
div.testWidget( "option", "foo.qux.newOpt", "newVal" );
});
test( ".enable()", function() {
expect( 2 );
$.widget( "ui.testWidget", {

View File

@ -208,20 +208,35 @@ $.Widget.prototype = {
},
option: function( key, value ) {
var options = key;
var options = key,
parts,
curOption,
i;
if ( arguments.length === 0 ) {
// don't return a reference to the internal hash
return $.extend( {}, this.options );
}
if (typeof key === "string" ) {
if ( typeof key === "string" ) {
if ( value === undefined ) {
return this.options[ key ];
}
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
options = {};
parts = key.split( "." );
key = parts.shift();
if ( parts.length ) {
curOption = options[ key ] = $.extend( true, {}, this.options[ key ] );
for ( i = 0; i < parts.length - 1; i++ ) {
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
curOption = curOption[ parts[ i ] ];
}
curOption[ parts.pop() ] = value;
} else {
options[ key ] = value;
}
}
this._setOptions( options );