PDA

View Full Version : Collapse "Group Header" and "Summary" in single row



joseaio
20 Aug 2010, 8:41 AM
I think this (mini) hack is very interesting :)



.x-grid-group-collapsed .x-grid-group-hd .x-grid-group-title {
position: absolute;
float: left;
}
See images (collapsed and expanded), see summary row goes to header (when collapsed) and goes to end (when expanded)

All groups (and sumaries collapsed): in three rows

22058

Expand first group (see how totals go to end of group):

22057

divyendu
14 Sep 2010, 8:51 AM
this does not work with the code in examples.....not with extjs 2.x.

this is the html code:


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Grid3 Group Summary Plugin</title>

<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />

<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->

<script type="text/javascript" src="../../ext-all.js"></script>


<script type="text/javascript" src="GroupSummary.js"></script>
<script type="text/javascript" src="totals.js"></script>

<link rel="stylesheet" type="text/css" href="summary.css" />
<link rel="stylesheet" type="text/css" href="grid-examples.css" />

<!-- Common Styles for the examples -->
<link rel="stylesheet" type="text/css" href="../shared/examples.css" />

<style type="text/css">
.negative {
color: #dd0000;
}
.positive {
color: green;
}
.x-grid-group-collapsed .x-grid-group-hd .x-grid-group-title {
position: absolute; !important
float: left; !important
}
.x-grid3-cell-inner {
font-family:"segoe ui",tahoma, arial, sans-serif;
}

.x-grid-group-hd div {
font-family:"segoe ui",tahoma, arial, sans-serif;
}

.x-grid3-hd-inner {
font-family:"segoe ui",tahoma, arial, sans-serif;
font-size:12px;
}
.x-grid3-body .x-grid3-td-cost {
background-color:#f1f2f4;
}
.x-grid3-summary-row .x-grid3-td-cost {
background-color:#e1e2e4;
}
.icon-grid {
background-image:url(../shared/icons/fam/grid.png) !important;
}
.x-grid3-dirty-cell {
background-image:none;
}
</style>
</head>
<body>
<script type="text/javascript" src="../shared/examples.js"></script><!-- EXAMPLES --> <h1>Group Summary Plugin</h1> <p>Note that the js is not minified so it is readable. See <a href="totals.js">totals.js</a>.</p>

</body>
</html>
the js:


/*
* Ext JS Library 2.2.1
* Copyright(c) 2006-2009, Ext JS, LLC.
* licensing@extjs.com
*
* http://extjs.com/license
*/

Ext.onReady(function(){

Ext.QuickTips.init();

var xg = Ext.grid;

var reader = new Ext.data.JsonReader({
idProperty:'taskId',
fields: [
{name: 'projectId', type: 'int'},
{name: 'project', type: 'string'},
{name: 'taskId', type: 'int'},
{name: 'description', type: 'string'},
{name: 'estimate', type: 'float'},
{name: 'rate', type: 'float'},
{name: 'cost', type: 'float'},
{name: 'due', type: 'date', dateFormat:'m/d/Y'}
]

});

// define a custom summary function
Ext.grid.GroupSummary.Calculations['totalCost'] = function(v, record, field){
return v + (record.data.estimate * record.data.rate);
}

var summary = new Ext.grid.GroupSummary();

var grid = new xg.EditorGridPanel({
ds: new Ext.data.GroupingStore({
reader: reader,
data: xg.dummyData,
sortInfo:{field: 'due', direction: "ASC"},
groupField:'project'
}),

columns: [
{
id: 'description',
header: "Task",
width: 80,
sortable: true,
dataIndex: 'description',
summaryType: 'count',
hideable: false,
summaryRenderer: function(v, params, data){
return ((v === 0 || v > 1) ? '(' + v +' Tasks)' : '(1 Task)');
},
editor: new Ext.form.TextField({
allowBlank: false
})
},{
header: "Project",
width: 20,
sortable: true,
dataIndex: 'project'
},{
header: "Due Date",
width: 25,
sortable: true,
dataIndex: 'due',
summaryType:'max',
renderer: Ext.util.Format.dateRenderer('m/d/Y'),
editor: new Ext.form.DateField({
format: 'm/d/Y'
})
},{
header: "Estimate",
width: 20,
sortable: true,
dataIndex: 'estimate',
summaryType:'sum',
renderer : function(v){
return v +' hours';
},
editor: new Ext.form.NumberField({
allowBlank: false,
allowNegative: false,
style: 'text-align:left'
})
},{
header: "Rate",
width: 20,
sortable: true,
renderer: Ext.util.Format.usMoney,
dataIndex: 'rate',
summaryType:'average',
editor: new Ext.form.NumberField({
allowBlank: false,
allowNegative: false,
style: 'text-align:left'
})
},{
id: 'cost',
header: "Cost",
width: 20,
sortable: false,
groupable: false,
renderer: function(v, params, record){
return Ext.util.Format.usMoney(record.data.estimate * record.data.rate);
},
dataIndex: 'cost',
summaryType:'totalCost',
summaryRenderer: Ext.util.Format.usMoney
}
],

view: new Ext.grid.GroupingView({
forceFit:true,
showGroupName: false,
enableNoGroups:false, // REQUIRED!
hideGroupedColumn: true
}),

plugins: summary,

frame:true,
width: 800,
height: 450,
clicksToEdit: 1,
collapsible: true,
animCollapse: false,
trackMouseOver: false,
//enableColumnMove: false,
title: 'Sponsored Projects',
iconCls: 'icon-grid',
renderTo: document.body
});
});

