CheckBox Group disappears when I set an id on it - checkbox

I'm trying to make a simple toolbar in ExtJS containing a checkbox group and a button and it works just fine but when I try to give an id to my check box group the whole toolbar doesn't display anymore.
Here is my code:
Ext.define
(
'CMS.view.TreeGrid.Filters',
{
extend: 'Ext.form.Panel',
title: 'Filters',
layout: 'fit',
alias: 'widget.filters',
bodyPadding: 10,
renderTo: Ext.getBody(),
vtype: 'hbox',
items :
[
{
xtype: 'toolbar',
vtype: 'vbox',
items:
[
{
xtype: 'checkboxgroup',
//id: 'propertiesCBG',
fieldLabel: 'Properties',
vertical: true,
layout: 'fit',
items:
[
{ boxLabel: 'id', name: 'rb', inputValue: '1' },
{ boxLabel: 'State', name: 'rb', inputValue: '2', checked: true },
{ boxLabel: 'headline', name: 'rb', inputValue: '3' },
{ boxLabel: 'severity', name: 'rb', inputValue: '4' },
{ boxLabel: 'country', name: 'rb', inputValue: '5' },
{ boxLabel: 'hasRelated', name: 'rb', inputValue: '6' }
]
},
{
xtype: 'button',
text: 'Request',
id: 'requestButton',
},
]
}
]
}
);
When the line "id: propertiesCGB" is commented i don't have any problem and the toolbar displays like I want it to display but I need an id for my checkbox group to get its values on my controller.
Please help me, I just can't understand what the problem is.

In general it is a bad practice to use the id property. If you must have some sort of id, use itemId, which will not have any type of global uniqueness constraint and also allow you to use # in your selector.
People generally use ids to make it easy to get a reference to a component, something like:
Ext.ComponentQuery.query('#myid');
What you should really be doing is:
Ext.ComponentQuery.query('filters checkboxgroup')
in order to get a reference to your checkboxgroup.
In your case, change the selector in your controller to be 'filters checkboxgroup' and you should be just fine. Note, if you have more than one of these in your application, add more specificity to your selector, for instance, if your filters component is a child of a particular panel:
Ext.ComponentQuery.query('panel1 filters checkboxgroup')

have you tried changing the id to something else temporarily to confirm you don't have a duplicate elsewhere in your project?
xtype: 'checkboxgroup',
id: 'propertiesCBG_temp',
fieldLabel: 'Properties',
I've seen similar behavior when having two components with the same id.

Finally, it appeared that I called my toolbar in two different views so I guess this created the conflict with the ID. I'll find another way to reuse my toolbar.

Related

Composite components

I'd like to create a component which combines other existing components. A simplified example is below:
Ext.define('CCC.ThreeNames', {
extend: '???',
alias: 'widget.threenames',
items: [
{
xtype: 'textfield',
label: 'First',
itemId: 'first',
name: 'first'
},
{
xtype: 'textfield',
label: 'Middle',
itemId: 'middle',
name: 'middle'
},
{
xtype: 'textfield',
label: 'Last',
itemId: 'last',
name: 'last'
}
]
});
So let's say I want to use it:
items: [
{
xtype: 'threenames',
itemId: 'applicant',
name: 'applicant'
},
{
xtype: 'threenames',
itemId: 'dependent',
name: 'dependent'
}
]
First of all, what do I extend ??? from? I was thinking xtype: 'fieldset', but this type isn't considered a form field, so instead when you're pulling data via getValues, it skips the fieldset and iterates down to the text fields. The text fields don't "know" their context, because that's in the parent element, so they just report as first, middle and last, and now there are duplicate fields in the data set.
I was thinking during initialization, maybe the parent component munges the name and prefixes them with its own name, e.g. first, middle, last to applicant.first, applicant.middle, applicant.last, etc. but then that's going to muck up any code in the components that uses the name for whatever.
How to handle this? We'd really like to be able to reuse some complex composite components so that our designers don't have to hand code them all the time, and have the component work as an independent unit to save and retrieve data, so for example form.getValues() pulls out the data, without knowing anything about the composite component.
Would really appreciate a solution to this.
Regarding the possible duplicate suggested by Coderino Javarino: This question is not a duplicate of that one. That component is able to work using a single value for both fields, i.e. the date field interprets the value as a date, the time field interprets the value as a time. In effect it's really just a single component with a custom display type.
Naming fields requested way is a simple task:
Ext.define('CCC.ThreeNames', {
extend: 'Ext.container.Container', //you can use Ext.form.Panel for additional functionality
alias: 'widget.threenames',
items: [
{ xtype: 'textfield', itemId: 'first', name: 'first', fieldLabel: 'First' },
{ xtype: 'textfield', itemId: 'middle', name: 'middle', fieldLabel: 'middle' },
{ xtype: 'textfield', itemId: 'last', name: 'last', fieldLabel: 'last' },
],
listeners: {
beforerender: function() {
let self = this;
this.query('textfield').forEach(function(field){
field.name = self.name + '.' + field.name;
field.itemId = field.name;
});
}
}
});
using such naming is completely different thing. But as I understood from your comment that MVC pattern is not in use then this solutions should give expected result.
Here is the recommended way to achieve what you want
Ext.define('CCC.ThreeNames', {
extend: '???',
**xtype: 'threenames',**
alias: 'widget.threenames',
items: [
{
xtype: 'textfield',
label: 'First',
itemId: 'first',
name: 'first'
},
{
xtype: 'textfield',
label: 'Middle',
itemId: 'middle',
name: 'middle'
},
{
xtype: 'textfield',
label: 'Last',
itemId: 'last',
name: 'last'
}
]});
Now you can use it like this
items: [
{
xtype: 'threenames',
itemId: 'applicant',
name: 'applicant'
},
{
xtype: 'threenames',
itemId: 'dependent',
name: 'dependent'
}
]

