[CLOSED] Filter functionality : Gridpanel + Multicombo column + Column FIlter(List filter)
Hi,
I have a grid panel with multicombo column in it. I managed to display the selected the values of a multicombo column using column renderer. That's fine. I try to add a list filter for the column displaying its values. When I apply it does not show any records at all. i.e. filter not at all working for this case.
Sample code below . Check the column sample. It displays 1,2 for all rows. Now try to apply the column filter for any of the displayed values. The issue will be reproduced. It would be great if you shall suggest/ provide a solution (any override or custom config) for this. Can use ext.net 3.1 or 3.2 to reproduce this.
Model file
Code:
namespace Ext.Net.MVC.Examples.Areas.GridPanel_ArrayGrid.ArrayWithPaging
{
public class Companies
{
private List<Company> companyList = new List<Company>();
private List<Sample> sampleList = new List<Sample>();
public List<Company> CompanyDetails
{
get
{
return companyList;
}
set
{
companyList = value;
}
}
public List<Sample> Samples
{
get
{
return sampleList;
}
set
{
sampleList = value;
}
}
public Companies GetSampleandCompanies()
{
Companies c = new Companies();
c.CompanyDetails = GetAllCompanies();
c.Samples = GetSampleStore();
return c;
}
public List<Company> GetAllCompanies()
{
DateTime now = DateTime.Now;
List<int> intList = new List<int>();
intList.Add(1);
intList.Add(2);
return new List<Company>
{
new Company{ company = "3m Co", price= 71.72,sample = intList,change= 0.02, pctchange = 0.03, lastchange = now },
new Company{ company = "Alcoa Inc", price= 71.72,sample = intList,change= 0.02, pctchange = 0.03, lastchange = now },
new Company{ company = "Altria Group Inc", price= 71.72,sample = intList,change= 0.02, pctchange = 0.03, lastchange = now },
new Company{ company = "American Express Company", price= 71.72,sample = intList,change= 0.02, pctchange = 0.03, lastchange = now },
new Company{ company = "American International Group, Inc.", price= 71.72,sample = intList,change= 0.02, pctchange = 0.03, lastchange = now },
};
}
public List<Sample> GetSampleStore()
{
var sampleList = new List<Sample>();
sampleList.Add(new Sample { SampleId = 1, SampleName = "1" });
sampleList.Add(new Sample { SampleId = 2, SampleName = "2" });
sampleList.Add(new Sample { SampleId = 3, SampleName = "3" });
sampleList.Add(new Sample { SampleId = 4, SampleName = "4" });
return sampleList;
}
}
public class Sample
{
public int SampleId { get; set; }
public string SampleName { get; set; }
}
public class Company
{
public string company { get; set; }
public double price { get; set; }
public List<int> sample { get; set; }
public double change { get; set; }
public double pctchange { get; set; }
public DateTime lastchange { get; set; }
}
}
Controller
Code:
namespace Ext.Net.MVC.Examples.Areas.GridPanel_ArrayGrid.ArrayWithPaging.Controllers
{
public class ArrayWithPagingController : Controller
{
private Companies comp;
public ArrayWithPagingController()
{
comp = new Companies();
}
public ActionResult Index()
{
return View(comp.GetSampleandCompanies());
}
public ActionResult GetData()
{
return this.Store(comp.GetSampleandCompanies());
}
public ActionResult GetSampleStore()
{
return this.Store(comp.GetSampleandCompanies());
}
}
}
cshtml file
Code:
@model Ext.Net.MVC.Examples.Areas.GridPanel_ArrayGrid.ArrayWithPaging.Companies
@{
ViewBag.Title = "Simple Array Grid With Local Paging and Remote Reloading - Ext.NET MVC Examples";
Layout = "~/Views/Shared/_BaseLayout.cshtml";
}
@section headtag
{
<script>
var template = '<span style="color:{0};">{1}</span>';
var change = function (value) {
return Ext.String.format(template, (value > 0) ? "green" : "red", value);
};
var pctChange = function (value) {
return Ext.String.format(template, (value > 0) ? "green" : "red", value + "%");
};
var onComboBoxSelect = function (combo) {
var store = combo.up("gridpanel").getStore();
store.pageSize = parseInt(combo.getValue(), 10);
store.reload();
};
var renderTagNames = function (value, meta, record) {
var b = '';
if (!Ext.isEmpty(record.data.sample)) // Setting ReviewerID with the array values of ReviewerIDArray. More than 1 reviewer is joined and set as one field to be saved
var tagIdArrayLength = record.data.sample.length;
for (var i = 0; i < tagIdArrayLength; i++) {
var a = record.data.sample[i];
b = b.concat(', ' + a);
}
return b.replace(new RegExp(',', 'g'), '<br />');
};
var validateTags = function (editor, e) {
if (e.value instanceof Array) {
// debugger;
// var isNotEqual = false;
var arrayOrgLen = 0;
var arrayNewLen = 0;
var arrayOrg = e.originalValue;
var arrayNew = e.value;
if (arrayOrg != null)
arrayOrgLen = arrayOrg.length
if (arrayNew != null)
arrayNewLen = arrayNew.length
if (arrayOrg == null || arrayOrg.length == 0) {
if (arrayNew == null || arrayNew.length == 0)
e.cancel = true;
}
else {
var is_same = arrayOrg.length == arrayNew.length && arrayOrg.equals(arrayNew);
if (is_same)
e.cancel = true;
}
}
};
Array.prototype.equals = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l = this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
</script>
<style>
.x-grid-row-summary .x-grid-cell-inner {
font-weight: bold;
font-size: 14px;
background-color: #f1f2f4;
}
.x-docked-top {
border-bottom-width: 1px !important;
}
.x-grid-header-ct {
border-bottom-color: #000000 !important;
}
.x-column-header-inner .x-column-header-text {
white-space: normal;
}
.wrap .x-grid-cell-inner {
white-space: normal;
}
.columnAlignLeft {
text-align: left;
}
</style>
}
@section example
{
<h1>Array Grid with Local Paging and Remote Reloading</h1>
<p>Demonstrates how to create a grid from Array data with Local Paging and Remote Reloading.</p>
<p>Notice <b>Last Updated</b> column is revised with a new server-side DateTime stamp when the GridPanel "Refresh" button is clicked.
<br />This demonstrates that when the GridPanel is refreshed, the Data is requested again from the server via an AJAX request initiated by AjaxProxy, but the Paging and Sorting is done completely client-side in the browser.</p>
@( Html.X().Window().ID("wnCommand").Width(500).Height(400).Hidden(true).Layout("Fit")
.Items
(
Html.X().TextArea().ID("txtDes")
)
)
@(Html.X().Store()
.ID("storeSample")
.Model
(
Html.X().Model().ID("modelSample").Name("ModelSample")
.IDProperty("SampleId")
.Fields
(
new ModelField("SampleId", ModelFieldType.Int),
new ModelField("SampleName", ModelFieldType.String)
)
)
.DataSource(Model.Samples)
//.Proxy(
// Html.X().AjaxProxy()
// .Url(Url.Action("GetSampleStore")))
)
@(Html.X().GridPanel()
.Title("Array Grid")
.Width(1200)
.Store(
Html.X().Store()
.PageSize(100)
.Model(
Html.X().Model()
.Fields(
new ModelField("company"),
new ModelField("price", ModelFieldType.Float),
new ModelField("sample",ModelFieldType.Object),
new ModelField("change", ModelFieldType.Float),
new ModelField("pctChange", ModelFieldType.Float),
new ModelField("lastChange", ModelFieldType.Date)
)
)
.DataSource(Model.CompanyDetails)
.ServerProxy(
Html.X().AjaxProxy()
.Url(Url.Action("GetData"))
)
)
.ColumnModel(
Html.X().RowNumbererColumn(),
Html.X().Column().Text("Company").DataIndex("company").Flex(1).Cls("columnAlignLeft"),
Html.X().Column().Text("Price").DataIndex("price").Width(75).Renderer(new Renderer{Format= RendererFormat.UsMoney}),
Html.X().Column().Text("sample").DataIndex("sample").Width(75).Editor
(
Html.X().MultiCombo().Items
(
Html.X().ListItem().Text("1").Value("1"),
Html.X().ListItem().Text("2").Value("2"),
Html.X().ListItem().Text("3").Value("3")
)
).Renderer("renderTagNames").Filter(Html.X().ListFilter().StoreID("storeSample").IDField("SampleId").LabelField("SampleName")),
Html.X().ImageCommandColumn().ID("descImgCmd").Text("").ToolTip("Task Description")
.Width(20)
.Commands
(
Html.X().ImageCommand().CommandName("Description").Icon(Icon.PageWhite).ToolTip(x => x.Text = "Enter Description")
).Listeners(ls=>ls.Command.Handler = "App.wnCommand.show();App.wnCommand.center();"),
Html.X().Column().Text("Change").DataIndex("change").Width(75).Renderer("change").Cls("columnAlignLeft")
.Align(Alignment.Right)
.SummaryRenderer(new Renderer { Handler = "return value.toFixed(2)" }).SummaryType(SummaryType.Sum),
Html.X().Column().Text("Change").DataIndex("pctChange").Width(75).Renderer("pctChange").Align(Alignment.Right)
.Cls("columnAlignLeft")
)
.SelectionModel(
Html.X().RowSelectionModel().Mode(SelectionMode.Multi)
)
.Listeners(ls=>ls.AfterRender.Handler="App.storeSample.reload();")
.Plugins(
Html.X().GridFilters(),Html.X().CellEditing().ClicksToEdit(1)
)
.Features
(
Html.X().Summary().ID("summary1")
)
.View(Html.X().GridView().StripeRows(true))
.BottomBar(
Html.X().PagingToolbar()
.Items(
Html.X().Label("Page size:"),
Html.X().ToolbarSpacer(10),
Html.X().ComboBox()
.Width(80)
.Items("1", "2", "10", "100")
.SelectedItems("100")
.Listeners(l=>{
l.Select.Fn = "onComboBoxSelect";
})
)
)
)
}
working sample using FilterHeader
Thanks for your reply.
In one of our application we have achieved this multicombo filter, the difference is we have used FilterHeader in the existing application (also in the sample provided below) whereas we need to achieve this in our current application using GridFilters (Column Filters). We need the override similar to the FilterHeader override (in the sample). We dont have any clue on the corresponding GridFilter extjs methods. Can you please help on this.
Code:
<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<ext:ResourceManager ID="ExtResourceManager" runat="server" />
<script runat="server">
public class CustomModel
{
public int MyID { get; set; }
public List<int> Colors { get; set; }
}
public class MyColor
{
public int ColorID { get; set; }
public string Color { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
List<MyColor> comboDatasource = new List<MyColor> {new MyColor { ColorID = 1, Color = "red"},
new MyColor { ColorID = 2, Color = "blue"},
new MyColor { ColorID = 3, Color = "green"},
new MyColor { ColorID = 4, Color = "yellow"}
};
List<CustomModel> gridDatasource = new List<CustomModel> { new CustomModel { MyID = 1, Colors = new List<int> { 1, 2}},
new CustomModel { MyID = 2, Colors = new List<int> { 1, 3}},
new CustomModel { MyID = 3, Colors = new List<int> { 2, 3}},
new CustomModel { MyID = 3, Colors = new List<int> { 1, 2}}
};
StoreColors.DataSource = comboDatasource;
StoreColors.DataBind();
StoreTagging.DataSource = gridDatasource;
StoreTagging.DataBind();
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<ext:XScript ID="XScript1" runat="server">
<script lang="javascript" type="text/javascript">
//for multicombo filter columns getting rendered text instead of value
Ext.define("my.overridden.FilterHeader", {
override: 'Ext.net.FilterHeader',
isSmartFilterValid: function (field) {
return true;
},
smartFilterValue: function (value, dataIndex, record, type, field) {
var recordValue = record && record.get(dataIndex),
isEmpty = Ext.isEmpty(value, false);
var column = field.column;
if (column && column.renderer && column.renderer.call) {
if (recordValue instanceof Array)
recordValue = column.renderer.call(column.scope, recordValue, null, record);
}
if (isEmpty) {
return true;
}
if (!type && (recordValue == null || !Ext.isDefined(recordValue))) {
return false;
}
return this.selectSmartFilter(type, recordValue, value, field);
}
});
//behavior for multicombo filter
Ext.net.FilterHeader.behaviour.addBehaviour("string", {
name: "anycontains",
is: function (value) {
return Ext.net.StringUtils.startsWith(value, "anycontains ");
},
getValue: function (value) {
var values = Ext.net.FilterHeader.behaviour.getStrValue(value).substring(12).split(","),
tmp = [];
Ext.each(values, function (v) {
v = v.trim();
if (!Ext.isEmpty(v)) {
tmp.push(v);
}
});
values = tmp;
// debugger;
return { value: values, valid: values.length > 0 };
},
match: function (recordValue, matchValue) {
// if (recordValue != null && recordValue != 'undefined')
// /debugger;
for (var i = 0; i < matchValue.length; i++) {
if (recordValue != null && recordValue.indexOf(matchValue[i]) > -1) {
return true;
}
}
return false;
},
isValid: function (value) {
return this.getValue(value, field).valid;
},
serialize: function (value) {
return {
type: "string",
op: "any",
value: value
};
}
});
var PTag1 = function (value, metadata, record)
{
var concatPTag1Data = '';
if(! Ext.isEmpty(record.data.Colors))
var PTagIDArrlength = record.data.Colors.length;
for (var i = 0; i < PTagIDArrlength; i++) {
var a = record.data.Colors[i];
var r = #{StoreColors}.getById(a);
if(r!=null)
concatPTag1Data = concatPTag1Data.concat(', ' + r.data.Color);
}
return concatPTag1Data.replace(new RegExp(',', 'g'), '<br />');
};
function getfilterResults() {
//debugger;
var text = [];
text = this.value;
if (text.length == 0) {
return "";
} else {
return "anycontains " + text.join(",");
}
}
</script>
</ext:XScript>
<form id="form1" runat="server">
<div>
<ext:Store ID="StoreColors" runat="server">
<Model>
<ext:Model ID="ModelStoreTag1" runat="server" IDProperty="ColorID">
<Fields>
<ext:ModelField Name="ColorID" />
<ext:ModelField Name="Color" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
<ext:GridPanel ID="TaggingGridPanel" runat="server">
<Store>
<ext:Store ID="StoreTagging" runat="server" PageSize="15">
<Model>
<ext:Model ID="ModelTagging" runat="server" IDProperty="MyID">
<Fields>
<ext:ModelField Name="MyID" Type="Int" />
<ext:ModelField Name="Colors" Type="Object" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column ID="clmGrpName" runat="server" DataIndex="MyID" Text="ID"
Width="170px">
</ext:Column>
<ext:Column ID="clmTag1" runat="server" Text="Colors" DataIndex="Colors"
Width="110px">
<Renderer Fn="PTag1" />
<Editor>
<ext:MultiCombo ID="cmbTag1" runat="server" StoreID="StoreColors" DisplayField="Color"
ValueField="ColorID" Editable="false">
</ext:MultiCombo>
</Editor>
<Items>
<ext:MultiCombo ID="ComboBox1" runat="server" StoreID="StoreColors" DisplayField="Color"
ValueField="Color" Editable="false">
<CustomConfig>
<ext:ConfigItem Name="getValue" Value="getfilterResults" Mode="Raw" />
</CustomConfig>
</ext:MultiCombo>
</Items>
</ext:Column>
</Columns>
</ColumnModel>
<Plugins>
<ext:FilterHeader ID="FilterHeader1"
runat="server" />
</Plugins>
</ext:GridPanel>
</div>
</form>
</body>
</html>