Sencha touch: Using XTemplate - javascript

I have a store with which i am populating a list. The store is as follows:
Ext.define('EventReminder.store.Upcoming', {
extend: 'Ext.data.Store',
requires: ['Ext.data.proxy.SQL'],
config: {
autoLoad: true,
storeId: 'Upcoming',
model: 'EventReminder.model.Event',
proxy: {
type: 'sql',
database: 'EventReminder',
table: 'NewEvents'
},
sorters: [{property: 'date', direction: 'ASC'}]}
});
The list is as follows:
{
xtype: 'list',
flex: 1,
autoDestroy: false,
itemId: 'upcomingEventList',
onItemDisclosure: true,
store: 'Upcoming',
cls: 'event-list',
scrollable: true,
}
I have created an XTemplate for this list as follows:
var xtpl = new Ext.XTemplate(
'<tpl for=".">',
' <tpl if="priority == \'high\'">',
' <div class = "color-event-high">',
' <div class="event-category">{category}</div>',
' <div class="event-date">On: {date} at: {eventTime}</div>',
' <div>Alert at : {alertTime}</div>',
' <div class="event-people">People: {people}</div>',
' <div class="event-message">{message}</div>',
' <div class="event-priority">{priority}</div>',
' <div class="event-activities">{activities}</div>',
' </div>',
' </tpl>',
'</tpl>'
);
Here i want to give a styling based on the priority value of the list item. I have set the tpl of the list as follows in the view's initialize function as follows:
this.down("#upcomingEventList").setItemTpl(xtpl);
I Normally specify ItemTpl for a list directly in its config and don't know much about using XTemplates. So when i use the above Xtemplate the list doesn't show the items. I've checked the documentation and but could'nt understand how these XTemplates work. I've seen other answers for similar questions but did'nt help much.
Is this the correct way to write an XTemplate for a List, if we want some conditional styling based on the list items?

Related

What is tpl and how do I interprete it in extJS context?

Ext.define('App.view.util.NavigationView', {
extend: 'Ext.panel.Panel',
tpl: [''
,'<ul class="app-navigation-container">'
, '<tpl for=".">'
, '<a href="#{navigationToken}">'
,'<li class="app-navigation-pane {iconCls}">'
, '<h2>{title}</h2>'
, '<p>{description}</p>'
, '</li>'
, '</a>'
, '</tpl>'
, '</ul>'
, '<div class="x-clear"></div>'
]
});
I am new to ExtJS and I am debugging some small client-side issues which involved ExtJS. How can I update the
navigationToken variable in other files. I have some listeners like 'select' listener in which I would like to change the value for navigationToken.
Your component has a property called 'data', which is part of the extended panel. This property is used to provide the template as defined in 'tpl' with data, which can set as a property.
So in your listener you can set the data property by calling
var data = [{
navigationToken: 'navigationToken1',
iconCls: 'iconCls',
title: 'title1',
description: 'description1'
}, {
navigationToken: 'navigationToken1',
iconCls: 'iconCls',
title: 'title2',
description: 'description2'
}];
[view].update(data);
where [view] should references to your 'App.view.util.NavigationView'.

Refreshing a dataview in Panel in extjs 3.4

I have an extjs Panel component that contain a dataview item. I use this to display the images from a store. It works as expected during the first load. But later when I reload the imgStore with new image url's (which occurs when user searches and loads a different city) the view does not refresh. Can someone point me in the best way to refresh the panel/dataview item when the associated datastore is refreshed?
The actual code has more than one item in the panel and many other buttons and toolbars. Please see the relevant part of the code below:
init: function() {
// image store
this.imgStore = new Ext.data.JsonStore({
idProperty: 'imgId',
fields: [{
name: 'imgId',
type: 'integer',
mapping: 'imgId'
}, {
name: 'url',
mapping: 'url'
}],
data: [],
});
// load images
Ext.each(myImgStore.data.items, function(itm, i, all) {
this.imgStore.loadData(itm.data, true);
});
// add to a dataview in a panel
this.myPanel = new Ext.Panel({
autoScroll: true,
items: [{
xtype: 'dataview',
store: this.imgStore,
autoScroll: true,
id: 'imgList',
tpl: new Ext.XTemplate(
'<ul class="imgGrid">',
'<tpl for=".">',
'<li>',
'<div class=\"imgThumbnail\" imgId="{imgId}">',
'<img src="{url}"/>',
'</div>',
'</li>',
'</tpl>',
'</ul>',
'<div class="x-clear"></div>'
),
listeners: {
afterrender: function() {
// do something
}
}
}]
});
// add this to the center region of parentpanel
Ext.getCmp('parentPanel').add([this.myPanel]);
this.myPanel.doLayout();
}
Everytime the store is reloaded, I want the dataview to be refreshed. I'm using extjs 3.4 version.
Thanks!
You need to refresh your dataview. I suggest putting it into a variable.
var dataView = new Ext.DataView({
store: this.imgStore,
autoScroll: true,
id: 'imgList',
tpl: new Ext.XTemplate(
.
.
.
),
listeners: {
afterrender: function() {
// do something
}
}
});
Then add a listener in your store:
this.imgStore = new Ext.data.JsonStore({
idProperty: 'imgId',
fields: [{
name: 'imgId',
type: 'integer',
mapping: 'imgId'
}, {
name: 'url',
mapping: 'url'
}],
data: []
});
// Define your dataView here
this.imgStore.on('load', function() {
dataView.refresh();
});
Note: Code is not tested.

