Grid rows with nested data from loaded store - extjs

I have a dataview that gets loaded with a parameter. I render this data in a template. I am trying to use the same data in which there is a nested item to render to a grid.
The data looks like this:
{
"myJson": {
"name": "abc",
"type": "faulty",
"notes": [
{
"date": "01-01-1970",
"note": "test note"
},
{
"date": "01-02-1970",
"note": "test note 2"
}
]
}
}
The store:
proxy: {
type: 'ajax',
url: '/api/detail/',
reader: {
type: 'json',
root: 'myJson'
}
}
Model:
{
name:'name',
},
{
name:'type',
},
{
name:'notes',
mapping:'notes'
},
Template:
{name} - {type}
That all works. What I'd like to do is use the notes chunk to display in a grid. Problem is I can't get it to read the notes group.
var notesListView = new Ext.list.ListView({
store: 'myStore',
multiSelect: false,
width:'100%',
id:'notesList',
columns: [{
header: 'Date',
width: 75,
dataIndex: 'date'
},{
header: 'Note',
width: 150,
dataIndex: 'note',
}]
});
Is it even possible to do this? Or do I need to create a new store and model to use this group of data in a grid?
I've tried mapping to notes.date, for instance, in both the model
name:'note_date',
mapping:'notes.date'
and in the grid itself
dataIndex:'notes.date'
neither of which worked.
I've also tried using renderer but this doesn't work either as it's an array
renderer:function(value, metaData, record, rowIndex, colIndex, store){
var value = value.date;//won't work; it needs an index a la value[0].date
return value;
}

You could create a nested model with the same data you are receiving. It would be like this
Ext.define("JsonModel", {
extend: 'Ext.data.Model',
fields: ['name','type'],
hasMany: [{
model: 'Note',
name: 'notes'
}]
});
Ext.define("Note", {
extend: 'Ext.data.Model',
fields: [
'date',
'note']
});
This way you could access the children of any give record like this
var jsonRecordChildren = jsronRecord.notes()
The variable jsonRecordChildren that I just created is of the type Store, so you could easily assign it to the attribute store of a grid.
Ext.create('Ext.grid.Panel', {
store: selectedRecord.notes(),
columns: [
{ text: 'Date', dataIndex: 'date' },
{ text: 'Note', dataIndex: 'note'}
],
renderTo: Ext.getBody()
});
http://jsfiddle.net/alexrom7/rF8mt/2/

Related

How to do Data binding in extjs 6

i have json like this.
firstName: 'xyz',
comments : [{
emailAddress : "abc#gmail.com", body : "PQR",
emailAddress : "xyz#gmail.com", body : "XYZ",
}]
i want to show firstName in the textfield which is editable. and want to show comments in the grid. i am not able to understand how to do it. please help me with that.
my view is following:
Ext.define("SampleView", {
extend: "Ext.panel.Panel",
alias: 'widget.sample',
id : 'sampleVId',
requires: ['StudentViewModel'],
viewModel: {
type: 'StudentViewModel'
},
layout: {
type: 'vbox',
align: 'stretch'
},
initComponent: function() {
Ext.apply(this, {
items: [this.form(), this.grid()],
});
this.callParent(arguments);
},
grid: function(){
return {
xtype: 'grid',
reference: 'samplegrid',
id : 'samplegridId',
bind: {
store: '{comment}'<-- not able to do the binding
},
flex:1,
margin: 10,
plugins: {
ptype: 'rowediting',
clicksToEdit: 2
},
columns: [{
text: 'Email',
dataIndex: 'email',
flex: 1,
editor: {
allowBlank: false
}
}, {
text: 'Role',
dataIndex: 'body',
}],
}
}
},
form : function(){
return{
xtype : 'form',
items:[{
xtype: 'textfield',
fieldLabel: 'First Name',
bind: {
value: '{firstName}'<---- how to bind this valuw to textfield
}
}]
}
}
});
my view model is like this:
Ext.define('StudentViewModel', {
extend: 'Ext.app.ViewModel',
alias:'viewmodel.StudentViewModel',
requires: [
'Student'
],
stores: {
orderStore: {
autoLoad:true,
type: 'sampleS'
}
}
});
my model is like this:
Ext.define('Student', {
extend: 'Ext.data.Model',
idProperty: 'Id',
schema: {
namespace: 'sample',
proxy: {
type:'ajax',
url: 'users.json',
reader:{
type:'json',
rootProperty:'data'
}
}
},
fields: [
{ name: 'Id', type: 'int' },
{ name: 'firstName', type: 'string' },
]
});
Your binding would have to be based on the record selected.
Your model for student needs to be defined to have a hasMany reference to a comments model so a proper store is built to be bound, or you would have to dynamically create a store based on the array data within the model. I would suggest just using a relation, its easier to do in the long run.
where you have the binding of
value: {firstName}
It should be
value: {student.firstName}
In your view controller you would have to bind student to the student model you are trying to display in the form using a line that looks like
vm.setValue('student', YOURMODELOBJECTHERE);
If the student model has a proper has many relation for comments, then the rest should be okay.

