Oct 01, 2011, 11:00 AM
[CLOSED] Problem applying grid filters programmatically
Hi,
I am sure I missing an obvious trick, but hopefully you can help:
I have taken your remote grid filters example and just added an additional menu to it.
This menu (when fully implemented) would offer some pre-canned views/filters the user can select from to quickly tailor the data to their liking.
I've been able to get individual filters, like a date range to work nicely using a small amount of JavaScript, something like this:
However, I have a problem when I try to use a List filter (in the sample below, click on the menu option "Medium or larger"):
The above list filter works IF you expand the size column manually (by clicking on it), first. (See screenshot 3)
(You do not need to open the list filter itself, just seeing the size column's own menu (with sort etc) is enough.) I believe this is because the menu is probably using lazy initialization which usually sounds like a good thing. The problem for me then is as per the above code - if the menu doesn't exist, I can't check the parent "filters" menu (the actual list of filters are already checked if you expand the list filter menu).
I tried to just call render, doLayout etc on the filters menu, but that didn't seem to work. Any thoughts what I can do here? [I think this would affect boolean filters too but have not tested that]
Here is a full working example to play with:
I am sure I missing an obvious trick, but hopefully you can help:
I have taken your remote grid filters example and just added an additional menu to it.
This menu (when fully implemented) would offer some pre-canned views/filters the user can select from to quickly tailor the data to their liking.
I've been able to get individual filters, like a date range to work nicely using a small amount of JavaScript, something like this:
<script type="text/javascript">
var Viewer = {
views : {
today: function() {
var filters = GridPanel1.filters.filters.items,
today = new Date(),
tomorrow = new Date();
tomorrow.setDate(today.getDate() + 1);
Viewer.views.applyFilters(function() {
filters[3].setValue({ 'before': tomorrow });
filters[3].setValue({ 'after': today });
});
},
clear: function() {
Viewer.views.applyFilters();
},
applyFilters: function(action) {
var i, numFilters;
GridPanel1.filters.clearFilters();
GridPanel1.suspendEvents();
if (action) {
action();
}
GridPanel1.resumeEvents();
GridPanel1.filters.reload();
}
}
};
</script>
(Screenshot 1 shows that working)However, I have a problem when I try to use a List filter (in the sample below, click on the menu option "Medium or larger"):
mediumAndMore : function() {
Viewer.views.applyFilters(function() {
GridPanel1.filters.filters.items[4].setValue(['medium', 'large', 'extra large']);
// only works if the column menu (not even the list items submenu) is just shown
// I think this is something to do with lazy loading? Not sure how to programmatically load/render
if (GridPanel1.filters.menu.parentMenu) {
GridPanel1.filters.menu.parentMenu.find('itemId', 'filters')[0].setChecked(true);
}
});
},
The above does not work IF you do not expand the size column manually first. (See screenshot 2)The above list filter works IF you expand the size column manually (by clicking on it), first. (See screenshot 3)
(You do not need to open the list filter itself, just seeing the size column's own menu (with sort etc) is enough.) I believe this is because the menu is probably using lazy initialization which usually sounds like a good thing. The problem for me then is as per the above code - if the menu doesn't exist, I can't check the parent "filters" menu (the actual list of filters are already checked if you expand the list filter menu).
I tried to just call render, doLayout etc on the filters menu, but that didn't seem to work. Any thoughts what I can do here? [I think this would affect boolean filters too but have not tested that]
Here is a full working example to play with:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Collections.ObjectModel" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<script runat="server">
public class FiltersTestData
{
public static List<object> Data
{
get
{
var today = DateTime.Now;
var yesterday = today.AddDays(-1);
var goods = new List<object>
{
new { Id = 1, Price = 71.72, Company = "3m Co", Date = today, Size = "large", Visible = true },
new { Id = 2, Price = 29.01, Company = "Aloca Inc", Date = yesterday, Size = "medium", Visible = false },
new { Id = 3, Price = 83.81, Company = "Altria Group Inc", Date = today, Size = "large", Visible = false },
new { Id = 4, Price = 52.55, Company = "American Express Company", Date = yesterday, Size = "extra large", Visible = true },
new { Id = 5, Price = 64.13, Company = "American International Group Inc.", Date = yesterday, Size = "small", Visible = true },
new { Id = 6, Price = 31.61, Company = "AT&T Inc.", Date = yesterday, Size = "extra large", Visible = false },
new { Id = 7, Price = 75.43, Company = "Boeing Co.", Date = yesterday, Size = "large", Visible = true },
new { Id = 8, Price = 67.27, Company = "Caterpillar Inc.", Date = today, Size = "medium", Visible = true },
new { Id = 9, Price = 49.37, Company = "Citigroup, Inc.", Date = today, Size = "large", Visible = true },
new { Id = 10, Price = 40.48, Company = "E.I. du Pont de Nemours and Company", Date = today, Size = "extra large", Visible = false },
new { Id = 11, Price = 68.1, Company = "Exxon Mobile Corp", Date = today, Size = "large", Visible = true },
new { Id = 12, Price = 34.14, Company = "General Electric Company", Date = yesterday, Size = "extra large", Visible = true },
new { Id = 13, Price = 30.27, Company = "General Motors Corporation", Date = new DateTime(2006, 12, 07), Size = "medium", Visible = true },
new { Id = 14, Price = 36.53, Company = "Hewlett-Packard Co.", Date = today, Size = "large", Visible = true },
new { Id = 15, Price = 38.77, Company = "Honweywell Intl Inc", Date = new DateTime(2006, 11, 07), Size = "medium", Visible = false },
new { Id = 16, Price = 19.88, Company = "Intel Corporation", Date = today, Size = "small", Visible = true },
new { Id = 17, Price = 81.41, Company = "International Business Machines", Date = new DateTime(2005, 01, 21), Size = "extra large", Visible = true },
new { Id = 18, Price = 64.72, Company = "Johnson & Johnson", Date = yesterday, Size = "extra large", Visible = true },
new { Id = 19, Price = 45.73, Company = "JP Morgan & Chase & Co", Date = yesterday, Size = "large", Visible = false },
new { Id = 20, Price = 36.76, Company = "McDonald's Corporation", Date = today, Size = "large", Visible = true },
new { Id = 21, Price = 27.96, Company = "Pfizer Inc", Date = today, Size = "small", Visible = false },
new { Id = 22, Price = 45.07, Company = "The Coca-Cola Company", Date = today, Size = "medium", Visible = false },
new { Id = 23, Price = 34.64, Company = "The Home Depot, Inc", Date = new DateTime(2006, 12, 31), Size = "small", Visible = true },
new { Id = 24, Price = 61.91, Company = "The Procter & Gamble Company", Date = today, Size = "extra large", Visible = true },
new { Id = 25, Price = 63.26, Company = "United Technologies Corporation", Date = new DateTime(2006, 06, 04), Size = "medium", Visible = true },
new { Id = 26, Price = 35.57, Company = "Verizon Communications", Date = new DateTime(2005, 07, 09), Size = "small", Visible = false },
new { Id = 27, Price = 45.45, Company = "Wal-Mart Stores, Inc", Date = new DateTime(2006, 09, 09), Size = "large", Visible = true }
};
return goods;
}
}
}
protected void Store1_RefreshData(object sender, StoreRefreshDataEventArgs e)
{
List<object> data = FiltersTestData.Data;
string s = e.Parameters[GridFilters1.ParamPrefix];
//or with hardcoding - string s = e.Parameters["gridfilters"];;
//-- start filtering ------------------------------------------------------------
if (!string.IsNullOrEmpty(s))
{
FilterConditions fc = new FilterConditions(s);
foreach (FilterCondition condition in fc.Conditions)
{
Comparison comparison = condition.Comparison;
string field = condition.Name;
FilterType type = condition.FilterType;
object value;
switch(condition.FilterType)
{
case FilterType.Boolean:
value = condition.ValueAsBoolean;
break;
case FilterType.Date:
value = condition.ValueAsDate;
break;
case FilterType.List:
value = condition.ValuesList;
break;
case FilterType.Numeric:
if (data.Count > 0 && data[0].GetType().GetProperty(field).PropertyType == typeof(int))
{
value = condition.ValueAsInt;
}
else
{
value = condition.ValueAsDouble;
}
break;
case FilterType.String:
value = condition.Value;
break;
default:
throw new ArgumentOutOfRangeException();
}
data.RemoveAll(
item =>
{
object oValue = item.GetType().GetProperty(field).GetValue(item, null);
IComparable cItem = oValue as IComparable;
switch (comparison)
{
case Comparison.Eq:
switch(type)
{
case FilterType.List:
return !(value as ReadOnlyCollection<string>).Contains(oValue.ToString());
case FilterType.String:
return !oValue.ToString().StartsWith(value.ToString());
default:
return !cItem.Equals(value);
}
case Comparison.Gt:
return cItem.CompareTo(value) < 1;
case Comparison.Lt:
return cItem.CompareTo(value) > -1;
default:
throw new ArgumentOutOfRangeException();
}
}
);
}
}
//-- end filtering ------------------------------------------------------------
//-- start sorting ------------------------------------------------------------
if (!string.IsNullOrEmpty(e.Sort))
{
data.Sort(delegate(object x, object y)
{
object a;
object b;
int direction = e.Dir == Ext.Net.SortDirection.DESC ? -1 : 1;
a = x.GetType().GetProperty(e.Sort).GetValue(x, null);
b = y.GetType().GetProperty(e.Sort).GetValue(y, null);
return CaseInsensitiveComparer.Default.Compare(a, b) * direction;
});
}
//-- end sorting ------------------------------------------------------------
//-- start paging ------------------------------------------------------------
var limit = e.Limit;
if ((e.Start + e.Limit) > data.Count)
{
limit = data.Count - e.Start;
}
List<object> rangeData = (e.Start < 0 || limit < 0) ? data : data.GetRange(e.Start, limit);
//-- end paging ------------------------------------------------------------
e.Total = data.Count;
GridPanel1.GetStore().DataSource = rangeData;
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>GridPanel with Remote Filtering, Sorting and Paging - Ext.NET Examples</title>
<script type="text/javascript">
var Viewer = {
views : {
today: function() {
var filters = GridPanel1.filters.filters.items,
today = new Date(),
tomorrow = new Date();
tomorrow.setDate(today.getDate() + 1);
Viewer.views.applyFilters(function() {
filters[3].setValue({ 'before': tomorrow });
filters[3].setValue({ 'after': today });
});
},
mediumAndMore : function() {
Viewer.views.applyFilters(function() {
GridPanel1.filters.filters.items[4].setValue(['medium', 'large', 'extra large']);
// only works if the column menu (not even the list items submenu) is just shown
// I think this is something to do with lazy loading? Not sure how to programmatically load/render
if (GridPanel1.filters.menu.parentMenu) {
GridPanel1.filters.menu.parentMenu.find('itemId', 'filters')[0].setChecked(true);
}
});
},
mediumAndMoreToday : function() {
var filters = GridPanel1.filters.filters.items,
today = new Date(),
tomorrow = new Date();
tomorrow.setDate(today.getDate() + 1);
Viewer.views.applyFilters(function() {
filters[3].setValue({ 'before': tomorrow });
filters[3].setValue({ 'after': today });
filters[4].setValue(['medium', 'large', 'extra large']);
// only works if the column menu (not even the list items submenu) is just shown
// I think this is something to do with lazy loading? Not sure how to programmatically load/render
if (GridPanel1.filters.menu.parentMenu) {
GridPanel1.filters.menu.parentMenu.find('itemId', 'filters')[0].setChecked(true);
}
});
},
clear: function() {
Viewer.views.applyFilters();
},
applyFilters: function(action) {
var i, numFilters;
GridPanel1.filters.clearFilters();
GridPanel1.suspendEvents();
if (action) {
action();
}
GridPanel1.resumeEvents();
GridPanel1.filters.reload();
}
}
};
</script>
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />
<h1>GridPanel with Remote Filtering, Sorting and Paging</h1>
<ext:Window
ID="Window1"
runat="server"
Width="700"
Height="400"
Closable="false"
Collapsible="true"
Title="Example"
Maximizable="true"
Layout="Fit">
<Items>
<ext:GridPanel ID="GridPanel1" runat="server" Border="false">
<TopBar>
<ext:Toolbar ID="Toolbar1" runat="server">
<Items>
<ext:Button ID="ViewButton" runat="server" ShowText="true" PrependText="View " Text="Common views">
<Menu>
<ext:Menu ID="Menu1" runat="server">
<Items>
<ext:CheckMenuItem runat="server" Text="Today" Icon="Date">
<Listeners>
<Click Fn="Viewer.views.today" />
</Listeners>
</ext:CheckMenuItem>
<ext:CheckMenuItem ID="CheckMenuItem1" runat="server" Text="Medium or larger">
<Listeners>
<Click Fn="Viewer.views.mediumAndMore" />
</Listeners>
</ext:CheckMenuItem>
<ext:CheckMenuItem runat="server" Text="Medium or larger, today" Icon="DateMagnify">
<Listeners>
<Click Fn="Viewer.views.mediumAndMoreToday" />
</Listeners>
</ext:CheckMenuItem>
<ext:MenuSeparator />
<ext:MenuItem ID="MenuItem2" runat="server" Text="Clear all filters">
<Listeners>
<Click Fn="Viewer.views.clear" />
</Listeners>
</ext:MenuItem>
</Items>
</ext:Menu>
</Menu>
</ext:Button>
</Items>
</ext:Toolbar>
</TopBar>
<Store>
<ext:Store ID="Store1" runat="server" RemoteSort="true" OnRefreshData="Store1_RefreshData">
<Proxy>
<ext:PageProxy />
</Proxy>
<Reader>
<ext:JsonReader IDProperty="Id">
<Fields>
<ext:RecordField Name="Id" Type="Int" />
<ext:RecordField Name="Company" Type="String" />
<ext:RecordField Name="Price" Type="Float" />
<ext:RecordField Name="Date" Type="Date" />
<ext:RecordField Name="Size" Type="String" />
<ext:RecordField Name="Visible" Type="Boolean" />
</Fields>
</ext:JsonReader>
</Reader>
<BaseParams>
<ext:Parameter Name="start" Value="0" Mode="Raw" />
<ext:Parameter Name="limit" Value="10" Mode="Raw" />
<ext:Parameter Name="sort" Value="" />
<ext:Parameter Name="dir" Value="" />
</BaseParams>
<SortInfo Field="Company" Direction="ASC" />
</ext:Store>
</Store>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column Header="Id" DataIndex="Id" />
<ext:Column Header="Company" DataIndex="Company" />
<ext:Column Header="Price" DataIndex="Price">
<Renderer Format="UsMoney" />
</ext:Column>
<ext:DateColumn Header="Date" DataIndex="Date" Align="Center" Format="yyyy-MM-dd" />
<ext:Column Header="Size" DataIndex="Size" />
<ext:Column Header="Visible" DataIndex="Visible" Align="Center">
<Renderer Handler="return (value) ? 'Yes':'No';" />
</ext:Column>
</Columns>
</ColumnModel>
<LoadMask ShowMask="true" />
<Plugins>
<ext:GridFilters runat="server" ID="GridFilters1">
<Filters>
<ext:NumericFilter DataIndex="Id" />
<ext:StringFilter DataIndex="Company" />
<ext:NumericFilter DataIndex="Price" />
<ext:DateFilter DataIndex="Date">
<DatePickerOptions runat="server" TodayText="Now" />
</ext:DateFilter>
<ext:ListFilter DataIndex="Size" Options="extra small,small,medium,large,extra large" />
<ext:BooleanFilter DataIndex="Visible" />
</Filters>
</ext:GridFilters>
</Plugins>
<BottomBar>
<ext:PagingToolbar ID="PagingToolbar1" runat="server" PageSize="10" />
</BottomBar>
</ext:GridPanel>
</Items>
</ext:Window>
</form>
</body>
</html>
Last edited by Daniil; Oct 03, 2011 at 8:50 AM.
Reason: [CLOSED]