PDA

View Full Version : [CLOSED] Refresh RowExpander Plugin on store reload/databind.



HansWapenaar
Feb 04, 2013, 7:59 PM
Hi,

I'm using the example of dynamic gridpanels in a rowexpander.
What I need is an adjustment in such a way that data that is in the rowexpander can be refreshed. In my case data is updated in other processes and when the user opens a row with a rowexpander again than the refreshed data should be shown.

Unfortunately I don't get this working. The data in a row that has been expanded earlier won't refresh.

I made the following adjustments:


<ext:RowExpander runat="server" SingleExpand="true">
<Loader runat="server" DirectMethod="#{DirectMethods}.GetGrid" Mode="Component" DisableCaching="true" >
<LoadMask ShowMask="true" />
<Params>
<ext:Parameter Name="id" Value="this.record.getId()" Mode="Raw" />
</Params>
</Loader>
</ext:RowExpander>



I read in an earlier thread a solution with a trick with a configitem. But also no result. This solution was suggested for an ext.net version 1.
http://forums.ext.net/showthread.php?5614-Refresh-RowExpander-Plugin-on-store-reload-databind



<CustomConfig>
<ext:ConfigItem Name="enableCaching" Value="false" Mode="Raw" />
<ext:ConfigItem Name="disableCaching" Value="true" Mode="Raw" />
</CustomConfig>



In the server script I added for the example a random number to change the contents of the rowexpander:



<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();
}

[DirectMethod]
public static string GetGrid(Dictionary<string, string> parameters)
{
List<object> data = new List<object>();
Random randomClass = new Random();
int iRandomNumber = randomClass.Next();
for (int i = 1; i <= 10; i++)
{
data.Add(new { ID = "P" + i, Name = "Product " + iRandomNumber });
}
GridPanel grid = new GridPanel
{
Height = 200,
EnableColumnHide = false,
Store =
{
new Store
{
Model = {
new Model {
IDProperty = "ID",
Fields =
{
new ModelField("ID"),
new ModelField("Name")
}
}
},
DataSource = data
}
},
ColumnModel =
{
Columns =
{
new Column { Text = "Products's Name", DataIndex = "Name" }
}
}
};

return ComponentLoader.ToConfig(grid);
}
</script>


Any idea how could get a refresh on the contents??

thanks,
Hans Wapenaar

Baidaly
Feb 05, 2013, 2:34 AM
Hello!

You have to remove RowExpander's inner components. You can find them in RowExpander.componentsCache and remove using RowExpander.removeComponent method

Also, try to use the following sample:



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

<%@ 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();
}

[DirectMethod]
public static string GetGrid(Dictionary<string, string> parameters)
{
// string id = parameters["id"];

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

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

GridPanel grid = new GridPanel
{
Height = 200,
EnableColumnHide = false,
Store =
{
new Store
{
Model = {
new Model {
IDProperty = "ID",
Fields =
{
new ModelField("ID"),
new ModelField("Name")
}
}
},
DataSource = data
}
},
ColumnModel =
{
Columns =
{
new Column { Text = "Products's Name", DataIndex = "Name" }
}
}
};

return ComponentLoader.ToConfig(grid);
}
</script>

<!DOCTYPE html>

<html>
<head runat="server">
<title>Ext.NET Examples</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" SourceFormatting="True" />

<ext:GridPanel
ID="GridPanel1"
runat="server"
Title="Expander Rows with GridPanel"
Collapsible="true"
AnimCollapse="true"
Icon="Table"
Width="600"
Height="450"
DisableSelection="true">
<Store>
<ext:Store ID="Store1" runat="server">
<Model>
<ext:Model runat="server" IDProperty="ID">
<Fields>
<ext:ModelField Name="ID" />
<ext:ModelField Name="Name" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel runat="server">
<Columns>
<ext:Column runat="server" Text="Supplier" DataIndex="Name" Flex="1" />
</Columns>
</ColumnModel>
<Plugins>
<ext:RowExpander runat="server" SingleExpand="True">
<Listeners>
<BeforeExpand Handler="this.removeComponents(); return true;"></BeforeExpand>
</Listeners>
<Loader runat="server" DirectMethod="#{DirectMethods}.GetGrid" Mode="Component" DisableCaching="False">
<LoadMask ShowMask="true" />
<Params>
<ext:Parameter Name="id" Value="this.record.getId()" Mode="Raw" />
</Params>
</Loader>
</ext:RowExpander>
</Plugins>
</ext:GridPanel>
</form>
</body>
</html>