Ext Js Paging not able to navigate to next Page, refresh, Last page not working

Sorry I think this may be a duplicate. But I am not getting correct answer from anywhere. Please help me to find the issue.
I am creating a Ext Js grid with store. Also with the help of this blog
http://blog.jardalu.com/2013/6/21/grid-paging-extjs-sencha
I am creating Grid whcih loads Data Page for the first PAge. But when I press next, last, refresh no events are working. Also from the console am getting an error like this from ext js file
Uncaught TypeError: Cannot read property 'name' of undefined
Please help me to find the issue.
Code:-
/*global Ext:false */
Ext.require([
'Ext.data.*',
'Ext.grid.*'
]);
Ext.onReady(function () {
var itemsPerPage = 2; // set the number of items you want per page
var store = Ext.create('Ext.data.Store', {
id: 'simpsonsStore',
autoLoad: false,
fields: ['name', 'email', 'phone'],
pageSize: itemsPerPage,
data: {
'items': [{
'name': 'Lisa',
"email": "lisa#simpsons.com",
"phone": "555-111-1224"
}, {
'name': 'Bart',
"email": "bart#simpsons.com",
"phone": "555-222-1234"
}, {
'name': 'Homer',
"email": "home#simpsons.com",
"phone": "555-222-1244"
}, {
'name': 'Marge',
"email": "marge#simpsons.com",
"phone": "555-222-1254"
}]
},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items',
totalProperty: 'total'
}
},
listeners : {
beforeload : function(store, operation, eOpts){
var page = operation.page;
var limit = operation.limit;
var dataResult = [];
var startPage = (page -1) * 2;
var totalCount = startPage + limit;
console.log(store.proxy.data);
for (var i = startPage; i < totalCount ; i++) {
dataResult.push(store.proxy.data.items[i]);
}
store.proxy.data.items = dataResult;
store.proxy.data.total = 4;
}
}
});
var TOTAL = 94; //random
// specify segment of data you want to load using params
store.loadPage(1);
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: store,
columns: [{
header: 'Name',
dataIndex: 'name'
}, {
header: 'Email',
dataIndex: 'email',
flex: 1
}, {
header: 'Phone',
dataIndex: 'phone'
}],
width: 400,
height: 125,
dockedItems: [{
xtype: 'pagingtoolbar',
store: store, // same store GridPanel is using
dock: 'bottom',
displayInfo: true
}],
renderTo: Ext.getBody()
});
});
Please see the DEMO here :- http://jsfiddle.net/B6qBN/
I don't know your problem ( actually I tried to fix issue but didn't want to spent much time ). Here is the working sample. It seems to me, there is a data model problem.
Sencha Fiddle: Paging Toolbar
// Json File for demostration
{
"total": 5,
"userList":[
{"uid": "1", "firstName":"Tommy","lastName":"Maintz"},
{"uid": "2", "firstName":"Ed","lastName":"Spencer"},
{"uid": "3", "firstName":"Oğuz","lastName":"Çelikdemir"},
{"uid": "4", "firstName":"Jamie","lastName":"Avins"},
{"uid": "5", "firstName":"Dave","lastName":"Kaneda"}
]
}
// the following is code section
var itemsPerPage = 2; // set the number of items you want per page
Ext.onReady(function(){
Ext.define('senchatest.model.Contact', {
extend: 'Ext.data.Model',
fields: [
{name: 'firstName', type: 'string'},
{name: 'lastName', type: 'string'}
]
});
var UserList = new Ext.data.JsonStore ({
model: 'senchatest.model.Contact',
pageSize: itemsPerPage,
proxy: {
type: 'ajax',
url : 'contacts.json',
reader: {
type: 'json',
root: 'userList',
totalProperty: 'total'
}
}
});
UserList.load();
var users = Ext.create('Ext.form.Panel', {
bodyPadding: 10,
width: 300,
height: 400,
title: 'User List',
items: [
{
xtype: 'gridpanel',
store: UserList,
columns: [
{text: 'Name', dataIndex: 'firstName'},
{text: 'Surname', dataIndex: 'lastName'}
],
dockedItems: [{
xtype: 'pagingtoolbar',
store: UserList, // same store GridPanel is using
dock: 'bottom',
displayInfo: true
}]
}
],
renderTo: Ext.getBody()
})
});

extJs - GridPanel with combobox cell editing

