I've implemented a slick grid with a custom selection model as well as a custom checkbox selection plugin.
I've also added group level checkboxes to allow toggling selection at the top level.
One of my requirements is that collapsed groupings are still selectable via any parent level grouping checkboxes.
My stumbling block seems to be that I can't figure out how to select rows that aren't currently visible on the group. The slick grid maintains the set of visually selected items while the grids data view maintains the full set of selected items, visible or not. However, I can't figure out how to pipe into data when clicking the group checkbox of a collapsed row.
I am configuring my grid like so:
let checkboxSelectionModel = new Slick.CheckboxSelectionModel();
this.grid.setSelectionModel(checkboxSelectionModel);
this.grid.registerPlugin(new Slick.Data.GroupItemMetadataProvider());
let onSelectedRowIdsChanged = this.dataProvider.syncGridSelection(this.grid, true, true);
onSelectedRowIdsChanged.subscribe(
function(e: any, args: any)
{
//business logic stuff
}
);
let groupedCheckboxSelector = new Slick.GroupedCheckboxSelectColumn({
cssClass: "slick-cell-checkboxsel",
onSelectedRowIdsChangedHandler: onSelectedRowIdsChanged
});
let columns = this.grid.getColumns();
columns.unshift(groupedCheckboxSelector.getColumnDefinition());
this.grid.setColumns(columns);
this.grid.registerPlugin(groupedCheckboxSelector);
gist to custom plugins, too long to include here
Specifically, if you look at line 57 of slick.checkboxselectionmodel:
$.each(dataItem.rows, function(index, groupRow) {
var groupRowIndex = _self._grid.getData().getRowById(groupRow.id);
if (groupRowIndex) {
selection.push(groupRowIndex);
}
});
groupRowIndex is never resolved for hidden rows, and so never get selected. I attempted to expand the group when clicked, then resolve the rows, which works but when the group is collapsed afterward, the wrong rows are selected in the grid.
any help would be greatly appreciated!
some notes:
if I select a row and collapse its group, the item retains its selection
there is a different branch of the slick grid which has an equally non-functional implementation of group selection
gist to updated plugins
A functional solution that I'm confident could put anyone seeking similar behavior on the right path, however, I'm not sure how well either of these plugins would work independently. one of my requirements was to only allow row selection via the row checkbox.
one gotcha (that I'm sure is easily improved) is that the group level checkbox still needs to be defined in your group format operator
the main solution to my issue was to expand all collapsed groups when making group-level selects/unselects, perform any select/unselect routines, then collapse any previously expanded groups
EDIT:
This fails when the grid has large amounts of data (10k rows).
Re-opening with a bounty.
It looks like the performance hit of having to expand and collapse so many groups cause issues.
Related
i am working on an app that that is using aggrid.
data is received from server, stored into state, and fed to the aggrid [rowData]="rowData"
separate task receives the settings of my data, like: column widths, row expanded, row selected...
i can apply column widths on initial data, and later listen for events when column is resized and save that back,
but for the expanded, no such thing.
i have onFirstDataRendered and there i iterate and set the expanded node, but i want to this before, in init like, because this fires the onRowGroupOpened(event: RowGroupOpenedEvent) every time node is expanded, and i cant distinguish programmatically expand from user click.
can anyone suggest solution for expanding the rows in initial data prep? or distinguish expand event programmatically vs user click?
is there any other way to expand node except node.setExpanded ?
You can use groupDefaultExpanded property to set the default group expansion settings at the start:
0: Don't expand
1: Expand all first level groups
2: Expand up to second level groups
-1: Expand all groups by default (what you need)
Live Demo
Are you using ag-Grid on its own or with AdapTable?
If the latter then that has the ability to set which rows should be expanded when app launches - and will also automatically save any expanded rows for next reload.
I think its AdapTable rather than ag-Grid which is doing this but I'm not 100% sure.
See demo at https://demo.adaptabletools.com/layout/aggridgroupedlayoutdemo
i took a look at the fluent detailsList grouped example in the official page of fluentUI:
https://developer.microsoft.com/en-us/fluentui#/controls/web/detailslist/grouped
and edited their example a bit so some of the groups has 1 row
now when I select the item in the row the group row (the group title) is also selected
I want to prevent that. is there a way?
A quick workaround would be doing it by CSS:
if an element has ms-GroupHeader is-selected classes, means it is a gruop header and also is selected, so you change set the background-color.
You probably can pass a className to group components like this
I have a handsontable table which is dynamic, meaning data can be added after initiation. The problem is, however, that new rows can be added to the table when dragging down while clicking the corner of a cell. How would I prevent users from expanding the table while making sure I can still add new rows if one would interact with a button for example.
I tried using
afterCreateRow: function(index, amount){
data.splice(index, amount)
},
but that prevents me from adding new rows using the alter function.
If this question was rather vague: See the link below for a default jsfiddle with handsontable. Click the corner of a cell and drag down, you'll see.
http://jsfiddle.net/warpech/hU6Kz/
TL;DR: Disable row creation when dragging cells, allow row creation using (in code) handsontable.alter('insert_row');
Thanks in advance.
You can add this code to prevent row creation when you are dragging cells :
fillHandle: {
autoInsertRow: false,
},
EDIT: Check out this fiddle.
So I added this
fillHandle: {
autoInsertRow: false
}
and removed minSpareRows: 1.
This gives you the drag functionality without the automatic creation of rows.
To test:
If you right-click and manually insert a row (Insert row below), and then click and drag some value into the new row using the fill handle, it should paste the value in without creating a new row underneath.
Note: If you need the same functionality horizontally (aka, being able to drag values horizontally without auto-creating new columns) remove minSparecols: 1
Hope this is what you're looking for!
Add the fillHandle: false option to your current options.
This removes the ability to drag and create new rows, but still leaves you with the ability to add new rows via the context menu (contextMenu: true) and the minimum spare rows option (minSpareRows: 1).
I understand your problem, I was in same situation.
I have solved with this:
maxRows: getFixedNumberOfRows(),
minRows: getFixedNumberOfRows(),
With this solution you can keep drag and drop for easy fill cells, and avoid add rows at the end
If anyone knows a better solution is welcome
Presently i have a Angular Js Grid which is pagination Enabled say 5 records per page for example and total number of records is 2000, so there are going to be 400 pages in All.
when pagination in ng-grid is handled the gridOption data is specified per page which means for 1st page the gridOption will be 1-5 rows for 2nd 6-10 rows and so on........
Here i have implemented a selection functionality through checkboxes thus whenever a row is selected[checkBox becomes selected] and it's stored in selectedItems array and i show selected items in another grid like this.....
Now when i move on to second page[pagination] and select further rows like this ...
The real trouble lies here when i again go back to the previous page i.e page 1 the checkboxes will not be checked because in pagination we load data runtime thus the pages shows following result...
Hope you must have understood my problem....
what i need here is a callback before/after data is loaded so that i can select the checkboxes as i have the number of selection preserved
OR any other workaround for my problem will be much helpful too.
Thanks!.
Can you store the checked value on the data model where you are storing the row values? Then you come back and its just checked by Angular bindings?
I am not sure of your setup, but I do this in a similar situation.
I have been working on this for a couple days now.
While I am still unable to preserve selection across pagination, I am able to clear selections while simultaneously "deselecting" the select all checkbox.
The allSelected variable is not exposed in the gridScope but you are able to grab it and address it using the following code.
// Use this to deselect all options.
$scope.gridOptions.$gridScope.toggleSelectAll(null, false);
// use this to find the allSelected variable which is tied to the
// (the ng-model related to the select all checkbox in the header row)
var header = angular.element(".ngSelectionHeader").scope();
// use this to turn off the checkbox.
header.allSelected = false;
I'll follow up again if I manage to get the "reselecting" to work as documented, but for now I might remain content with this.
So this is a very specific question for SlickGrid, but I was wondering if anyone has ever tried to change the way the rows look when grouped? I was thinking that it would be cool to add a border around the grouped rows to show that they are part of that heading.
The way that SlickGrid works doesn't give any indication the rows are grouped in the DOM, they just appear under the header. I have tried to do something like this:
dataView.getItemMetadata = function(index) {
return {cssClasses: "myRowCssClass"};
}
but unfortunately, this broke other things in terms of the grouping. There is some stuff in the native getItemMetadata function that the groupBy function needs to process. I could copy that stuff into this function and add a condition for this, but that doesn't seem right. Does anyone who has some experience with SlickGrid know how to achieve this effect?
I know this is an old question. But I have done something similar to what you are asking about.
In my data, I have information about assets at several sites within an organization. So for each group of records, the name of the site will be the same. As I am reading my data (obtained via an $.ajax call), whenever the site name changes, I insert a 'parent' row in the data array.
I wanted to display these parent rows in bold. I accomplished this by defining a CSS class for the parent rows and using getItemMetadata() to apply the class.
dataView.getItemMetadata = function(row) {
if (row is a parent) {
return { 'cssClasses' : 'my-parent-row-class' };
}
};
In my application, I also made use of Slickgrid filters and a 'toggle' class (applied in a click handler) to implement a drill-down feature where you can click on a parent row and collapse/expand the rows grouped under that parent row.
I hope this helps.
Tim