HansWapenaar
Feb 05, 2013, 7:27 AM
Ok, Thanks a lot. I have got that working!

Now a step further: the adjusments in the grid in the rowexpander are made in another panel. A change in this panel generates a rowexpander.collapseAll and a rowexpander.ExpandRow(..) to refresh the contents.

Is it possible to refresh the grid/datastore in the rowexpander and the rerender the contents of the rowexpander? I have the idea that hardly possible to find the components that are generated with 'getGrid'.

It is a 'nice to have' feature: not closing and opening a row when something is changing, but a refresh of the grid itselves.
I am also having a chart in a rowexpander and then a fancy refresh without closing and opening looks much better.

Hans

Daniil
Feb 05, 2013, 9:40 AM
Hello everybody,

Probably, the BeforeExpand listener can be replaced with the RecreateComponent="true" for the RowExpander.




Now a step further: the adjusments in the grid in the rowexpander are made in another panel. A change in this panel generates a rowexpander.collapseAll and a rowexpander.ExpandRow(..) to refresh the contents.

Is it possible to refresh the grid/datastore in the rowexpander and the rerender the contents of the rowexpander? I have the idea that hardly possible to find the components that are generated with 'getGrid'.


I don't understand well the requirement. Could you provide a sample to demonstrate?



It is a 'nice to have' feature: not closing and opening a row when something is changing, but a refresh of the grid itselves.
I am also having a chart in a rowexpander and then a fancy refresh without closing and opening looks much better.


Maybe, I would think about a Refresh cell command or a Toolbar with a RowExpander's Component.

Please clarify do you really need to re-render the whole component? Maybe, you just need to bind new data to the Store? If so, I think it would cheaper and elegant to reload just the Store.

HansWapenaar
Feb 05, 2013, 10:52 AM
Hello all,



Probably, the BeforeExpand listener can be replaced with the RecreateComponent="true" for the RowExpander.


I tried this but it is not resulting in any refresh of the contents.


Please clarify do you really need to re-render the whole component? Maybe, you just need to bind new data to the Store? If so, I think it would cheaper and elegant to reload just the Store.

I think that reloading the store should be enough. Although I experienced when I put a chart under a rowexpander directly and not by creating it dynamically, the rendering of the chart gets a bit confused when also the number of columns is adjusted.


Could you provide a sample to demonstrate?

Here you find an example where I added a button to refresh the contents of the rowexpander.

Thanks, Hans