I have a grid panel populated from local store. I added combo box for editing type cell. I want my combo box to be populated from a remote source. But I can't make it load any data. Here is my code:
Ext.define('System.view.MainTab.NewConnection.Contacts', {
extend: 'Ext.grid.Panel',
alias: 'widget.newConnectionContactsPanel',
requires: [
'Ext.grid.View',
'Ext.grid.column.Column',
'Ext.form.field.ComboBox',
'Ext.toolbar.Toolbar',
'Ext.toolbar.Fill',
'Ext.button.Button',
'Ext.grid.plugin.RowEditing'
],
height: 250,
width: 400,
itemId: 'contactsGridPanel',
title: 'My Grid Panel',
initComponent: function() {
var records = [];
var store = new Ext.data.ArrayStore({
fields: [
{name: 'type'},
{name: 'value'}
]
});
store.loadData(records);
var me = this;
Ext.applyIf(me, {
columns: [
{
dataIndex: 'type',
xtype: 'gridcolumn',
text: 'Type',
flex: 1,
editor: {
xtype: 'combobox',
displayField: 'neme',
valueField: 'id',
queryMmode: 'remote',
store: new Ext.data.JsonStore({
proxy: {
type: 'ajax',
url: '/ws/rest/contacts/getKeywords.json?keywordType=CONTACTS',
reader: {
type: 'json',
root: 'data',
idProperty: 'id'
}
},
autoLoad: true,
fields: [
{type: 'integer', name: 'id'},
{type: 'string', name: 'name'}
]
})
}
},
{
dataIndex: 'value',
xtype: 'gridcolumn',
text: 'Value',
flex: 1,
editor: {
xtype: 'textfield'
}
}
],
dockedItems: [
{
xtype: 'toolbar',
dock: 'bottom',
items: [
{
xtype: 'tbfill'
},
{
xtype: 'button',
itemId: 'removeBtn',
text: 'Remove'
},
{
xtype: 'button',
itemId: 'addBtn',
text: 'Add',
listeners: {
click: function (button, e, eOpts) {
var grid = button.up('#contactsGridPanel');
var store = grid.getStore();
var rowEditing = grid.getPlugin('rowediting');
rowEditing.cancelEdit();
var record = store.add({})[0];
rowEditing.startEdit(record, 0);
}
}
}
]
}
],
plugins: [
Ext.create('Ext.grid.plugin.RowEditing', {
pluginId: 'rowediting',
listeners: {
edit: function() {
}
}
})
]
});
me.callParent(arguments);
}
});
Here is a json response I get from the server:
{
"success": true,
"data": [
{
"id": 1,
"name": "Fax"
},
{
"id": 2,
"name": "Home page"
}
]
}
Can't make it all work. The combo box is empty. What am I doing wrong?
The most likely is that you have a typo in your displayField config.
As a side note, you should really say what kind of debugging you've done. Saying you "can't make it work" doesn't really help. Does the request hit the server? Does the store get data in it? Mentioning what you've done would help someone answering you.
You should catch the column Values from your remote source. Try adding the mapping attribute.
autoLoad: true,
fields: [
{type: 'integer', name: 'id', **mapping:'id'**},
{type: 'string', name: 'name', **mapping :'name'**}
]

Setting data from a store to a form panel which has a grid in extjs 4.2

