PDA

View Full Version : ListViewTotals plugin



Animal
31 Dec 2009, 7:33 AM
Courtesy of Athena Capital Research who sponsored the development of this plugin, here is a totals plugin for the Ext.list.ListView class.

It totals any columns with a dataIndex field defined as type "int" or "float".

A numeric column may contain a sumFunction member which is a function to perform special processing when adding a cell value to the column total. Its use is demonstrated below.

Drop this example page into example/view



<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>ListView Totals Plugin Example</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<script type="text/javascript" src="../../adapter/ext/ext-base-debug.js"></script>
<script type="text/javascript" src="../../ext-all-debug.js"></script>
<link rel="stylesheet" type="text/css" href="list-view.css" />
<link rel="stylesheet" type="text/css" href="../shared/examples.css" />
<style style="text/css">
div.x-listview-total-row {
clear: left;
overflow: hidden;
zoom: 1;
}

div.x-listview-total-row div.listview-total-cell {
cursor: pointer;
display: block;
float: left;
overflow: hidden;
white-space: nowrap;
}

/* Styling for total cells. */
div.x-listview-total-row div.listview-total-cell em {
-x-system-font: none;
font-family: arial,tahoma,helvetica,sans-serif;
font-size: 11px;
font-size-adjust: none;
font-stretch: normal;
font-style: normal;
font-variant: normal;
font-weight: bold;
line-height: normal;
-moz-user-select: none;
display: block;
overflow: hidden;
padding: 3px 4px;
}
</style>
<script type="text/javascript">

var data = {
"images": [{
"name": "kids_hug2.jpg",
"size": 2476,
"lastmod": 1260763250000,
"url": "images\/thumbs\/kids_hug2.jpg"
}, {
"name": "zack_hat.jpg",
"size": 2323,
"lastmod": 1260763250000,
"url": "images\/thumbs\/zack_hat.jpg"
}, {
"name": "zack.jpg",
"size": 2901,
"lastmod": 1260763250000,
"url": "images\/thumbs\/zack.jpg"
}, {
"name": "zack_sink.jpg",
"size": 2303,
"lastmod": 1260763250000,
"url": "images\/thumbs\/zack_sink.jpg"
}, {
"name": "sara_pink.jpg",
"size": 2154,
"lastmod": 1260763250000,
"url": "images\/thumbs\/sara_pink.jpg"
}, {
"name": "dance_fever.jpg",
"size": 2067,
"lastmod": 1260763250000,
"url": "images\/thumbs\/dance_fever.jpg"
}, {
"name": "gangster_zack.jpg",
"size": 2115,
"lastmod": 1260763250000,
"url": "images\/thumbs\/gangster_zack.jpg"
}, {
"name": "zacks_grill.jpg",
"size": 2825,
"lastmod": 1260763250000,
"url": "images\/thumbs\/zacks_grill.jpg"
}, {
"name": "kids_hug.jpg",
"size": 2477,
"lastmod": 1260763250000,
"url": "images\/thumbs\/kids_hug.jpg"
}, {
"name": "zack_dress.jpg",
"size": 2645,
"lastmod": 1260763250000,
"url": "images\/thumbs\/zack_dress.jpg"
}, {
"name": "sara_pumpkin.jpg",
"size": 2588,
"lastmod": 1260763250000,
"url": "images\/thumbs\/sara_pumpkin.jpg"
}, {
"name": "sara_smile.jpg",
"size": 2410,
"lastmod": 1260763250000,
"url": "images\/thumbs\/sara_smile.jpg"
}, {
"name": "up_to_something.jpg",
"size": 2120,
"lastmod": 1260763250000,
"url": "images\/thumbs\/up_to_something.jpg"
}]
};

