/**
* A Widget to create groups of buttons
*
* @module button-group
* @since 3.5.0
*/
var CONTENT_BOX = "contentBox",
CLICK_EVENT = "click",
CLASS_NAMES = Y.ButtonCore.CLASS_NAMES;
/**
* Creates a ButtonGroup
*
* @class ButtonGroup
* @extends Widget
* @param config {Object} Configuration object
* @constructor
*/
function ButtonGroup() {
ButtonGroup.superclass.constructor.apply(this, arguments);
}
/* ButtonGroup extends Widget */
Y.ButtonGroup = Y.extend(ButtonGroup, Y.Widget, {
/**
* @method renderUI
* @description Creates a visual representation of the widget based on existing parameters.
* @public
*/
renderUI: function() {
this.getButtons().plug(Y.Plugin.Button);
},
/**
* @method bindUI
* @description Hooks up events for the widget
* @public
*/
bindUI: function() {
var group = this,
cb = group.get(CONTENT_BOX);
cb.delegate(CLICK_EVENT, group._handleClick, Y.ButtonGroup.BUTTON_SELECTOR, group);
group.after('disabledChange', group._afterDisabledChange);
},
_afterDisabledChange: function (e) {
this.getButtons().each(e.newVal
? Y.ButtonCore.prototype.disable
: Y.ButtonCore.prototype.enable
);
},
/**
* @method getButtons
* @description Returns all buttons inside this this button group
* @public
*/
getButtons: function() {
var cb = this.get(CONTENT_BOX);
return cb.all(Y.ButtonGroup.BUTTON_SELECTOR);
},
/**
* @method getSelectedButtons
* @description Returns all Y.Buttons instances that are selected
* @public
*/
getSelectedButtons: function() {
var group = this,
selected = [],
buttons = group.getButtons(),
selectedClass = ButtonGroup.CLASS_NAMES.SELECTED;
buttons.each(function(node){
if (node.hasClass(selectedClass)){
selected.push(node);
}
});
return selected;
},
/**
* @method getSelectedValues
* @description Returns the values of all Y.Button instances that are selected
* @public
*/
getSelectedValues: function() {
var selected = this.getSelectedButtons(),
values = [],
value;
Y.Array.each(selected, function(node){
value = node.getContent();
values.push(value);
});
return values;
},
/**
* @method _handleClick
* @description A delegated click handler for when any button is clicked in the content box
* @param e {Object} An event object
* @private
*/
_handleClick: function(e){
var group = this,
clickedNode = e.target.ancestor('.' + ButtonGroup.CLASS_NAMES.BUTTON, true),
type = group.get('type'),
selectedClass = ButtonGroup.CLASS_NAMES.SELECTED,
isSelected = clickedNode.hasClass(selectedClass),
buttons;
// TODO: Anything for 'push' groups?
if (type === 'checkbox') {
clickedNode.toggleClass(selectedClass, !isSelected);
/**
* @event selectionChange
* @description fires when any button in the group changes its checked status
* @param {Event} the event object. It contains an "originEvent" property
* linking to the original DOM event that triggered the selection change
*/
group.fire('selectionChange', {originEvent: e});
}
else if (type === 'radio' && !isSelected) {
buttons = group.getButtons(); // Todo: getSelectedButtons()? Need it to return an arraylist then.
buttons.removeClass(selectedClass);
clickedNode.addClass(selectedClass);
group.fire('selectionChange', {originEvent: e});
}
}
}, {
// Y.ButtonGroup static properties
/**
* The identity of the widget.
*
* @property NAME
* @type {String}
* @default 'buttongroup'
* @readOnly
* @protected
* @static
*/
NAME: 'buttongroup',
/**
* Static property used to define the default attribute configuration of
* the Widget.
*
* @property ATTRS
* @type {Object}
* @protected
* @static
*/
ATTRS: {
/**
* @attribute type
* @type String
*/
type: {
writeOnce: 'initOnly',
value: 'radio'
}
},
/**
* List of class names to use for ButtonGroups
*
* @property CLASS_NAMES
* @type {Object}
* @static
*/
CLASS_NAMES: CLASS_NAMES,
/**
* Selector used to find buttons inside a ButtonGroup
* @property BUTTON_SELECTOR
* @type {String}
*/
BUTTON_SELECTOR: "button, input[type=button], input[type=reset], input[type=submit], input[type=radio], input[type=checkbox]"
});