ExtJs: How to get parent tab of control

I am currently working on ExtJs and I am stuck at a place where I want to iterate through all components and find the parent tab of each component.
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('Ext.tab.Panel', {
width: 300,
height: 200,
activeTab: 0,
items: [
{
title: 'Tab 1',
bodyPadding: 10,
items : [{
xtype: 'fieldset',
itemId: 'fieldsetId',
items: [{
xtype: 'checkbox',
fieldLabel: 'Check 1'
},{
xtype: 'checkbox',
fieldLabel: 'Check 2'
},{
fieldLabel: 'Combo 1',
xtype: 'combobox',
store: ['value1','value2','value3']
}]
},
{
xtype: 'button',
text: 'Reset',
}]
},
{
title: 'Tab 2',
html : 'Another one',
items: [{
xtype: 'button',
text: 'Test',
}]
}
],
renderTo : Ext.getBody()
});
}
});
In above code, when I iterate through all components and log name of the parent tab whether it is Tab 1 or Tab 2
Whenever you are iterating through all the components, just do
field.up().up()
where field is the component of your tab and above statement will return you the parent tabpanel and so with
field.up().up().title
will return you "Tab 1"
In the same way for tab 2 components it will be
field.up() only.
If you have only one loop or something to go through all components then you can put a condition that
if(field.up()) returns you the panel then read it\'s title
else do field.up().up() and then read the title.
I hope this solves you issue.
You can use , field.up('tabPanel') to get the reference of the tabPanel, and then from the reference you can get name,title for the tabPanel

Prevent page reload on form field press enter in ExtJS

I have a problem with ExtJS modern toolkit's Form component.
I create a form with no buttons (you can test it in sencha fiddle). The only button is in the titlebar and it isn't working at the moment.
The problem is :
Form submission on pressing Enter. My form is empty, default method is POST, but my page is reloading when I press Enter while the focus is on any of my fields. Url address string in browser complemented form field names, but the form's method is POST.
Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
requires: [
'Ext.form.FieldSet',
'Ext.field.Text',
'Ext.field.TextArea',
'Ext.TitleBar'
],
items: [{
xtype: 'titlebar',
docked: 'top',
title: 'Searching',
items: [{
iconCls: 'fa fa-search',
iconAlign: 'right',
text: 'Search',
align: 'right',
handler: function() {
//
}
}]
}, {
xtype: 'fieldset',
border: false,
shadow: 'true',
defaults: {
value: ''
},
items: [{
xtype: 'numberfield',
label: 'Some ID',
allowBlank: true,
name: 'id'
},
{
xtype: 'textfield',
label: 'Some Article',
name: 'article'
}
]
}]
});
How to prevent page reloading?
I've never seen this behaviour in ExtJS form's by default.
Just replace id with something else could be Id in field name, it is conflicting with Ext id property
{
xtype: 'numberfield',
label: 'Some ID',
allowBlank: true,
name: 'Id'
},

