PDA

View Full Version : Radio Onload Challenge



JeffBurr
22 Aug 2007, 6:45 AM
I have searched the forum for this and there are several posts, but no answer so far.

I have a form with two Ext.Radio - like so:



new Ext.form.Radio({
fieldLabel: '',
labelSeparator: ' ',
boxLabel: 'Yes',
itemCls: 'justyncheck',
id: 'SignRefs1Yes',
name: 'SignRefs1',
valueField: 'SignRefs1',
inputValue: "1"
}),
new Ext.form.Radio({
fieldLabel: '',
labelSeparator: ' ',
boxLabel: 'No',
itemCls: 'justyncheck',
id: 'SignRefs1No',
name: 'SignRefs1',
valueField: 'SignRefs1',
inputValue: "0"
})


These are part of a form that uses a "basic" JsonReader as a parameter of the form which gets loaded when the form is displayed.

This is saving the data correctly when the form is submitted but, despite many different attempts, I can not get the radio buttons to populate (check the appropriate one) from the data when the form loads.

I am using 1.1. Thanks for any help!

marco.braga
22 Aug 2007, 7:32 AM
I am just a beginner with Exp, but I've had the same problem. Basically each radio is a single widget, they aren't managed as a group, even if they return a single value when they have the same name.

Moreover I've found other problems with Radios, for example in the management of 'check' event. I've solved my problems reading this forum. No solution was complete or perfect (for me) so I had to modify the proposed solutions a bit. But thanks to everyone for the help

This is My "FixRadio.js" pack:



Ext.form.BasicForm.prototype.setValues = function(values){
if(values instanceof Array){
for(var i = 0, len = values.length; i < len; i++){
var v = values[i];
var f = this.findField(v.id);
if(f){
if ( f.getEl().dom.type == 'radio' ) {
var group = this.el.dom.elements[f.getName()];
for (var i=0; i < group.length; i++ ) {
if(group[i].__ext_field) {
group[i].__ext_field.setValue(group[i].value == v);
if(this.trackResetOnLoad){
group[i].__ext_field.originalValue = group[i].__ext_field.getValue();
}
}
}
}
else
{
f.setValue(v.value);
if(this.trackResetOnLoad){
f.originalValue = f.getValue();
}
}
}
}
}else{
var field, id;
for(id in values){
if(typeof values[id] != 'function' && (field = this.findField(id))){
if( field.getEl().dom.type == 'radio' ) {
var group = this.el.dom.elements[field.getName()];
for (var i=0; i < group.length; i++ ) {
if(group[i].__ext_field) {
group[i].__ext_field.setValue(group[i].value == values[id]);
if(this.trackResetOnLoad){
group[i].__ext_field.originalValue = group[i].__ext_field.getValue();
}
}
}
}
else
{
field.setValue(values[id]);
if(this.trackResetOnLoad){
field.originalValue = field.getValue();
}
}
}
}
}
return this;
}



Ext.form.Radio.prototype.onRender = function(ct, position) {
Ext.form.Radio.superclass.onRender.call(this, ct, position);
this.el.dom.__ext_field = this;
}

Ext.form.Radio.prototype.setValue = function(v) {
if(v === true || v === 'true' || v == '1' || v === false || v === 'false' || v == '0') {

// Select all radios of this group
var radios = this.el.up('form').select('input[type=radio]');

// Uncheck all other values
for(var i = 0; i < radios.elements.length; i++) {
if(radios.elements[i].__ext_field && radios.elements[i].__ext_field != this && radios.elements[i].name == this.el.dom.name)
{
radios.elements[i].__ext_field.checked = false;

// DOM checked is set by the browser

radios.elements[i].__ext_field.fireEvent("check", this, this.checked);
}
}

this.checked = (v === true || v === 'true' || v == '1');
if(this.el && this.el.dom) {
this.el.dom.checked = this.checked;
}
this.fireEvent("check", this, this.checked);
}
}

JeffBurr
22 Aug 2007, 9:46 AM
Very grateful for this code addition! I added it in and "boom" everything with the radios worked as they should. What a relief!

