-
Notifications
You must be signed in to change notification settings - Fork 186
/
Copy path_RadioButtonMixin.js
112 lines (96 loc) · 3.28 KB
/
_RadioButtonMixin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
define([
"dojo/_base/array", // array.forEach
"dojo/_base/declare", // declare
"dojo/dom-attr", // domAttr.set
"dojo/_base/lang", // lang.hitch
"dojo/query!css2", // query
"../registry" // registry.getEnclosingWidget
], function(array, declare, domAttr, lang, query, registry){
// module:
// dijit/form/_RadioButtonMixin
return declare("dijit.form._RadioButtonMixin", null, {
// summary:
// Mixin to provide widget functionality for an HTML radio button
// type: [private] String
// type attribute on `<input>` node.
// Users should not change this value.
type: "radio",
_getRelatedWidgets: function(){
// Private function needed to help iterate over all radio buttons in a group.
var ary = [];
query("input[type=radio]", this.focusNode.form || this.ownerDocument).forEach(// can't use name= since query doesn't support [] in the name
lang.hitch(this, function(inputNode){
if(inputNode.name == this.name && inputNode.form == this.focusNode.form){
var widget = registry.getEnclosingWidget(inputNode);
if(widget){
ary.push(widget);
}
}
})
);
return ary;
},
_setCheckedAttr: function(/*Boolean*/ value){
// If I am being checked then have to deselect currently checked radio button
this.inherited(arguments);
if(!this._created){
return;
}
if(value){
array.forEach(this._getRelatedWidgets(), lang.hitch(this, function(widget){
if(widget != this && widget.checked){
widget.set('checked', false);
}
}));
}
},
_getSubmitValue: function(/*String*/ value){
return value == null ? "on" : value;
},
_onClick: function(/*Event*/ e){
if(this.checked || this.disabled){ // nothing to do
e.stopPropagation();
e.preventDefault();
return false;
}
if(this.readOnly){ // ignored by some browsers so we have to resync the DOM elements with widget values
e.stopPropagation();
e.preventDefault();
array.forEach(this._getRelatedWidgets(), lang.hitch(this, function(widget){
domAttr.set(this.focusNode || this.domNode, 'checked', widget.checked);
}));
return false;
}
// RadioButton has some unique logic since it must enforce only a single button being checked at once
// For this reason the "_onClick" method does not call this.inherited
var canceled = false;
var previouslyCheckedButton;
array.some(this._getRelatedWidgets(), function(radioButton){
if(radioButton.checked){
previouslyCheckedButton = radioButton;
return true;
}
return false;
});
// We want to set the post-click values correctly for any event handlers, but since
// the event handlers could revert them, we don't want to fully update the widget state
// yet and trigger notifications
this.checked = true;
previouslyCheckedButton && (previouslyCheckedButton.checked = false);
// Call event handlers
// If event handler prevents it, the clicked radio button will not be checked
if(this.onClick(e) === false || e.defaultPrevented){
canceled = true;
}
// Reset internal state to how it was before the click
this.checked = false;
previouslyCheckedButton && (previouslyCheckedButton.checked = true);
if(canceled){
e.preventDefault();
}else{
this.set('checked', true);
}
return !canceled;
}
});
});