<ext:Panel ID="pnlSelection" runat="server" Header="true" FrameHeader="false" AutoHeight="true" >
<Items>
<ext:GridPanel
ID="gridSelection" ClientIDMode="Static"
runat="server"
Border="false"
Header="false" Title="xx"
HideHeaders="true"
Hidden="false"
DisableSelection="false"
>
<Store>
<ext:Store ID="StoreSelection" IDMode="Explicit" runat="server" >
<Model>
<ext:Model ID="ModelSelection" runat="server" IDProperty="secondname" >
<Fields>
<ext:ModelField Name="firstname" Type="String" />
<ext:ModelField Name="secondname" Type="String" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel>
<Columns>
<ext:Column ID="Column1" ColumnID="firstname" runat="server" DataIndex="firstname" Width="100" />
<ext:Column ID="Column2" ColumnID="secondname" runat="server" DataIndex="secondname" Width="100" />
</Columns>
</ColumnModel>
<Plugins>
<ext:RowExpander ID="RowExpanderSelection" SelectRowOnExpand="true" SingleExpand="true" ExpandOnEnter="true" runat="server" RecreateComponent="true" >
<Listeners>
<BeforeExpand Handler="this.removeComponents(); return true;"></BeforeExpand>
</Listeners>
<Loader ID="LoaderSelection" runat="server" DirectMethod="#{DirectMethods}.GetGrid" Mode="Component" AutoLoad="true" DisableCaching="true" DisableCachingParam="true" >
<LoadMask ShowMask="true" />
<Params>
<ext:Parameter Name="usergroupcode" Value="this.record.getId()" Mode="Raw" />
</Params>
</Loader>
</ext:RowExpander>
</Plugins>
<SelectionModel>
<ext:RowSelectionModel ID="rowselectionmodel" runat="server" Mode="Single" >
</ext:RowSelectionModel>
</SelectionModel>
</ext:GridPanel>
</Items>
</ext:Panel>

<ext:Panel ID="PanelChange" runat="server" Header="true" FrameHeader="false" AutoHeight="true" >
<Items>
</Items>
<Buttons>
<ext:Button ID="btnRefresh" runat="server" Text="Refresh Store">
<DirectEvents>
<Click OnEvent="btnRefresh_OnClick" />
</DirectEvents>
</ext:Button>
</Buttons>
</ext:Panel>


And the script:


Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
If (Not ExtX.IsAjaxRequest) Then
Me.StoreSelection.DataSource = getData()
Me.StoreSelection.DataBind()
End If
End Sub

Public Class Customer
Property firstname As String
Property secondname As String
End Class

Public Class Orders
Property orderid As String
Property orderamount As Integer
End Class


Function getData() As List(Of Customer)
Dim data As List(Of Customer) = New List(Of Customer)
For i As Integer = 0 To 9
Dim cFirstName As String = "FirstName" + i.ToString
Dim cSecondName As String = "SecondName" + i.ToString
data.Add(New Customer With {.firstname = cFirstName, .secondname = cSecondName})
Next
Return data
End Function


<DirectMethod()> _
Public Function GetGrid(parameters As Dictionary(Of String, String)) As String
Dim randomRows As New Random()
Dim iRandomRows As Integer = randomRows.Next(6, 15)
Dim data As List(Of Orders) = New List(Of Orders)

For i As Integer = 0 To iRandomRows
Dim randomClass As New Random()
Dim iRandomNumber As Integer = randomClass.Next()
Dim cId As String = "Order " + i.ToString
Dim iAmount As Integer = iRandomNumber
data.Add(New Orders With {.orderid = cId, .orderamount = iAmount})
Next

Dim grid As GridPanel = New GridPanel
grid.ID = "gridGroup_" + ID
grid.IDMode = IDMode.Static
grid.HideHeaders = True
grid.Header = False
Dim m As Model = New Model
m.IDProperty = "orderid"
m.Fields.Add("orderid")
m.Fields.Add("orderamount")
Dim store As Store = New Store
store.ID = "storeGroup_" + ID
store.Model.Add(m)
store.DataSource = data

Dim col1 As Column.Config = New Column.Config
col1.Text = "orderid"
col1.DataIndex = "orderid"
col1.Width = 80
col1.Flex = "1"

Dim col2 As Column.Config = New Column.Config
col2.Text = "orderamount"
col2.DataIndex = "orderamount"
col2.Width = 100
col2.Flex = "1"

grid.ColumnModel.Columns.Add(New Column(col1))
grid.ColumnModel.Columns.Add(New Column(col2))
grid.ClientIDMode = UI.ClientIDMode.AutoID
grid.Height = 20 + (iRandomRows * 20)
grid.EnableColumnHide = False
grid.Store.Add(store)

Return ComponentLoader.ToConfig(grid)

End Function

