PDA

View Full Version : [CLOSED] Gridpanel with CheckboxSelectionModel on filtering (with GridFilters) does not maintain previous selection



Arohan
Feb 13, 2015, 7:12 AM
Hi,

On a page I have a Gridpanel with CheckBoxSelectionModel with Multiple Row Selection Mode. Also I am using GridFilters (with Local = true) to filter the records in the GridPanel.

Is it possible to maintain Selections after filtering using GridPanel properties.? If No, is there a way to handle this. Please guide.

Thanks & BR,
PRASAD

Dimitris
Feb 13, 2015, 9:17 AM
Hello,

Since you do not provide a code sample I have tested by combining the following two examples from the Examples Explorer:


http://examples2.ext.net/#/GridPanel/Plugins/GridFilters_Local/
http://examples2.ext.net/#/GridPanel/Selection_Models/Checkbox_Selection/



Everything seems to work beautifully. Selected rows remain checked after filtering.

If this is not what you are referring to please provide a simple code example to work with.

Arohan
Feb 13, 2015, 10:53 AM
Please test with the following sample code. Please note that I have used BufferedRenderer apart from the Local Filter & CheckBoxSelection Model.



<%@ Page Language="C#" %>

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

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
this.Store1.DataSource = this.TestData(5000);
this.Store1.DataBind();
}
}

private object[] TestData(int count)
{
string[] firstNames = new string[] { "Russel", "Clark", "Steve", "Sam", "Lance", "Robert", "Sean", "David", "Justin", "Nicolas", "Brent" };
string[] lastNames = new string[] { "Wood", "Lewis", "Scott", "Parker", "Ross", "Garcia", "Bell", "Kelly", "Powell", "Moore", "Cook" };

int[] ratings = new int[] { 1, 2, 3, 4, 5 };
int[] salaries = new int[] { 100, 400, 900, 1500, 1000000 };

object[] data = new object[count];
Random rnd = new Random();

for (int i = 0; i < count; i++)
{
int ratingId = rnd.Next(ratings.Length);
int salaryId = rnd.Next(salaries.Length);
int firstNameId = rnd.Next(firstNames.Length);
int lastNameId = rnd.Next(lastNames.Length);

int rating = ratings[ratingId];
int salary = salaries[salaryId];
string name = String.Format("{0} {1}", firstNames[firstNameId], lastNames[lastNameId]);
string myid = "rec-" + i;

data[i] = new object[] { myid, name, rating, salary };
}

return data;
}
</script>

<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<title>Buffered Scrolling - Ext.NET Examples</title>
<link href="/resources/css/examples.css" rel="stylesheet" />

<script>
var jumpToRow = function() {
var me = this,
field = me.up('toolbar').down('#gotoLine');

if (field.isValid()) {
me.up('grid').view.bufferedRenderer.scrollTo(field .getValue() - 1, true);
}
};
</script>

