extjs remove/readd textfield to form bug? - extjs

I have a form where i have a radiogroup 'yes', 'no'.
When i click on 'yes' i got a textfield added to a fieldset on the form with the config option: allowBlank: false. So there is validation on the field. When I click on 'no' all fields are removed from the fieldset that is present on the form.
The problem is when the validation is active, so when you go inside the textfield and you click away from it without entering any characters into it and i click on the radiobutton 'no' the textfield disappears and gives me the following error when i catch it:
Element.alignToXY with an element that doesn't exist
When i click afterwards on the radiobutton 'yes', the textfield is shown again BUT i get an error:
TypeError: dom is undefined
I could catch these errors and do nothing with it because in fact the form seems to be working, the textfields got added and removed like it should, there are only errors present and i don't like the concept of it. Does anyone has a clue why this error occurs and how to get rid of it so it's working 100% properly?
Here is an example of the code:
var radiogroup = new Ext.form.RadioGroup({
fieldLabel: 'Radio group test',
allowBlank: false,
anchor: '85%',
items: [{
boxLabel: 'Yes',
name: 'radio',
inputValue: 1
}, {
boxLabel: 'No',
name: 'radio',
inputValue: 2
}],
listeners: {
change: function (rg, radio) {
if (radio.inputValue == 1) {
var textfield_test = new Ext.form.TextField({
fieldLabel: 'Test',
allowBlank: false,
id: 'test',
name: 'test',
anchor: '85%',
width: 320,
helpText: 'test'
});
textfield_fieldset.insert(textfield_fieldset.items.length, textfield_test);
} else {
try {
txt_test = Ext.getCmp('test');
if (txt_test) {
textfield_fieldset.remove(txt_test);
}
textfield_fieldset.doLayout();
} catch (err) {
alert(err);
}
}
}
}
});

I've done this successfully not just for one textbox, but for an entire panel, and it works pretty well. In my case, any number of panel can be added and removed dynamically and it works pretty well. The relevant code that I used were:
panel.insert(medIndex,getNewPanel());
panel.doLayout();
And for remove i used,
var cmp = Ext.getCmp('Panel-' + Id);
if (cmp) {
treatment.remove(cmp, true); // True is the autoDestroy option.
}
These two in combination works for me. Though I would suggest that if you're doing this only for one textbox, then convert it into a hidden field and disable it. When you disable a field, it does not get submitted in a post, or ajax post request.
Hope this helps.

first, why did you re-add/re-remove a component like that?,..
if i was you... i will use the hide / show method of textfield class..
after read your code, i assuming that you are make a formPanel with 2 items (radiogroup and fieldset) where in the fieldset, there is a textfield... so, guestly.. mybe like this ??
var radiogroup = new Ext.form.RadioGroup({
fieldLabel: 'Radio group test',
allowBlank: false,
anchor: '85%',
items: [
{
boxLabel: 'Yes',
name: 'radio',
inputValue: 1},
{
boxLabel: 'No',
name: 'radio',
inputValue: 2}
],
listeners: {
change : function(a,b){
if (b.inputValue==1){
Ext.getCmp("textfield").enable();
Ext.getCmp("textfield").show();
}else{
Ext.getCmp("textfield").disable(); // set disable to prevent send empty data
Ext.getCmp("textfield").hide();
}
}
}
});
var formPanel = new Ext.form.FormPanel({
url : 'www.google.com',
method : "GET",
layout:'column',
frame :true,
border : false,
items : [
radiogroup,
{
xtype:'fieldset',
id : 'test',
title: 'Fieldset',
collapsible: true,
height : 200,
width : 350,
items :[{
xtype : "textfield",
id : 'textfield',
fieldLabel : "input data",
name : "text",
hidden:true,
disabled:true
}]
}
]
});
var win = new Ext.Window({
title : "holla",
width : 400,
height: 300,
border : false,
layout:'fit',
items : [formPanel]
});
win.show();

I created a jsfiddle to answer this question. The textfield seemed to get added / removed properly there: http://jsfiddle.net/jaycode/PGSb7/4/
Cheers.
Edit: For completeness, I guess I'll just post the code here as well
HTML
<div id="radios"></div>
<div id="textfield_fieldset"></div>
JS
var textfield_fieldset = new Ext.form.FieldSet({
renderTo: 'textfield_fieldset',
});
var radiogroup = new Ext.form.RadioGroup({
renderTo: 'radios',
width: 200,
height: 60,
fieldLabel: 'Radio group test',
allowBlank: false,
layout: {
type: 'vbox'
},
items: [
{
boxLabel: 'Yes',
name: 'radio',
inputValue: 1
},
{
boxLabel: 'No',
name: 'radio',
inputValue: 2
}
],
listeners: {
change: function(rg, radio) {
if (rg.lastValue.radio == 1) {
var textfield_test = new Ext.form.TextField({
fieldLabel: 'Test',
allowBlank: false,
id: 'test',
name: 'test',
anchor: '85%',
width: 320,
helpText: 'test'
});
textfield_fieldset.insert(textfield_fieldset.items.length, textfield_test);
} else {
txt_test = Ext.getCmp('test');
if (txt_test) {
textfield_fieldset.remove(txt_test);
}
textfield_fieldset.doLayout();
}
}
}
});

