- Home
- Forum
- Angular - EJ 2
- Use Switch instead of CheckBox for selection in Grid
Use Switch instead of CheckBox for selection in Grid
Is there a good way to use the Grid's native selection functionality but to swap out the CheckBox with a Switch?
SIGN IN To post a reply.
24 Replies
BS
Balaji Sekar
Syncfusion Team
February 19, 2020 02:03 PM UTC
Hi Tomas,
Greetings from syncfusion support
In the below sample, we have bind the keyUp event for search input element in created event of Grid and based on the search value we have performed the search operation in Grid by using the search method. Please refer the below code example and sample for more information.
|
created() {
document.getElementById("Grid_searchbar").addEventListener('keyup', (event) => {
clearTimeout(this.debounceTimer); // you can customize as per your requirement
this.debounceTimer
= setTimeout(() => { this.searchFun(event); }, 600);
})
}
searchFun(event) {
var value = (event.target as HTMLInputElement).value;
this.grid.search(value);
clearTimeout(this.debounceTimer);
} |
Help documentation :
Regards,
Balaji Sekar.
Balaji Sekar.
CB
Collin Barrett
February 19, 2020 02:09 PM UTC
Balaji,
Was your response posted to the
correct thread? My name is Collin (not Tomas) and my question was
regarding selection in the Grid, not searching in the Grid.
Thanks.
BS
Balaji Sekar
Syncfusion Team
February 19, 2020 02:16 PM UTC
Hi Collin,
Sorry for inconvenience caused,
Query : Is there a good way to use the Grid's native selection functionality but to swap out the CheckBox with a Switch?
Yes, because we have default support for grid with checkboxes. If you need switch component instead of checkboxes we need to do some customization in the sample level. Please follow the below workaround.
As per your requirement we have achieved the checkbox features with the switch component. By default checkbox rendered with multiple selection mode. So for the switch component, we have set the selection mode as multiple and enable the enableSimpleMultiRowSelection in the grid.
While on row selection and deselection we have dynamically changed the checked state of the switch component in rowSelected and rowDeselecting event.
If we click the headercell switch we need to select all the records in that page. This is achieved by using the addRowsToSelection method in the change event of switch component. addRowsToSelection is a method used to select the row with the rowIndex. please refer the below sample and code example for more information.
|
App.component.html
<ejs-grid #grid [dataSource]='data' height='315px' [selectionSettings]='selectionOptions' (dataBound)='dataBound($event)' (rowSelected)='rowSelected($event)'
(rowDeselecting)='rowDeselecting($event)'[allowPaging]='true'(rowDeselected)='rowDeselected($event)'(detailDataBound)='detailDataBound($event)' >
<e-columns>
<e-column headerText='Employee Image' width='150' textAlign='Center'>
<ng-template #headerTemplate let-data>
<div>
<ejs-switch class='headerswitch' [checked]="false" (change)='change($event)'></ejs-switch>
</div>
</ng-template>
<ng-template #template let-data>
<div class="image">
<ejs-switch [checked]="false" (change)='change($event)'></ejs-switch>
</div>
</ng-template>
</e-column>
-------
</e-columns>
</ejs-grid>
|
|
App.component.ts
export class AppComponent {
@ViewChild('grid') public grid: GridComponent;
public data: object[];
public selectionOptions: SelectionSettingsModel;
ngOnInit(): void {
this.data = hierarchyOrderdata;
this.selectionOptions = { type: 'Multiple', enableSimpleMultiRowSelection: true };
}
dataBound(args){
}
detailDataBound(args){
}
change(args){
if(args.event.target.closest('th')){
if(args.checked){
var allrecords = this.grid.getCurrentViewRecords();
// selecting and deselecting all the records in the grid when change the checked state of the header cell switch
for(var i=0;i<allrecords.length;i++){
if(this.grid.getSelectedRowIndexes().indexOf(i) >-1)
{
continue;
}
// selecting the records in the current page
this.grid.selectionModule.addRowsToSelection([i])
}
}else{
// clearing the selection
this.grid.clearSelection();
}
}
}
rowDeselecting(args){
// changed the checked state of the switch component
args.target.closest('tr').getElementsByClassName('e-switch')[0].ej2_instances[0].checked = false
if(args.row.length>1){
for(var i=0;i<args.row.length;i++){
args.row[i].getElementsByClassName('e-switch')[0].ej2_instances[0].checked = false
}
}
}
rowSelected(args){
// changed the checked state of the row cell switch component
args.row.getElementsByClassName('e-switch')[0].ej2_instances[0].checked = true;
if( this.grid.getCurrentViewRecords().length == this.grid.getSelectedRecords().length){
// changed the checked state of the headercell switch component
this.grid.element.getElementsByClassName('headerswitch')[0].ej2_instances[0].checked = true;
}
}
rowDeselected(args){
// changed the checked state of the headercell switch component
if( this.grid.getCurrentViewRecords().length > this.grid.getSelectedRecords().length){
this.grid.element.getElementsByClassName('headerswitch')[0].ej2_instances[0].checked = false;
}
}
}
|
Please get back to us if you need further assistance.
Regards,
Balaji Sekar.
CB
Collin Barrett
February 19, 2020 05:47 PM UTC
Thanks! I think this is going to work.
I do get a couple of TypeScript errors. I am not sure if there is a way to resolve?
BS
Balaji Sekar
Syncfusion Team
February 20, 2020 09:33 AM UTC
Hi Collin,
Greeting from syncfusion support.
Query : I do get a couple of TypeScript errors. I am not sure if there is a way to resolve?
We have validated the provided details. We suggest you to set the element type as any for such cases to resolve the problem. Please refer the below code.
|
rowSelected(args){
args.row.getElementsByClassName('e-switch')[0].ej2_instances[0].checked = true;
if( this.grid.getCurrentViewRecords().length == this.grid.getSelectedRecords().length){
(<any>this.grid.element.getElementsByClassName('headerswitch')[0]).ej2_instances[0].checked = true;
}
}
rowDeselected(args){
if( !(this.grid.getCurrentViewRecords().length == this.grid.getSelectedRecords().length)){
(<any>this.grid.element.getElementsByClassName('headerswitch')[0]).ej2_instances[0].checked = false;
}
}
|
Please get back to us if you need further assistance.
Regards,
Balaji Sekar.
CB
Collin Barrett
February 25, 2020 07:49 PM UTC
Do you know if there is a way to get selection with switches working with the following setting enabled?
We want to toggle selection of a row only if the user actually clicks the switch rather than anywhere in the row. checkboxOnly seems to be the feature that enables that, however when we enable it with the switches, it seems like the same events (rowSelected, rowDeselecting, rowDeselected, etc.) are not firing.
I noticed this note in the API for checkboxOnly:
To enable checkboxOnly selection, should specify the column type as
checkbox.However, when specifying the column's type='checkBox', we see switches and checkboxes side-by-side. The switches then do nothing.
Thanks for any help you may be able to provide.
PK
Prasanna Kumar Viswanathan
Syncfusion Team
February 26, 2020 09:32 AM UTC
Hi Collin,
Thanks for your update.
Query : Do you know if there is a way to get selection with switches working with the following setting enabled?
The checkboxOnly API is used to select the records using checkbox and checkbox column is enabled by specifying the column's type='checkBox'
Based on your requirement we found that you need select the row only with switch element. So, we have created sample in which we select the rows only with the switch. In that sample we have prevent the row selection when the target element does not contains switch in the rowSelecting event.
Please refer the below sample and code example for more information.
|
export class AppComponent {
@ViewChild('grid') public grid: GridComponent;
public data: object[];
public selectionOptions: SelectionSettingsModel;
ngOnInit(): void {
this.data = hierarchyOrderdata;
this.selectionOptions = { type: 'Multiple', enableSimpleMultiRowSelection: true };
}
change(args){
if(args.event.target.closest('th')){
if(args.checked){
var allrecords = this.grid.getCurrentViewRecords();
for(var i=0;i<allrecords.length;i++){
if(this.grid.getSelectedRowIndexes().indexOf(i) >-1)
{
continue;
}
this.grid.selectionModule.addRowsToSelection([i])
}
}else{
this.grid.clearSelection();
}
}
}
rowDeselecting(args){
if(args.row.length>1){
for(var i=0;i<args.row.length;i++){
args.row[i].getElementsByClassName('e-switch')[0].ej2_instances[0].checked = false
}
}
}
rowSelecting(args){
// prevent the selection when the target does not contains switch element
if( !( args.target && args.target.closest('td') && args.target.closest('td').getElementsByClassName('e-switch').length > 0 && args.target.closest('td').getElementsByClassName('e-switch')[0].ej2_instances[0].checked == true )){
if(<any>this.grid.element.getElementsByClassName('headerswitch')[0].ej2_instances[0].checked == false)
args.cancel = true;
}
}
rowSelected(args){
if (this.grid.element.getElementsByClassName('headerswitch')[0].ej2_instances[0].checked == true){
args.row.getElementsByClassName('e-switch')[0].ej2_instances[0].checked = true;
}
if( this.grid.getCurrentViewRecords().length == this.grid.getSelectedRecords().length){
( <any>this.grid.element.getElementsByClassName('headerswitch')[0]).ej2_instances[0].checked = true;
}
}
rowDeselected(args){
if( !(this.grid.getCurrentViewRecords().length == this.grid.getSelectedRecords().length)){
(<any>this.grid.element.getElementsByClassName('headerswitch')[0]).ej2_instances[0].checked = false;
}
}
}
|
Please get back to us if you need further assistance on this.
Regards,
Prasanna Kumar N.S.V
CB
Collin Barrett
February 26, 2020 07:44 PM UTC
Thanks for that solution. That seems to mostly work, but there is one bug. I can see this both in your StackBlitz and when porting into my application.
To reproduce:
- Use the headerswitch to select all
- Click anywhere in a selected row other than the switch
Bug:
Notice that the switch remains selected, but the record is deselected.
I'll look into this a bit myself and see if I can resolve it, but please let me know if you know how to fix this. Thanks.
PK
Prasanna Kumar Viswanathan
Syncfusion Team
February 27, 2020 09:07 AM UTC
Hi Collin,
Thanks for your update.
We can able to reproduce the mentioned behavior at our end. In the previous sample we have handled row selection only through the switch element. Now we have handled both rowSelection and rowDeselection only through the switch element by preventing the selection and deselection of row when the target element does not contains switch in the rowSelecting and rowDeselecting event respectively.
Please refer the sample and code example for more information.
|
rowDeselecting(args){
// prevent the deselection when the target does not contains switch element
if( !( args.target && args.target.closest('td') && args.target.closest('td').getElementsByClassName('e-switch').length > 0 && args.target.closest('td').getElementsByClassName('e-switch')[0].ej2_instances[0].checked == false )){
args.cancel = true;
}
-------
}
rowSelecting(args){
// prevent the selection when the target does not contains switch element
if( !( args.target && args.target.closest('td') && args.target.closest('td').getElementsByClassName('e-switch').length > 0 && args.target.closest('td').getElementsByClassName('e-switch')[0].ej2_instances[0].checked == true )){
if(<any>this.grid.element.getElementsByClassName('headerswitch')[0].ej2_instances[0].checked == false)
args.cancel = true;
}
}
|
Please get back to us if you need further assistance on this.
Regards,
Prasanna Kumar N.S.V
CB
Collin Barrett
February 27, 2020 03:11 PM UTC
Thanks, that change seems to be working! Thanks again for your help with this.
CB
Collin Barrett
February 27, 2020 04:35 PM UTC
I spoke too soon. There is one more bug.
If there is only one row in the grid, deselecting all with the headerswitch does not work.
I can fix this by changing line 47 to "if (args.row.length > 0) {" rather than "if (args.row.length > 1) {", however then the user can deselect a selected row by clicking anywhere in the row again.
I'm investigating myself, but if you have any more ideas, please let me know.
RS
Rajapandiyan Settu
Syncfusion Team
February 28, 2020 01:10 PM UTC
Hi Collin,
Thanks for your update.
Query : If there is only one row in the grid, deselecting all with the headerswitch does not work.
We can able to reproduce the mentioned behavior at our end. To resolve this problem, we have to change the code ( as you mentioned ) args.row.length > 0 from args.row.length > 1 but we have to do this action in the rowDeselected event instead of rowDeselecting event. Please refer the below code example and sample for more information.
|
rowDeselecting(args) {
if (!(args.target && args.target.closest('td') && args.target.closest('td').getElementsByClassName('e-switch').length > 0 && args.target.closest('td').getElementsByClassName('e-switch')[0].ej2_instances[0].checked == false)) {
args.cancel = true;
}
}
---------
rowDeselected(args) {
if (!(this.grid.getCurrentViewRecords().length == this.grid.getSelectedRecords().length)) {
(<any>this.grid.element.getElementsByClassName('headerswitch')[0]).ej2_instances[0].checked = false;
}
if ( args.row.length > 0 ) {
for (var i = 0; i < args.row.length; i++) {
args.row[i].getElementsByClassName('e-switch')[0].ej2_instances[0].checked = false
}
}
}
|
Please get back to us if you need further assistance on this.
Regards,
Rajapandiyan S.
CB
Collin Barrett
February 28, 2020 08:56 PM UTC
Thanks! That did it.
BS
Balaji Sekar
Syncfusion Team
March 2, 2020 09:18 AM UTC
Hi Collin,
We glad that your issue has been fixed.
Please get back to us if you require further other assistance from us.
Regards,
Balaji Sekar.
CB
Collin Barrett
March 17, 2020 08:37 PM UTC
Do you have any suggestions for selecting one or more rows in the grid with this solution via the TypeScript code? I have tried things like:
dataBound() {
this.grid.selectRows([1, 2, 3, 4, 5]);
}
and
dataBound() {
this.grid.selectionModule.addRowsToSelection([1, 2, 3, 4, 5]);
}
I can hit a breakpoint inside that dataBound() function, but the rows in the grid are not selected.
Thanks!
BS
Balaji Sekar
Syncfusion Team
March 18, 2020 06:13 AM UTC
Hi Collin,
We have validated your query with provided the information and we suggest you to defined the selection type in Multiple state. Since you can select multiple rows in dataBound event without fails. Please refer the below code example and sample for more information.
|
[app.component.html]
<ejs-grid [allowSelection]='true' [selectionSettings]='selectOptions' (dataBound)="dataBound($event)">
. . . .
</ejs-grid>
[app.component.ts]
dataBound(){
this.grid.selectRows([2,4,6])
} |
Please get back to us if you have any query,
Regards,
Balaji Sekar.
CB
Collin Barrett
March 18, 2020 01:15 PM UTC
Thanks for your response. I did already have 'Multiple' selection enabled, however. Would you be able to fork this last stackblitz with the working toggle switch selection and demo how to select one or more rows from the TypeScript?
BS
Balaji Sekar
Syncfusion Team
March 19, 2020 05:54 AM UTC
Hi Collin,
Thanks for your update,
We applied multiple selections through the dataBound event using the Grid method of selectRows. In the code example below, we selected multiple grid rows using index array values and we changed the switch state from the corresponding selected rows. For more information, please refer to the example code below and the sample.
|
dataBound(args) {
var index = [ 2, 4, 6, 7, 10, 11]
this.grid.selectRows(index);
for (var i = 0, len = index.length; i < len; i++) {
(<any>this.grid.getRowByIndex(index[i]).getElementsByClassName('e-switch')[0]).ej2_instances[0].checked = true;
}
}
|
Please get back to us if you need further assistance.
Regards,
Balaji Sekar.
CB
Collin Barrett
March 19, 2020 01:18 PM UTC
Thanks for that solution.
It does check the switches, however it does not mark them as actually selected in the grid's selection module. (The background color of those switched rows does not update to mark them selected.) I am using the selected rows from this component by calling this.grid.getSelectedRecords() , which does not return the default selected rows with that solution. Any other ideas?
Thanks!
RS
Rajapandiyan Settu
Syncfusion Team
March 20, 2020 01:37 PM UTC
Hi Collin ,
Thanks for your update.
Query : Do you have any suggestions for selecting one or more rows in the grid with this solution via the TypeScript code? I have tried things like: dataBound() {this.grid.selectRows([1, 2, 3, 4, 5])};
From your query we could see that you need to select the rows by programmatical way. So now we have handled the programmatical way of selection also in the given sample, by using the grid’s selection API isInteracted ( row selection occurs when isInteracted is false i.e. programmatical way ) and checked the selected row’s switch component in the rowSelecting event. Please refer the below code example and sample for more information.
|
App.component.ts
export class AppComponent {
--------
ngOnInit(): void {
--------
}
dataBound(args) {
this.grid.selectRows([1,2,3]);
}
detailDataBound(args) {
}
change(args) {
-----
}
rowDeselecting(args) {
if (!(args.target && args.target.closest('td') && args.target.closest('td').getElementsByClassName('e-switch').length > 0 && args.target.closest('td').getElementsByClassName('e-switch')[0].ej2_instances[0].checked == false)) {
if(this.grid.selectionModule.isInteracted){
args.cancel = true;
}
}
}
rowSelecting(args) {
if (!(args.target && args.target.closest('td') && args.target.closest('td').getElementsByClassName('e-switch').length > 0 && args.target.closest('td').getElementsByClassName('e-switch')[0].ej2_instances[0].checked == true)) {
if ((<any>this.grid.element.getElementsByClassName('headerswitch')[0]).ej2_instances[0].checked == false && this.grid.selectionModule.isInteracted == true ){
args.cancel = true;
this.grid.selectionModule.isInteracted = false;
}
else{
// enable the switch component to the checked state
if(args.rowIndexes && args.rowIndexes.length > 0){
for(var i=0; i<args.rowIndexes.length ; i++ ) {
this.grid.getRows()[args.rowIndexes[i]].getElementsByClassName("e-switch")[0].ej2_instances[0].checked = true;
}
}else{
this.grid.getRows()[args.rowIndex].getElementsByClassName("e-switch")[0].ej2_instances[0].checked = true;
}
}
}
}
rowSelected(args) {
---------
}
rowDeselected(args) {
-------
}
}
}
|
Please get back to us if you need further assistance on this.
Regards,
Rajapandiyan S.
CB
Collin Barrett
March 20, 2020 08:12 PM UTC
Thanks! That works.
RS
Rajapandiyan Settu
Syncfusion Team
March 23, 2020 04:37 AM UTC
Hi Collin,
We are glad that your reported problem has been resolved.
Please get back to us if you need further assistance on this.
Regards,
Rajapandiyan S.
CB
Collin Barrett
April 1, 2020 08:05 PM UTC
Hi Syncfusion,
Do you have any suggestions to resolve the bugs described below after enabling allowSorting with this Switch Selection solution? Thanks!
Changes from previous Stackblitz provided by Syncfusion represented in ^that fork
- Enable allowSorting on the grid.
- Enable persistSelection in the grid's selectionSettings.
- Comment out the default selected rows in dataBound().
Bug 1:
- Select 1 or more rows via their switch.
- Click a column header to sort.
- See that the rows that were selected are still grayed out as selected, but their switches are not selected.
Bug 2:
- Click the select all headerswitch at the top of the switch column.
- Click the select all headerswitch again to deselct all
- See that the row switches are not all deselected.
RS
Rajapandiyan Settu
Syncfusion Team
April 2, 2020 11:57 AM UTC
Hi Collin,
Thanks for your update.
Query : Do you have any suggestions to resolve the bugs described below after enabling allowSorting with this Switch Selection solution?
See that the rows that were selected are still grayed out as selected, but their switches are not selected.
Click the select all headerswitch again to deselct all.See that the row switches are not all deselected.
We are able to reproduce the reported behaviors at our end. Please use the below modified codes to resolve the problem.
For Issue #1:
|
rowSelecting(args) {
if(args.rowIndex != undefined){
if (!(args.target && args.target.closest('td') && args.target.closest('td').getElementsByClassName('e-switch').length
> 0 && args.target.closest('td').getElementsByClassName('e-switch')[0].ej2_instances[0].checked == true)) {
if ((<any>this.grid.element.getElementsByClassName('headerswitch')[0]).ej2_instances[0].checked == false && ( <any>
this.grid.selectionModule).isInteracted == true ){
args.cancel = true;
( <any>this.grid.selectionModule).isInteracted = false;
}
else{
if(args.rowIndexes && args.rowIndexes.length > 0){
for(var i=0; i<args.rowIndexes.length ; i++ ) {
( <any>this.grid.getRows()[args.rowIndexes[i]].getElementsByClassName("e-switch")[0]).ej2_instances[0].checked = true;
}
}else{
(<any>this.grid.getRows()[args.rowIndex].getElementsByClassName("e-switch")[0]).ej2_instances[0].checked = true;
}
}
}
}
}
rowSelected(args) {
if(args.rowIndex != undefined){
( <any>this.grid.selectionModule).isInteracted = false;
if ((<any> this.grid.element.getElementsByClassName('headerswitch')[0]).ej2_instances[0].checked == true) {
args.row.getElementsByClassName('e-switch')[0].ej2_instances[0].checked = true;
}
if (this.grid.getCurrentViewRecords().length == this.grid.getSelectedRecords().length) {
(<any>this.grid.element.getElementsByClassName('headerswitch')[0]).ej2_instances[0].checked = true;
}
}
}
|
For Issue #2:
|
change(args) {
if (args.event.target.closest('th')) {
if (args.checked) {
---------------
} else {
this.grid.clearSelection();
if (this.grid.isPersistSelection) {
var rowstoclear = this.grid.getRows();
for (var i = 0; i < rowstoclear.length; i++) {
// uncheck the switch component in the row
(<any>rowstoclear[i].getElementsByClassName('e-switch')[0]).ej2_instances[0].checked = false;
}
}
}
}
}
|
Please get back to us if you need further assistance on this.
Regards,
Rajapandiyan S.
SIGN IN To post a reply.
- 24 Replies
- 4 Participants
-
CB Collin Barrett
- Feb 18, 2020 02:53 PM UTC
- Apr 2, 2020 11:57 AM UTC