</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />
<h1>
Buffered Scrolling</h1>
<p>
Ext.Net 2's brand new grid supports infinite scrolling, which enables you to load
any number of records into a grid without paging.</p>
<p>
The new grid uses a virtualized scrolling system to handle potentially infinite
data sets without any impact on client side performance.</p>
<p>
This example illustrates loading of all the records up front and buffering the rendering.</p>
<ext:GridPanel ID="GridPanel1" runat="server" Title="Buffered Grid of 5,000 random records"
Width="700" Height="500" SelectionMemory="true" >
<Store>
<ext:Store ID="Store1" runat="server">
<Model>
<ext:Model ID="Model1" runat="server" IDProperty="myid">
<Fields>
<ext:ModelField Name="myid" />
<ext:ModelField Name="name" />
<ext:ModelField Name="rating" Type="Int" />
<ext:ModelField Name="salary" Type="Float" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<Plugins>
<ext:BufferedRenderer ID="BufferedRenderer1" runat="server" />
</Plugins>
<View>
<ext:GridView ID="GridView1" runat="server" TrackOver="false" />
</View>
<SelectionModel>
<ext:CheckboxSelectionModel ID="CheckboxSelectionModel1" runat="server" Mode="Simple" />
</SelectionModel>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:RowNumbererColumn ID="RowNumbererColumn1" runat="server" Width="40" Sortable="false" />
<ext:Column ID="Column1" runat="server" Text="Name" Flex="1" DataIndex="name" />
<ext:Column ID="Column2" runat="server" Text="Rating" Width="125" DataIndex="rating" />
<ext:Column ID="Column3" runat="server" Text="Salary" Width="125" DataIndex="salary"
Align="Right">
<Renderer Format="UsMoney" />
</ext:Column>
</Columns>
</ColumnModel>
<BottomBar>
<ext:Toolbar ID="Toolbar1" runat="server">
<Items>
<ext:NumberField ID="NumberField1" runat="server" LabelWidth="70" FieldLabel="Jump to row"
MinValue="1" MaxValue="5000" AllowDecimals="false" EnableKeyEvents="true" ItemID="gotoLine">
<Listeners>
<SpecialKey Handler="if (e.getKey() === e.ENTER) { jumpToRow.call(this); }" />
</Listeners>
</ext:NumberField>
<ext:Button ID="Button1" runat="server" Text="Go">
<Listeners>
<Click Fn="jumpToRow" />
</Listeners>
</ext:Button>
</Items>
</ext:Toolbar>
</BottomBar>
<Features>
<ext:GridFilters runat="server" ID="GridFilters1" Local="true">
<Filters>
<ext:StringFilter DataIndex="name" />
<ext:NumericFilter DataIndex="rating" />
<ext:NumericFilter DataIndex="salary" />
</Filters>
</ext:GridFilters>
</Features>
</ext:GridPanel>
</form>
</body>
</html>

Arohan
Feb 14, 2015, 9:19 AM
I have handled this as follows.


Added a temporary store "SelectedRowStore" to maintain the selected rows in GridPanel1
Added Listners On "Select" and "DeSelect" of GridPanel1 to Add and Remove selected row to above temporary store
On FIlterUpdate Event of GridFilters given a call to user defined function "SelectRow" to Mark previously selected rows



If any one comes across the same situation following is the working sample code...



<%@ Page Language="C#" %>

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

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
this.Store1.DataSource = this.TestData(5000);
this.Store1.DataBind();
}
}

private object[] TestData(int count)
{
string[] firstNames = new string[] { "Russel", "Clark", "Steve", "Sam", "Lance", "Robert", "Sean", "David", "Justin", "Nicolas", "Brent" };
string[] lastNames = new string[] { "Wood", "Lewis", "Scott", "Parker", "Ross", "Garcia", "Bell", "Kelly", "Powell", "Moore", "Cook" };

int[] ratings = new int[] { 1, 2, 3, 4, 5 };
int[] salaries = new int[] { 100, 400, 900, 1500, 1000000 };

object[] data = new object[count];
Random rnd = new Random();

for (int i = 0; i < count; i++)
{
int ratingId = rnd.Next(ratings.Length);
int salaryId = rnd.Next(salaries.Length);
int firstNameId = rnd.Next(firstNames.Length);
int lastNameId = rnd.Next(lastNames.Length);

int rating = ratings[ratingId];
int salary = salaries[salaryId];
string name = String.Format("{0} {1}", firstNames[firstNameId], lastNames[lastNameId]);
string myid = "rec-" + i;

data[i] = new object[] { myid, name, rating, salary };
}

return data;
}
</script>

<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<title>Buffered Scrolling - Ext.NET Examples</title>
<link href="/resources/css/examples.css" rel="stylesheet" />

<script>
var jumpToRow = function() {
var me = this,
field = me.up('toolbar').down('#gotoLine');

if (field.isValid()) {
me.up('grid').view.bufferedRenderer.scrollTo(field .getValue() - 1, true);
}
};

// Added Following Code
var AddRowToTempStore = function(s, record) {
s.insert(0, record);
};

var RemoveRowFromTempStore = function(s, record) {
s.remove(record);
};

var SelectRows = function(s, grid) {
var r = [];
s.each(function(record) {
r.push(record);
});
grid.selModel.select(r, true);
};
//
</script>