Ext.grid.dummyProjects = [
{projectId: 100, project: 'Ext Forms: Field Anchoring'},
{projectId: 101, project: 'Ext Grid: Single-level Grouping'},
{projectId: 102, project: 'Ext Grid: Summary Rows'} ];

Ext.grid.dummyData = [
{projectId: 100, project: 'Ext Forms: Field Anchoring', taskId: 112, description: 'Integrate 2.0 Forms with 2.0 Layouts', estimate: 6, rate: 150, due:'06/24/2007'},
{projectId: 100, project: 'Ext Forms: Field Anchoring', taskId: 113, description: 'Implement AnchorLayout', estimate: 4, rate: 150, due:'06/25/2007'},
{projectId: 100, project: 'Ext Forms: Field Anchoring', taskId: 114, description: 'Add support for multiple types of anchors', estimate: 4, rate: 150, due:'06/27/2007'},
{projectId: 100, project: 'Ext Forms: Field Anchoring', taskId: 115, description: 'Testing and debugging', estimate: 8, rate: 0, due:'06/29/2007'},
{projectId: 101, project: 'Ext Grid: Single-level Grouping', taskId: 101, description: 'Add required rendering "hooks" to GridView', estimate: 6, rate: 100, due:'07/01/2007'},
{projectId: 101, project: 'Ext Grid: Single-level Grouping', taskId: 102, description: 'Extend GridView and override rendering functions', estimate: 6, rate: 100, due:'07/03/2007'},
{projectId: 101, project: 'Ext Grid: Single-level Grouping', taskId: 103, description: 'Extend Store with grouping functionality', estimate: 4, rate: 100, due:'07/04/2007'},
{projectId: 101, project: 'Ext Grid: Single-level Grouping', taskId: 121, description: 'Default CSS Styling', estimate: 2, rate: 100, due:'07/05/2007'},
{projectId: 101, project: 'Ext Grid: Single-level Grouping', taskId: 104, description: 'Testing and debugging', estimate: 6, rate: 100, due:'07/06/2007'},
{projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 105, description: 'Ext Grid plugin integration', estimate: 4, rate: 125, due:'07/01/2007'},
{projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 106, description: 'Summary creation during rendering phase', estimate: 4, rate: 125, due:'07/02/2007'},
{projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 107, description: 'Dynamic summary updates in editor grids', estimate: 6, rate: 125, due:'07/05/2007'},
{projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 108, description: 'Remote summary integration', estimate: 4, rate: 125, due:'07/05/2007'},
{projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 109, description: 'Summary renderers and calculators', estimate: 4, rate: 125, due:'07/06/2007'},
{projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 110, description: 'Integrate summaries with GroupingView', estimate: 10, rate: 125, due:'07/11/2007'},
{projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 111, description: 'Testing and debugging', estimate: 8, rate: 125, due:'07/15/2007'} ];
any help on how to make this hack work with this example?