How do I add a custom xtype to another view?

I have two views and I want one to be nested inside the other, like a partial view. My two views are as follows:
ChemicalRisksView.js
Ext.define('HandSurvey.view.ChemicalRisksView', {
extend: 'Ext.form.Panel',
xtype: 'chemicalrisksview',
requires: [
'Ext.form.FieldSet',
'Ext.field.Text',
'Ext.Button',
'HandSurvey.view.SpecificChemicalView'
],
config: {
items:[{
xtype: 'fieldset',
title: 'Fiberglass & Resins',
items: [
{
name: 'test',
xtype: 'specificchemicalview'
},
{
xtype: 'button',
text: 'Save',
action: 'saveChemicalRisks',
margin: '10 5',
ui: 'confirm'
}
]
}]
}
});
SpecificChemicalView.js
Ext.define('HandSurvey.view.SpecificChemicalView', {
extend: 'Ext.form.Panel',
xtype: 'specificchemicalview',
requires: [
'Ext.form.FieldSet',
'Ext.field.Toggle',
'Ext.field.Select',
'Ext.field.Text',
'Ext.Button'
],
config: {
items:[{
xtype: 'fieldset',
title: 'Edit Specific Chemical',
items: [
{
name: 'name',
xtype: 'textfield',
label: 'Name'
},
{
name: 'model',
xtype: 'textfield',
label: 'Model #'
},
{
name: 'manufacturer',
xtype: 'textfield',
label: 'Manufacturer'
},
{
name: 'averageExposure',
xtype: 'textfield',
label: 'Average Exposure Time'
},
{
name: 'msdsOnFile',
xtype: 'checkboxfield',
label: 'MSDS On File'
},
{
name: 'additionalInfo',
xtype: 'textfield',
label: 'Additional Info'
},
{
xtype: 'button',
text: 'Save Chemical',
action: 'saveChemical',
margin: '10 5',
ui: 'confirm'
}
]
}]
}
});
So I have defined the xtype as specificchemicalview and added it to the items in the 'parent' view. But, nothing happens. It just shows nothing in the ChemicalRisksView. I am debugging in Chrome and there are no error messages.
I am using this same method to add all my views to my main navigation view and that works fine. What am I missing here?
In HTML, form cannot contain another form. Although it could work in Ext as it does not use <form> tag, I do not think it is a good idea. Form is designed to contain form fields (isFormField:true) that another form is definitely not one.
I would consider a re-design where the "specific view" would extend FieldSet adding necessary form fields as its items.
That should solve the problem.

Extjs radiogroup fieldLabel not displaying inside panel

I am using ExtJs 2.3.0.
I have a panel and inside it a radiogroup as follows
var testPanel = {
xtype: 'panel',
border: false,
items: [
{ fieldLabel: 'Please select ',
xtype: 'radiogroup',
id: 'id1',
columns: 2,
vertical: false
}
],
items: [
{ boxLabel: 'Yes', name: 'yes', inputValue: 'Yes', xtype: 'radio'},
{ boxLabel: 'No', name: 'no', inputValue: 'No', xtype: 'radio' }
]
}
The issue is-
The fieldLabel 'Please select' of radioBox is not displaying. I am able to see 'Yes'/ 'No' radiobuttons.
When I change xtype of testPanel to 'form', the label displays.
However, I can't use 'form' xtype. I want to use 'Panel' only.
Please let me know why the fieldLabel is not diaplying inside panel and any workaround for this.
For one thing, the individual radio buttons must be items of the radio group. Here, you've got the items keys that is duplicated in your config object, meaning you actually end up with 2 radios in your panel, but no radio group.
Then, simple panels do not have support for displaying labels. You must use a form panel for that.
Finally, you probably want to give all the radio in the group the same name, so that myForm.getForm().getValues() returns something like {myField: "Yes"} (the value will be taken from inputValue).
So here's what you're trying to do:
Ext.ComponentMgr.create({
xtype: 'form', // notice the changed xtype
renderTo: Ext.getBody(),
border: false,
items: [{
fieldLabel: 'Please select ',
xtype: 'radiogroup',
id: 'id1',
columns: 2,
vertical: false,
// radio buttons must be children of the radio group
items: [{
boxLabel: 'Yes',
// you probably want to give your radios the same name
name: 'myField',
inputValue: 'Yes'
}, {
boxLabel: 'No',
name: 'myField',
inputValue: 'No'
}]
}]
});

Resources