Get current Sort Key Of Backgrid Table - backbone.js

I have following table made by Backgrid.js:
this.grid = new FixedWidthGrid({
columns: this.columns,
row: SelectableDocumentContextMenuRow.extend({
contextMenu: ContextMenuHelper.onRightClick
}),
collection: self.collection,
header: FilterHeader,
contextMenu: ContextMenuHelper.onRightClick
});
Now, when I click on a header label, the entire table gets sorted by that attribute on the client.
How can I get the current sort key/attribute (e.g. name, age etc.) of the collection?

If you are using backbone.paginator you should be able to get this by checking the value of collection.state.sortKey

Related

How can I filter records by their ObjectID (_id) in Ag-grid

I'm using MongoDB to store my records and am using Ag-grid react to display them. The grid has several columns including the record's ObjectID (_id), name, type, etc. Using the filter agColumnTextFilter works for the name and type fields with the columnDef of:
{
headerName: 'Column Name',
field: 'name',
filter: 'agTextColumnFilter',
},
which then leads to this query setup (using the contains filter option):
case "contains":
qp[fieldName] = new RegExp(['.*', user input string, '.*'].join(''), 'ig');
this logs the correct query:
"query db { name: /.*query string.*/gi }"
and the proper rows are displayed. Since the displayed _id is a string as well I tried something similar:
{
headerName: 'ID',
field: '_id',
valueGetter: (params) => {
let id = params.data._id;
return id.slice(id.length-5); //only display last part of ID instead of entire thing
},
filter: 'agTextColumnFilter',
},
Using the same contains logic as above the following query is logged to the console:
query db { _id: /.*_id segment.*/gi }
However, no rows are returned in this case (even though there should be rows returned). Do I need to use different logic or is there a problem with this current logic? Any advice is appreciated.
Edit: Turns out even though the ID displays as a String a cast of the string to an ObjectID is needed:
qp[fieldName] = new ObjectID(_id string)
Problem with this is searching for part of a specific ID won't work because it's not a valid ID. Searching for a full ID works but isn't ideal either. If anyone has any ideas on how I can filter just part of the ID I'd appreciate it.
You can probably set a valueFormatter on the column that displays the partial ObjectId. The filtering will be done using the full ObjectId.

How to update autoGroupColumnDef property of ag-Grid after table is initialized

