"each" method in extjs data store - extjs

So, I got a data store in my code that I'm loading in a function. In that store I want to use the each method to append each record to the body of a panel in a certain format.
What I'm trying to figure out is how to use this "each" method. Has anyone ever had to use it before? I'm relatively new to functions and programming in general so I'm trying to figure out what the "fn" and "scope" are relative to my own code.
Any help would be awesome if anyone has used this method in the ExtJS framework before.

Use Dataview for your case. Add the store and the XTemplate to your dataview and add this dataview as an item to your panel. It will be something like this:
this.store = new Ext.data.JsonStore({
url : 'myproxy.php',
baseParams : {
action : 'get_basket_files'
},
root : 'rows',
id : 'filename',
fields : ['filename', 'filepath', 'filesize', 'fileclass']
});
this.filesTemplate = new Ext.XTemplate(
'<div class="files_container"><tpl for=".">',
'<div id="{filename}" class="basket-fileblock"><div class="{fileclass}"></div>',
'<div class="filetext">{filename}</div></div> ','</tpl></div>');
this.filesTemplate.compile();
this.filesDataView = new Ext.DataView({
itemSelector : 'div.basket-fileblock', //Required
style : 'overflow:auto',
multiSelect : true,
store : this.store,
tpl : this.filesTemplate
});
var panel = new Ext.Panel({
layout : 'fit',
items : [this.filesDataView]
});
Here XTemplate is the HTML template of each of the items. Have a look at the ExtJS documentation which provides a number of examples for XTemplate.
And for an example, ExtJS each function can be used this way:
Suppose an array of items is myItems. So,
Ext.each(myItems, function(eachItem){
//Do whatever you want to do with eachItem
}, this);

It sounds like you want an Ext.DataView.
DataView use Template or XTemplate to create a rendering of data in a store.
So you instantiate a configured dataview, including a reference to your store, and the template to use, and add that DataView to your panel.

Related

ExtJS 4.2.1 Grid view overriden with custom XTemplate shows nothing