joseaio
14 Sep 2010, 9:36 AM
Only for 3.2 version... (I don't work with 2.X version)

Try with:



.x-grid-group-collapsed .x-grid-group-hd div{
position: absolute; !important
float: left; !important
}

divyendu
14 Sep 2010, 11:27 AM
worked perfectly joseaio! thanks so much :-)

just for my understanding, could you pls tell me what makes it work when we add the 'div' in the code?

joseaio
15 Sep 2010, 1:57 AM
You can install Firebug (on your Firefox browser) and see de HTML/CSS Styles of ExtJS components (to understand CSS selectors you can see W3Schools)

ExTriqui
24 Sep 2010, 3:52 AM
I think I have improved it a little bit. Just in case your group header and summary overlap.

When collapsed you hide the header.


.x-grid-group-collapsed .x-grid-group-hd .x-grid-group-title {
position: absolute;
float: left;
width: 0px;
padding-right: 0px;
overflow: hidden;
white-space: nowrap;
}

Then use a group summary calculation to display the text for that column in the summary.
* If the column is grouped it will always display the group value.
* If the column is not grouped it won't display anything unless all the rows have the same value in that field.


Ext.ux.grid.GroupSummary.Calculations["text"] = function(value, record, field, data) {
if (value == 0) {
value = record.data[field];
}
// Only displayed when all rows have the same value. Otherwise return &#38;#160; or &#38;nbsp;.
// if you return " ", null or undefined, it will display the value for the last row.
return value == record.data[field]? value: "&#38;#160;";
};

Make sure you don't hide the grouped column (it's shown by default).
When collapsed you will see one row with all the values (including the grouped text) aligned under their columns and they won't overlap.
When expanded you will see the group header displayed according to the template you defined.

joseaio
24 Sep 2010, 5:24 AM
Can you add some images to show your improvement?

ExTriqui
28 Sep 2010, 12:46 AM
As you can see collapsed groups don't display the group header but the column summary (which is a "text" summary type) which is properly aligned and thus avoid overlapping.

22581

joseaio
28 Sep 2010, 1:03 AM
Yes, this way allows large summary (without overlaps header & summary) or summary on first columns.

I like that summary/totals go to end columns: You can avoid overlap if shows empty "Client Traffic" column on summary and overwrite header to remove the preffix "Client Traffic:"

Of course this is a valid alternative.

ExTriqui
28 Sep 2010, 5:39 AM
Well, your idea was great, simple and clean. I just needed collapsed groups to look exactly like normal rows, so when I saw your hack I thought it was a good idea to completely replace the group header with the group summary row, since you can add anything you need to it.

joseaio
28 Sep 2010, 6:20 AM
You are right, I have one list/table that use your idea... (Thanks)

On entry list of account bank, some entries must be grouped (showing totals/sumary of their entries) and looks as "normal rows" (of course, expand show all grouped rows)

One question: It's more intuitive that summary row showed always as first row? or, It's better that go to end when expand group?

ExTriqui
30 Sep 2010, 5:26 AM
In my previous custom javascript grouping I had the group row with column summaries. That's why I'm working with this, cause I need it to look as close as possible to the previous version.
I think that it's easier to read the data when the summary is the first row (and merged with the group header) no matter whether the group is expanded or collapsed.