</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />
<h1>
Buffered Scrolling</h1>
<p>
Ext.Net 2's brand new grid supports infinite scrolling, which enables you to load
any number of records into a grid without paging.</p>
<p>
The new grid uses a virtualized scrolling system to handle potentially infinite
data sets without any impact on client side performance.</p>
<p>
This example illustrates loading of all the records up front and buffering the rendering.</p>
<ext:GridPanel ID="GridPanel1" runat="server" Title="Buffered Grid of 5,000 random records"
Width="700" Height="500" SelectionMemory="true">
<Store>
<ext:Store ID="Store1" runat="server">
<Model>
<ext:Model ID="Model1" runat="server" IDProperty="myid">
<Fields>
<ext:ModelField Name="myid" />
<ext:ModelField Name="name" />
<ext:ModelField Name="rating" Type="Int" />
<ext:ModelField Name="salary" Type="Float" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<Plugins>
<ext:BufferedRenderer ID="BufferedRenderer1" runat="server" />
</Plugins>
<View>
<ext:GridView ID="GridView1" runat="server" TrackOver="false" />
</View>
<SelectionModel>
<ext:CheckboxSelectionModel ID="CheckboxSelectionModel1" runat="server" Mode="Simple">
<%-- Added Following Code--%>
<Listeners>
<Select Handler="AddRowToTempStore(#{SelectedRowStore},#{GridPanel1 }.selModel.getSelection());" />
<Deselect Handler="RemoveRowFromTempStore(#{SelectedRowStore},record) ;" />
</Listeners>
<%--End --%>
</ext:CheckboxSelectionModel>
</SelectionModel>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<%--<ext:RowNumbererColumn ID="RowNumbererColumn1" runat="server" Width="40" Sortable="false" />--%>
<ext:Column ID="Column4" runat="server" Text="Name" Flex="1" DataIndex="myid" />
<ext:Column ID="Column1" runat="server" Text="Name" Flex="1" DataIndex="name" />
<ext:Column ID="Column2" runat="server" Text="Rating" Width="125" DataIndex="rating" />
<ext:Column ID="Column3" runat="server" Text="Salary" Width="125" DataIndex="salary"
Align="Right">
<Renderer Format="UsMoney" />
</ext:Column>
</Columns>
</ColumnModel>
<BottomBar>
<ext:Toolbar ID="Toolbar1" runat="server">
<Items>
<ext:NumberField ID="NumberField1" runat="server" LabelWidth="70" FieldLabel="Jump to row"
MinValue="1" MaxValue="5000" AllowDecimals="false" EnableKeyEvents="true" ItemID="gotoLine">
<Listeners>
<SpecialKey Handler="if (e.getKey() === e.ENTER) { jumpToRow.call(this); }" />
</Listeners>
</ext:NumberField>
<ext:Button ID="Button1" runat="server" Text="Go">
<Listeners>
<Click Fn="jumpToRow" />
</Listeners>
</ext:Button>
</Items>
</ext:Toolbar>
</BottomBar>
<Features>
<ext:GridFilters runat="server" ID="GridFilters1" Local="true">
<Filters>
<ext:StringFilter DataIndex="name" />
<ext:NumericFilter DataIndex="rating" />
<ext:NumericFilter DataIndex="salary" />
</Filters>
<%-- Added Following Code--%>
<Listeners>
<FilterUpdate Handler="SelectRows(#{SelectedRowStore},#{GridPanel1})" />
</Listeners>
<%--End --%>
</ext:GridFilters>
</Features>
</ext:GridPanel>

<%-- Added Following Code--%>
<ext:Store ID="SelectedRowStore" runat="server">
<Model>
<ext:Model ID="Model2" runat="server" IDProperty="myid">
<Fields>
<ext:ModelField Name="myid">
</ext:ModelField>
</Fields>
</ext:Model>
</Model>
</ext:Store>
<%--End --%>
</form>
</body>
</html>



You may mark this thread as closed. Thanks for the support.

Thanks & BR,
PRASAD

Daniil
Feb 15, 2015, 6:18 AM
Hello @Arohan,

Or you can try with PruneRemoved="false" setting on CheckboxSelectionModel. Instead of your solution I mean.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.selection.Model-cfg-pruneRemoved

Appears to be working well with your scenario.

Arohan
Feb 16, 2015, 4:04 AM
Hello Daniil,

Your solution works great.

I would like to share that In case of virtual scrolling, if we use On Demand loading of store data either by Service or OnReadData, then we may have to handle it manually as shown in earlier sample code.

Or is there any other way to handle this ?

