PDA

View Full Version : Set readOnly for all form fields (window, form, tabpanel) / MVC



sir_holmes
22 Apr 2012, 9:42 AM
Hey, I've got a strange behavior in my formpanel. I want to set all form field to readOnly=false when a button is used. The form fields are split into several tabpanels. The strange thing is: my function works for all fields in all tabpanels except the active tabpanel. Any idea what's wrong in my code?!

Thanks!

Window / Formpanel:
Ext.define('carabids.view.tools.carabidDataView', {
extend: 'Ext.window.Window',
alias : 'widget.carabidDataView',
title : langFragments[1],
layout: 'fit',
autoShow: true,
autoScroll: true,
draggable: true,
width: 500,
initComponent: function(){
this.carabidDataForm = new Ext.FormPanel({
id: 'carabidDataForm',
name: 'carabidDataForm',
height: 320,
border: false,
bodyBorder: false,
fieldDefaults: {
labelWidth: 200,
maxLength: 50,
msgTarget: 'side',
allowBlank: true,
readOnly: true
},
defaults: {
anchor: '100%'
},
items: {
xtype: 'tabpanel',
activeTab: 0,
defaults: {
bodyStyle: 'padding:10px'
},
items:[{
title: langCarabidData[28],
defaultType: 'textfield',
items: [{
fieldLabel: 'id',
name: 'carabidId',
id: 'carabidId'
},{
fieldLabel: langCarabidData[0],
name: 'subfamily',
id: 'subfamily'
},{
...

Controller function called by a Button of the formpanel:
init: function() {
this.control({
'carabidDataView button[action=edit]': {
click: function(button){
button.up('form').query('tabpanel field, .tabpanel, .field').forEach(function(field){
field.readOnly = false; // works for all tabpanels except the active
});
Ext.getCmp('carabidDataSaveButton').setDisabled(false);
}
},
....

pavel.psycho.kurnosov
22 Apr 2012, 11:27 AM
Hi,
using your method you change the property for js object not for dom, that's why your method not work for active tab and work for all other - they are not on the dom (or will update dom from object that you change when will be active).
In this case you should use for your field:

field.inputEl.dom.setAttribute('readOnly', false);

And remove from your query '.tabpanel,' it's not field.
Also I think better to use items for adding elements to your view.

sir_holmes
24 Apr 2012, 12:43 PM
Thanks for the answer! If I got it right, I need to manipulate the dom element instead of the object. Makes sense!

Anyway, if I put the field.el.dom in the console.log(), it prints the right dom html. But I cannot access the dom node, console says: Uncaught TypeError: Cannot read property 'dom' of undefined
Same with field.inputEl.dom.....


'carabidDataView button[action=edit]': {
click: function(button){
button.up('form').query('.field').forEach(function(field){
console.log(field.el.dom); // works
field.el.dom.setAttribute('readOnly', false); // does not work, console says 'undefined'
});
}
}

pavel.psycho.kurnosov
24 Apr 2012, 1:07 PM
Sorry it's my fault )) You should use this feature only for rendered items - in your case it's active tab because all other tabs elements may not attach to the dom :) that's why you have undefined. So the simplest way is:

if(field.inputEl){
field.inputEl.dom.setAttribute('readOnly', true);
} else {
field.readOnly = true;
}
But actually i think it's kind of bug on ext because all this stuff accordingly manipulation with DOM is should be made by ext.

sir_holmes
25 Apr 2012, 8:26 AM
Ok then, makes sense.... theoretically. This code throws no error in the console, but does not take effect in case of dom. If else construct works, but the setAttribute does not take effect. Strange thing. Any idea?

if(field.inputEl){
field.inputEl.dom.setAttribute('readOnly', false);
console.log('dom');
}
else{
field.readOnly = false;
console.log('non dom');
}

pavel.psycho.kurnosov
25 Apr 2012, 10:56 AM
Sorry, it's not working )) yep you are right its' working for me because I set to true ) from enable option.
Actually I found a solution but it's strange tomorrow at work I will find out the correct way but this is also works for me - now I do the same as you ) trying to enable elements, not disable :

if(field.inputEl){
field.inputEl.dom.removeAttribute('readonly');
console.log('dom');
}
else{
field.readOnly = false;
console.log('non dom');
}

P.s. Which version of extjs are you using?

pavel.psycho.kurnosov
25 Apr 2012, 11:13 AM
We both misstaken... I was trying to fix your solutions instead of using correct. So this snippet works correctly.
First instead of using readOnly attribute - use 'disabled' attr on your config, because as said on documentation for readOnly
Note: this only sets the element's readOnly DOM attribute. Setting readOnly=true, for example, will not disable triggering a ComboBox or Date; it gives you the option of forcing the user to choose via the trigger without typing in the text box. To hide the trigger use hideTrigger (http://docs.sencha.com/ext-js/4-0/#%21/api/Ext.form.field.Trigger-cfg-hideTrigger).

And for enable/disable field use field.setDisabled(false)/field.setDisabled(true).
The correct snippet:

Ext.create('Ext.window.Window', {
title:'Hello',
height:200,
width:400,
layout:'fit',
items:[
{
xtype:'button',
text:'Enable all',
renderTo:Ext.getBody(),
handler:function () {
this.up('window').down('form').query('tabpanel field, .field').forEach(function (field) {
field.setDisabled(false);
});
}
},
{
xtype:'button',
text:'Disable all',
renderTo:Ext.getBody(),
handler:function () {
this.up('window').down('form').query('tabpanel field, .field').forEach(function (field) {
field.setDisabled(true);
});
}
},
{ // Let's put an empty grid in just to illustrate fit layout
xtype:'form',
id:'carabidDataForm',
name:'carabidDataForm',
height:320,
border:false,
bodyBorder:false,
fieldDefaults:{
labelWidth:200,
maxLength:50,
msgTarget:'side',
allowBlank:true
},
defaults:{
anchor:'100%'
},
items:{
xtype:'tabpanel',
activeTab:0,
defaults:{
bodyStyle:'padding:10px'
},
items:[
{
title:'asd1',
defaultType:'textfield',
items:[
{
fieldLabel:'id',
name:'carabidI1',
disabled:true,
id:'carabidId'
},
{
fieldLabel:'asd2',
disabled:true,
name:'subfamily',
id:'subfamil2'
}
]
},
{
title:'asd1',
defaultType:'textfield',
items:[
{
fieldLabel:'id',
disabled:true,
name:'carabidId',
id:'carabidId3'
},
{
fieldLabel:'asd2',
name:'subfamily',
disabled:true,
id:'subfamily4'
}
]
}
]
}
}
]
}).show();

sir_holmes
28 Apr 2012, 9:43 AM
Thank you again! This works very well... now, another probelm arises: opacity is set for the disabled fields. Actually, I don't want that. So, disabled fields should look like enabled fields. I did not find any config option for that. Is opacity for disabled fields set by CSS?

Cheers

Alexei Ptitchkin
5 Oct 2012, 9:23 AM
Hi. I've tried to use your "dom" trick

var container = form.down('container');
var fieldset = container.down('fieldset');
var codeNumberField = fieldset.getComponent('ProductCodeNumber');
codeNumberField.inputEl.dom.setAttribute('readOnly', false);

I even can see that proper field have readOnly set to false


<input id="textfield-1425-inputEl" class="x-form-field x-form-required-field x-form-text x-form-invalid-field" type="text" autocomplete="off" style="width: 100%; -moz-user-select: text;" readonly="false" maxlength="15" name="codeNumber" size="1" aria-invalid="true" data-errorqtip="<ul><li>This field is required</li></ul>">

but textfield still read only.

Any idea what I could do wrong?