(Another feature I had is that groups with only one child would show all the child values and not be able to expand, so you don't have the user clicking on a row that just shows the same information again and repeated in two rows).

22632

22633

As you can see, the first row (group header + summary) is always the same.

joseaio
1 Oct 2010, 8:08 AM
Cool!

Can you post a complete example?

· group header with summary
· groups with only one child would show all the child values and not be able to expand

Please...

Mubin
6 Oct 2010, 9:21 PM
I'm also join to joseaio. ExTriqui, your example would be very helpful.

ExTriqui
7 Oct 2010, 4:12 AM
Well, the thing is ... the screeshot posted are from a custom javascript table. It's just a normal html table with some javascript for the expanders and the data properly loaded in advance. I'm just trying to port that behaviour to extjs grids. So, I have no example of this in extjs yet. All I have is what I previously posted which is just a small improvement over joseaio idea for css. Anyway, I'll post anything I come up with if I think it can be useful for other developers.

ExTriqui
17 Nov 2010, 4:07 AM
Almost got it. If everything works fine, I'll post it today in a couple of hours (I have to go and have lunch now).

ExTriqui
17 Nov 2010, 6:58 AM
Here it is, hope you like it.
There is only one thing, but it's not so bad: when startCollapsed is false, the "single-row" groups will be expanded whenever groups are re-renderer. I'm not in a hurry to fix that yet.


var grid = new Ext.grid.GridPanel({
cls: "overlapGroupSummary",
view: new Ext.grid.GroupingView({
startCollapsed: true,
expandSingleRow: false,
startGroup: custom.template.singleRowGroupTpl("{group}"), // Use your groupTextTpl as a parameter here
forceFit: true,
plugins: [groupSummary]
})
});




custom.template.singleRowGroupTpl = function(groupTextTpl) {
return new Ext.XTemplate(
'<div id="{groupId}" class="x-grid-group {cls}{[values.rs.length > 1 ? "" : " single-row"]}">',
'<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div class="x-grid-group-title">', groupTextTpl ,'</div></div>',
'<div id="{groupId}-bd" class="x-grid-group-body">');
};
/**
* @cfg {Boolean} expandSingleRow <tt>false</tt> to keep groups with only one child always collapsed (defaults to <tt>true</tt>)
*/
Ext.grid.GroupingView.expandSingleRow = true;

// *** Maybe overriding toggleAllGroups would be enough and give better performance,
// since we are using css to hide the expand button in single-row groups.
Ext.grid.GroupingView.override({
/**
* Toggles the specified group if no value is passed, otherwise sets the expanded state of the group to the value passed.
* @param {String} groupId The groupId assigned to the group (see getGroupId)
* @param {Boolean} expanded (optional)
*/
toggleGroup: function(group, expanded) {
var gel = Ext.get(group);
expanded = Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed');
if (!this.expandSingleRow && gel.hasClass('single-row') && expanded) {
return;
}
if (this.state[gel.id] !== expanded) {
if (this.cancelEditOnToggle !== false) {
this.grid.stopEditing(true);
}
this.state[gel.id] = expanded;
gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
}
}
});

/**
* This is used to display a summary for text columns.
* <p>
* It will show the content of the field only if all the rows have the same
* value in it. It will be empty otherwise.
*/
Ext.ux.grid.GroupSummary.Calculations["unique"] = function(value, record, field, data) {
var v = data[field];
if (v === undefined) {
return record.data[field];
}
return v == record.data[field]? v: "";
};



.x-grid-group-hd {
padding-top: 0px !important;
}
.overlapGroupSummary .x-grid-group-collapsed .x-grid-group-hd .x-grid-group-title {
position: absolute;
float: left;
width: 0px;
padding-right: 0px;
overflow: hidden;
white-space: nowrap;
}
.overlapGroupSummary .x-grid-group-collapsed.single-row .x-grid-group-hd .x-grid-group-title {
padding-left: 0px;
}

devtig
18 Nov 2010, 12:14 AM
I used you mini hack (first post). Excellent!

ExTriqui
18 Nov 2010, 3:07 AM
One little fix to my previous post, just in case you are using a fixed height with a scroller instead of autoHeight:


.overlapGroupSummary .x-grid-group-collapsed .x-grid-group-hd {
position: relative;
}

This applies to the first mini hack in the first post (I think), it should be:


.x-grid-group-collapsed .x-grid-group-hd {
position: relative;
}
.x-grid-group-collapsed .x-grid-group-hd .x-grid-group-title {
position: absolute;
float: left;
}

Otherwise group titles will be fixed in their positions and won't scroll with the rest of the rows.

niyioyelade
16 Dec 2010, 8:08 AM
Can someone point out how to do this in java with ExtGWT? I can see the javascript code but would love to see the java version. I am interested in making the summary row replace the group header.