Related

ExtJS : Unable to mark checkbox false in change event

We have an on-screen business rule, where on the particular condition I can perform some action. Now after upgrade to ExtJS 6.5 something is broken.
Below code summarizes my problem
I basically want to set the checkbox to false whenever someone clicks it.
FYI, I can't use setReadonly() in my problem.
behavior on version 5.1.3.228: The checkbox doesn't get checked, which is expected
behavior on version 6.5.2.463: The checkbox gets checked and after that, you can't unchecked it.
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('Ext.form.Panel', {
bodyPadding: 10,
width: 300,
title: 'Checkbox Title',
items: [
{
xtype: 'fieldcontainer',
fieldLabel: 'This is Checkbox',
defaultType: 'checkbox',
items: [
{
boxLabel : 'Check me',
name : 'checkbox',
listeners : {
change : function (){
this.setValue(false)
}
}
}
]
}
],
renderTo: Ext.getBody()
});
}
});
You can use this.setChecked to retain your functionality.
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.Msg.show({
bodyPadding: 10,
width: 300,
title: 'Checkbox Title',
items: [
{
xtype: 'fieldcontainer',
fieldLabel: 'This is Checkbox',
defaultType: 'checkbox',
items: [
{
boxLabel : 'Check me',
name : 'checkbox',
checked: true,
listeners : {
change : function () {
this.setChecked(false);
}
}
}
]
}
],
});
}
});
(Used Ext.Msg.show to see the panel in a fiddle)

Display issue with RowEditor and checkcolumn on ExtJS GridPanel

I'm using an ExtJS (v3.4.0) GridPanel with the RowEditor extension to allow users to add lines of text to a grid. I have also used the checkcolumn extension so users can check certain lines of text for later processing. So far, it looks like this:
However, when editing a row, the problem at hand becomes apparent:
The value underlying the checkcolumn is being displayed in text form along with the actual checkbox. I figured since users can check the checkboxes without editing the row, I would make this column uneditable to fix my issue. However, after modifying my code the true/false value is still being displayed in edit mode, the text value is just not editable anymore.
My code so far:
Ext.QuickTips.init();
var FreeText = Ext.data.Record.create([{
name: 'text',
type: 'string'
}, {
name: 'active',
type: 'bool'
}]);
var store = new Ext.data.GroupingStore({
reader: new Ext.data.JsonReader({fields: FreeText}),
sortInfo: {field: 'text', direction: 'ASC'}
});
var editor = new Ext.ux.grid.RowEditor({
saveText: 'Update'
});
var freeTextPanel = new Ext.grid.GridPanel({
store: store,
width: 600,
region:'center',
margins: '0 5 5 5',
autoExpandColumn: 'text',
plugins: [editor],
view: new Ext.grid.GroupingView({
markDirty: false
}),
tbar: [{
iconCls: 'icon-add',
text: 'Add',
handler: function(){
var e = new FreeText({
text: "",
active: true
});
editor.stopEditing();
store.insert(0, e);
freeTextPanel.getView().refresh();
freeTextPanel.getSelectionModel().selectRow(0);
editor.startEditing(0);
}
},{
ref: '../removeBtn',
iconCls: 'icon-delete',
text: 'Delete',
disabled: true,
handler: function(){
editor.stopEditing();
var s = freeTextPanel.getSelectionModel().getSelections();
for(var i = 0, r; r = s[i]; i++){
store.remove(r);
}
}
}, {
xtype: 'tbseparator'
}, {
iconCls: 'icon-excel-import',
//text: 'Import from CSV',
tooltip: 'Import CSV',
handler: function() {
alert( "Excel import here!" );
}
}],
columns: [
{
xtype: 'checkcolumn',
header: 'Active',
dataIndex: 'active',
align: 'center',
width: 50
}, {
id: 'text',
header: 'Free Text',
dataIndex: 'text',
width: 220,
sortable: true,
editor: {
xtype: 'textfield',
allowBlank: false
}
}],
isCellEditable: function(col, row) {
var record = store.getAt(row);
if (record.get('active')) {
return false;
}
return Ext.grid.ColumnModel.prototype.isCellEditable.call(this, col, row);
}
});
var layout = new Ext.Panel({
title: 'Free text entry',
layout: 'border',
layoutConfig: {
columns: 1
},
width:600,
height: 600,
items: [freeTextPanel]
});
layout.render(Ext.getBody());
freeTextPanel.getSelectionModel().on('selectionchange', function(sm){
freeTextPanel.removeBtn.setDisabled(sm.getCount() < 1);
});
Is there an easy way to simply get rid of the true/false text when editing a row?
Just in case, below are my RowEditor.js and CheckColumn.js files:
RowEditor.js
http://trac.geoext.org/browser/ext/3.4.0/examples/ux/RowEditor.js?rev=2740
CheckColumn.js
http://trac.geoext.org/browser/ext/3.4.0/examples/ux/CheckColumn.js?rev=2740
Turns out the solution to my problem was rather simple.
In the startEditing method of the RowEditor.js file I added the following code. I checked implicitly on the name of my item instead of for the checkbox type, in case I still need this functionality for other checkboxes later on:
for(var i = 0, len = cm.getColumnCount(); i < len; i++){
val = this.preEditValue(record, cm.getDataIndex(i));
if( cm.getDataIndex(i) == 'active' ) {
val = "";
}
f = fields[i];
f.setValue(val);
this.values[f.id] = Ext.isEmpty(val) ? '' : val;
}

