PDA

View Full Version : [CLOSED] Hide RowExpander when subgrid has no rows



CarWise
Oct 11, 2012, 1:23 PM
I've achieved the following scenario in my own code (which is a bit more complicated so I'm using an EXTNET example code)



<%@ Page Language="C#" %>
<%@ Import Namespace="System.Collections.Generic"%>
<%--<%@ Import Namespace="ListView=Ext.Net.ListView"%>--%>


<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>


<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (X.IsAjaxRequest)
{
//We do not need to DataBind on an DirectEvent
return;
}

List<object> data = new List<object>();

for (int i = 1; i <= 10; i++)
{
data.Add(new { ID = "S" + i, Name = "Supplier " + i});
}

this.Store1.DataSource = data;
this.Store1.DataBind();
}

private void RemoveFromCache(string id)
{
X.Js.Call("removeFromCache", id);
}


private void AddToCache(string id)
{
X.Js.Call("addToCache", id);
}


protected void BeforeExpand(object sender, DirectEventArgs e)
{
string id = e.ExtraParams["id"];

Store store = new Store { ID = "StoreRow_"+id };


Model model = new Model();
model.IDProperty = "ID";
model.Fields.Add("ID", "Name");
store.Model.Add(model);


List<object> data = new List<object>();

for (int i = 1; i <= 10; i++)
{
data.Add(new { ID = "P"+i, Name = "Product " + i });
}


store.DataSource = data;

GridPanel grid = new GridPanel
{
ID = "GridPanelRow_" + id,
Height = 200,
Store = { store }
};

grid.ColumnModel.Columns.Add(new Column
{
Text = "Products's Name",
DataIndex = "Name"
});
grid.ColumnModel.ID = "GridPanelRowCM_" + id;


grid.View.Add(new Ext.Net.GridView { ID = "GridPanelRowView_" + id });


//X.Get("row-" + id).SwallowEvent(new string[] { "click", "mousedown", "mouseup", "dblclick"}, true);


this.RemoveFromCache(grid.ID);
grid.Render("row-" + id, RenderMode.RenderTo);
this.AddToCache(grid.ID);


GridPanel1.DoLayout();
}

</script>


<!DOCTYPE html>


<html>
<head id="Head1" runat="server">
<title>RowExpander with GridPanel - Ext.NET Examples</title>
<link href="/resources/css/examples.css" rel="stylesheet" type="text/css" />

<ext:ResourcePlaceHolder ID="ResourcePlaceHolder1" runat="server" Mode="Script" />

<script type="text/javascript">
var ns = App;
ns.lookup = [];


var clean = function () {
if (ns.lookup.length > 0) {
ns.RowExpander1.collapseAll();


Ext.each(ns.lookup, function (control) {
if (control) {
control.destroy();
}
});


ns.lookup = [];
}
};


var removeFromCache = function (c) {
c = window[c];
Ext.Array.remove(ns.lookup, c);


if (c) {
c.destroy();
}
};


var addToCache = function (c) {
ns.lookup.push(ns[c]);
};


var beforeUpdate = function (view, record, rowIndex) {
var grid = window["GridPanelRow_" + record.getId()];
if (grid && !grid.moved) {
var ce = grid.getEl(),
el = Ext.net.ResourceMgr.getAspForm() || Ext.getBody();


ce.addCls("x-hidden");


el.dom.appendChild(ce.dom);
grid.moved = true;


view.on("itemupdate", function () {
if (!grid.moved) {
return;
}
var row = view.getNode(rowIndex),
body = Ext.DomQuery.selectNode("div.x-grid-rowbody", row);


Ext.fly("row-" + record.getId()).appendChild(ce.dom);
ce.removeCls("x-hidden");
grid.moved = false;
body.rendered = true;
}, view, { single: true });
}
};


var beforeRemove = function (view, record, rowIndex) {
removeFromCache("GridPanelRow_" + record.getId());
};
</script>
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />

<h1>Row Expander Plugin with GridPanel</h1>

<p>The caching is presented, GridPanel renders once only (until view refresh)</p>

<ext:Store ID="Store1" runat="server">
<Model>
<ext:Model ID="Model1" runat="server" IDProperty="ID">
<Fields>
<ext:ModelField Name="ID" />
<ext:ModelField Name="Name" />
</Fields>
</ext:Model>
</Model>
</ext:Store>