I have an ag-grid table (Enterprise version: 22.1.0) which is grouped using autoGroupColumnDef property. The grouping is dependent on the table's data and the data loads on a button click. I need to update the autoGroupColumnDef property's field name (_this.colName in the below code) after the page is loaded, right before loading the data.
Table's grid options:
_this.gridOptions = {
defaultColDef: {
sortable: true,
resizable: true,
filter: true
},
columnDefs: _this.columnDefs,
rowData: [],
enableRangeSelection: true,
autoGroupColumnDef: {
headerName: "Sector",
field: _this.colName,
cellRendererParams: {
suppressCount: true
},
tooltipValueGetter: function(params) {
return _this.tooltipVal
}
},
suppressAggFuncInHeader: true,
enableBrowserTooltips: true
};
I update the variable _this.colName before setting data to the grid. I have tried the following options and none of them worked for me:
_this.gridOptions.api.refreshClientSideRowModel('group');
_this.gridOptions.api.refreshCells();
_this.gridOptions.autoGroupColumnDef.field = 'Column's Name'
Any help would be appreciated!
There is a good workaround for this. You can set autoGroupColumnDef, then remove and readd all row groupings. It will redraw the group column with the new name.
gridOptions.autoGroupColumnDef.headerName = 'new_name';
// Get current groupings
var colstate = gridOptions.columnApi.getColumnState();
var colstateclear = gridOptions.columnApi.getColumnState();
// Clear groupings
var x = 0, xcount = colstateclear.length;
while ( x < xcount ) {
colstateclear[x].rowGroupIndex = null;
x += 1;
}
gridOptions.columnApi.setColumnState(colstateclear);
// Reset groupings
gridOptions.columnApi.setColumnState(colstate);
I contacted ag-grid support and apparently this is a bug and they have it in their backlog with no ETA available for now. A workaround they provided was to use: https://www.ag-grid.com/javascript-grid-grouping/#showRowGroup.
This is not really a good workaround because the grouped columns are separated and makes the page feel cramped. Also there are some look and feel issues that keep popping up (Eg: empty space added before each column that increases with each grouped column. ie second column has 1 cm added before it, third column has 2 cm added before it and so on. I guess this was added to bring the grouped look in the group column but you wouldn't expect this behavior when the columns are separated.)
ag-grid's backlog ID for the ticket: AG-3359 - Allow the autoGroupColumn to be used in the API calls for columns, at the moment there is no way to dynamically change it after creation. (ie, setColumnDefs …)
Link to track the progress: https://www.ag-grid.com/ag-grid-pipeline/
there is a straight forward method to update the autoGroupColumnDef object and its properties with setAutoGroupColumnDef
this.gridOptions.api.setAutoGroupColumnDef(<ColDef>{
...this.gridOptions.autoGroupColumnDef, // preserve the other settings except the ones you need to change
minWidth: 500
})
if any problems with the spread operator,
do it manually:
this.gridOptions.api.setAutoGroupColumnDef(<ColDef>{
// ...this.gridOptions.autoGroupColumnDef, // preserve the other settings except the ones you need to change
headerName: this.gridOptions.autoGroupColumnDef.headerName,
minWidth: 500
})
and one more thing, add this if you have any visual bugs, like: header row gets resized but bellow rows stays the same as previus state, so the refresh of model is required:
this.gridOptions.api.refreshClientSideRowModel();
this refresh is not ideal solution, because it refreshes everything, so you will loose expanded levels for example, still no clue how to preserve all settings.
https://angulargrid.com/angular-grid/client-side-model/#refreshing-the-client-side-model
and best solution for now is tu use:
this.gridOptions.api.redrawRows();
it keeps the rows expanded if are, checkbox selected if is.

Backgrid doesn't render the grid with the updated collection

I'm using Backgrid and I create the Backgrid Object as follows in my Controller:
$.when(recipeRequest).done(function (recipes) {
List.grid = new Backgrid.Grid({
columns: columns, // where columns is defined elsewhere
collection: recipes // recipes is the result of a fetch
})
// Then add it to the Marionette template
}
The above works perfectly and items display as expected
Once the table is displayed we are providing filtering functionality ServerSide as follows:
filterRecipes: function (query) {
// remove any incomplete network requests
_.each(RecipeManager.fetchXhrs, function (r) {
r.abort()
})
// get a filtered set of recipes
var filteredRecipes = RecipeManager.request('recipe:entities', query)
$.when(filteredRecipes).done(function (recipes) {
// this line shows that the result set is being updated as expected with for example 6 results
console.log(recipes)
// setting the new recipe result set to the grid.collection
List.grid.collection = recipes
// here the table rerenders but there are a LOT more results on the table - not 6 as expected
List.grid.render()
})
}
I'm expecting the table to be repopulated with the new collection once the results are returned but my table still shows all the old records.
I'm following the example written here How would I refresh a Backgrid table with new data? So it should redraw the table once the collection has been reset? Or do I need to empty the table first? Any ideas where I might be going wrong?
From backgridjs
Fully reactive. Relevant parts of the grid re-renders automatically upon data changes.
I have not gone through annotated source code but am guessing rerendering is tied to collection events. So, you do not need to explicitly call the render method.
$.when(filteredRecipes).done(function (recipes) {
// this line shows that the result set is being updated as expected with for example 6 results
console.log(recipes)
// setting the new recipe result set to the grid.collection
// considering recipes is backbone collection
// if result is array of objects then List.grid.collection.reset(recipes)
// it should re render the grid
List.grid.collection.reset(recipes.models);
})

Adding new column in sencha grid before the last column

Suppose i have a sencha grid which has columns
Name, Email, Address, Phone, City, State, Country
Now out this initially i am only displaying Name, Email, Address and Phone.
I have given the provision to display more columns, the pending ones, City, State and Country.
But the problem in that when ever i add a new column in the grid then it gets appended to the last...in my case suppose i add City then it gets appended after Phone...
But i want Phone to always remain the last column and if any other column is added then it should be prefixed before Phone column.
I am using sencha grid.
Kindly suggest
Use headerCt for this. You can insert a new column to any position.
handler: function(btn) {
var grid = btn.up('gridpanel');
var column = Ext.create('Ext.grid.column.Column', {
text: 'Country',
dataIndex: 'country'
});
grid.headerCt.insert(
grid.columns.length - 1, // that's index column
column);
grid.getView().refresh();
}
Fiddle

ExtJs 4 - Copy records from store to treestore (grid to treegrid)

First of all: I'm using ExtJs 4.2.1
I have two grids: the first one collects records from a database (countries) and the second is a treegrid (should show countries and each country should expand a list of cities).
The behaviour I'm trying to achieve is that once you select a record (or multiple records) on the first grid, those records are copied to the treegrid as leafs so then I can fill those leafs with more records (cities).
I get the records from the first grid with:
grid.getSelectionModel().getSelection()
But I don't know how to copy them on the treegrid. I've tried using setRootNode and I can see the records on the "raw" property of the root node but I'm not able to show them on the grid.
What am I missing?
Updated: I've manage to get the countries with:
var records = grid.getSelectionModel().getSelection();
treegrid.getStore().setRootNode({ root: true, expanded: true, children: records})
Now I'm having problems to load the subrecords. As a test I've tried using the same "country records" to make sure there's no conflicts with the model. This is what I've tried:
var records = grid.getSelectionModel().getSelection();
for (record in records){
records[record].expanded = true;
records[record].children = records;
}
treegrid.getStore().setRootNode({ root: true, expanded: true, children: records})
This should show a list of countries and when expanding one of the records, it should show again the list as children of the selected record. It's not working :(
Solved it. I didn't liked the solution so eventually I constructed the whole thing on the backend but it was working.
Using insert/appendChild as Reimius said wasn't working since my records were not nodes so I had to loop over the country array and make each country a node with createNode(). For every country node I created, I looped through its cities, created a node for each one and then used insertChild() to associate it with the country.
Once everything was done I used:
treegrid.getStore().setRootNode({ root: true, expanded: true, children: records})
With "records" being an array of this monstrous creation of nodes.

Resources