I created a filter and added it to my store
checkchange: function(item, checked) {
if (checked) {
Ext.getCmp('gridPanel').getStore().removeFilter(item.filter);
} else {
Ext.getCmp('gridPanel').getStore().addFilter(item.filter);
}
}
addFilter() works the way I want it to, but removeFilter() does nothing.
clearFilter() works as well, but I want to remove only one filter, not all of them.
This will not worked you have pass exact filter object to remove filter from store
var store = Ext.getCmp('gridPanel').getStore();
store.removeFilter(store.filters.items[0]);
Extjs Doc has state that:
Removes an individual Filter from the current filter set using the
passed Filter/Filter id and by default, applies the updated filter set
to the Store's unfiltered dataset.
Please refer link.
Related
I'm trying to keep a grid's filter after updating a row.
When I click on a row in the grid, I open a dialog where I update the informations for this row, and then I look for the clicked row in the grid's rowData after that I update the corresponding record in the rowData with the values from the dialog, as following :
row[0].x = dg.x;
row[0].y = dg.y;
dg.gridOptions.rowData[index] = row[0];
dg.gridOptions.api.setRowData(newRows);
But after this I loose the filter on the grid, I did some search and I tried all the following solutions :
Setting the gridOptions property deltaRowDataMode to true.
filterParams: {apply: true, newRowsAction: 'keep'}
But none of these has worked.
How can I solve this ?
You can set the filterParams newRowsAction to keep, like that
dg.defaultColDef = { filterParams: { newRowsAction: 'keep'}} ;
refer to https://www.ag-grid.com/javascript-grid-filtering/index.php
Use this method (gridOptions.api.refreshCells()) instead of setRowData. Or if you need to use setRowData, save the filter model before the call and apply the filter again afterwards using these methods:
const model = this.gridOptions.api.getFilterModel();
//some code
this.gridOptions.api.setFilterModel(model);
I had same issue and this what I did to resolve it (kinda hacky).
Subscribe to rowDataChanged event of the ag grid.
(rowDataChanged)="onRowDataChanged($event)"
Inside the onRowDataChanged put your filtration logic
// Get a reference to the name filter instance
const filterInstance = this.gridApi.getFilterInstance('fieldNameHere');
// Call some methods on Set Filter API that don't apply the filter
filterInstance.setModel({
type: 'contains', // type of filter
filter: 'yourData' // set filter on data
});
// Get grid to run filter operation again
this.gridApi.onFilterChanged();
onRowDataChanged will be triggered twice, first when the grid clears everything and second when the data reloaded. So, you should put some conditions to avoid any errors.
For example, I needed to set the filter from the data that was loaded after the refresh this is what I did:
const filtered = this.rowData.filter(x => x.Id === this.Id);
if (filtered.length > 0) {
// Get a reference to the name filter instance
const filterInstance = this.gridApi.getFilterInstance('fieldNameHere');
// Call some methods on Set Filter API that don't apply the filter
filterInstance.setModel({
type: 'contains', // type of filter
filter: filtered[0].name // set filter on data
});
// Get grid to run filter operation again
this.gridApi.onFilterChanged();
}
Just doing these steps:
I have grid filled with data from store.
I filter it (for example: Show only with status "late").
Data in store is updated.
I still see filtered old data (old records with status late).
I remove filter, All new data appear, with all old records which were not visible during filter.
Maybe someone know why and how to fix this?
FIXED
This code in store made a trick:
listeners : {
beforeload : function() {
this.data.clear();
if(this.data._source)
this.data._source.clear();
}
},
You can bind yourStore.reload() to your update event.
I have a weird situation. I have multiple filters applied to same store LOCALLY. But whenever there is a new value, I have to update a specific filter (either delete and create or update).
Therefore I can't use store.clearFilter as it clears everything.
I tried
store.filters.removeAtKey(prop);
store.filters.add(prop, new Ext.util.Filter({
property: prop,
value: event.value
}));
No luck.
Any help appreciated
Tharahan
you can get all the filters before clean:
store.filters
var filtersAux = [];
// get filter
Ext.Array.each(store.filters.items,function(element,pos,array){
// if Not (filter to remove)
filtersAux.push(element);
});
// remove all filters
store.clearFilter();
// add the filters:
Ext.Array.each(filtersAux,function(element,pos,array){
store.filter(element.property,element.value);
});
It work perfect for me.
Shouldn't you use the store's removeFilter method instead?
// false prevents useless update until you've added the new filter
store.removeFilter(prop, false);
I have a dijit Select widget and need to do something when the user clicks one of the dropdown items. Meaning I need access to the clicked item, to retrive some information, and call one of my own functions.
I've tested to attach an onChange on the select and I can get the text value selected fine. But I need the object and not the value. The object holds more values in a data-info-attribute.
Basically what I'm trying to achieve is to show one value in the list but send along more values to populate other fields when selected.
Background: This is a typeahead field populated thru AJAX by a server function. There IS a store attached but it's empty (as far as I can tell) so I've been unsuccessful trying with: .store.fetchItemByIdentity - always returns nothing.
ta.store.fetchItemByIdentity({
identity: ta.getValue(),
onItem: function(item, request){
console.log(item),
console.log(request)
}
})
I expect the log to show item- and request-object, but they're both undefined.
ta.getValue() get's the selected value as expected.
What's the best way to achieve this?
Have a look at my answer to onChange not sufficient to trigger query from Dojo Combobox and also to jsFiddle mentioned there. I added code specific for your needs there:
select.dropDown.on("itemClick", function(dijit, event) {
var node = dijit.domNode;
console.log(domAttr.get(node, "data-info-attribute"));
// or
console.log(node.dataset.infoAttribute);
});
I have the following html that is bound to an object containing id and status. I want to translate status values into a specific color (hence the converter function convertStatus). I can see the converter work on the first binding, but if I change status in the binding list I do not see any UI update nor do I see convertStatus being subsequently called. My other issue is trying to bind the id property of the first span does not seem to work as expected (perhaps it is not possible to set this value via binding...)
HTML:
<span data-win-bind="id: id">person</span>
<span data-win-bind="textContent: status converter.convertStatus"></span>
Javascript (I have tried using to modify the status value):
// persons === WinJS.Binding.List
// updateStatus is a function that is called as a result of status changing in the system
function updateStatus(data) {
persons.forEach(function(value, index, array) {
if(value.id === data.id) {
value.status = data.status;
persons.notifyMutated(index);
}
}, this);
}
I have seen notifyMutated(index) work for values that are not using a converter.
Updating with github project
Public repo for sample (not-working) - this is a really basic app that has a listview with a set of default data and a function that is executed when the item is clicked. The function attempts to randomize one of the bound fields of the item and call notifyMutated(...) on the list to trigger a visual updated. Even with defining the WinJS.Binding.List({ binding: true }); I do not see updates unless I force it via notifyReload(), which produces a reload-flicker on the listview element.
To answer your two questions:
1) Why can't I set id through binding?
This is deliberately prevented. The WinJS binding system uses the ID to track the element that it's binding to (to avoid leaking DOM elements through dangling bindings). As such, it has to be able to control the id for bound templates.
2) Why isn't the converter firing more than once?
The Binding.List will tell the listview about changes in the contents of the list (items added, removed, or moved around) but it's the responsibility of the individual items to notify the listview about changes in their contents.
You need to have a data object that's bindable. There are a couple of options:
Call WinJS.Binding.as on the elements as you add them to the collection
Turn on binding mode on the Binding.List
The latter is probably easier. Basically, when you create your Binding.List, do this:
var list = new WinJS.Binding.List({binding: true});
That way the List will call binding.as on everything in the list, and things should start updating.
I've found that if I doing the following, I will see updates to the UI post-binding:
var list = new WinJS.Binding.List({binding: true});
var item = WinJS.Binding.as({
firstName: "Billy",
lastName: "Bob"
});
list.push(item);
Later in the application, you can change some values like so:
item.firstName = "Bobby";
item.lastName = "Joe";
...and you will see the changes in the UI
Here's a link on MSDN for more information:
MSDN - WinJS.Binding.as
Regarding setting the value of id.
I found that I was able to set the value of the name attribute, for a <button>.
I had been trying to set id, but that wouldn't work.
HTH
optimizeBindingReferences property
Determines whether or not binding should automatically set the ID of an element. This property should be set to true in apps that use Windows Library for JavaScript (WinJS) binding.
WinJS.Binding.optimizeBindingReferences = true;
source: http://msdn.microsoft.com/en-us/library/windows/apps/jj215606.aspx