<ext:GridPanel
ID="GridPanel1"
runat="server"
StoreID="Store1"
Title="Expander Rows with ListView"
Collapsible="true"
AnimCollapse="true"
Icon="Table"
Width="600"
Height="600">
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column ID="Column1" runat="server" Text="Supplier" DataIndex="Name" Flex="1" />
</Columns>
</ColumnModel>
<View>
<ext:GridView ID="GridView1" runat="server">
<Listeners>
<BeforeRefresh Fn="clean" />
<BeforeItemUpdate Fn="beforeUpdate" />
<BeforeItemRemove Fn="beforeRemove" />
</Listeners>
</ext:GridView>
</View>
<SelectionModel>
<ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Multi" />
</SelectionModel>
<Plugins>
<ext:RowExpander ID="RowExpander1" runat="server" EnableCaching="true" SwallowBodyEvents="true">
<Template ID="Template1" runat="server">
<Html>
<div id="row-{ID}" style="background-color:White;"></div>
</Html>
</Template>
<DirectEvents>
<BeforeExpand
OnEvent="BeforeExpand"
Before="return !body.rendered;"
Success="body.rendered=true;">
<EventMask ShowMask="true" Target="CustomTarget" CustomTarget="={#{GridPanel1}.body}" />
<ExtraParams>
<ext:Parameter Name="id" Value="record.getId()" Mode="Raw" />
</ExtraParams>
</BeforeExpand>
</DirectEvents>
</ext:RowExpander>
</Plugins>
</ext:GridPanel>
</form>
</body>
</html>


In my own code the Rowexpander is filled with a grid with records from another query (using the ID of the parent row). Sometimes there are no subrows, (datasource is datatable. Datatables.Rows.Count = 0) so the Rowexpander only shows the header of the grid. That's not what I want. I would like to remove the + sign and underlying grid. How to achieve. I still would like to keep the parent row..

Martin

Daniil
Oct 11, 2012, 6:35 PM
Hi Martin,

Hope this example for Ext.NET v1 will help you to start.
http://forums.ext.net/showthread.php?10326&p=41347&viewfull=1#post41347

Possibly, this example can be also helpful.
http://forums.ext.net/showthread.php?16982&p=72905&viewfull=1#post72905

Certainly, RowExpander JavaScript sources has been changed since Ext.NET v1. You might need to look at the sources:

<Ext.NET v2 sources root>\Ext.Net\Build\Ext.Net\extnet\src\grid\plugin\RowE xpander.js

But the ideas in the examples above should be actual for Ext.NET v2 as well.

CarWise
Oct 15, 2012, 2:27 PM
Hi Martin,

Hope this example for Ext.NET v1 will help you to start.
http://forums.ext.net/showthread.php?10326&p=41347&viewfull=1#post41347

Possibly, this example can be also helpful.
http://forums.ext.net/showthread.php?16982&p=72905&viewfull=1#post72905

Certainly, RowExpander JavaScript sources has been changed since Ext.NET v1. You might need to look at the sources:

<Ext.NET v2 sources root>\Ext.Net\Build\Ext.Net\extnet\src\grid\plugin\RowE xpander.js

But the ideas in the examples above should be actual for Ext.NET v2 as well.

Will look into your info... when I need help I will get back to you ! :)

Martin

Daniil
Oct 15, 2012, 2:56 PM
Good luck, Martin!:)

Marked the thread closed. If needed, please bump.

CarWise
Oct 16, 2012, 10:54 AM
Hi Daniil..

Well..no succes yet. I'm trying to override the rowexpander, but it seems not to work. Nothing happens. It seems like the override is not happening..
Where am I going wrong ?

Martin



<%@ Page Language="C#" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (X.IsAjaxRequest)
{
//We do not need to DataBind on an DirectEvent
return;
}

List<object> data = new List<object>();

for (int i = 1; i <= 10; i++)
{
data.Add(new { ID = "S" + i, Name = "Supplier " + i});
}

this.Store1.DataSource = data;
this.Store1.DataBind();
}

private void RemoveFromCache(string id)
{
X.Js.Call("removeFromCache", id);
}


private void AddToCache(string id)
{
X.Js.Call("addToCache", id);
}


protected void BeforeExpand(object sender, DirectEventArgs e)
{
string id = e.ExtraParams["id"];

Store store = new Store { ID = "StoreRow_"+id };


Model model = new Model();
model.IDProperty = "ID";
model.Fields.Add("ID", "Name");
store.Model.Add(model);


List<object> data = new List<object>();

for (int i = 1; i <= 10; i++)
{
data.Add(new { ID = "P"+i, Name = "Product " + i });
}


store.DataSource = data;

GridPanel grid = new GridPanel
{
ID = "GridPanelRow_" + id,
Height = 200,
Store = { store }
};

grid.ColumnModel.Columns.Add(new Column
{
Text = "Products's Name",
DataIndex = "Name"
});
grid.ColumnModel.ID = "GridPanelRowCM_" + id;


grid.View.Add(new Ext.Net.GridView { ID = "GridPanelRowView_" + id });


//X.Get("row-" + id).SwallowEvent(new string[] { "click", "mousedown", "mouseup", "dblclick"}, true);


RemoveFromCache(grid.ID);
grid.Render("row-" + id, RenderMode.RenderTo);
AddToCache(grid.ID);
GridPanel1.DoLayout();
}
</script>


<!DOCTYPE html>


<html>
<head id="Head1" runat="server">
<title>RowExpander with GridPanel - Ext.NET Examples</title>
<link href="/resources/css/examples.css" rel="stylesheet" type="text/css" />