Thanks & BR,
PRASAD

Daniil
Feb 16, 2015, 5:07 AM
Sorry, it seems I don't quite understand the requirement/question. Could you, please, elaborate on that? Maybe, with a test case.

Arohan
Feb 16, 2015, 10:13 AM
Here is the sample code,



<%@ Page Language="C#" %>

<%@ Import Namespace="System.Collections.Generic" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<script runat="server">

protected void Store_ReadData(object sender, StoreReadDataEventArgs e)
{
Store store = (Store)sender;
List<StockQuotation> data = new List<StockQuotation>();

int start = e.Start,
limit = e.Limit;
Random randow = new Random();
DateTime now = DateTime.Now;

for (int i = start + 1; i <= start + limit; i++)
{
StockQuotation qoute = new StockQuotation()
{
ID = i,
Company = "Company " + i,
Price = i,
//LastUpdate = now
};

data.Add(qoute);
}
store.Data = data;
e.Total = 50000;
}

class StockQuotation
{
public int ID { get; set; }
public string Company { get; set; }
public int Price { get; set; }
//public DateTime LastUpdate { get; set; }
}
</script>


<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<title>Infinite Scrolling - Ext.NET Examples</title>
<link href="/resources/css/examples.css" rel="stylesheet" />
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />
<h1>
Infinite Scrolling</h1>
<p>
Ext.Net 2's brand new grid supports infinite scrolling, which enables you to load
any number of records into a grid without paging.</p>
<p>
The new grid uses a virtualized scrolling system to handle potentially infinite
data sets without any impact on client side performance.</p>
<ext:GridPanel ID="GridPanel1" runat="server" Width="500" Height="500" Title="Stock Price">
<Store>
<ext:Store ID="Store1" runat="server" Buffered="true" PageSize="200" TrailingBufferZone="10"
LeadingBufferZone="10" OnReadData="Store_ReadData">
<Proxy>
<ext:PageProxy>
<Reader>
<ext:JsonReader Root="data" />
</Reader>
</ext:PageProxy>
</Proxy>
<Model>
<ext:Model ID="Model1" runat="server" IDProperty="ID">
<Fields>
<ext:ModelField Name="ID" />
<ext:ModelField Name="Company" />
<ext:ModelField Name="Price" />
<ext:ModelField Name="LastUpdate" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column ID="Column4" runat="server" Text="ID" DataIndex="ID" Width="70" Align="Center" />
<ext:RowNumbererColumn ID="RowNumbererColumn1" runat="server" Width="50" />
<ext:Column ID="Column1" runat="server" Text="Company" DataIndex="Company" Flex="1" />
<ext:Column ID="Column2" runat="server" Text="Price, $" DataIndex="Price" Width="70"
Align="Center" />
<ext:Column ID="Column3" runat="server" Text="Last Update" DataIndex="LastUpdate"
Width="140">
<Renderer Format="Date" FormatArgs="'n/j/Y g:i:s A'" />
</ext:Column>
</Columns>
</ColumnModel>
<Features>
<ext:GridFilters ID="aa" runat="server">
<Filters>
<ext:NumericFilter DataIndex="Price" />
<ext:StringFilter DataIndex="Company" />
</Filters>
</ext:GridFilters>
</Features>
<View>
<ext:GridView ID="GridView1" runat="server" TrackOver="false" />
</View>
<SelectionModel>
<ext:CheckboxSelectionModel ID="CheckboxSelectionModel1" runat="server" Mode="Simple" PruneRemoved="false">
</ext:CheckboxSelectionModel>
</SelectionModel>
</ext:GridPanel>

</form>
</body>
</html>


How to maintain the selections in this scenario ?

Thanks & BR,
PRASAD

Daniil
Feb 17, 2015, 12:18 PM
Thank you for the test case. I would expect your test case should be working. I checked it with the latest Ext.NET 3 and it works. The selection persists on filtering. I assume it is a bug in Ext.NET v2 / ExtJS 4 and fixed in Ext.NET 3 / ExtJS 5.

For Ext.NET v2 you can try to use your own solution.

Arohan
Feb 18, 2015, 4:44 AM
Hi Daniil,

Thanks for the support and your timely suggestions. You may mark this thread as closed.

Thanks & BR,
PRASAD