I am working on a switch from version 4.1.1 to 4.2.1 and finally I need to fix hopefully the last bug. We have a gridview with view being overriden by simple (?) Ext.XTemplate, as follows:
Ext.define('view.monitoring.Event',
{
extend: 'Ext.view.View',
alias: 'widget.default_monitoring_event',
itemSelector: '.monitoring-thumb-fumb',
tplWriteMode: 'overwrite',
autoWidth: true,
initComponent: function()
{
var tplPart1 = new Ext.XTemplate('<SOME HTML 1>');
var tplPart2 = new Ext.XTemplate('<SOME HTML 2>');
var tplPart3 = new Ext.XTemplate('<SOME HTML 3>');
var tplPart4 = new Ext.XTemplate('<SOME HTML 4>');
this.tpl = new Ext.Template('<BUNCH OF HTML AND TPL and TPL INSIDE TPL',
callFunc1: function(data) { /* do something with tplPart1 */ },
callFunc2: function(data) { /* do something with tplPart2 */ },
callFunc3: function(data) { /* do something with tplPart3 */ },
callFunc4: function(data) { /* do something with tplPart4 */ },
);
this.callParent(arguments;
}
}
This view is set for the grid in this way:
Ext.define('view.monitoring.WeeklyOverview',
{
extend: 'Ext.grid.Panel',
alias: 'widget.default_monitoring_weeklyoverview',
layout: 'border',
title: Lang.translate('event_monitoring_title'),
overflowX: 'hidden',
overflowY: 'auto',
initComponent: function()
{
//...
this.view = Ext.widget('default_monitoring_event', {
store: Ext.create('store.monitoring.Rows')
});
//...
}
}
Then in controller onRender the stores gets populated (the store of the grid is AJAX, loads the data and passes them to a memory store of the view). In ExtJS 4.1.1 this is working properly, data are loaded and the template is parsed and HTML is displayed containing the data.
But after the switch to 4.2.1 the HTML is no longer filled with the data and nothing is displayed but an empty HTML table (which appears as like nothing would be rendered). As there is at least some part of HTML but no data, I guess the problem might be with the data being applied for the template.
Does anybody know what might be/went wrong?
UPDATE: After debugging and the custom view template simplification I have found out, that even the custom view has set it's own store with it's own root for the data returned, it ignores that setting and simply loads the data for the store of the Ext.grid.Panel component. The AJAX response looks like:
{
user: {},
data: [
0: { ... },
1: { ... },
...
],
rows: [
0: { ... },
1: { ... },
...
]
}
Here the data should be used for Ext.grid.Panel component and the rows should be then populated by the custom view (configured with Ext.XTemplate). Seems like for the children views always the parent's store's root element is returned. Any way how to workaround this behaviour and make the custom view to use it's own store???
Finally found a solution.
The problem was that after the main grid.Panel loaded the data it distributed them also to it's (sub)view. After that even I had manually loaded the right data into this custom XTemplate, it needed to also manually override previously rendered view.
In my controller (init -> render) I needed to do this:
var me = this;
this.getMainView().store.load({
params: params || {},
callback: function(records, operation, success) {
// this line was already there, working properly for ExtJS 4.1.1, probably is now useless for ExtJS 4.2.1 with the next line
me.getCustomView().store.loadRawData(this.proxy.reader.rawData);
// I had to add this line for ExtJS 4.2.1...
me.getCustomView().tpl.overwrite(me.getCustomView().el, this.proxy.reader.rawData.rows);
}
});
This is kinda strange as I thought that with a definition within a custom view (see my question above)
tplWriteMode: 'overwrite',
it should just automatically overwrite it's view...

How to implement jqGrid with Marionette?

I am trying to render jqGrid in my Marionette application, everything goes fine until I cannot find the way to render the pager.
I am using Handlebars that holds the template, this is the code:
hb template:
<script id='llantas_grid_tmpl' type='text/x-handlebars-template'>
<table id='llantas_catalog_list'></table>
<div id="llantas_catalog_pager">pager</div>
</script>
layout...
ui: {
table: '#llantas_catalog_list',
pager: '#llantas_catalog_pager'
},
onRender: function(){
var table = this.ui.table,
pager = this.ui.pager;
table
.jqGrid({
url: '/llantas',
datatype: "json",
colNames:['Id','Orden De Compra', 'Marca', 'Medida', 'Modelo'],
colModel:[
{name:'id',index:'id', width:55},
{name:'ordencompra',index:'ordencompra', width:90},
{name:'marca',index:'marca', width:90},
{name:'medida',index:'medida', width:90},
{name:'modelo',index:'modelo', width:90}
],
rowNum:10,
rowList:[10,20,30],
pager: '#llantas_catalog_pager',
width:1060,
height:375,
sortname: 'id',
viewrecords: true,
sortorder: "desc",
caption:"<h3>Catalogo llantas<h3>"
});
table
.jqGrid('navGrid','#llantas_catalog_pager',{edit:false,add:false,del:false});
}
is there a way to set the pager placeholder into the jqGrid as object?
like this:
table
.jqGrid('navGrid',pager,{edit:false,add:false,del:false});
EDIT: PLEASE ANSWER ONLY IF YOU KNOW BACKBONE MARIONETTE AND JQGRID.
In a word, No.
jqGrid does a check to make sure it is a string,
if(!$t.grid || typeof elem !== 'string') {return;}
You would need to modify the jqGrid source.
I found the way to make it work:
Once the child view (the one I was trying to render with jqGrid) has been rendered and displayed in the region of the main view I just search for the template table selector and pass the pager id inside the jqGrid pager option.
main layout...
onRender: function(){
// llantasGridView is the view holding only the template without the jqGrid (I erased everything)
var llantasGridView = new LlantasGrid.View();
// table_container is the region that will hold the llantasGridView template
this.table_container.show( llantasGridView );
// once is rendered I search for the table
var table = llantasGridView.$el.find('#llantas_catalog_list');
// here I pass the jqGrid
table
.jqGrid({
url: G.API + '/llantas',
datatype: "json",
colNames:['Id','PO'...
pager: '#llantas_catalog_pager', // pager for grid is now being displayed
...

How get html content from panel in ExtJs

I am new to ExtJs.
I have been facing a problem in panels for getting panel html content.
xtype : 'panel',
id : 'first_block',
html : '<p>Hi this is belongs to first block.</p>',
listeners : {
render : function(c) {
c.body.on('click', function() {
alert('' + this.id);
alert(Ext.getCmp('first_block').items.getAt(0).getValue());
});
}
I am not getting html content, but i am getting id like "first_block-body".
Thanks in advance.
The html property defined the HTML you want in the content of your component, in this case an Ext.Panel.
Ext.Panels create a few layers of divs in order to provide things like headers, footers, toolbars, etc.
If all you want is a div with some content, you instead want to use an Ext.Component. Components don't have a body, so a couple things change in your code.
xtype : 'component',
id : 'first_block',
html : '<p>Hi this is belongs to first block.</p>',
listeners : {
render : function(c) {
c.on('click', function() {
alert('' + this.id);
alert(this.el.dom.innerHTML);
}, this);
}
Notice that I added a third parameter to your on call, which specifies the this scope of the function call. I also edited your alert to print out the innerHTML of the element, assuming that's what you were trying to do.
UPDATE:
If you are going to use this component in a layout, it may need to be able to have its height and width set, meaning it needs to be of type box in order to be an Ext.BoxComponent.
Ext.getElementById('yourId').innerHTML

Nested Grid IN EXTJS

HI
How to design Nested grids in ExtJS
Please provide some samples(How to use RowExpander in ExtJS GridPanel)
Try something like this:
//Create the Row Expander.
var expander = new Ext.ux.grid.RowExpander({
tpl : new Ext.Template('<div id="myrow-{Id}" ></div>')
});
//Define the function to be called when the row is expanded.
function expandedRow(obj, record, body, rowIndex){
//absId parameter for the http request to get the absence details.
var absId = record.get('Id');
var dynamicStore = //the new store for the nested grid.
//Use Id to give each grid a unique identifier. The Id is used in the row expander tpl.
//and in the grid.render("ID") method.
var row = "myrow-" + record.get("Id");
var id2 = "mygrid-" + record.get("Id");
//Create the nested grid.
var gridX = new Ext.grid.GridPanel({
store: dynamicStore,
stripeRows: true,
columns: [
//columns
],
height: 120,
id: id2
});
//Render the grid to the row expander template(tpl).
gridX.render(row);
gridX.getEl().swallowEvent([ 'mouseover', 'mousedown', 'click', 'dblclick' ]);
}
//Add an expand listener to the Row Expander.
expander.on('expand', expandedRow);
You can find more information on this Here
How to use RowExpander in grid? Here's an example: http://dev.sencha.com/deploy/dev/examples/grid/grid-plugins.html
More examples can be found from http://dev.sencha.com/deploy/dev/examples/
It is possible to do it as the others have mentioned, however I recommend against it.
Reasons:
Memory leaks due to the sub-grids not being destroyed properly.
Selection model doesn't work correctly
Events get messed up.

Extjs Dynamic Grid

I'm trying to create a dynamic grid using ExtJS. The grid is built and displayed when a click event is fired then an ajax request is sent to the server to fetch the columns, records and records definition a.k.a store fields.
Each node could have different grid structure and that depends on the level of the node in the tree.
The only way I came up with so far is :
function showGrid(response, request) {
var jsonData = Ext.util.JSON.decode(response.responseText);
var grid = Ext.getCmp('contentGrid' + request.params.owner);
if (grid) {
grid.destroy();
}
var store = new Ext.data.ArrayStore({
id: 'arrayStore',
fields: jsonData.recordFields,
autoDestroy: true
});
grid = new Ext.grid.GridPanel({
defaults: {
sortable: true
},
id: 'contentGrid' + request.params.owner,
store: store,
columns: jsonData.columns,
//width:540,
//height:200,
loadMask: true
});
store.loadData(jsonData.records);
if (Ext.getCmp('tab-' + request.params.owner)) {
Ext.getCmp('tab-' + request.params.owner).show();
} else {
grid.render('grid-div');
Ext.getCmp('card-tabs-panel').add({
id: 'tab-' + request.params.owner,
title: request.params.text,
iconCls: 'silk-tab',
html: Ext.getDom('grid-div').innerHTML,
closable: true
}).show();
}
}
The function above is called when a click event is fired
'click': function(node) {
Ext.Ajax.request({
url: 'showCtn',
success: function(response, request) {
alert('Success');
showGrid(response, request);
},
failure: function(results, request) {
alert('Error');
},
params: Ext.urlDecode(node.attributes.options);
}
});
}
The problem I'm getting with this code is that a new grid is displayed each time the showGrid function is called. The end user sees the old grids and the new one. To mitigate this problem, I tried destroying the grid and also removing the grid element on each request, and that seems to solve the problem only that records never get displayed this time.
if (grid) {
grid.destroy(true);
}
The behaviour I'm looking for is to display the result of a grid within a tab and if that tab exists replaced the old grid.
Any help is appreciated.
When you are trying to add your grid to the tab like this:
html:Ext.getDom('grid-div').innerHTML,
Ext is not aware of it being a valid grid component. Instead, you are simply adding HTML markup that just happens to look like a grid, but the TabPanel will not be aware that it is a grid component.
Instead you should add the grid itself as the tab (a GridPanel is a Panel and does not need to be nested into a parent panel). You can do so and also apply the needed tab configs like this:
Ext.getCmp('card-tabs-panel').add({
Ext.apply(grid, {
id: 'tab-' + request.params.owner,
title: request.params.text,
iconCls: 'silk-tab',
closable: true
});
}).show();
BTW, constantly creating and destroying grids is not an ideal strategy if you can avoid it. It might be better to simply hide and re-show grids (and reload their data) based on which type of grid is needed if that's possible (assuming the set of grid types is finite).
A potential option is to use the metaData field on the JsonStore that allows dynamic reconfiguring of the grid columns as per new datasets.
From
One of the most helpful blog posts about this that Ive found is this one:
http://blog.nextlogic.net/2009/04/dynamic-columns-in-ext-js-grid.html and the original info is well documented at http://docs.sencha.com/ext-js/3-4/#!/api/Ext.data.JsonReader

Resources