Some of these issues have been mentioned in other bugreports, but the implications are far more dangerous than I thought!
Most important issue:
On all browsers except IE: A click on a Checkbox or Radio fieldLabel causes the component to toggle/set checked, but the hidden input doesn't change!
On IE: Clicking a Checkbox or Radio fieldLabel does nothing.
Example:
-Click on the 'Checkbox' field label (checkbox looks checked)
-Click on the 'Radio 2' field label (radio 2 looks selected)
-Click on the Submit button
-The checkbox is unchecked and the first radio is checked!
Code:
Ext.onReady(function() {
var form = new Ext.form.FormPanel({
width: 200,
items: [{
xtype: 'checkbox',
name: 'checkbox',
fieldLabel: 'Checkbox'
},{
xtype: 'radio',
name: 'radio',
inputValue: '1',
fieldLabel: 'Radio 1',
checked: true
},{
xtype: 'radio',
name: 'radio',
inputValue: '2',
fieldLabel: 'Radio 2'
}],
buttons: [{
text: 'Submit',
handler: function() {
alert(Ext.encode(form.getForm().getValues()));
}
}],
renderTo: document.body
});
});
Other issues with checkboxes and radios:
2. On IE a disabled checkbox or radio doesn't look different (in fact all disabled images are not used).
3. The down state images are not used because the order of CSS rules is wrong.
4. The over/focused state images are not used for focus because the focusCls class is applied to the wrong element.
5. Radio tab and arrow-key handling is different than default.
6. Setting autoShow:true causes the hidden input to be visible.
7. IE 6 doesn't and FF3 and IE8b2 do show a focus rectangle on the label (in contrast to Ext 2.1).
8. Clicking on a checkbox/radio doesn't fire focus and blur events.
9. boxLabel is not sized correctly.
Suggested fix for all issues:
Note: This fix does not include validation support (see here).
Code:
Ext.override(Ext.form.Checkbox, {
onRender: function(ct, position){
Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
if(this.inputValue !== undefined){
this.el.dom.value = this.inputValue;
}
//this.el.addClass('x-hidden');
this.innerWrap = this.el.wrap({
//tabIndex: this.tabIndex,
cls: this.baseCls+'-wrap-inner'
});
this.wrap = this.innerWrap.wrap({cls: this.baseCls+'-wrap'});
this.imageEl = this.innerWrap.createChild({
tag: 'img',
src: Ext.BLANK_IMAGE_URL,
cls: this.baseCls
});
if(this.boxLabel){
this.labelEl = this.innerWrap.createChild({
tag: 'label',
htmlFor: this.el.id,
cls: 'x-form-cb-label',
html: this.boxLabel
});
}
//this.imageEl = this.innerWrap.createChild({
//tag: 'img',
//src: Ext.BLANK_IMAGE_URL,
//cls: this.baseCls
//}, this.el);
if(this.checked){
this.setValue(true);
}else{
this.checked = this.el.dom.checked;
}
this.originalValue = this.checked;
},
afterRender: function(){
Ext.form.Checkbox.superclass.afterRender.call(this);
//this.wrap[this.checked ? 'addClass' : 'removeClass'](this.checkedCls);
this.imageEl[this.checked ? 'addClass' : 'removeClass'](this.checkedCls);
},
initCheckEvents: function(){
//this.innerWrap.removeAllListeners();
this.innerWrap.addClassOnOver(this.overCls);
this.innerWrap.addClassOnClick(this.mouseDownCls);
this.innerWrap.on('click', this.onClick, this);
//this.innerWrap.on('keyup', this.onKeyUp, this);
},
onFocus: function(e) {
Ext.form.Checkbox.superclass.onFocus.call(this, e);
//this.el.addClass(this.focusCls);
this.innerWrap.addClass(this.focusCls);
},
onBlur: function(e) {
Ext.form.Checkbox.superclass.onBlur.call(this, e);
//this.el.removeClass(this.focusCls);
this.innerWrap.removeClass(this.focusCls);
},
onClick: function(e){
if (e.getTarget().htmlFor != this.el.dom.id) {
if (e.getTarget() !== this.el.dom) {
this.el.focus();
}
if (!this.disabled && !this.readOnly) {
this.toggleValue();
}
}
//e.stopEvent();
},
onEnable: Ext.form.Checkbox.superclass.onEnable,
onDisable: Ext.form.Checkbox.superclass.onDisable,
onKeyUp: undefined,
setValue: function(v) {
var checked = this.checked;
this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
if(this.rendered){
this.el.dom.checked = this.checked;
this.el.dom.defaultChecked = this.checked;
//this.wrap[this.checked ? 'addClass' : 'removeClass'](this.checkedCls);
this.imageEl[this.checked ? 'addClass' : 'removeClass'](this.checkedCls);
}
if(checked != this.checked){
this.fireEvent("check", this, this.checked);
if(this.handler){
this.handler.call(this.scope || this, this, this.checked);
}
}
},
getResizeEl: function() {
//if(!this.resizeEl){
//this.resizeEl = Ext.isSafari ? this.wrap : (this.wrap.up('.x-form-element', 5) || this.wrap);
//}
//return this.resizeEl;
return this.wrap;
}
});
Ext.override(Ext.form.Radio, {
checkedCls: 'x-form-radio-checked'
});
with:
Code:
<style type="text/css">
.x-form-check-group .x-form-check-wrap,.x-form-radio-group .x-form-radio-wrap{height:auto;}
.ext-ie .x-form-check-group .x-form-check-wrap,.ext-ie .x-form-radio-group .x-form-radio-wrap{height:auto;}
.x-form-check-wrap,.x-form-radio-wrap{padding:1px 0 3px;line-height:18px;}
.ext-ie .x-form-check-wrap,.ext-ie .x-form-radio-wrap{padding-top:3px;}
.ext-strict .ext-ie7 .x-form-check-wrap,.ext-strict .ext-ie7 .x-form-radio-wrap{padding-bottom:1px;}
.x-form-check-wrap-inner,.x-form-radio-wrap-inner{display:inline;padding:0;}
.x-form-check,.x-form-radio{height:13px;width:13px;vertical-align:bottom;margin:2px 0;}
.ext-ie .x-form-check,.ext-ie .x-form-radio{margin-top:1px;}
.ext-strict .ext-ie7 .x-form-check,.ext-strict .ext-ie7 .x-form-radio{margin-bottom:4px;}
.ext-opera .x-form-check,.ext-opera .x-form-radio{margin-top:3px;}
.x-form-check-focus .x-form-check,.x-form-check-over .x-form-check,.x-form-check-focus .x-form-radio,.x-form-check-over .x-form-radio{background-position:-13px 0;}
.x-form-check-down .x-form-check,.x-form-check-down .x-form-radio{background-position:-26px 0;}
.x-item-disabled .x-form-check,.x-item-disabled .x-form-radio{background-position:-39px 0;}
.x-form-check-checked,.x-form-radio-checked{background-position:0 -13px;}
.x-form-check-focus .x-form-check-checked,.x-form-check-over .x-form-check-checked,.x-form-check-focus .x-form-radio-checked,.x-form-check-over .x-form-radio-checked{background-position:-13px -13px;}
.x-form-check-down .x-form-check-checked,.x-form-check-down .x-form-radio-checked{background-position:-26px -13px;}
.x-item-disabled .x-form-check-checked,.x-item-disabled .x-form-radio-checked{background-position:-39px -13px;}
.x-form-check-wrap-inner input,.x-form-radio-wrap-inner input{position:absolute;-ms-filter:"alpha(opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;}
</style>
Tested: IE 6/7/8b2, Firefox 3.0.3, Safari 3.1.2 and Opera 9.52 on Windows XP SP3.
ps.
To enhance the visibility of focused state it might be better to add special focused images that show a dotted line around the checkbox/radio.
Actually, IE8b2 does show a focus rectangle, but IMHO that is a bug in IE8!