I hope that the official Ext people are aware of this need. Your code should get incorporated into the core ASAP!

Thanks again. You made my week!

marco.braga
23 Aug 2007, 1:07 AM
Well, notice that I am an expert C programmer but my knowledge with HTML, JavaScript and Ext is very, very limited (sadly Ext lacks and needs a good manual for the beginners).
Luckly the forum support is very good so previous replies guided me to the solution I've posted. Still I think that radio buttons should have a better support in Ext.

mystix
23 Aug 2007, 1:11 AM
i'd advise you to use Ext.override instead, like this


Ext.override(Ext.form.BasicForm, {
setValues : function(values){
if(values instanceof Array){
for(var i = 0, len = values.length; i < len; i++){
var v = values[i];
var f = this.findField(v.id);
if(f){
if ( f.getEl().dom.type == 'radio' ) {
var group = this.el.dom.elements[f.getName()];
for (var i=0; i < group.length; i++ ) {
if(group[i].__ext_field) {
group[i].__ext_field.setValue(group[i].value == v);
if(this.trackResetOnLoad){
group[i].__ext_field.originalValue = group[i].__ext_field.getValue();
}
}
}
}
else
{
f.setValue(v.value);
if(this.trackResetOnLoad){
f.originalValue = f.getValue();
}
}
}
}
}else{
var field, id;
for(id in values){
if(typeof values[id] != 'function' && (field = this.findField(id))){
if( field.getEl().dom.type == 'radio' ) {
var group = this.el.dom.elements[field.getName()];
for (var i=0; i < group.length; i++ ) {
if(group[i].__ext_field) {
group[i].__ext_field.setValue(group[i].value == values[id]);
if(this.trackResetOnLoad){
group[i].__ext_field.originalValue = group[i].__ext_field.getValue();
}
}
}
}
else
{
field.setValue(values[id]);
if(this.trackResetOnLoad){
field.originalValue = field.getValue();
}
}
}
}
}
return this;
}
});

Ext.override(Ext.form.Radio, {
onRender : function(ct, position) {
Ext.form.Radio.superclass.onRender.call(this, ct, position);
this.el.dom.__ext_field = this;
},

setValue : function(v) {
if(v === true || v === 'true' || v == '1' || v === false || v === 'false' || v == '0') {

// Select all radios of this group
var radios = this.el.up('form').select('input[type=radio]');

// Uncheck all other values
for(var i = 0; i < radios.elements.length; i++) {
if(radios.elements[i].__ext_field && radios.elements[i].__ext_field != this && radios.elements[i].name == this.el.dom.name)
{
radios.elements[i].__ext_field.checked = false;

// DOM checked is set by the browser

radios.elements[i].__ext_field.fireEvent("check", this, this.checked);
}
}

this.checked = (v === true || v === 'true' || v == '1');
if(this.el && this.el.dom) {
this.el.dom.checked = this.checked;
}
this.fireEvent("check", this, this.checked);
}
}
});

marco.braga
24 Aug 2007, 8:13 AM
Thanx, I'll use it!

Just to improve my knowledge: I've seen people here on the forum posting code where they set prototype instead of using override. Is there a manual or document explaining the difference (something more understandable than the override method entry in the manual)?

mystix
24 Aug 2007, 10:56 AM
Ext.override simply adds all methods in the passed config to the target object's prototype.

i.e. it's a convenience method for writing cleaner code. :)