<ext:ResourcePlaceHolder ID="ResourcePlaceHolder1" runat="server" Mode="Script" />
<script type="text/javascript">
Ext.ux.RowExpander.override({
renderer: function (value, metadata, record) {
if (record.getId() % 2 == 0) {
metadata.tdCls = value + 'grid-cell-special';
return '<div class="' + Ext.baseCSSPrefix + 'grid-row-expander">*</div>';
}
else return '<div class="x-no-expander">*</div>';
}
});
</script>
<script type="text/javascript">
var ns = App;
ns.lookup = [];


var clean = function () {
if (ns.lookup.length > 0) {
ns.RowExpander1.collapseAll();


Ext.each(ns.lookup, function (control) {
if (control) {
control.destroy();
}
});


ns.lookup = [];
}
};


var removeFromCache = function (c) {
c = window[c];
Ext.Array.remove(ns.lookup, c);


if (c) {
c.destroy();
}
};


var addToCache = function (c) {
ns.lookup.push(ns[c]);
};


var beforeUpdate = function (view, record, rowIndex) {
var grid = window["GridPanelRow_" + record.getId()];
if (grid && !grid.moved) {
var ce = grid.getEl(),
el = Ext.net.ResourceMgr.getAspForm() || Ext.getBody();


ce.addCls("x-hidden");


el.dom.appendChild(ce.dom);
grid.moved = true;


view.on("itemupdate", function () {
if (!grid.moved) {
return;
}
var row = view.getNode(rowIndex),
body = Ext.DomQuery.selectNode("div.x-grid-rowbody", row);


Ext.fly("row-" + record.getId()).appendChild(ce.dom);
ce.removeCls("x-hidden");
grid.moved = false;
body.rendered = true;
}, view, { single: true });
}
};


var beforeRemove = function (view, record, rowIndex) {
removeFromCache("GridPanelRow_" + record.getId());
};
</script>
<style type="text/css">
.my-grid .x-no-expander {
background-image: none;
}
</style>
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />

<h1>Row Expander Plugin with GridPanel</h1>

<p>The caching is presented, GridPanel renders once only (until view refresh)</p>

<ext:Store ID="Store1" runat="server">
<Model>
<ext:Model ID="Model1" runat="server" IDProperty="ID">
<Fields>
<ext:ModelField Name="ID" />
<ext:ModelField Name="Name" />
</Fields>
</ext:Model>
</Model>
</ext:Store>

<ext:GridPanel
ID="GridPanel1"
runat="server"
StoreID="Store1"
Title="Expander Rows with ListView"
Collapsible="true"
AnimCollapse="true"
Icon="Table"
Width="600"
Height="600">
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column ID="Column1" runat="server" Text="Supplier" DataIndex="Name" Flex="1" />
</Columns>
</ColumnModel>
<View>
<ext:GridView ID="GridView1" runat="server">
<Listeners>
<BeforeRefresh Fn="clean" />
<BeforeItemUpdate Fn="beforeUpdate" />
<BeforeItemRemove Fn="beforeRemove" />
</Listeners>
</ext:GridView>
</View>
<SelectionModel>
<ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Multi" />
</SelectionModel>
<Plugins>
<ext:RowExpander ID="RowExpander1" runat="server" EnableCaching="true" SwallowBodyEvents="true">
<Template ID="Template1" runat="server">
<Html>
<div id="row-{ID}" style="background-color:White;"></div>
</Html>
</Template>
<DirectEvents>
<BeforeExpand
OnEvent="BeforeExpand"
Before="return !body.rendered;"
Success="body.rendered=true;">
<EventMask ShowMask="true" Target="CustomTarget" CustomTarget="={#{GridPanel1}.body}" />
<ExtraParams>
<ext:Parameter Name="id" Value="record.getId()" Mode="Raw" />
</ExtraParams>
</BeforeExpand>
</DirectEvents>
</ext:RowExpander>
</Plugins>
</ext:GridPanel>
</form>
</body>
</html>

Daniil
Oct 16, 2012, 12:03 PM
I think you had to override the getHeaderConfig function.

But never mind, Vladimir just added the Renderer property for RowExpander. Returning false from a Renderer function prevents an expandable icon from appearing and expanding such row at all.

Please update from SVN and enjoy:)

CarWise
Oct 16, 2012, 12:20 PM
I think you had to override the getHeaderConfig function.

But never mind, Vladimir just added the Renderer property for RowExpander. Returning false from a Renderer function prevents an expandable icon from appearing and expanding such row at all.

Please update from SVN and enjoy:)


Great !!!!! Best news of the week :)

Martin

CarWise
Oct 16, 2012, 1:29 PM
It works ! (ofcourse)..

One small question. How can i use the current record in the function using with the Renderer property ?

This is not possible: (record is undefined)



<Renderer Handler="renderRow" runat="server" />

<script type="text/javascript">
var renderRow = function (record) {
return (record.getId() != 2)
}
</script>


Martin

Daniil
Oct 16, 2012, 1:53 PM
Please use:

var renderRow = function (value, metadata, record) {
/* the function body */
}

CarWise
Oct 16, 2012, 2:30 PM
Please use:

var renderRow = function (value, metadata, record) {
/* the function body */
}

Check ! .. thanks. Works superb !

Martin