How would I select all the child components of a FormPanel that are of the component type TextField?
I want to loop through only the TextField components and set their values to "".
I have this inside a method on a FormPanel
this.query('textfield').forEach(function(item) { console.log(item.id); } );
It selects too much stuff, it selects all the nested TextFields inside of ComboBox and DateField and what not.
How can I get only the Ext.form.field.TextField instances?
You need call the function getXType().
Extjs documentation http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.Component-method-getXType
Example
var t = new Ext.form.field.Text();
alert(t.getXType()); // alerts 'textfield'
Using this form of query causes the Ext.ComponentQuery to lookup if the current component either is a textfield or extend from textfield. Simply use a property query for such a case like [xtype=textfield]. Is doesn'T matter if you create the textfield without setting the xtype or creating it by it's xtype it be set on the instance.
Here's example will return two results.
var form = Ext.create('Ext.form.Panel', {
title: 'Contact Info',
width: 300,
bodyPadding: 10,
renderTo: Ext.getBody(),
items: [Ext.create('Ext.form.field.Text',{
name: 'name',
fieldLabel: 'Name',
allowBlank: false // requires a non-empty value
}), {
xtype: 'textfield',
name: 'email',
fieldLabel: 'Email Address',
vtype: 'email' // requires value to be a valid email address format
}]
});
console.log(Ext.ComponentQuery.query('[xtype=textfield]', form));
Related
I am using Ext JS 3.4 and in the composite field, there are three fields, code is as below:
xtype: 'compositefield',
name: 'comboField',
fieldLabel: 'Partner with',
width: 400,
cItems:[{
xtype: 'combo',
name: 'partnerTypeCombo',
value: 'ProviderName',
mode: 'local',
store: new Ext.data.ArrayStore({
fields: ['id', 'displayValue'],
data: [
['ProviderName', 'Provider Partner Name'],
['OtherProvider', 'Other Provider Partner']
]
}),
valueField: 'id',
displayField: 'displayValue',
listeners: {
scope: this,
select: function(combo, record, index) {
var providerField = this.formPanel.getForm().findField('comboField_providerPartnerNameField');
var otherProviderField = this.formPanel.getForm().findField('comboField_otherProviderPartnerNameField');
if (combo.value == "OtherProvider") {
providerField.setVisible(false);
otherProviderField.setVisible(true);
}
else {
providerField.setVisible(true);
otherProviderField.setVisible(false);
}
}
}
}, {
xtype: 'spacer',
width: 10,
flex: 0
}, {
xtype: 'modellinkfield',
name: 'providerPartnerNameField',
modelLevelType: 'Organization',
modelType: 'Organization',
pickerReport: {
reportName: 'TMS.SupplierVendorOrgPicker',
targetLevelType: 'Organization'
}
}, {
xtype: 'textfield',
name: 'otherProviderPartnerNameField',
hidden: true
}]
By using the above code and without hiding any field, I got the below result
But My expectation is
By default third field (which is text field) should be hidden
On selecting Combobox values, the next two fields should be visible/hidden.
Like if dropdown field value is "Provider Partner Name" then only second
field (modeling field) should be visible (shown as below)
And if dropdown field value is "Other Provider Name" then only third
field (i.e text field) should be visible.
But I am unable to achieve this third objective. I am getting the following output for this (the field is getting overridden)
And I am expecting the following output.
Looks like this may be some layout issue or maybe I need to apply some CSS style to handle this. Can someone please help me to solve this issue.
Able to solve this issue by using below code :
otherProviderField.ownerCt.doLayout();
I have a requirement to display combobox and datefield in Grid columns. So used widgetcolumn and created grid with those fields.
But now on changing data in combobox or datefield, new values should be updated in grid store so that after going to next page and coming back, values should persist in previous pages.
Can someone let me know how I can achieve this?
Fiddle: https://fiddle.sencha.com/#fiddle/183r
Option1: Use both widget and cell editor.
Add CellEditing plugin and set editor to same component as widget.
{ xtype: 'widgetcolumn', text: 'Gender', dataIndex: 'gender', flex: 1,
widget: { xtype: 'combo', store: genderStore, displayField: 'name', valueField: 'value'},
editor: { xtype: 'combo', store: genderStore, displayField: 'name', valueField: 'value'}
},
Example: https://fiddle.sencha.com/#fiddle/1843
Option2: Manually update the record.
I feel this solution is better.
widget: {xtype: 'datefield',
listeners:{
select: function(datefield, value, eOpts){
var rowIndex = datefield.up('gridview').indexOf(datefield.el.up('table'));
var record = datefield.up('gridview').getStore().getAt(rowIndex);
record.set('dob', value);
}
}
}
Example: https://fiddle.sencha.com/#fiddle/1842
To get rowIndex in widgetColumn, I referenced "How to get rowIndex in extjs widget column" DrakeES's answer.
The best solution i could find.
The function "getWidgetRecord" is not findable with the search.
It is discribed within the widget config description.
Have a look at the following Links.
https://docs.sencha.com/extjs/5.1.3/api/Ext.grid.column.Widget.html#cfg-widget
https://docs.sencha.com/extjs/6.0.2/classic/Ext.grid.column.Widget.html#cfg-widget
A config object containing an xtype.
This is used to create the widgets or components which are rendered into the cells of this column.
This column's dataIndex is used to update the widget/component's defaultBindProperty.
The widget will be decorated with 2 methods: getWidgetRecord - Returns
the Ext.data.Model the widget is associated with. getWidgetColumn -
Returns the Ext.grid.column.Widget the widget was associated with.
widget:{
xtype:'combo',
editable: false,
store: Ext.create('Ext.data.Store',{
fields:['name','text'],
data:[
{"name":"integer", "text":"Integer"},
{"name":"float","text":"Float"}
]
}),
listeners:{
select: function(combo, value, eOpts){
var record = combo.getWidgetRecord();
record.set('type', value.get('name'));
}
},
valueField:'name',
displayField:'text',
allowBlank: false
}
or
widget: {
xtype: 'textfield',
allowBlank: false,
listeners:{
change: function(textfield, value, eOpts){
var record = textfield.getWidgetRecord();
record.set('field', value);
}
}
}
PROBLEM: We toggle fields on form. When secondField is shown instead of firstField, then form is changed. But secondField is still marked as not dirty, because both fields remain unchanged. Showing secondField should always make it and the form (model) dirty.
RESEARCH: setDirty() method is done on whole record, setValue() acts as expected, but smells like a hack and can't be used for various field types (textfield, combobox).
QUESTION: How to manually set a single form field state changed to invoke saving its data?
You are mixing up data state with form visualisation. By default, "field is shown" has no relation to data, so you need to explicitly create one. This can be done by changing some data on toggling, or other way round — toggling on changing data.
For example, toggling can occur on checking/unchecking a checkbox field which will represent a piece of form data (also see fiddle):
Ext.create('Ext.form.Panel', {
viewModel: {
type: 'default'
},
items: [
{
xtype: 'checkbox',
reference: 'toggle',
itemId: 'toggle',
boxLabel: 'Toggle',
hidden: true
},
{
xtype: 'button',
text: 'Toggle',
enableToggle: true,
toggleHandler: function() {
var form = this.up('form'),
checkbox = form.child('#toggle');
checkbox.setValue(!checkbox.getValue());
console.log(form.isDirty() ? 'Dirty!' : 'Not dirty');
}
},
{
xtype: 'textfield',
name: 'firstField',
fieldLabel: 'First Field',
bind: {
hidden: '{toggle.checked}'
}
},
{
xtype: 'textfield',
name: 'secondField',
fieldLabel: 'Second Field',
bind: {
hidden: '{!toggle.checked}'
}
}
],
renderTo: Ext.getBody()
});
I'm working with Extjs 4.0.7, and I am using a panel, and inside that panel I'm using two tabs, each tab contains a form for inserting data.
For each form I added a dockedItem component with same id. From here my problems started, that component was added to display error message from server or validation error of form.
If we are using that form only one time in a window there is no problem, I used Ext.getCmp('component-id'); to setError to that component.
But while using two or more forms in an active window, displays form1's error in some times in form2 error fieldl, because every form uses the same component id.
I read that you should try to avoid the usage of getCmp() in extjs.
How can I solve this problem?
Use an itemId. The itemId only needs to be unique inside it's container hierarchy:
Ext.require('*');
Ext.onReady(function() {
new Ext.form.Panel({
renderTo: document.body,
width: 300,
items: {
xtype: 'textfield',
fieldLabel: 'Field 1',
itemId: 'field1'
},
tbar: [{
text: 'Mark',
handler: function(){
this.up('form').down('#field1').markInvalid('Foo');
}
}]
});
new Ext.form.Panel({
renderTo: document.body,
width: 300,
items: {
xtype: 'textfield',
fieldLabel: 'Field 1',
itemId: 'field1'
},
tbar: [{
text: 'Mark',
handler: function(){
this.up('form').down('#field1').markInvalid('Foo');
}
}]
});
});
While you are creating the form object pass id dynamically so that you will have different form ids.
You can try with component query as well.
I can't seem to be able to focus a field in a form in extjs 4.
The doc lists a focus function for Text field (inherited from Component) but it doesn't do anything in terms of focusing to the input field.
Here's a sample code from the docs
Ext.create('Ext.form.Panel', {
title: 'Contact Info',
width: 300,
bodyPadding: 10,
renderTo: Ext.getBody(),
items: [{
xtype: 'textfield',
name: 'name',
fieldLabel: 'Name',
allowBlank: false
}, {
xtype: 'textfield',
id:'email',
name: 'email',
fieldLabel: 'Email Address',
vtype: 'email'
}]
});
If I call Ext.getCmp('email').focus() nothing visible happens.
What's the correct way to focus a field in extjs 4?
Sometimes a simple workaround is to slightly defer the focus call in case it's a timing issue with other code or even with the UI thread allowing the focus to take place. E.g.:
Ext.defer(function(){
Ext.getCmp('email').focus();
}, 0);
There isn't anything wrong with your code. I've made a jsfiddle for it and it works fine. Are you wrapping code in and Ext.onReady()? Also what browser are you using?
Try this:
Ext.getCmp('email').focus(false, 20);
Rather than work around with a delay, look for what is getting focus instead. Look out for focusOnToFront property on the parent.