Ext.ux.ListViewTotals = Ext.extend(Ext.util.Observable, {
cellTpl: new Ext.Template(
'<div style="width:{width}%;text-align:{align};" class="listview-total-cell">',
'<em unselectable="on" class="{cls}">',
'{value}',
'</em>',
'</div>'
),

init: function(v) {
v.onResize = this.onResize;
v.setHdWidths = this.setHdWidths;
v.refresh = v.refresh.createSequence(this.updateTotals);
v.onUpdate = v.onUpdate.createSequence(this.updateTotals);
},

onResize : function(w, h){
Ext.list.ListView.prototype.onResize.apply(this, arguments);
Ext.ux.ListViewTotals.prototype.updateTotals.call(this);
},

setHdWidths : function(){
Ext.list.ListView.prototype.setHdWidths.apply(this, arguments);
Ext.ux.ListViewTotals.prototype.setFooterWidths.call(this);
},

adjustBodyHeight: function() {
if (this.totalsRow) {
var bdp = Ext.get(this.innerBody.dom.parentNode);
var hdp = this.innerHd.dom.parentNode;
bdp.setHeight(this.el.getHeight() - (hdp.offsetHeight + this.totalsRow.offsetHeight));
Ext.fly(this.totalsRow).setWidth(this.innerBody.dom.offsetWidth);
}
},

setFooterWidths: function() {
Ext.ux.ListViewTotals.prototype.updateTotals.call(this);
},

updateTotals: function() {
if (!this.totalsRow) {
this.totalsRow = this.el.createChild({
tag: 'div',
cls: 'x-listview-total-row'
}, null, true);
}
var cs = this.columns,
nc = cs.length,
totals = {},
store = this.store,
fields = store.recordType.prototype.fields,
i, l = this.store.getCount(), rec,
cells = '', c, nc, csc, f, fn, t, v;
for (i = 0; i < l; i++) {
rec = store.getAt(i);
for (c = 0; c < nc; c++) {
if ((t = fields.get(f = cs[c].dataIndex).type) == 'int' || t == 'float') {
var v = rec.get(f);
if (!Ext.isDefined(totals[f])) {
totals[f] = 0;
}
if (Ext.isFunction(fn = cs[c].sumFunction)) {
totals[f] = fn(totals[f], v);
} else {
totals[f] += v;
}
}
}
}
while(this.totalsRow.firstChild) {
this.totalsRow.removeChild(this.totalsRow.lastChild);
}
for (c = 0; c < nc; c++) {
csc = cs[c];
v = (Ext.isDefined(totals[csc.dataIndex])) ? csc.tpl.apply(totals) : ' ';
cells += Ext.ux.ListViewTotals.prototype.cellTpl.apply({
value: v,
cls: csc.cls || '',
align: csc.align,
width: csc.width * 100
});
}
Ext.DomHelper.insertHtml('afterBegin', this.totalsRow, cells);
Ext.ux.ListViewTotals.prototype.adjustBodyHeight.call(this);
}
});

Ext.onReady(function(){

var store = new Ext.data.JsonStore({
data: data,
root: 'images',
fields: ['name', 'url', {name:'size', type: 'float'}, {name:'lastmod', type:'date', dateFormat:'timestamp'}]
});

var listView = new Ext.list.ListView({
store: store,
multiSelect: true,
emptyText: 'No images to display',
reserveScrollOffset: true,

plugins: new Ext.ux.ListViewTotals(),

columns: [{
header: 'File',
width: .5,
dataIndex: 'name'
},{
header: 'Last Modified',
xtype: 'datecolumn',
format: 'm-d h:i a',
width: .35,
dataIndex: 'lastmod'
},{
header: 'Size',
dataIndex: 'size',
tpl: '{size:fileSize}',
align: 'right',
cls: 'listview-filesize',
sumFunction: function(total, value) {
return total + Math.abs(value) * 10;
}
}]
});

// put it in a Panel so it looks pretty
var panel = new Ext.Panel({
id:'images-view',
width:425,
height:250,
collapsible:true,
layout:'fit',
title:'Simple ListView <i>(0 items selected)</i>',
items: listView
});
panel.render(document.body);

// little bit of feedback
listView.on('selectionchange', function(view, nodes){
var l = nodes.length;
var s = l != 1 ? 's' : '';
panel.setTitle('Simple ListView <i>('+l+' item'+s+' selected)</i>');
});
});
</script>
</head>
<body>
<h1>ListView Totals Plugin Example</h1>
</body>
</html>

medusadelft
4 Jun 2010, 11:01 AM
Hi Animal,

It might just be me, but I don't see any totals anywhere. Only a count of the number of selected records in the header.
I'm using Ext.3.2.1 & FF3.5
No errors in Firebug...

Thanks in advance,
Maurice

Animal
5 Jun 2010, 12:47 AM
Just a guess, but:



It totals any columns with a dataIndex field defined as type "int" or "float".

medusadelft
5 Jun 2010, 11:09 PM
Even YOUR example doesn't show a total!

b091
1 Oct 2010, 4:09 AM
You need to change one line to get it work.

As fields.get(f = cs[c].dataIndex).type returns an object so the if statement has to be chnged from :

if ((t = fields.get(f = cs[c].dataIndex).type) == 'int' || t == 'float') {To:

if ((t = fields.get(f = cs[c].dataIndex).type.type) == 'int' || t == 'float') {line 172 in Animal's example

After that it works just fine.