keep filter after ag-grid update - javascript

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();
}

Related

How to implement initial sorting in SAP UI5 Smart Table

I have a smart table, with some custom columns inside it. I would like to sort the table initially based on a certain field, how do I achieve it?
Till now I have tried the following, but it didn't work.
var oSmartTableBatches = this.getView().byId("sapAffectedBatchesSmartTable2");
oSmartTableAlerts.applyVariant({
sort: {
sortItems: [{
columnKey: "FieldName",
operation: "Descending"
}]
}
});
I have also tried annotating the entity set with Presentation Variant
<Annotation Term="com.sap.vocabularies.UI.v1.PresentationVariant">
<Record>
<PropertyValue Property="SortOrder">
<Collection>
<Record>
<PropertyValue Property="Property" PropertyPath="FieldName"/>
<PropertyValue Property="Descending" Boolean="true"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
I am using odata v2 model.
I also tried using beforeRebindTable function add a sorter, however it breaks the table personaliation dialog, and grouping and filtering doesn't work on table anymore.
The sorter must be an array of sap.ui.model.Sorter objects, see the documentation.
That applyVariant is only for showing the sorted column in P13N dialog.
The annotation that you used only applied on Grid tables and not responsive tables!
If you want to apply initial sorting you need to have the following event handler:
// define this variable in onInit function or in the controller class level
initView: true,
// smart table event handler
onBeforeRebindTable: function (oEvent) {
var mBindingParams = oEvent.getParameter("bindingParams");
if(this.initView){
// to apply the sort
mBindingParams.sorter = [new sap.ui.model.Sorter({ path: "FieldName", descending: true})];
// to short the sorted column in P13N dialog
var oSmartTable = oEvent.getSource();
oSmartTable.applyVariant({
sort: {
sortItems: [{
columnKey: "FieldName",
operation: "Descending"
}]
}
});
// to prevent applying the initial sort all times
this.initView = false;
}
},
This code sorts the data only when the app is loaded or if user presses on the browser refresh button!
Don't forget to keep the line mBindingParams.sorter = [new sap.ui.model.Sorter({ path: "FieldName", descending: true})]; inside a if condition, otherwise each time that user applies a sort you will overwrite it.
This condition also is possible:
if(mBindingParams.sorter.length === 0)
But in this case user cannot remove the sort conditions. Therefore when he or she removes all sorts in P13N dialog, not only in the initialization time, but in such kind of condition also the initial sort order will be applied!

select2: Is it possible to pass custom input and access it in methods

I want to pass custom property while creating select2. Example (my custom property being myFilterEnabled):
$('#mySelId2').select2({
myFilterEnabled: false, //Pass my initial state
query: function(query) {
var res = {
results: CityFilter.cities
};
query.callback(res);
}
});
And use it in the query or render functions. Like:
$('#mySelId2').select2({
myFilterEnabled: false,
query: function(query) {
var fltEnabled = this.myFilterEnabled; //Read current state
var res = {
results: fltEnabled ? [] : CityFilter.cities
};
query.callback(res);
}
});
This is so that, there is an initial state for the variable. But, it can change externally, and I want to check that state during each re-render/query.
Edit: Seems I made a mistake before posting. Above code seems to work. I am planning to add a common prefix like 'my' or 'myProj' so that it doesn't conflict with any variables of select2 itself.
Edit2: As mentioned, passing initial state and reading current state are working. I still need a way to change that state from outside. If select2 doesn't have a method for that I could set a data attribute on the element.
This is the full cycle that I wanted:
Set custom state -> Read custom state during query/render -> Change custom state on user action -> Trigger re-render on state change
This is how I managed to do it as of now:
1) I can pass a custom parameter in options while setting up select2
$('#mySelId2').select2({
myFilterEnabled: false,
query: function(query){ ...
2) I am able to read the custom parameter within the callbacks as
this.myFilterEnabled
3) I can set the custom parameter from outside as
$('#s2id_<myId>').data('select2').opts.myFilterEnabled = true;
3) After setting the property as shown above, i want select2 to
re-apply the query function. I can trigger change on
input.select2-input. But, there is a check to prevent re-execution
of query while the text remains the same. So, I go a step further
and call the updateResults function with a 'true' argument. That
forces updateResult to proceed to run query again. Example:
$('#s2id_<myId>').data('select2').updateResults(true);

extjs removeFilter() doesn't work

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.

Getting original data from kendo UI DataSource

In the Kendo UI documentation for the DataSource component, it states that the data function is used to get data items for the data source.
However it also states that if the data source is bound to a JavaScript array (via the data option) the data method will return the items of that array. Every item from the array is wrapped in a kendo.data.ObservableObject or kendo.data.Model.
How can I retrieve the original unwrapped data items (i.e. having same reference) that were passed into the data source?
I ask because I'm using a Kendo UI treeview control and in its event handlers (e.g. check event) I want to update the original data item for a tree node based on some custom logic.
Update
For example here is a simple treeview having a single node (of course in a realistic scenario the tree would contain many nodes) . When checking the node I want to get a reference to the original data item for the checked node. this.dataItem(e.node) does not return the original data item as the log statement outputs false.
<div id="treeview"></div>
<script>
var mydata = [
{ text: "foo", checked: false}
];
$("#treeview").kendoTreeView({
checkboxes: true,
dataSource: mydata,
check: function(e) {
console.log(this.dataItem(e.node) == mydata[0]); //I want this to output true
}
});
</script>
If I understand your question correctly, you can get to the records independently by referencing your data source and using the .at(x) function, where x equals whatever record of your data source you are attempting to access. So to get the first.
var theData = yourDataSource.at(0);
To update it, you then use .set and .sync.
theData.set('userFirstName', 'Joe');
theData.set('userAverageTime', 10);
yourDataSource.sync();
Using .set() is handy because if you store all your updates into an iterable collection, then you can just run through them.
$.each(updatedVars, function(key, element) {
theData.set(key, element);
});
yourDataSource.sync();

Ext JS 4:Remove or update specific filter in Store

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);

Categories