Paging toolbar on custom component querying local data store

I have a few questions regarding paging a Ext Store.
The Store will pull an amount of historical data on page load.
If the number of records is greater than 10 then I need to implement paging on a custom component/view. The view will be generated with Ext.view.View and a XTemplate.
I would like to know if i can use the paging toolbar on a custom component and if i can query a Store where all the data is held locally. Therefore, not passing parameters to the server and pulling new data back but querying the data Store itself and displaying the results to the user.
It is possible using the Ext.ux.data.PagingMemoryProxy proxy. It is located in examples\ux\data\PagingMemoryProxy.js
The follow example show you how to paging images in a custom view create with generated with Ext.view.View and a XTemplate:
Ext.define('Image', {
extend: 'Ext.data.Model',
fields: [
{ name:'src', type:'string' },
{ name:'caption', type:'string' }
]
});
Ext.create('Ext.data.Store', {
id:'imagesStore',
model: 'Image',
proxy: {
type: 'pagingmemory'
},
data: [
{ src:'http://www.sencha.com/img/20110215-feat-drawing.png', caption:'Drawing & Charts' },
{ src:'http://www.sencha.com/img/20110215-feat-data.png', caption:'Advanced Data' },
{ src:'http://www.sencha.com/img/20110215-feat-html5.png', caption:'Overhauled Theme' },
{ src:'http://www.sencha.com/img/20110215-feat-perf.png', caption:'Performance Tuned' }
],
pageSize: 2
});
var imageTpl = new Ext.XTemplate(
'<tpl for=".">',
'<div style="margin-bottom: 10px;" class="thumb-wrap">',
'<img src="{src}" />',
'<br/><span>{caption}</span>',
'</div>',
'</tpl>'
);
var store = Ext.data.StoreManager.lookup('imagesStore');
Ext.create('Ext.panel.Panel', {
title: 'Pictures',
autoScroll: true,
height: 300,
items: {
xtype: 'dataview',
store: store,
tpl: imageTpl,
itemSelector: 'div.thumb-wrap',
emptyText: 'No images available'
},
dockedItems: [{
xtype: 'pagingtoolbar',
store: store,
dock: 'bottom',
displayInfo: true
}],
renderTo: Ext.getBody()
});​
You can see it working in jsfiddle.net: http://jsfiddle.net/lontivero/QHDZU/
I hope this is useful.
Good luck!

How to implement this custom grid in ExtJS?

I am new to ExtJS. Currently I have grid implemented as shown below.
But I want to show the same information in a different way like showing in boxes, as shown below. How do I implement this?
You haven't specified which version of Ext JS you are using. So, will give you solution for both versions:
In ExtJS 3.x
You can make use of the Ext.DataView class. Here is an example of dataview. Even though the example makes use of the images, you can easily modify the view, but changing the template. Now, you have to work on the pagination bar. You will have to make use of the bbar property and create a toolbar. This toolbar will have your navigation buttons. So, you will have something like this:
var panel = new Ext.Panel({
id:'person-view',
frame:true,
title:'User Grid',
bbar: [{
text: Prev,
iconCls: 'prev-icon'
},{
text: Next,
iconCls: 'next-icon'
}],
items: new Ext.DataView({
store: yourStore,
tpl: yourTemplate,
autoHeight:true,
multiSelect: false,
overClass:'x-view-over',
itemSelector:'div.thumb-wrap',
emptyText: 'No users to display',
})
});
[Obviously, the above code is not complete. You will have to add your store, template, other properties and event listeners according to user needs.]
In ExtJS 4.x
You will have to make use of Ext.view.View class. Here is a skeleton code:
Ext.define('MyApp.view.members.Display',{
extend: 'Ext.panel.Panel',
alias : 'widget.memberslist',
initComponent: function() {
this.template = Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="member">',
'Name : {name} <br/>',
'Title : {title}',
'</div>',
'</tpl>'
);
this.store = Ext.create('MyApp.store.Members');
this.bbar = this.buildToolbar();
this.items = this.buildItems();
this.callParent(arguments);
},
buildItems: function() {
return [{
xtype: 'dataview',
store: this.store,
id: 'members',
tpl: this.template,
itemSelector: 'div.member',
overItemCls : 'member-hover',
emptyText: 'No data available!'
}]
},
buildToolbar : function() {
return [{
text: 'Previous',
action: 'prev'
},{
text: 'Next',
action: "next"
}];
}
});
The above code makes use of the new MVC architecture. You will have to add the event listeners etc in your controller.