I'm trying to set values for the components in a form panel and below is my code.
Form Panel with grid:
Ext.define('MyApp.view.MyForm', {
extend: 'Ext.form.Panel',
height: 436,
width: 754,
layout: {
columns: 4,
type: 'table'
},
bodyPadding: 10,
title: 'My Form',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'displayfield',
colspan: 4,
fieldLabel: '',
value: 'Display Field'
},
{
xtype: 'displayfield',
colspan: 2,
margin: '0 50 0 0 ',
fieldLabel: 'Age',
labelAlign: 'top',
value: 'Display Field'
},
{
xtype: 'displayfield',
colspan: 2,
fieldLabel: 'Country',
labelAlign: 'top',
value: 'Display Field'
},
{
xtype: 'gridpanel',
colspan: 4,
header: false,
title: 'My Grid Panel',
store: 'MyJsonStore',
columns: [
{
xtype: 'gridcolumn',
dataIndex: 'DeptName',
text: 'Dept Name'
},
{
xtype: 'gridcolumn',
dataIndex: 'DeptId',
text: 'Dept ID'
}
]
}
]
});
me.callParent(arguments);
}
});
Models:
Ext.define('MyApp.model.EmpModel', {
extend: 'Ext.data.Model',
uses: [
'MyApp.model.DeptModel'
],
fields: [
{
name: 'Name'
},
{
name: 'Age'
},
{
name: 'Country'
},
{
name: 'Dept'
}
],
hasMany: {
associationKey: 'Dept',
model: 'MyApp.model.DeptModel'
}
});
Ext.define('MyApp.model.DeptModel', {
extend: 'Ext.data.Model',
uses: [
'MyApp.model.EmpModel'
],
fields: [
{
name: 'DeptName'
},
{
name: 'DeptId'
}
],
belongsTo: {
associationKey: 'Dept',
model: 'MyApp.model.EmpModel'
}
});
Store:
Ext.define('MyApp.store.MyJsonStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.EmpModel'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
model: 'MyApp.model.EmpModel',
storeId: 'MyJsonStore',
data: {
EmpDet: [
{
EmpName: 'Kart',
Age: '29',
Dept: [
{
DeptName: 'Dev',
DeptId: '1000'
}
]
}
]
},
proxy: {
type: 'ajax',
url: 'data/empDet.json',
reader: {
type: 'json'
}
}
}, cfg)]);
}
});
Json data:
{
"EmpDet": [
{
"EmpName": "Kart",
"Age": "29",
"Dept": [
{
"DeptName": "Dev",
"DeptId": "1000"
}
]
}
]
}
Questions:
1) I had left the value of the component as "Display Field" itself because if I remove this value the width of the grid below decreases. I feel this is because of the table layout and colspans. Is there any other best way to display labels without any alignment change on value load.
2) I'm trying to set the value for the display field. I tried to do it with the afterrender event but the problem is that it throws a undefined error at Ext.getStore('MyJsonStore').getAt(0). I found that this works fine if I write the same in the click event of a button. So, I feel that the store is not loaded when I try the afterrender event of the displayfield (autoload for store is set to true). Is there an alternative for afterrender event of a component. Also, Is there a way to set all the field values at a stretch instead of setting every component one by one?
3) Also I find it difficult to do the association properly. I'm using Sencha Architect 2.2 and when I go the data index of the grid, I'm not able to get the "DeptName" and "DeptId" in the dropdown.
Please help.
For the question number 2, I want to suggest the below way. I hope it works for you.
My solution:
You can set the display fields values when the store is loaded. So you can use load event of store as below:
yourStoe.on('load',function()
{
//set display field values here
});

extjs 4 How too keep combobox in grid cell

I've seen similar questions go unanswered elsewhere. I want to have a combobox in a column with two options (ASC, DEC) in it. I want it to show up in each row, or at least have its value show up when it's not selected.
I know that its not a 'good idea' to render a combobox in each row, but in this case I know I will have a maximum of about 20 rows, so it shouldn't be a huge deal. If this can't be done I want to have the selected value from the combobox show. Currently I just have the comboboxes appearing when I click a row, which doesn't make much sense since you can't see your selection unless you are making it. What is the solution to this?
Also, I want to get rid of the change and cancel buttons that pop up when I click a row, I just want to be able to edit the cell with the combobox, and have it automatically change/save.
You can set a default value for the combo.
That should then get that rendered at startup.
Use cell renderer to render the displayField of the combo into your grid. Following a working example that can be poster in one of the API code boxes.
Working JSFiddle
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
fields: ['name', 'email', 'phone', 'id'],
data: {
'items': [{
"name": "Lisa",
"email": "lisa#simpsons.com",
"phone": "555-111-1224",
"id": 0
}, {
"name": "Bart",
"email": "bart#simpsons.com",
"phone": "555-222-1234",
"id": 1
}, {
"name": "Homer",
"email": "home#simpsons.com",
"phone": "555-222-1244",
"id": 2
}, {
"name": "Marge",
"email": "marge#simpsons.com",
"phone": "555-222-1254",
"id": 3
}]
},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});
// the renderer. You should define it within a namespace
var comboBoxRenderer = function(combo) {
return function(value) {
var idx = combo.store.find(combo.valueField, value);
var rec = combo.store.getAt(idx);
return (rec === null ? '' : rec.get(combo.displayField));
};
}
// the combo store
var store = new Ext.data.SimpleStore({
fields: ["value", "text"],
data: [
[1, "Option 1"],
[2, "Option 2"]
]
});
// the edit combo
var combo = new Ext.form.ComboBox({
store: store,
valueField: "value",
displayField: "text"
});
// demogrid
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [{
header: 'Name',
dataIndex: 'name',
editor: 'textfield'
}, {
header: 'Email',
dataIndex: 'email',
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: false
}
}, {
header: 'Phone',
dataIndex: 'phone'
}, {
header: 'id',
dataIndex: 'id',
editor: combo,
renderer: comboBoxRenderer(combo)
}],
selType: 'cellmodel',
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
],
height: 200,
width: 400,
renderTo: Ext.getBody()
});
{
header: 'Your header',
dataIndex: 'your Column',
editor: {
xtype: 'combobox',
store: yourStore,
queryMode: 'local',
displayField: 'Your Display..',
valueField: 'Your Value'
}

Resources