diff --git a/packages/main/src/RadioButton.hbs b/packages/main/src/RadioButton.hbs
index a3f4fc6d7402..1be1cbd9b064 100644
--- a/packages/main/src/RadioButton.hbs
+++ b/packages/main/src/RadioButton.hbs
@@ -11,7 +11,7 @@
-
+
{{#if ctr._label.text}}
diff --git a/packages/main/src/RadioButton.js b/packages/main/src/RadioButton.js
index de9869d8633a..baff873cd55a 100644
--- a/packages/main/src/RadioButton.js
+++ b/packages/main/src/RadioButton.js
@@ -92,12 +92,17 @@ const metadata = {
},
/**
- * Defines the group to which the ui5-radiobutton belongs.
+ * Defines the name of the ui5-radiobutton.
+ * Radio buttons with the same name will form a radio button group.
+ * Note:
+ * The selection can be changed with ARROW_UP/DOWN and ARROW_LEFT/RIGHT keys between radios in same group.
+ * Note:
+ * Only one radio button can be selected per group.
*
* @type {string}
* @public
*/
- group: {
+ name: {
defaultValue: "",
type: String,
},
@@ -127,8 +132,8 @@ const metadata = {
* When a ui5-radiobutton is selected by the user, the
* select event is fired.
* When a ui5-radiobutton that is within a group is selected, the one
- * that was previously selected gets
- * automatically deselected.
+ * that was previously selected gets automatically deselected. You can group radio buttons by using the name property.
+ *
*
*
ES6 Module Import
*
@@ -170,24 +175,24 @@ class RadioButton extends UI5Element {
}
syncGroup() {
- const oldGroup = this._group;
- const currentGroup = this.group;
-
- if (currentGroup === oldGroup) {
- return;
- }
-
- if (oldGroup) {
- // remove the control from the previous group
- RadioButtonGroup.removeFromGroup(this, oldGroup);
- }
-
- if (currentGroup) {
- // add the control to the existing group
- RadioButtonGroup.addToGroup(this, currentGroup);
+ const oldGroup = this._name;
+ const currentGroup = this.name;
+
+ if (currentGroup !== oldGroup) {
+ if (oldGroup) {
+ // remove the control from the previous group
+ RadioButtonGroup.removeFromGroup(this, oldGroup);
+ }
+
+ if (currentGroup) {
+ // add the control to the existing group
+ RadioButtonGroup.addToGroup(this, currentGroup);
+ }
+ } else if (currentGroup) {
+ RadioButtonGroup.enforceSingleSelection(this, currentGroup);
}
- this._group = this.group;
+ this._name = this.name;
}
onclick() {
@@ -195,7 +200,7 @@ class RadioButton extends UI5Element {
}
_handleDown(event) {
- const currentGroup = this.group;
+ const currentGroup = this.name;
if (!currentGroup) {
return;
@@ -206,7 +211,7 @@ class RadioButton extends UI5Element {
}
_handleUp(event) {
- const currentGroup = this.group;
+ const currentGroup = this.name;
if (!currentGroup) {
return;
@@ -245,13 +250,13 @@ class RadioButton extends UI5Element {
return this;
}
- if (!this.group) {
+ if (!this.name) {
this.selected = !this.selected;
this.fireEvent("select");
return this;
}
- RadioButtonGroup.selectItem(this, this.group);
+ RadioButtonGroup.selectItem(this, this.name);
return this;
}
diff --git a/packages/main/src/RadioButtonGroup.js b/packages/main/src/RadioButtonGroup.js
index ebfddfdb16a1..2efb8f55197b 100644
--- a/packages/main/src/RadioButtonGroup.js
+++ b/packages/main/src/RadioButtonGroup.js
@@ -7,42 +7,55 @@ class RadioButtonGroup {
return this.groups.get(groupName);
}
+ static getSelectedRadioFromGroup(groupName) {
+ return this.selectedRadios.get(groupName);
+ }
+
static removeGroup(groupName) {
+ this.selectedRadios.delete(groupName);
return this.groups.delete(groupName);
}
- static addToGroup(control, groupName) {
+ static addToGroup(radioBtn, groupName) {
if (this.hasGroup(groupName)) {
- this.getGroup(groupName).push(control);
+ this.enforceSingleSelection(radioBtn, groupName);
+ this.getGroup(groupName).push(radioBtn);
} else {
- this.createGroup(control, groupName);
+ this.createGroup(radioBtn, groupName);
}
}
- static removeFromGroup(control, groupName) {
+ static removeFromGroup(radioBtn, groupName) {
if (!this.hasGroup(groupName)) {
return;
}
const group = this.getGroup(groupName);
+ const selectedRadio = this.getSelectedRadioFromGroup(groupName);
- // Remove the control from the given group
- group.forEach((_control, idx, arr) => {
- if (control._id === _control._id) {
+ // Remove the radio button from the given group
+ group.forEach((_radioBtn, idx, arr) => {
+ if (radioBtn._id === _radioBtn._id) {
return arr.splice(idx, 1);
}
});
+ if (selectedRadio === radioBtn) {
+ this.selectedRadios.set(groupName, null);
+ }
+
// Remove the group if it is empty
if (!group.length) {
this.removeGroup(groupName);
}
}
- static createGroup(control, groupName) {
- if (!this.hasGroup(groupName)) {
- this.groups.set(groupName, [control]);
+ static createGroup(radioBtn, groupName) {
+ if (radioBtn.selected) {
+ this.selectedRadios.set(groupName, radioBtn);
}
+
+ this.groups.set(groupName, [radioBtn]);
}
static selectNextItem(item, groupName) {
@@ -56,16 +69,7 @@ class RadioButtonGroup {
const nextItemToSelect = this._nextSelectable(currentItemPosition, group);
- // de-select all the rest
- group.forEach(radio => {
- if (radio._id !== nextItemToSelect._id) {
- radio.selected = false;
- radio.fireEvent("select", { selected: radio.selected });
- }
- });
-
- // select the next item
- this._selectItem(nextItemToSelect);
+ this.updateSelectionInGroup(nextItemToSelect, groupName);
}
static selectPreviousItem(item, groupName) {
@@ -79,81 +83,103 @@ class RadioButtonGroup {
const previousItemToSelect = this._previousSelectable(currentItemPosition, group);
- // de-select all the rest
- group.forEach(radio => {
- if (radio._id !== previousItemToSelect._id) {
- radio.selected = false;
- radio.fireEvent("select", { selected: radio.selected });
- }
- });
-
- // select the next item
- this._selectItem(previousItemToSelect);
+ this.updateSelectionInGroup(previousItemToSelect, groupName);
}
static selectItem(item, groupName) {
- const group = this.getGroup(groupName);
+ this.updateSelectionInGroup(item, groupName);
+ }
- // de-select all the rest
- group.forEach(radio => {
- if (radio._id !== item._id) {
- radio.selected = false;
- radio.fireEvent("select", { selected: radio.selected });
- }
- });
+ static updateSelectionInGroup(radioBtnToSelect, groupName) {
+ const selectedRadio = this.getSelectedRadioFromGroup(groupName);
- this._selectItem(item);
+ this._deselectRadio(selectedRadio);
+ this._selectRadio(radioBtnToSelect);
+ this.selectedRadios.set(groupName, radioBtnToSelect);
}
- static get groups() {
- if (!this._groups) {
- this._groups = new Map();
+ static _deselectRadio(radioBtn) {
+ if (radioBtn) {
+ radioBtn.selected = false;
}
- return this._groups;
}
- static _selectItem(item) {
- item.focus();
- item.selected = true;
- item.fireEvent("select", { selected: item.selected });
+ static _selectRadio(radioBtn) {
+ if (radioBtn) {
+ radioBtn.focus();
+ radioBtn.selected = true;
+ radioBtn._selected = true;
+ radioBtn.fireEvent("select");
+ }
}
static _nextSelectable(pos, group) {
const groupLength = group.length;
- let nextItemToSelect = null;
+ let nextRadioToSelect = null;
if (pos === groupLength - 1) {
if (!group[0].disabled) {
- nextItemToSelect = group[0];
+ nextRadioToSelect = group[0];
} else {
return this._nextSelectable(0, group);
}
} else if (!group[++pos].disabled) {
- nextItemToSelect = group[pos];
+ nextRadioToSelect = group[pos];
} else {
return this._nextSelectable(pos, group);
}
- return nextItemToSelect;
+ return nextRadioToSelect;
}
static _previousSelectable(pos, group) {
const groupLength = group.length;
- let previousSelectable = null;
+ let previousRadioToSelect = null;
if (pos === 0) {
if (!group[groupLength - 1].disabled) {
- previousSelectable = group[groupLength - 1];
+ previousRadioToSelect = group[groupLength - 1];
} else {
return this._previousSelectable(groupLength - 1, group);
}
} else if (!group[--pos].disabled) {
- previousSelectable = group[pos];
+ previousRadioToSelect = group[pos];
} else {
return this._previousSelectable(pos, group);
}
- return previousSelectable;
+ return previousRadioToSelect;
+ }
+
+ static enforceSingleSelection(radioBtn, groupName) {
+ const selectedRadio = this.getSelectedRadioFromGroup(groupName);
+
+ if (!selectedRadio) {
+ return;
+ }
+
+ if (radioBtn.selected) {
+ if (radioBtn !== selectedRadio) {
+ this._deselectRadio(selectedRadio);
+ this.selectedRadios.set(groupName, radioBtn);
+ }
+ } else if (radioBtn === selectedRadio) {
+ this.selectedRadios.set(groupName, null);
+ }
+ }
+
+ static get groups() {
+ if (!this._groups) {
+ this._groups = new Map();
+ }
+ return this._groups;
+ }
+
+ static get selectedRadios() {
+ if (!this._selectedRadios) {
+ this._selectedRadios = new Map();
+ }
+ return this._selectedRadios;
}
}
diff --git a/packages/main/src/RadioButtonTemplateContext.js b/packages/main/src/RadioButtonTemplateContext.js
index 629865cc19f6..1fc1a3faef1e 100644
--- a/packages/main/src/RadioButtonTemplateContext.js
+++ b/packages/main/src/RadioButtonTemplateContext.js
@@ -25,7 +25,7 @@ class RadioButtonTemplateContext {
context = {
ctr: state,
readOnly: state.disabled || state.readOnly,
- tabIndex: state.disabled || (!state.selected && state.group) ? "-1" : "0",
+ tabIndex: state.disabled || (!state.selected && state.name) ? "-1" : "0",
circle: compact ? SVGConfig.compact : SVGConfig.default,
classes: { main: mainClasses, inner: innerClasses },
styles: {
diff --git a/packages/main/test/sap/ui/webcomponents/main/pages/RadioButton.html b/packages/main/test/sap/ui/webcomponents/main/pages/RadioButton.html
index 15076f891848..a06f20e835af 100644
--- a/packages/main/test/sap/ui/webcomponents/main/pages/RadioButton.html
+++ b/packages/main/test/sap/ui/webcomponents/main/pages/RadioButton.html
@@ -34,18 +34,29 @@
ui5-radiobutton
ui5-radiobutton in group
-
-
-
+
+
+ ui5-radiobutton in group
-
-
-
+
+
+
+