As I am using
Simple Grid with some of your plugins as:
1.
Page Size
2.
Filters
3.
Checkbox Selection Model
The situation is as follows:
As I am binding my grid's store
@model object
@{
ViewBag.Title = "GridPanel with MultiHeader Row Filters - 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 applyFilter = function (field) {
var store = App.GridPanel1.getStore();
store.filterBy(getRecordFilter());
};
var clearFilter = function () {
App.ComboBox1.reset();
App.PriceFilter.reset();
App.ChangeFilter.reset();
App.PctChangeFilter.reset();
App.LastChangeFilter.reset();
App.Store1.clearFilter();
}
var filterString = function (value, dataIndex, record) {
var val = record.get(dataIndex);
if (typeof val != "string") {
return value.length == 0;
}
return val.toLowerCase().indexOf(value.toLowerCase()) > -1;
};
var filterDate = function (value, dataIndex, record) {
var val = Ext.Date.clearTime(record.get(dataIndex), true).getTime();
if (!Ext.isEmpty(value, false) && val != Ext.Date.clearTime(value, true).getTime()) {
return false;
}
return true;
};
var filterNumber = function (value, dataIndex, record) {
var val = record.get(dataIndex);
if (!Ext.isEmpty(value, false) && val != value) {
return false;
}
return true;
};
var getRecordFilter = function () {
var f = [];
f.push({
filter: function (record) {
return filterString(App.ComboBox1.getValue()||"", "company", record);
}
});
f.push({
filter: function (record) {
return filterNumber(App.PriceFilter.getValue(), "price", record);
}
});
f.push({
filter: function (record) {
return filterNumber(App.ChangeFilter.getValue(), "change", record);
}
});
f.push({
filter: function (record) {
return filterNumber(App.PctChangeFilter.getValue(), "pctChange", record);
}
});
f.push({
filter: function (record) {
return filterDate(App.LastChangeFilter.getValue(), "lastChange", record);
}
});
var len = f.length;
return function (record) {
for (var i = 0; i < len; i++) {
if (!f[i].filter(record)) {
return false;
}
}
return true;
};
};
</script>
}
@section example
{
@(
Html.X().GridPanel()
.ID("GridPanel1")
.Title("Filter Grid")
.Width(600)
.Height(350)
.ResizableConfig(new Resizer { Handles = ResizeHandle.East })
.Store(
Html.X().Store()
.ID("Store1")
.DataSource(Model)
.Model(Html.X().Model()
.Fields(
Html.X().ModelField().Name("company"),
Html.X().ModelField().Name("price").Type(ModelFieldType.Float),
Html.X().ModelField().Name("change").Type(ModelFieldType.Float),
Html.X().ModelField().Name("pctChange").Type(ModelFieldType.Float),
Html.X().ModelField().Name("lastChange").Type(ModelFieldType.Date).DateFormat("MM/dd/yyyy")
)
)
)
.ColumnModel(
Html.X().Column()
.Text("Company")
.DataIndex("company")
.Flex(1)
.Items(
Html.X().ComboBox()
.ID("ComboBox1")
.Icon(Icon.Magnifier)
.TriggerAction(TriggerAction.All)
.QueryMode(DataLoadMode.Local)
.DisplayField("company")
.ValueField("company")
.Store(
Html.X().Store()
.PageSize(24)
.DataSource(Model)
.Model(Html.X().Model()
.Fields(
Html.X().ModelField().Name("company")
)
)
)
.Listeners(l =>
{
l.Change.Handler = "applyFilter(this);";
l.Change.Buffer = 250;
})
.Plugins(Html.X().ClearButton())
),
Html.X().Column()
.Text("Price")
.DataIndex("price")
.Width(75)
.Renderer(RendererFormat.UsMoney)
.Items(
Html.X().TextField()
.ID("PriceFilter")
.Listeners(l => {
l.Change.Handler = "applyFilter(this);";
l.Change.Buffer = 250;
})
.Plugins(Html.X().ClearButton())
),
Html.X().Column()
.Text("Changes")
.Columns(
Html.X().Column()
.Text("Change")
.DataIndex("change")
.Width(75)
.HideTitleEl(true)
.Renderer("change")
.Items(
Html.X().TextField()
.ID("ChangeFilter")
.Listeners(l => {
l.Change.Handler = "applyFilter(this);";
l.Change.Buffer = 250;
})
.Plugins(Html.X().ClearButton())
),
Html.X().Column()
.Text("Change %")
.DataIndex("pctChange")
.Width(75)
.HideTitleEl(true)
.Renderer("pctChange")
.Items(
Html.X().TextField()
.ID("PctChangeFilter")
.Listeners(l => {
l.Change.Handler = "applyFilter(this);";
l.Change.Buffer = 250;
})
.Plugins(Html.X().ClearButton())
)
),
Html.X().DateColumn()
.Text("Last Updated")
.Width(95)
.DataIndex("lastChange")
.Items(
Html.X().DateField()
.ID("LastChangeFilter")
.Editable(false)
.Listeners(l => {
l.Change.Handler = "applyFilter(this);";
})
.Plugins(Html.X().ClearButton())
),
Html.X().Column()
.Width(25)
.DataIndex("company")
.Sortable(false)
.MenuDisabled(true)
.Text(" ")
.Resizable(false)
.Renderer("return '';")
.Items(
Html.X().Container()
.Items(
Html.X().Button()
.ID("ClearFilterButton")
.Icon(Icon.Cancel)
.ToolTip("Clear filter")
.Handler("clearFilter")
)
)
)
)
}
After rendering this view I am able to see total 500 records which is as expected.
Now as I mentioned above I am using column Header for each column as to filter records, when I type some text in lets say on
Company Column, then I get 50 filtered records.
As in this case when I apply quick watch to see store of my grid then the results are as follows:
App.GridPanel1.getStore().totalCount = 500 // here I have 500 total records in the grid
App.GridPanel1.getStore().data.length = 24 // as I mentioned in above code my store's page size is 24
App.GridPanel1.getStore().allData.length = 50 //here I have 50 filtered records
Now as you can see my above code where I set my store's page size as
24. Also keeping in mind that I am also using
Checkbox Selection Model to select records, now what happens in this example as follows:
<script>
/* A header Checkbox of CheckboxSelectionModel deals with the current page only.
This override demonstrates how to take into account all the pages.
It works with local paging only. It is not going to work with remote paging.
*/
Ext.selection.CheckboxModel.override({
selectAll: function (suppressEvent) {
var me = this,
selections = me.store.getAllRange(), // instead of the getRange call
i = 0,
len = selections.length,
start = me.getSelection().length;
me.suspendChanges();
for (; i < len; i++) {
me.doSelect(selections[i], true, suppressEvent);
}
me.resumeChanges();
if (!suppressEvent) {
me.maybeFireSelectionChange(me.getSelection().length !== start);
}
},
deselectAll: Ext.Function.createSequence(Ext.selection.CheckboxModel.prototype.deselectAll, function () {
this.view.panel.getSelectionMemory().clearMemory();
}),
updateHeaderState: function () {
var me = this,
store = me.store,
storeCount = store.getTotalCount(),
views = me.views,
hdSelectStatus = false,
selectedCount = 0,
selected, len, i;
if (!store.buffered && storeCount > 0) {
selected = me.view.panel.getSelectionMemory().selectedIds;
hdSelectStatus = true;
for (s in selected) {
++selectedCount;
}
hdSelectStatus = storeCount === selectedCount;
}
if (views && views.length) {
me.toggleUiHeader(hdSelectStatus);
}
}
});
Ext.grid.plugin.SelectionMemory.override({
memoryRestoreState: function (records) {
if (this.store !== null && !this.store.buffered && !this.grid.view.bufferedRenderer) {
var i = 0,
ind,
sel = [],
len,
all = true,
cm = this.headerCt;
if (!records) {
records = this.store.getAllRange(); // instead of getRange
}
if (!Ext.isArray(records)) {
records = [records];
}
if (this.selModel.isLocked()) {
this.wasLocked = true;
this.selModel.setLocked(false);
}
if (this.selModel instanceof Ext.selection.RowModel) {
for (ind = 0, len = records.length; ind < len; ind++) {
var rec = records[ind],
id = rec.getId();
if ((id || id === 0) && !Ext.isEmpty(this.selectedIds[id])) {
sel.push(rec);
} else {
all = false;
}
++i;
}
if (sel.length > 0) {
this.surpressDeselection = true;
this.selModel.select(sel, false, !this.grid.selectionMemoryEvents);
this.surpressDeselection = false;
}
} else {
for (ind = 0, len = records.length; ind < len; ind++) {
var rec = records[ind],
id = rec.getId();
if ((id || id === 0) && !Ext.isEmpty(this.selectedIds[id])) {
if (this.selectedIds[id].dataIndex) {
var colIndex = cm.getHeaderIndex(cm.down('gridcolumn[dataIndex=' + this.selectedIds[id].dataIndex + ']'))
this.selModel.setCurrentPosition({
row: i,
column: colIndex
});
}
return false;
}
++i;
}
}
if (this.selModel instanceof Ext.selection.CheckboxModel) {
if (all) {
this.selModel.toggleUiHeader(true);
} else {
this.selModel.toggleUiHeader(false);
}
}
if (this.wasLocked) {
this.selModel.setLocked(true);
}
}
}
});
</script>
A header Checkbox of CheckboxSelectionModel deals with the current page only.
This override demonstrates how to take into account all the pages.
It works with local paging only. It is not going to work with remote paging.
As in my case I just wanna deals with the current page only. So if I do so I can select only 24 records i.e the records in
App.GridPanel1.getStore().data
and after selecting I click on
"Delete" button on my grid. This button handler is as follows:
var records = App.GridPanel1.selModel.getSelection();
App.GridPanel1.getStore().remove(records);
App.GridPanel1.getStore().loadData(App.GridPanel1.getStore().allData.items)
After doing so I again apply quick watch to see store of my grid then the results are as follows:
App.GridPanel1.getStore().totalCount = 476 // here I have remaining 476 total records in the grid
App.GridPanel1.getStore().data.length = 24 // as I mentioned in above code my store's page size is 24
App.GridPanel1.getStore().allData.length = 26 //here I have remaining 26 filtered records
I hope that till now you understand that this is going really very smooth and working as expected.
Now the real problem is here when I try to fetch these 476 records, there is no array where I can find these records but yes I am able to see the total count of my store as 476.
FYI
1. I understand the fact that in above code I am loading the filtered records into my store.
App.GridPanel1.getStore().loadData(App.GridPanel1.getStore().allData.items)
2. I am also aware that Ext.net uses in-built feature to store the unfiltered records into an array known as
"snapshot" which by the way got vanished the time when I run the code
App.GridPanel1.getStore().loadData(App.GridPanel1.getStore().allData.items)
3. I can also find those initial 500 records in proxy array
App.GridPanel1.getStore().proxy.data.items
Knowing these facts again my question is from where I can find those unfiltered 476 records, If these records also vanished then from where my store's total count is coming as
476
I hope this time you understand the problem, as the project I am working on is confidential so I cannot give you the code, but from situation above you can do a little efforts and create an identical situation in one of your example and try to figure out some solution.
Thanks and Regards