kkbear
30 Aug 2007, 11:26 PM
Thx very much, i have :((in this problem about 2 hours....

marco.braga
31 Aug 2007, 5:11 AM
Since I've seen your interest, I have a small update to my previous code post. I've used "Ext.override" as suggested by Mystix (thanks) and updated the "setValue" function, to fix some problems I've encountered with "check" events.

Ext is fantastic, but still I don't understand why radio buttons have been ignored...

This is the new code:



Ext.override(Ext.form.BasicForm, {
setValues : function(values) {
if(values instanceof Array){
for(var i = 0, len = values.length; i < len; i++){
var v = values[i];
var f = this.findField(v.id);
if(f){
if ( f.getEl().dom.type == 'radio' ) {
var group = this.el.dom.elements[f.getName()];
for (var i=0; i < group.length; i++ ) {
if(group[i].__ext_field) {
group[i].__ext_field.setValue(group[i].value == v);
if(this.trackResetOnLoad){
group[i].__ext_field.originalValue = group[i].__ext_field.getValue();
}
}
}
}
else
{
f.setValue(v.value);
if(this.trackResetOnLoad){
f.originalValue = f.getValue();
}
}
}
}
}else{
var field, id;
for(id in values){
if(typeof values[id] != 'function' && (field = this.findField(id))){
if( field.getEl().dom.type == 'radio' ) {
var group = this.el.dom.elements[field.getName()];
for (var i=0; i < group.length; i++ ) {
if(group[i].__ext_field) {
group[i].__ext_field.setValue(group[i].value == values[id]);
if(this.trackResetOnLoad){
group[i].__ext_field.originalValue = group[i].__ext_field.getValue();
}
}
}
}
else
{
field.setValue(values[id]);
if(this.trackResetOnLoad){
field.originalValue = field.getValue();
}
}
}
}
}
return this;
}
});

Ext.override(Ext.form.Radio, {
onRender : function(ct, position) {
Ext.form.Radio.superclass.onRender.call(this, ct, position);
this.el.dom.__ext_field = this;
},

setValue : function(v) {
if(v === true || v === 'true' || v == '1' || v === false || v === 'false' || v == '0') {

// Select all radios of this group
var radios = this.el.up('form').select('input[type=radio]');

this.checked = (v === true || v === 'true' || v == '1');
if(this.el && this.el.dom) {
this.el.dom.checked = this.checked;
}

// When a radio il checked, all other radios with the same name are unchecked automatically by
// the browser, so the DOM part is done. Now we must set checked = false on the Ext object
// and fire the "check" (false) event with the correct parameters
// This cycles over all the radios...
for(var i = 0; i < radios.elements.length; i++) {
if(radios.elements[i].__ext_field && radios.elements[i].__ext_field != this && radios.elements[i].name == this.el.dom.name && radios.elements[i].__ext_field.el.dom.checked == false)
{
radios.elements[i].__ext_field.checked = false;
radios.elements[i].__ext_field.fireEvent("check", radios.elements[i].__ext_field, false);
}
}

// Lastly, we must fire the "check" (true) event on the selected radio
this.fireEvent("check", this, this.checked);
}
}
});

DigitalSkyline
5 Sep 2007, 2:59 PM
It seems to me that radios are completely broken. I've tried your fix unfortunately it didn't help. :s

I use the following code: (see comments)




dsTrackerForm.fieldset({legend:'Report Type', hideLabels:true},
new Ext.form.Radio({
name: 'rType',
id: 'rType1',
boxLabel: 'Site',
checked: true,
value: 'Site'
}),

new Ext.form.Radio({
name: 'rType',
id: 'rType2',
boxLabel: 'Network',
value: 'Network'
})
);

var statechange = function(){
var tf = Ext.ux.Callback.dsTrackerForm;

var rdo = tf.findField('rType1').getValue();
// returns true/false - not the expected 'value'
// alert(rdo);

// var rdo = tf.findField('rType').getValue();
// returns an error, rType is not an object

// the following block obviously won't work, because of the radio problems
if (rdo=='Site') {
tf.findField('report_cb4').disable();
tf.findField('report_cb3').enable();
} else if(rdo=='Network') {
tf.findField('report_cb4').enable();
tf.findField('report_cb3').disable();
};
};


// rType = dsTrackerForm.findField('rType');
// returns an error, rtype not an object

rType = dsTrackerForm.findField('rType1');
rType.addListener('focus', statechange, this);
// using focus, as 'check' returns an error, object doesn't support this method (as documented)
rType = dsTrackerForm.findField('rType2');
rType.addListener('focus', statechange, this);



Also I notice inconsistencies when I click the radio label as opposed to the radio button itself. Sometimes it triggers the event, sometimes it doesn't.

I'm assuming these are known bugs, but its been broken since its inception - any other work arounds? Spending too much time on this I thinks. /:)