-
4 Oct 2012 8:31 AM #1
Answered: How to load a nested model into a single form
Answered: How to load a nested model into a single form
I've created a script to dynamically generate a form, but I'm having problem loading the data of the nested model. I've tried loading the whole record and I've tried loading each sub store, but neither works.
I've through about using form.load(), but from my understanding that requires a proxy connection and also require to store json data inside a 'data' array.
I'm having problem loading the store data into form fields. For static forms I normally use loadRecord to load the nested model into a form, but in this case all the fields are nested in their own little model, so would there be a way to load each nested model value into their own field with loadRecord?
The HeaderModel stores field set information.
The purpose of ColumnModel is to create the container that will surround a set of fields, for styling purpose. It simply creates two columns of fields.
The FieldModel stores the field specific attributes and data.
Does anyone have any suggestions on how might I approach this problem?
Here's the code:
Here's a sample of the json response object:Code:<div id="view-@pageSpecificVar" class="grid-container even"></div><div id="button"></div> <script> Ext.define('HeaderForm', { extend: 'Ext.form.Panel', initComponent: function () { var me = this; Ext.applyIf(me, { id: Ext.id(), defaultType: 'textfield' }); me.callParent(arguments); } }); // Define our data model Ext.define('HeaderModel', { extend: 'Ext.data.Model', fields: [ { name: 'HeaderSequence', type: 'int'} ], hasMany:[ { name: 'Columns', model: 'ColumnModel' } ], proxy: { type: 'ajax', actionMethods: { create: 'POST', read: 'GET', update: 'POST', destroy: 'POST' }, url: '@Url.Content("~/Test/Header")', timeout: 1200000, }, }); Ext.define('ColumnModel', { extend: 'Ext.data.Model', fields: [ { name: 'ColumnWidth', type: 'float'} ], hasMany:[ { name: 'Fields', model: 'FieldModel'} ], belongsTo: 'HeaderModel' }); Ext.define('FieldModel', { extend: 'Ext.data.Model', fields: [ { name: 'XType', type: 'string'}, { name: 'FieldLabel', type: 'string'}, { name: 'Name', type: 'string'}, { name: 'Data', type: 'string'}, { name: 'FieldSpecify', type: 'bool'} ], belongsTo: 'ColumnModel' }); var store = Ext.create('Ext.data.Store', { storeId: 'HeaderStore', model: 'HeaderModel', autoDestroy: true, listeners: { load: function (result, records, successful, eOpts) { //console.log(result); var form = dynamicForm(records[0]); form.add(submitButton); form.render('view-@pageSpecificVar'); } } }); store.load(); var dynamicForm = function(record) { var form = new HeaderForm(); var columnContainer = new Ext.widget({ xtype: 'container', layout: 'column' }); var formItems = new Ext.util.MixedCollection(); Ext.each(record.ColumnsStore.data.items, function(item) { Ext.iterate(item.data, function (key, value) { var fieldContainer = new Ext.widget({ xtype: 'container', columnWidth: value }); Ext.each(item.FieldsStore.data.items, function(item) { if(item.data["FieldSpecify"]) { fieldContainer.add(new Ext.widget({ xtype: item.data["XType"], fieldLabel: item.data["FieldLabel"], name: item.data["Name"], //value: item.data["Name"] })); } }, this); columnContainer.add(fieldContainer); }, this); }, this); formItems.add(columnContainer); form.add(formItems.items); Ext.each(record.ColumnsStore.data.items, function(item) { Ext.each(item.FieldsStore.data.items, function(fields) { form.loadRecord(fields); }); }); //form.loadRecord(record); return form; }; var submitButton = new Ext.widget({ xtype: 'toolbar', dock: 'bottom', items:[{ xtype: 'button', text: 'Save', handler: function(button) { var basic = button.up('form').form; basic.updateRecord(basic.getRecord()); var store = Ext.StoreMgr.get('HeaderStore'); store.each(function(record) { record.dirty = true; }); store.sync(); } }] }); </script>
ThanksCode:{ "HeaderSequence":1, "Columns":[{ "ColumnWidth":0.5,"Fields":[ {"XType":"textfield","FieldLabel":"FieldA","Name":"NameA","Data":"A","FieldSpecify":true}, {"XType":"textfield","FieldLabel":"FieldB","Name":"NameA","Data":"B","FieldSpecify":true}] },{ "ColumnWidth":0.5,"Fields":[ {"XType":"textfield","FieldLabel":"FieldA2","Name":"NameA2","Data":"A2","FieldSpecify":true}, {"XType":"textfield","FieldLabel":"FieldB2","Name":"NameB2","Data":"B2","FieldSpecify":true}] } ]}
-
Best Answer Posted by STi88
I've figure out how to load the nested model into the form. We can't simply use load or loadRecord, as by default that method tries to get a model's data and iterate through the data object and call setValues.
What I have to do is manually get the basic form element and call setValues myself to assign the values.
To Follow up with that, a custom submit handler needs to be put in place as well. Which loops through the store and sets the submitted value to store before sync the store.Code:// loop through each field store to load the data into the form by field id Ext.each(record.ColumnsStore.data.items, function(item) { Ext.each(item.FieldsStore.data.items, function(fields) { form.getForm().setValues([{ id: fields.data['Id'], value: fields.data['DisplayName'] }]); }); });
Code:// define form submit button var submitButton = new Ext.widget({ xtype: 'toolbar', dock: 'bottom', items:[{ xtype: 'button', text: 'Save', handler: function(button) { // get basic form for button var basic = button.up('form').form; // get form submit values var formSubmitValues = basic.getValues(); // get header store var store = Ext.StoreMgr.get('HeaderStore'); // loop through each field store and update the data values by id from the form store.each(function(record) { Ext.each(record.ColumnsStore.data.items, function(item) { Ext.each(item.FieldsStore.data.items, function(fields) { fields.data['Data'] = formSubmitValues[fields.data['Id']]; }); }); // mark the record as dirty to be sync record.dirty = true; }); // sync store object with the database store.sync(); } }] });
-
10 Oct 2012 9:19 AM #2Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 34,085
- Vote Rating
- 453
- Answers
- 3153
Can you resolve the record that you need to use?
Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
10 Oct 2012 9:41 AM #3
I've found a solution to my problem
I've found a solution to my problem
I've figure out how to load the nested model into the form. We can't simply use load or loadRecord, as by default that method tries to get a model's data and iterate through the data object and call setValues.
What I have to do is manually get the basic form element and call setValues myself to assign the values.
To Follow up with that, a custom submit handler needs to be put in place as well. Which loops through the store and sets the submitted value to store before sync the store.Code:// loop through each field store to load the data into the form by field id Ext.each(record.ColumnsStore.data.items, function(item) { Ext.each(item.FieldsStore.data.items, function(fields) { form.getForm().setValues([{ id: fields.data['Id'], value: fields.data['DisplayName'] }]); }); });
Code:// define form submit button var submitButton = new Ext.widget({ xtype: 'toolbar', dock: 'bottom', items:[{ xtype: 'button', text: 'Save', handler: function(button) { // get basic form for button var basic = button.up('form').form; // get form submit values var formSubmitValues = basic.getValues(); // get header store var store = Ext.StoreMgr.get('HeaderStore'); // loop through each field store and update the data values by id from the form store.each(function(record) { Ext.each(record.ColumnsStore.data.items, function(item) { Ext.each(item.FieldsStore.data.items, function(fields) { fields.data['Data'] = formSubmitValues[fields.data['Id']]; }); }); // mark the record as dirty to be sync record.dirty = true; }); // sync store object with the database store.sync(); } }] });


Reply With Quote