/* by: Daniel Barreiro (aka Satyam) * based on Anthony Pipkin's at: * http://www.assembla.com/code/yui/git/nodes/yui3-gallery/src/gallery-button/js/button.js?rev=master */ /*jslint browser: true, nomen: true, maxerr: 50, indent: 4 */ /*global YUI */ /** * Provides a container to group buttons. * It can hold instances of Y.Button, Y.ButtonToggle or Y.ButtonSeparator. * @module button-group */ YUI.add('button-group', function (Y) { "use strict"; var Lang = Y.Lang, BBX = 'boundingBox', EVENT_PRESS = 'press', LABEL = 'label'; /** * The ButtonSeparator class provides a passive divider to use in between groups of buttons * @class ButtonSeparator * @extends Y.Widget * @constructor */ Y.ButtonSeparator = Y.Base.create( 'button-separator', Y.Widget, [], { /** * Overrides the standard bounding box template to produce a <span> * @property BOUNDING_TEMPLATE * @type String */ BOUNDING_TEMPLATE: '' }, { } ); /** * The ButtonGroup class provides a container for sets of Buttons. * All buttons added will be extended with Y.WidgetChild. * @class ButtonGroup * @extends Y.Widget * @uses Y.WidgetParent, Y.Makenode * @constructor * @param cfg {object} Configuration attributes */ Y.ButtonGroup = Y.Base.create( 'button-group', Y.Widget, [Y.WidgetParent,Y.MakeNode], { /** * Overrides the standard bounding box template to produce a <fieldset> * @property BOUNDING_TEMPLATE * @type String */ BOUNDING_TEMPLATE: '
', /** * Sets the listener for the addChild event to extend children with Y.WidgetChild. * Publishes thepress
event
*/
initializer: function () {
this.on('addChild', function (ev) {
var child = ev.child,
WC = Y.WidgetChild;
if (child) {
if (child instanceof Y.Button || child instanceof Y.ButtonSeparator) {
if (!child.ancestor) {
Y.augment(child, WC);
child.addAttrs(child._protectAttrs(WC.ATTRS));
WC.constructor.apply(child);
}
} else {
ev.preventDefault();
}
}
});
this.publish(EVENT_PRESS);
},
/**
* Sets listeners for the press event of child buttons, see _onButtonPress.
* @method bindUI
*/
bindUI : function() {
this.on(['button:press','button-toggle:press'], this._onButtonPress ,this);
},
/**
* Processes the press event of child Buttons to enforce the _alwaysSelected attribute,
* and to propagate the press event
* @method _onButtonPress
* @param ev {EventFacade}
* @private
*/
_onButtonPress: function(ev) {
if(this.get('alwaysSelected')) {
var selection = this.get('selection'),
button = ev.target;
if(selection === button || // selection is the button OR
(
selection instanceof Y.ArrayList && // selection is an array AND
selection.size() === 1 && // there is only one item AND
selection.item(0) === button // that one item is the button
)
) {
ev.preventDefault();
return;
}
}
this.fire(EVENT_PRESS, {pressed: ev.target});
},
/**
* Sets the label of the container from the value of the label configuration attribute.
* Creates the <legend> element to hold it if it does not exists.
* @method _uiSetLabel
* @param value {String} text to be shown
* @private
*/
_uiSetLabel: function (value) {
if (!this._labelNode) {
this.get(BBX).prepend(this._makeNode());
this._locateNodes();
}
this._labelNode.setContent(value);
}
}, {
/**
* Template for the <legend> element to hold the label. Used by MakeNode.
* @property Y.ButtonGroup._TEMPLATE
* @type String
* @static
* @protected
*/
_TEMPLATE: '',
/**
* Creates the label className key to be used in the template
* @property Y.ButtonGroup._CLASS_NAMES
* @type [Strings]
* @static
* @protected
*/
_CLASS_NAMES: [LABEL],
/**
* Hooks up _uiSetLabel to respond to changes in the label attribute.
* @property Y.ButtonGroup._ATTRS_2_UI
* @type Object
* @static
* @protected
*/
_ATTRS_2_UI: {
BIND: LABEL,
SYNC: LABEL
},
ATTRS : {
/**
* Holds the label for this group of buttons
* @attribute label
* @type String
* @default ""
*/
label : {
value:'',
validator : Lang.isString
},
/**
* Defines the default type of child to be contained in this group.
* Used by WidgetParent to create the default children
* @attribute defaultChildType
* @type object
* @default Y.Button
*/
defaultChildType : {
value : Y.Button
},
/**
* Forces this group to always have at least one toggle button selected
* @attribute alwaysSelected
* @type Boolean
* @default false
*/
alwaysSelected : {
value : false,
validator: Lang.isBoolean
}
}
}
);
}, '0.9', {
requires: ['base-build','widget', 'makenode', 'widget-parent','widget-child', 'button'],
skinnable: true
});