Adding dynamic fields on click of button in extjs 4

I want to add a field dynamically when click on button in extjs 4.What I have done is added a onchange function on add button and write the adding textfield logic in that function.
Here is my code.
Ext.define('AM.view.user.Edit', {
extend: 'Ext.window.Window',
alias : 'widget.useredit',
requires: ['Ext.form.Panel'],
title : 'Edit User',
layout: 'fit',
autoShow: true,
height: 300,
width: 280,
id : 'mainPanel',
initComponent: function() {
this.items = [
{
xtype: 'form',
id: 'dyForm',
padding: '5 5 0 5',
border: false,
style: 'background-color: #fff;',
items: [
{
xtype: 'textfield',
name : 'name',
fieldLabel: 'Name'
},
{
xtype: 'textfield',
name : 'email',
fieldLabel: 'Email'
}
]
}
];
this.buttons = [
{
text: 'Save',
action: 'save'
},
{
text: 'Add',
scope: this,
handler: this.onChange
},
];
this.callParent(arguments);
},
onChange : function(){alert('test');
var form=Ext.getCmp("mainPanel");
form.items.add(Ext.create("Ext.form.field.Text", {fieldLabel:"First Name"}));
form.doLayout(true);
}
});
And I also want that on edit of this form I will load data to those new fields that i have newly created dynamically.
Change the onChange function to
onChange : function(btn){
// var form=Ext.getCmp("mainPanel");
var form = btn.up('window').down('form'); // this is a better approach
form.add(Ext.create("Ext.form.field.Text", {fieldLabel:"First Name"}));
}
should do it. You added the field directly to the collection where you should have use the supplied add method of the form component.
see JSFiddle

Enable/disable checkbox in extjs

