devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
372 lines (310 loc) • 11.7 kB
JavaScript
"use strict";
var $ = require("../../core/renderer"),
noop = require("../../core/utils/common").noop,
devices = require("../../core/devices"),
extend = require("../../core/utils/extend").extend,
registerComponent = require("../../core/component_registrator"),
Editor = require("../editor/editor"),
inkRipple = require("../widget/utils.ink_ripple"),
DataExpressionMixin = require("../editor/ui.data_expression"),
themes = require("../themes"),
CollectionWidget = require("../collection/ui.collection_widget.edit"),
ChildDefaultTemplate = require("../widget/child_default_template");
var RADIO_GROUP_CLASS = "dx-radiogroup",
RADIO_GROUP_VERTICAL_CLASS = "dx-radiogroup-vertical",
RADIO_GROUP_HORIZONTAL_CLASS = "dx-radiogroup-horizontal",
RADIO_BUTTON_CLASS = "dx-radiobutton",
RADIO_BUTTON_ICON_CLASS = "dx-radiobutton-icon",
RADIO_BUTTON_ICON_DOT_CLASS = "dx-radiobutton-icon-dot",
RADIO_VALUE_CONTAINER_CLASS = "dx-radio-value-container",
RADIO_BUTTON_CHECKED_CLASS = "dx-radiobutton-checked",
ITEM_DATA_KEY = "dxItemData",
RADIO_FEEDBACK_HIDE_TIMEOUT = 100;
var RadioCollection = CollectionWidget.inherit({
_getDefaultOptions: function _getDefaultOptions() {
return extend(this.callBase(), DataExpressionMixin._dataExpressionDefaultOptions(), {
_itemAttributes: { role: "radio" }
});
},
_supportedKeys: function _supportedKeys() {
var parent = this.callBase();
return extend({}, parent, {
enter: function enter(e) {
e.preventDefault();
return parent.enter.apply(this, arguments);
},
space: function space(e) {
e.preventDefault();
return parent.space.apply(this, arguments);
}
});
},
_focusTarget: function _focusTarget() {
return this.$element().parent();
},
_keyboardEventBindingTarget: function _keyboardEventBindingTarget() {
return this._focusTarget();
},
_refreshContent: function _refreshContent() {
this._prepareContent();
this._renderContent();
}
});
var RadioGroup = Editor.inherit({
_activeStateUnit: "." + RADIO_BUTTON_CLASS,
_getDefaultOptions: function _getDefaultOptions() {
return extend(this.callBase(), extend(DataExpressionMixin._dataExpressionDefaultOptions(), {
/**
* @name dxRadioGroupOptions.hoverStateEnabled
* @publicName hoverStateEnabled
* @type boolean
* @default true
* @inheritdoc
*/
hoverStateEnabled: true,
/**
* @name dxRadioGroupOptions.activeStateEnabled
* @publicName activeStateEnabled
* @type boolean
* @default true
* @inheritdoc
*/
activeStateEnabled: true,
/**
* @name dxRadioGroupOptions.layout
* @publicName layout
* @type Enums.Orientation
* @default "vertical"
*/
layout: "vertical",
useInkRipple: false
/**
* @name dxRadioGroupOptions.value
* @publicName value
* @ref
* @inheritdoc
*/
/**
* @name dxRadioGroupOptions.name
* @publicName name
* @type string
* @hidden false
* @inheritdoc
*/
}));
},
_defaultOptionsRules: function _defaultOptionsRules() {
return this.callBase().concat([{
device: { tablet: true },
options: {
/**
* @name dxRadioGroupOptions.layout
* @publicName layout
* @default 'horizontal' @for tablets
*/
layout: "horizontal"
}
}, {
device: function device() {
return devices.real().deviceType === "desktop" && !devices.isSimulator();
},
options: {
/**
* @name dxRadioGroupOptions.focusStateEnabled
* @publicName focusStateEnabled
* @type boolean
* @default true @for desktop
* @inheritdoc
*/
focusStateEnabled: true
}
}, {
device: function device() {
return (/android5/.test(themes.current())
);
},
options: {
useInkRipple: true
}
}]);
},
_setOptionsByReference: function _setOptionsByReference() {
this.callBase();
extend(this._optionsByReference, {
value: true
});
},
_dataSourceOptions: function _dataSourceOptions() {
return { paginate: false };
},
_init: function _init() {
this.callBase();
this._initDataExpressions();
this._feedbackHideTimeout = RADIO_FEEDBACK_HIDE_TIMEOUT;
},
_initTemplates: function _initTemplates() {
this.callBase();
this._defaultTemplates["item"] = new ChildDefaultTemplate("item", this);
},
_initMarkup: function _initMarkup() {
this.$element().addClass(RADIO_GROUP_CLASS);
this._renderSubmitElement();
this.setAria("role", "radiogroup");
this._renderRadios();
this.option("useInkRipple") && this._renderInkRipple();
this.callBase();
},
_render: function _render() {
this._renderLayout();
this.callBase();
this._updateItemsSize();
},
_renderInkRipple: function _renderInkRipple() {
this._inkRipple = inkRipple.render({
waveSizeCoefficient: 3.3,
useHoldAnimation: false,
isCentered: true
});
},
_toggleActiveState: function _toggleActiveState($element, value, e) {
this.callBase.apply(this, arguments);
if (!this._inkRipple) {
return;
}
if (value) {
this._inkRipple.showWave({
element: $element.find("." + RADIO_BUTTON_ICON_CLASS),
event: e
});
} else {
this._inkRipple.hideWave({
element: $element.find("." + RADIO_BUTTON_ICON_CLASS),
event: e
});
}
},
_renderFocusState: noop,
_renderRadios: function _renderRadios() {
var $radios = $("<div>").appendTo(this.$element());
this._radios = this._createComponent($radios, RadioCollection, {
dataSource: this._dataSource,
onItemRendered: this._itemRenderedHandler.bind(this),
onItemClick: this._itemClickHandler.bind(this),
itemTemplate: this._getTemplateByOption("itemTemplate"),
scrollingEnabled: false,
focusStateEnabled: this.option("focusStateEnabled"),
accessKey: this.option("accessKey"),
tabIndex: this.option("tabIndex"),
noDataText: ""
});
this._setCollectionWidgetOption("onContentReady", this._contentReadyHandler.bind(this));
this._contentReadyHandler();
},
_renderSubmitElement: function _renderSubmitElement() {
this._$submitElement = $("<input>").attr("type", "hidden").appendTo(this.$element());
this._setSubmitValue();
},
_setSubmitValue: function _setSubmitValue(value) {
value = value || this.option("value");
var submitValue = this.option("valueExpr") === "this" ? this._displayGetter(value) : value;
this._$submitElement.val(submitValue);
},
_getSubmitElement: function _getSubmitElement() {
return this._$submitElement;
},
_contentReadyHandler: function _contentReadyHandler() {
this.itemElements().addClass(RADIO_BUTTON_CLASS);
this._refreshSelected();
},
_itemRenderedHandler: function _itemRenderedHandler(e) {
if (e.itemData.html) {
return;
}
var $radio, $radioContainer;
$radio = $("<div>").addClass(RADIO_BUTTON_ICON_CLASS);
$("<div>").addClass(RADIO_BUTTON_ICON_DOT_CLASS).appendTo($radio);
$radioContainer = $("<div>").append($radio).addClass(RADIO_VALUE_CONTAINER_CLASS);
$(e.itemElement).prepend($radioContainer);
},
_itemClickHandler: function _itemClickHandler(e) {
this._saveValueChangeEvent(e.event);
this.option("value", this._getItemValue(e.itemData));
},
_getItemValue: function _getItemValue(item) {
return !!this._valueGetter ? this._valueGetter(item) : item.text;
},
itemElements: function itemElements() {
return this._radios.itemElements();
},
_renderLayout: function _renderLayout() {
var layout = this.option("layout");
this.$element().toggleClass(RADIO_GROUP_VERTICAL_CLASS, layout === "vertical");
this.$element().toggleClass(RADIO_GROUP_HORIZONTAL_CLASS, layout === "horizontal");
},
_refreshSelected: function _refreshSelected() {
var selectedValue = this.option("value");
this.itemElements().each(function (_, item) {
var $item = $(item);
var itemValue = this._valueGetter($item.data(ITEM_DATA_KEY));
$item.toggleClass(RADIO_BUTTON_CHECKED_CLASS, this._isValueEquals(itemValue, selectedValue));
this.setAria("checked", this._isValueEquals(itemValue, selectedValue), $item);
}.bind(this));
},
_updateItemsSize: function _updateItemsSize() {
if (this.option("layout") === "horizontal") {
this.itemElements().css("height", "auto");
} else {
var itemsCount = this.option("items").length;
this.itemElements().css("height", 100 / itemsCount + "%");
}
},
_getAriaTarget: function _getAriaTarget() {
return this.$element();
},
_setCollectionWidgetOption: function _setCollectionWidgetOption() {
this._setWidgetOption("_radios", arguments);
},
focus: function focus() {
this._radios && this._radios.focus();
},
_optionChanged: function _optionChanged(args) {
this._dataExpressionOptionChanged(args);
switch (args.name) {
case "useInkRipple":
this._invalidate();
break;
case "focusStateEnabled":
case "accessKey":
case "tabIndex":
this._setCollectionWidgetOption(args.name, args.value);
break;
case "disabled":
this.callBase(args);
this._setCollectionWidgetOption(args.name, args.value);
break;
case "dataSource":
this._setCollectionWidgetOption("dataSource");
break;
case "valueExpr":
this._refreshSelected();
break;
case "value":
this._refreshSelected();
this._setSubmitValue(args.value);
this.callBase(args);
break;
case "items":
case "itemTemplate":
case "displayExpr":
break;
case "layout":
this._renderLayout();
this._updateItemsSize();
break;
default:
this.callBase(args);
}
}
}).include(DataExpressionMixin);
registerComponent("dxRadioGroup", RadioGroup);
module.exports = RadioGroup;