I put something like this together a little while ago with help for 3.4. Its by no means perfect, but it may be of use to someone as a start...
js:
Code:
//handles onclicks and fires a before edit check event
//add suppress check event on set value
//checkbox validation with vtypes
//adds the styles, qtips and checkbox mark/clear invalid
Ext.override(Ext.form.Checkbox, {
// private
initComponent : function(){
Ext.form.Checkbox.superclass.initComponent.call(this);
this.addEvents(
/**
* @event check
* Fires when the checkbox is checked or unchecked.
* @param {Ext.form.Checkbox} this This checkbox
* @param {Boolean} checked The new checked value
*/
'check',
'beforeedit'
);
},
// private
initEvents : function(){
Ext.form.Checkbox.superclass.initEvents.call(this);
this.mon(this.el, {
scope: this,
click: this.onClick,
change: this.onChange
});
},
onClick: function (e,o)
{
//don't do anything on click because onChange fired at same time, so do all handling through there
},
onChange: function (e,o)
{
var initStartValue = o.startValue;
if (this.readOnly === true && !this.isXType('radio', true))
{
e.preventDefault();
this.reset();
return false;
}
if((this.fireEvent('beforeedit', this, o)) !== false)
{
if(this.el.dom.checked != this.checked)
{
this.setValue(this.el.dom.checked);
return true;
}
}
initStartValue = o.startValue;
this.setValue(initStartValue);
return false;
},
setValue : function(v, suppressCheckEvent){
if(suppressCheckEvent == null)
{
suppressCheckEvent = false;
}
var checked = this.checked,
inputVal = this.inputValue;
if (v === false) {
this.checked = false;
} else {
this.checked = (v === true || v === 'true' || v == '1' || (inputVal ? v == inputVal : String(v).toLowerCase() == 'on'));
}
if(this.rendered){
this.el.dom.checked = this.checked;
this.el.dom.defaultChecked = this.checked;
}
if(checked != this.checked){
if(suppressCheckEvent !== true)
{
this.fireEvent('check', this, this.checked);
}
if(this.handler){
this.handler.call(this.scope || this, this, this.checked);
}
}
return this;
},
//this adds the styles, qtips and checkbox validation
preventMark: false,
onRender : function(ct, position){
Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
if(this.inputValue !== undefined){
this.el.dom.value = this.inputValue;
}
this.wrap = this.el.wrap({cls: 'x-form-check-wrap'});
if(this.boxLabel){
this.childLabel = this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
}
if(this.checked){
this.setValue(true);
}else{
this.checked = this.el.dom.checked;
}
if (Ext.isIE && !Ext.isStrict) {
this.wrap.repaint();
}
this.resizeEl = this.positionEl = this.wrap;
},
markInvalid : function(msg){
if (this.rendered && !this.preventMark) {
msg = msg || this.invalidText;
var mt = this.getMessageHandler();
if(this.msgTarget){
this.wrap.addClass(this.invalidClass);
if(this.msgTarget == 'qtip')
{
Ext.QuickTips.register({
target: this.wrap,
text: msg,
cls: "x-tip x-form-invalid-tip"
});
if(this.childLabel)
{
Ext.QuickTips.register({
target: this.childLabel,
text: msg,
cls: "x-tip x-form-invalid-tip"
});
}
}
}
}
this.setActiveError(msg);
},
clearInvalid : function(){
if (this.rendered && !this.preventMark) {
this.wrap.removeClass(this.invalidClass);
if(this.msgTarget){
if(this.msgTarget == 'qtip') {
Ext.QuickTips.unregister(this.wrap);
Ext.QuickTips.unregister(this.childLabel);
}
}
}
this.unsetActiveError();
},
//this is for vtype validation and errors
vtype : null,
getErrors: function(value) {
var errors = Ext.form.Checkbox.superclass.getErrors.apply(this, arguments);
value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());
if (Ext.isFunction(this.validator)) {
var msg = this.validator(value);
if (msg !== true) {
errors.push(msg);
}
}
if (value.length < 1 || value === this.emptyText) {
if (this.allowBlank) {
//if value is blank and allowBlank is true, there cannot be any additional errors
return errors;
} else {
errors.push(this.blankText);
}
}
if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) { // if it's blank
errors.push(this.blankText);
}
if (this.vtype) {
console.log('into vtype test');
var vt = Ext.form.VTypes;
if(!vt[this.vtype](value, this)){
errors.push(this.vtypeText || vt[this.vtype +'Text']);
}
}
if (this.regex && !this.regex.test(value)) {
errors.push(this.regexText);
}
return errors;
}
});
css:
Code:
/*
This fixes the checkbox validation styles for checkbox group
*/
.x-form-check-group .x-column {
overflow: visible;
margin-right: 3px;
}