PDA

View Full Version : autoLoad data from xml (Store) to textfield



Snelius
25 Aug 2011, 12:04 AM
Hi.
I have follow code for subj.
xml

<message success="true">
<network>
<ip>127.0.0.2</ip>
<mask>255.255.255.0</mask>
<gateway>127.0.0.1</gateway>
</network>
</message>
Model

Ext.define('OG.model.IPv4', {
extend: 'Ext.data.Model',
fields: ['ip','mask','gateway']
});


Store

Ext.define('OG.store.IPv4Store', {
extend: 'Ext.data.Store',
requires: ['Ext.data.reader.Xml'],
model: 'OG.model.IPv4',
autoLoad: true,
autoSync: true,
proxy: {
type: 'ajax',
url: 'network.xml',
reader: {
type: 'xml',
record: 'network',
root: 'message',
successProperty: '@success'
}
},
});
Form


Ext.define('OG.view.settings.Network_ipv4' ,{
extend: 'Ext.form.Panel',
alias : 'widget.ipv4tab',
layout: 'anchor',
bodyStyle: 'padding: 20px',
store : 'IPv4Store',
id: 'ipv4tabid',
fieldDefaults: {
msgTarget: 'side',
labelWidth: 150
},
items: [
{xtype: 'fieldset',
title: 'IP адрес',
// layout: 'anchor',
defaults: {
anchor: '100%'
},
items: [
{xtype:'textfield',name:'ip',fieldLabel:'ip address',disabled:false},
{xtype:'textfield',name:'mask',fieldLabel:'network mask',vtype:'IPAddress',disabled:false},
{xtype:'textfield',name:'gateway',fieldLabel:'default gateway',vtype:'IPAddress',disabled:false},
],
},
]
});

Ext.define('OG.view.settings.Network' ,{
extend: 'Ext.tab.Panel',
alias : 'widget.network_settings',
bodyStyle: 'padding: 0px',
items: [
{title:'IPv4',xtype:'ipv4tab'},
{title:'IPv6',html:'<div style="text-align:center;margin-top:40%"><h1>in work</h1></div>'},
],
buttons: [
{text: 'Save',handler:function(){this.up('window').close();}},
{text: 'Close',handler:function(){this.up('window').close();}}
],
});


.. but no data load in the textfields. "xml form" example from extjs4 docs did't help me :( where's my wrong? Thanks!

HTK
25 Aug 2011, 12:16 AM
I don´t know if it could work like you do. I´ve never seen that you place a store in the form panel configuration. Normally you would use a selected record from the store to load it into the form. So if you select one record and do a form.load(record), your form fields will be filled. If you got 40 records in your store and you have a form with 3 fields. Which of the 40 would be loaded by autoLoad ? If you only got one record in your store, you could use a listener on the store that fills the form after store is loaded with this lonesome record. Maybe this helps

Snelius
25 Aug 2011, 12:27 AM
added to my Store

listeners: {
load: function (store, records){
var f = Ext.getCmp('ipv4tabid').getForm();
f.load(records[0]);
}
},
without changes

Snelius
25 Aug 2011, 10:23 PM
Ext.define('OG.model.Net', {
extend: 'Ext.data.Model',
fields: [{ name: 'ip', mapping: 'network > ip'},'mask','gateway']
});

Ext.define('OG.view.settings.Network_ipv4' ,{
extend: 'Ext.form.Panel',
alias : 'widget.ipv4tab',
layout: 'anchor',
bodyStyle: 'padding: 20px',
waitMsgTarget: true,
//store : 'IPv4Store',
//id: 'ipv4tabid',
fieldDefaults: {
msgTarget: 'side',
labelWidth: 150
},
reader : Ext.create('Ext.data.reader.Xml', {
model: 'OG.model.Net',
record : 'network',
//root : 'network',
successProperty: '@success'
}),
items: [
{xtype: 'fieldset',
title: 'IP адрес',
// layout: 'anchor',
defaults: {
anchor: '100%'
},
items: [
{xtype:'textfield',name:'ip',fieldLabel:'IP адрес'},
{xtype:'textfield',name:'mask',fieldLabel:'Маска подсети'},
{xtype:'textfield',name:'gateway',fieldLabel:'Шлюз по умолчанию'},
],
},
],
buttons: [{text:'Load',handler:function(){
this.up('form').getForm().load({url: 'network.xml',waitMsg: 'Loading...',method: 'get'});
}}]
});

xml

<message success="true">
<network>
<ip>127.0.0.2</ip>
<mask>255.255.255.0</mask>
<gateway>127.0.0.1</gateway>
</network>
</message>