Sencha Touch List 'sticks' when in a Panel with other elements

I have a Panel where I would like to have some other elements in it and a list. When I have the list in the parent panel on it's own, the list functions properly. However, when I add another item to the parent panel, the list now won't scroll downward (it's no longer constrained to the size of the screen).
This is how I'd like my layout to be:
Viewport
|--------------------|
| Revenue Panel |
|--------------------|
| EventList |
| |
|--------------------|
Though the list appears to be getting rendered offscreen for all of the data in it's store.
This is what I have for my view:
DashboardIndex.js
shopifymobile.views.DashboardIndex = Ext.extend(Ext.Panel, {
dockedItems: [
{
xtype: 'toolbar',
title: 'SHOP NAME',
dock: 'top',
defaults: {
iconMask: true,
ui: 'plain'
},
items: [
{xtype: 'spacer'},
{
iconCls: 'refresh',
listeners: {
'tap' : function(){
shopifymobile.stores.onlineEventStore.load();
}
}
}
]
}
],
layout: 'fit',
fullscreen: true,
});
Revenue.js
shopifymobile.views.RevenuePanel = Ext.extend(Ext.Panel, {
styleHtmlContent: true,
flex: 1,
items: [
{
tpl: [
'<div class="revenuepanel">',
'<div id="revenuedata">',
'<h3 class="label">TODAY\'S REVENUE</h3>',
'<p>{revenue}</p>',
'</div>',
'<div id="orderdata">',
'<div id="orders">',
'<p><span class="label">ORDERS</span>{count}</p>',
'</div>',
'<div id="items">',
'<p><span class="label">ITEMS</span>{items}</p>',
'</div>',
'</div>',
'</div>'
],
}
],
updateWithRecord: function(record){
Ext.each(this.items.items, function(item){
item.update(record.data);
});
},
//*************HACK FIXME***********************
fetchStoreData: function(){
var store = shopifymobile.stores.onlineProductStore;
this.updateWithRecord(store.getAt(0));
store.removeListener('load', this.fetchStoreData);
},
initComponent: function(){
shopifymobile.stores.onlineProductStore.addListener('load', this.fetchStoreData, this);
shopifymobile.stores.onlineProductStore.load();
shopifymobile.views.RevenuePanel.superclass.initComponent.apply(this, arguments);
}
});
EventList.js
shopifymobile.views.EventList = Ext.extend(Ext.Panel, {
layout: 'fit',
items: [
{
id: 'eventList',
xtype: 'list',
store: shopifymobile.stores.onlineEventStore,
itemTpl: [
'<div class="eventitem">',
'<div id="eventdata">',
'<ul>',
'<li>New {verb}</li>',
'<li>{message}</li>',
'<ul>',
'</div>',
'<div id="eventtime">',
'<p>{created_at}</p>',
'</div>',
'</div>'
]
},
],
initComponent: function(){
shopifymobile.views.OrderList.superclass.initComponent.apply(this, arguments);
}
});
When I initialize my Viewport I add a new RevenuePanel and Eventlist to a dashboardIndex object:
shopifymobile.views.dashboardIndex.add(new shopifymobile.views.RevenuePanel());
shopifymobile.views.dashboardIndex.add(new shopifymobile.views.EventList());
The only way I can get the list to somewhat work is if I set it to fullscreen, but since i have a toolbar on the bottom of my screen the last item is being overlapped by it.
The way I've done this is to embed the list inside of a panel, and that panel containing should use layout:fit. I've also had to specify width :100% in the containing panel but that may vary based on your specific case. Here's what I did - note that I'm also using DataVIew and not Panel as the list base, but it should work either way.
var panel = new Ext.Panel({
flex: 1,
frame:true,
autoHeight: true,
collapsible: true,
width: '100%',
layout: 'fit',
items: [
new Ext.DataView({.....} ) ] } );

Categories

Resources