PDA

View Full Version : [2.2] CheckboxGroup - Struggling with item search



ZooKeeper
14 Aug 2008, 6:35 AM
I've got a reeeeally basic layout and I cann't reference a checkbox.
Extreamly annoying.


items: [{
xtype: 'checkboxgroup',
hideLabel: true,
items:[{
boxLabel: this.strEverywhere,
name: 'cb_everywhere',
listeners: {
'check': {
fn: function(checkBox, checked){
if (!checked) return
var fields = this.findParentByType('checkboxgroup')
//this.scope.items.get(0).items.find('name', 'cb_everywhere')
Ext.each(fields, function(item){
if (item.name != 'cb_everywhere')
item.setValue('on')}
)
}
}
}
},{
boxLabel: this.strInTitle,
name: 'title',
scope: this,
listeners: this.checkAllReset
}
]}, {

No matter how i try it, it throws 'fn.call is not a function'
What is the best practice way to find a object in the items? get() works only on the index. find is really confusing and I'm not sure that's the best way.

Thanks

jsakalos
14 Aug 2008, 10:24 AM
Provided that you've given your checkbox a name and that form is variable that holds FormPanel, you should be able to get reference to the checkbox by:


var cb = form.getForm().findField('cb-name');

ZooKeeper
15 Aug 2008, 12:37 AM
Played with it a little. If i set id to the checkgroup it finds it. If i set name - no.
And it doesn't find checkboxes nested in it no matter what i specify name or id...

saJoshua
15 Aug 2008, 4:18 AM
var checkboxgroup = new Ext.FormPanel({
title: 'Checkbox Group',
width: 350,
bodyStyle:'padding:5px 5px 0',
width: 450,
items: [{
xtype: 'checkboxgroup',
hideLabel: true,
items:[{
boxLabel: 'strEverywhere',
name: 'cb_everywhere',
listeners: {
'check': {
fn: function(checkBox, checked){
if (!checked) {
return;
}
var fields = checkboxgroup.findByType(Ext.form.CheckboxGroup)[0].items.items;
Ext.each(fields, function(field){
if (field.name !== 'cb_everywhere') {
field.setValue('on');
}
})
}
}
}
},{
boxLabel: 'strInTitle',
name: 'title'
},{
boxLabel: 'strInTitle',
name: 'title 1'
},{
boxLabel: 'strInTitle',
name: 'title 2'
}]
}]
});

checkboxgroup.render(document.body);


does that help?

Joshua

jsakalos
15 Aug 2008, 5:06 AM
I've delved a bit more into it and these are my findings:



BasicForm::findField doc says: Find a Ext.form.Field in this form by id, dataIndex, name or hiddenName
Checkboxgroup extends Field therefore it is a special form field.
If you specify name for a checkboxgroup it is not found by findField (I would classify this as a bug)
The fact that you findField doesn't find individual checkboxes is annoying but I could live with it knowing that they can be accessed via checkboxgroup's items collection.

Here is my testing code:


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="./ext/resources/css/ext-all.css">
<script type="text/javascript" src="./ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="./ext/ext-all-debug.js"></script>
<title id="page-title">Checkboxgroup</title>
<script type="text/javascript">

Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif';
Ext.onReady(function() {
var form = new Ext.form.FormPanel({
renderTo:Ext.getBody()
,width:450
,height:300
,title:'Checkboxgroup'
,items:[{
xtype:'checkboxgroup'
,hideLabel:true

// specifying the name is not enough for BasicForm::findField
// to find the checkgboxgroup
,name:'cbgroup'

// if we specify id, BasicForm::findField finds the checkboxgroup
// ,id:'cbgroup'

// individual checkboxes are not found in any case - annoying
,items:[{
name:'cb1'
,id:'cb1'
,boxLabel:'Checkbox 1'
},{
name:'cb2'
,id:'cb2'
,boxLabel:'Checkbox 2'
}]
}]
,listeners:{
afterlayout:{fn:function() {
console.log(this.getForm().findField('cb1'));
console.log(this.getForm().findField('cb2'));
console.log(this.getForm().findField('cbgroup'));
}}
}
});
});
</script>
</head>
<body>
</body>
</html>
I'm moving this thread to bugs.

ZooKeeper
18 Aug 2008, 4:18 AM
Thanks for the research.

There was also some weird behavior with 'find' I was facing after 2.2 release. Cann't pinpoint what was going wrong, hope devteam will investigate this issue.

Searching checkboxes under items is a pain as well. There's no find method. The only way to go here is forEach items which is stoneage bs. I would be glad if there get could search by id or name. That'll be a lifesaver.

ZooKeeper
22 Aug 2008, 1:18 AM
Just wondering if the issue is confirmed or classified as not significant

Condor
26 Aug 2008, 7:01 AM
The fact that a BasicForm isn't able to find fields inside a checkbox group is a bug.

But it could also be argued that a checkboxgroup should act as a single field instead of multiple fields (see here (http://extjs.com/forum/showthread.php?t=39161)).

ZooKeeper
28 Aug 2008, 2:09 AM
If I can find fields nested behind form columns and fieldsets, which are also separate objects, I expect to find checkboxes behind checkboxgroup.
Anyway I can see no way it can heart anyone.

cdomigan
28 Aug 2008, 6:07 PM
If I can find fields nested behind form columns and fieldsets, which are also separate objects, I expect to find checkboxes behind checkboxgroup.
Anyway I can see no way it can heart anyone.

Yes there seems to be some confusion. Is Checkboxgroup merely a container (like Fieldset) that just makes our checkboxes look and behave nicely (while allowing access to them with form.findField() etc), or is it meant to be working as a proper Field (with all the expected setValue/getValue behaviour) and abstract out the contained checkboxes.

Currently it seems to be living up to neither definition - it's a bit of a mess.

The items property isn't documented either, I'm not sure which others are missing.

ZooKeeper
10 Sep 2008, 3:11 AM
The post is almost a month old and no one is going to investigate a COMFIRMED bug dealing with essential Ext functionality?

jsakalos
10 Sep 2008, 11:06 AM
You can escalate the priority of the issue by mailing to support@extjs.com.

biggena
16 Nov 2008, 8:53 AM
I have created following patch to BasicForm.findField()




Ext.override(Ext.form.BasicForm, {

findField : function(id){
var field = this.items.get(id);

if(!field){
// --------- It was: ---------
// //Iterate through children on first level
// this.items.each(function(f){
// if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
// field = f;
// return false;
// }
// });

// --------- It is now: ---------
// Iterate through children on all levels
var fn = function(f) {
if(field)
return false; //stop iteration, if field was found already

if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
field = f; // field was found
return false;
}
else if(f.items) {
f.items.each(fn); // iterate through child items
}
}
this.items.each(fn);
// --------- End of my changes ---------

}

return field || null;
}

});
It will allow you to access checkboxes inside group by name, not only id.
Also, this fixes a problem with loading form values via BasicForm.load() method.

streetpc
25 Mar 2009, 6:21 AM
Good, I used this patch to get Checkboxes checked on form load, in CheckboxGroups, in TabPanel :p.

Actually I added a condition to the last else if:

else if(f.items && typeof(f.items.each) == 'function' )That, to avoid errors on lazy-rendered container having lazy-instanciated elements (like in TabPanels with defferedRender left to true).
Works in 2.2 and 2.2.1.

By the way, to those who, like me, use dynamic form loading and want to check Checkboxes in CheckboxGroups used as tabs or inside a TabPanel, remember to set defferedRender to false. This took me a few minutes to figure out :-?

iBeb
26 May 2009, 9:23 AM
hi,
the problem with this solution is that your findField function returns one (the first one) of a checkboxgroup if you have that kind of group :

{
xtype : 'checkboxgroup'
,fieldLabel : ''
,anchor : '95%'
,items : [
{
columnWidth : .5
,items : [
{xtype: 'label',text: 'Travel',cls:'x-form-check-group-label',anchor:'100%'}
,{name:'type',inputValue:'t_pro',boxLabel: 'Propriétaire'}
,{name:'type',inputValue:'t_app',boxLabel: 'Contact Appartement'}
,{name:'type',inputValue:'t_pre',boxLabel: 'Prestataire Service'}
]
}
,{
columnWidth : .5
,items : [
{xtype:'label',text:'Dream',cls:'x-form-check-group-label',anchor:'100%'}
,{name:'type',inputValue:'d_equ',boxLabel: 'Equipe'}
,{name:'type',inputValue:'d_prb',boxLabel: 'Prestataire Bureau / Société'}
,{name:'type',inputValue:'d_prm',boxLabel: 'Prestataire Maintenance / Travaux'}
]
}
]
}

In this particular case, it returns this one :{name:'type',inputValue:'t_pro',boxLabel: 'Propriétaire'}

But now, if I want to setValue to the whole group (ie check every box if necessary), using this checkboxgroup override :

setValue : function(value){
console.log('CheckboxGroup.setValue('+v+')');
if(this.rendered){
this.items.each(function(item){
item.setValue(false);
},this);
if(value){
value.each(function(itemm){
this.items.each(function(item){
if(item.inputValue==itemm){item.setValue(true)}
},this);
}, this);
}
}
}

it doesn't work, because the setValue is the checkbox setValue, and not the checkboxgroup setValue

So, I still don't have a real solution for my checkbox group.
I still have to create my group with this :

this.group={blabla}
and have an "afterload" method calling

this.group.setValue(action.result.data.type);

I think it's a complex problem. For me, it comes because the conception of the checkboxgroup is between 2 things:
- is it only a "thing" that provides you layout and design capabilities : columns, headers, alignment...
- or a form component which has ONE name and where items haven't but are defined with their value, and can work with arraies

In the first case, you know that you have to manage each item individually, and set the values one by one, with a unique dataIndex.
In the second one, you know that you cannot merge different field names, but you know that you can manage the whole group as a single element.

I'm sorry if my English is weird, and I hope I've been comprehensible.

_bertrand

jsakalos
26 May 2009, 11:36 AM
What if you used findField(...).ownerCt?

(I haven't tested it, it's just an idea how to get checkboxgroup once having one of the checkboxes.)

leonardb
10 Jun 2010, 9:37 AM
Same problem still exists in 3.2.1 so I thought I'd just add my overrides here for anyone who runs into the same problem.



// add type flag to RadioGroup
Ext.override(Ext.form.RadioGroup, {
//private
isRadioGroup: true
});

// add type flag to CheckboxGroup
Ext.override(Ext.form.CheckboxGroup, {
//private
isCheckboxGroup: true
});

//Override for finding fields in checkboxgroups or radiogroups
Ext.override(Ext.BasicForm, {
findField: function(id) {
var field = this.items.get(id);

if (!Ext.isObject(field)) {
//searches for the field corresponding to the given id. Used recursively for composite fields
var findMatchingField = function(f) {
if (f.isFormField) {
if (f.dataIndex == id || f.id == id || f.getName() == id) {
field = f;
return false;
} else if (f.isComposite && f.rendered) {
return f.items.each(findMatchingField);
} else if (f.isRadioGroup && f.rendered) {
return f.items.each(findMatchingField);
} else if (f.isCheckboxGroup && f.rendered) {
return f.items.each(findMatchingField);
}
}
};

this.items.each(findMatchingField);
}
return field || null;
}
});

jsakalos
10 Jun 2010, 12:21 PM
I guess it is a good idea to post your overrides to Bugs forum so that devel team can incorporate them in core Ext, if they do not break anything.

leonardb
10 Jun 2010, 2:35 PM
@jsakalos
Apologies, I assumed this thread was already in bugs as I'd read on page one that it was being moved to Bugs. I'll repost to bugs as soon as I can put a test case together.
Leonard

jsakalos
10 Jun 2010, 2:46 PM
Aaah, I didn' mention, sorry. It's 2.x Bugs so the above are only for 2.x or also for 3.x?

leonardb
10 Jun 2010, 3:40 PM
What I posted was for 3.2.1 as the override is just a simple expansion on the std code for findField in the BasicForm class.

I've 'fixed' what I posted so that the checked radio in a radio group is returned instead of the first radio.

I've posted the test case with overrides to the 3.0 Bug forum at http://www.extjs.com/forum/showthread.php?101373-findField()-access-for-RadioGroup-and-CheckboxGroup&p=475897

Tim Toady
10 Aug 2010, 4:42 AM
Same problem still exists in 3.2.1 so I thought I'd just add my overrides here for anyone who runs into the same problem.



// add type flag to RadioGroup
Ext.override(Ext.form.RadioGroup, {
//private
isRadioGroup: true
});

// add type flag to CheckboxGroup
Ext.override(Ext.form.CheckboxGroup, {
//private
isCheckboxGroup: true
});

//Override for finding fields in checkboxgroups or radiogroups
Ext.override(Ext.BasicForm, {
findField: function(id) {
var field = this.items.get(id);

if (!Ext.isObject(field)) {
//searches for the field corresponding to the given id. Used recursively for composite fields
var findMatchingField = function(f) {
if (f.isFormField) {
if (f.dataIndex == id || f.id == id || f.getName() == id) {
field = f;
return false;
} else if (f.isComposite && f.rendered) {
return f.items.each(findMatchingField);
} else if (f.isRadioGroup && f.rendered) {
return f.items.each(findMatchingField);
} else if (f.isCheckboxGroup && f.rendered) {
return f.items.each(findMatchingField);
}
}
};

this.items.each(findMatchingField);
}
return field || null;
}
});


This works for me. My only issue now is that I have a checkbox with a name in a fieldset header that isn't found by findField when I search for the name specified in my fieldset's checkboxName property.

Edit----
I am on 3.2

Edit again----
Should it find checkboxes in fieldset headers?? They are however, submitted with other fields so I think they should be.

jlindbergh
25 Nov 2010, 3:18 AM
Thanks for the 3.2.1 Overrides, leonardb!