It a just load by button handler and still not work ...

mberrie
26 Aug 2011, 9:17 PM
Looks like you've found one problem already. That is that in order to match your XML file you must *not* set the 'root' property to 'message' (since the 'network' node is not nested inside the 'message' node).

For the second problem - when I ran your code (slightly adapted), the error message I got was this:


Uncaught Ext.Error: You're trying to decode an invalid JSON String: <message success="true"> ..

Obviously your xml reader definition doesn't get picked up and it falls back to a JSON reader.


The docs actually give a good hint of why this actually happens - this is from Ext.form.Panel



BasicForm
Although not listed as configuration options of FormPanel, the FormPanel class accepts all of the config options supported by the Ext.form.Basic (http://localhost:88/ext-4.0.2a/docs/index.html#/api/Ext.form.Basic) class, and will pass them along to the internal BasicForm when it is created.
Note**: If subclassing FormPanel, any configuration options for the BasicForm must be applied to the initialConfig property of the FormPanel. Applying BasicForm (http://localhost:88/ext-4.0.2a/docs/index.html#/api/Ext.form.Basic) configuration settings to this will not* affect the BasicForm's configuration.



Well, even with that information it took me some time and a look at the Ext source code to find the 'proper' way of declaring the reader:



initComponent: function() {
Ext.apply(this.initialConfig, {
reader: Ext.create('Ext.data.reader.Xml', {
model: 'OG.model.Net',
record : 'network',
//root : 'network',
successProperty: '@success'
})
});
this.callParent(arguments);
}


This is the ONLY way I've found to define the reader config in a subclass extending Ext.form.Panel!

You can't do that in the constructor, or as part of the sub-class definition (like you tried), and even if you do it in initComponent but do it after the this.callParent() call, it will not work. So be careful!

This is my working setup:



<html>
<head>
<title></title>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8"/>
<link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css"/>
<script type="text/javascript" src="ext/ext-debug.js"></script>

<script type="text/javascript">
Ext.Loader.setPath('Ext', 'ext/src');
Ext.Loader.config.disableCaching = false;


Ext.define('OG.model.Net', {
extend: 'Ext.data.Model',
fields: [
{ name: 'ip', mapping: 'network > ip'},
'mask',
'gateway'
]
});

Ext.define('NetworkPanel', {
extend: 'Ext.form.Panel',
alias : 'widget.ipv4tab',
layout: 'anchor',
bodyStyle: 'padding: 20px',
waitMsgTarget: true,
//store : 'IPv4Store',
//id: 'ipv4tabid',
fieldDefaults: {
msgTarget: 'side',
labelWidth: 150
},
items: [
{xtype: 'fieldset',
title: 'IP адрес',
// layout: 'anchor',
defaults: {
anchor: '100%'
},
items: [
{xtype:'textfield',name:'ip',fieldLabel:'IP адрес'},
{xtype:'textfield',name:'mask',fieldLabel:'Маска подсети'},
{xtype:'textfield',name:'gateway',fieldLabel:'Шлюз по умолчанию'},
]
},
],
buttons: [
{text:'Load',handler:function() {
this.up('form').getForm().load({url: 'forum-145013.xml',waitMsg: 'Loading...',method: 'get'});
}}
],

initComponent: function() {
this.callParent(arguments);
Ext.apply(this.initialConfig, {
reader: Ext.create('Ext.data.reader.Xml', {
model: 'OG.model.Net',
record : 'network',
//root : 'network',
successProperty: '@success'
})
});
}
})

Ext.onReady(function() {
Ext.create('NetworkPanel', {
renderTo: Ext.getBody()
})
});
</script>

</head>
<body></body>
</html>

Snelius
28 Aug 2011, 6:58 PM
Yes, it's works, thx,
I think I need to further explore the architecture of ExtJS, because that many decisions are not obvious to me.
I can't find "initComponent" description in docs for example, and when and how it calling...

skirtle
30 Aug 2011, 5:05 AM
I can't find "initComponent" description in docs for example, and when and how it calling...

ExtJS contains a lot of protected template methods that are designed to be overridden. initComponent is probably the most common example of such a method. The API docs historically only included public methods and have only recently started including the protected methods, most of them still aren't documented. You'll find that most such methods have names that sound like event handlers, like onShow or afterRender, however it is important to realize that they are entirely separate from the events infrastructure and have a slightly different role. Discovering which template methods exist is usually just a case of looking at the code when you need to override some aspect of the current behaviour.

You may find some of the things discussed in this thread useful for your understanding:

http://www.sencha.com/forum/showthread.php?143869