Sub btnRefresh_OnClick(ByVal sender As Object, ByVal e As DirectEventArgs)
Dim iRowIndex As Integer = -1
Dim cRecordId As String = ""
Dim selrow As SelectedRow = rowselectionmodel.SelectedRow
If (selrow IsNot Nothing) Then
iRowIndex = selrow.RowIndex
cRecordId = selrow.RecordID
End If
If (iRowIndex >= 0) Then

RowExpanderSelection.CollapseAll()
RowExpanderSelection.ExpandRow(iRowIndex)
End If

End Sub

Daniil
Feb 06, 2013, 6:37 AM
Probably, the BeforeExpand listener can be replaced with the RecreateComponent="true" for the RowExpander.


I tried this but it is not resulting in any refresh of the contents.


You are right. RecreateComponent="true" affects only on a record update or a view refresh. Also it works with SingleExpand="true" only.

We can suggest the following way.

Example

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

<%@ 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();
}

[DirectMethod]
public static string GetGrid(Dictionary<string, string> parameters)
{
// string id = parameters["id"];

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

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

GridPanel grid = new GridPanel
{
Height = 200,
EnableColumnHide = false,
Store =
{
new Store
{
Model = {
new Model {
IDProperty = "ID",
Fields =
{
new ModelField("ID"),
new ModelField("Name")
}
}
},
DataSource = data
}
},
ColumnModel =
{
Columns =
{
new Column { Text = "Products's Name", DataIndex = "Name" }
}
}
};

return ComponentLoader.ToConfig(grid);
}
</script>

<!DOCTYPE html>

<html>
<head runat="server">
<title>RowExpander with GridPanel - Ext.NET Examples</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />

<ext:GridPanel
runat="server"
Title="Expander Rows with GridPanel"
Collapsible="true"
AnimCollapse="true"
Icon="Table"
Width="600"
Height="450"
DisableSelection="true">
<Store>
<ext:Store ID="Store1" runat="server">
<Model>
<ext:Model runat="server" IDProperty="ID">
<Fields>
<ext:ModelField Name="ID" />
<ext:ModelField Name="Name" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel runat="server">
<Columns>
<ext:Column runat="server" Text="Supplier" DataIndex="Name" Flex="1" />
</Columns>
</ColumnModel>
<Plugins>
<ext:RowExpander runat="server">
<Loader
runat="server"
DirectMethod="#{DirectMethods}.GetGrid"
Mode="Component"
AutoLoad="false"
RemoveAll="true">
<LoadMask ShowMask="true" />
<Params>
<ext:Parameter Name="id" Value="this.record.getId()" Mode="Raw" />
</Params>
</Loader>
<Listeners>
<Expand Handler="var cmp = this.getComponent(record);
cmp.getLoader().load();" />
</Listeners>
</ext:RowExpander>
</Plugins>
</ext:GridPanel>
</form>
</body>
</html>




Please clarify do you really need to re-render the whole component? Maybe, you just need to bind new data to the Store? If so, I think it would cheaper and elegant to reload just the Store.

I think that reloading the store should be enough. Although I experienced when I put a chart under a rowexpander directly and not by creating it dynamically, the rendering of the chart gets a bit confused when also the number of columns is adjusted.


Can you provide a sample to reproduce, please?





Could you provide a sample to demonstrate?

Here you find an example where I added a button to refresh the contents of the rowexpander.


Thank you for the sample.

I would try to define a ServerProxy for the Store. You can use a PageProxy with DirectFn.
http://examples2.ext.net/#/GridPanel/Paging_and_Sorting/DirectMethod/

Please note that a ServerProxy will be used for reloading only, not for initial load. So, you can still bind the data via the DataSource property.

To reload the Store of the expanded row you can use the following JavaScript code.

Example


var expander = App.RowExpander1,
rec = expander.getExpanded()[0],
innerGrid = expander.getComponent(rec).child("grid");
store = innerGrid.getStore();

store.reload();

Hope this helps.