I want to enable or disable checkboxes in EXTJS
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
xtype: 'radiofield',
id: 'all',
name: 'show',
boxLabel: 'All',
checked: true,
inputValue: 'all'
}, {
xtype: 'radiofield',
id: 'online',
name: 'show',
boxLabel: 'Online',
inputValue: 'online'
}, {
xtype: 'radiofield',
id: 'offline',
name: 'show',
boxLabel: 'Offline',
inputValue: 'offline'
}, {
xtype: 'checkboxfield',
id: 'cb1',
boxLabel: 'Sometimes',
checked: true,
inputValue: 'sometimes'
}, {
xtype: 'checkboxfield',
id: 'cb2',
boxLabel: 'Always',
checked: true,
inputValue: 'always'
}],
listeners: {
change: function (field, newValue, oldValue) {
var value = newValue.show;
if (value == 'all') {
var cb1 = Ext.getCmp('cb1');
var cb2 = Ext.getCmp('cb2');
cb1.disable();
cb2.disable();
}
if (value == 'online') {
var cb1 = Ext.getCmp('cb1');
var cb2 = Ext.getCmp('cb2');
cb1.disable();
cb2.disable();
}
if (value == 'offline') {
var cb1 = Ext.getCmp('cb1');
var cb2 = Ext.getCmp('cb2');
cb1.enable();
cb2.enable();
}
}
}
}]
How can I enable these checkboxes? They should be enabled when the user selects the offline option and disabled when the user selects other option.
Thanks for your help!
A couple errors I noticed:
The checkbox components cant be referred to by their id directly, you could call them with Ext.getCmp('id') though.
Your listener in the example above is attached to the toolbar, which doesn't have a change event. You need to attach it to the radio instead.
Actually, if you only want the checkboxes enabled when the 'offline' radio is filled then I would recommend adding a handler config to the 'offline' radio with a function to enable or disable the checkboxes depending on what value this radio is changed to. For example, this works:
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
xtype: 'radiofield',
id: 'all',
name: 'show',
boxLabel: 'All',
checked: true,
}, {
xtype: 'radiofield',
id: 'online',
name: 'show',
boxLabel: 'Online',
inputValue: 'online',
}, {
xtype: 'radiofield',
id: 'offline',
name: 'show',
boxLabel: 'Offline',
inputValue: 'offline',
handler: function(field, value) {
if (value) {
Ext.getCmp('cb1').enable();
Ext.getCmp('cb2').enable();
} else {
Ext.getCmp('cb1').disable();
Ext.getCmp('cb2').disable();
}
}
}, {
xtype: 'checkboxfield',
id: 'cb1',
boxLabel: 'Sometimes',
checked: true,
inputValue: 'sometimes',
disabled: true
}, {
xtype: 'checkboxfield',
id: 'cb2',
boxLabel: 'Always',
checked: true,
inputValue: 'always',
disabled: true
}]
}],
I suggest using handler config (as above) and not having a listener on the change event.
If you add a change listener it will override the default change handler used by ExtJS internally to deselect the other radio fields in the same name group. E.g. with a change listener on the 'offline' radio, when you select it, 'all' will remain selected.
In other words... just copy the example above and all will be well.
You can do the following you need to set ids for the checkboxs to look them up in this example:
if (value == 'offline') {
var cb1 = Ext.getCmp('cbox1');//look up by given checkbox ids
var cb2 = Ext.getCmp('cbox2');//look up by given checkbox ids
cb1.enable();
cb2.enable();
online
}
else {
var cb1 = Ext.getCmp('cbox1');//look up by given checkbox ids
var cb2 = Ext.getCmp('cbox2');//look up by given checkbox ids
cb1.disable();
cb2.disable();
}
A standard approach to enable / disable checkbox in ExtJS is to set configuration parameters disable: true or disable: false when creating component.
But as for ExtJS 4.2 - it has some inconvenience. Disabling or setting checkbox to readOnly makes component look very transparent. In classic framework design and maybe some others you won't even see a tick in the box if it's disabled or set to readOnly. As if it were empty.
The best solution we found is to create a project global css class for all ExtJS elements of this type. It shifts to a better tick sign in standard framework theme image and adds some opacity:
.x-form-readonly .x-form-checkbox {
background-image: url(/extjs/resources/ext-theme-classic/images/form/checkbox.gif);
opacity: 0.4;
}

EXTJS : TreePanel click for set item change

Hi everybody
I'm a beggining with extjs and I have issue with change / set a item to a layout when i click on one of my node .
Here my contentPanel :
var contentPanel = {
id: 'content-panel',
region: 'center', // this is what makes this panel into a region within the containing layout
layout: 'card',
margins: '2 5 5 0',
activeItem: 0,
border: false,
items: layoutExamples // HERE I WANT TO CHANGE DYNAMIC
};
My "listener" on my treenode :
treePanel.getSelectionModel().on('select', function(selModel, record) {
if (record.get('leaf')) {
//Ext.getCmp('content-panel').layout.setActiveItem(record.getId() + '-panel'); <== It's work.
Ext.getCmp('content-panel').setActive(formPanel); // HERE I TRY TO CHANGE ITEM ON CLICK AND SET FORMPANEL
});
My item for test :
var formPanel = Ext.create('Ext.form.Panel', {
frame: true,
title: 'Form Fields',
width: 340,
bodyPadding: 5,
fieldDefaults: {
labelAlign: 'left',
labelWidth: 90,
anchor: '100%'
},
items: [{
xtype: 'textfield',
name: 'textfield1',
fieldLabel: 'Text field',
value: 'Text field value'
}, {
xtype: 'textfield',
name: 'password1',
inputType: 'password',
fieldLabel: 'Password field'
}, {
xtype: 'filefield',
name: 'file1',
fieldLabel: 'File upload'
}, {
xtype: 'textareafield',
name: 'textarea1',
fieldLabel: 'TextArea',
value: 'Textarea value'
} }]
});
So, my objective is to change item of my content panel when i click on a node.. !
Thanks a lot for your helps buddies !
try that and tell me in the comments:
var formPanel = Ext.create('Ext.form.Panel',
{
'id': 'form-panel-1', // or what you want to give
// and all the properties you already defined
}
);
And in your event, based on http://docs.sencha.com/ext-js/4-0/#/api/Ext.layout.container.Card-method-setActiveItem :
treePanel.getSelectionModel().on('select', function(selModel, record) {
if (record.get('leaf')) {
Ext.getCmp('content-panel').getLayout().setActiveItem(Ext.getCmp('form-panel-1'));
}
});
By the way, in the code you provided, there is an error in the listener, it misses a } for closing the if!

Resources