Bronzato
Bronzato

Reputation: 9342

Using checkboxes inside my ag-grid with boolean fields behind and check/uncheck only with the keyboard

I have some boolean fields inside my ag-grid. In addition to be possible to navigate with the keyboard, I would also like to be possible to check/uncheck these checkboxes with the keyboard. I mean let the user move inside the grid with cursor keys, then when the current cell is a checkbox simply use the Space of Enter keys to check/uncheck.

I ended with the solution showed below but I am curious if there is a better/nicer solution for that ?

The trick I used is to catch keyboard events on the grid and change values (true/false) if focused cell is a checkbox.

Example: Plunker demo here

enter image description here

var columnDefs = [
    {headerName: "Athlete", field: "athlete", width: 150, editable: true},
    {headerName: "Age", field: "age", width: 60, editable: true},
    {headerName: "Country", field: "country", width: 120, editable: true},
    {headerName: "Boo1", field: "boo1", width: 60, cellRenderer: boolRenderer},
    {headerName: "Boo2", field: "boo2", width: 60, cellRenderer: boolRenderer} 
];

function boolRenderer(params) {
    return `<input type="checkbox" ${params.value ? 'checked' : ''} />`;
}

var gridOptions = {
    columnDefs: columnDefs,
    onCellKeyPress: cellKeyPress
}; 

function cellKeyPress(e) {
  
    let ENTER_KEY = 13;
    let SPACE_KEY = 32;

    var event = e.event;

    if (event.keyCode == SPACE_KEY || event.keyCode == ENTER_KEY) 
    {    
        var isCheckbox = $(event.target).find("input[type='checkbox']").length > 0;
        if (isCheckbox) 
        {
            var currentCell = gridOptions.api.getFocusedCell();
            var rowIndex = currentCell.rowIndex;
            var colId = currentCell.column.getId();
            var rowNode = gridOptions.api.getDisplayedRowAtIndex(rowIndex);
            var cellValue = gridOptions.api.getValue(colId, rowNode) || false;
            rowNode.setDataValue(colId, !cellValue);
        }
    }
}

// setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', function() {
    var gridDiv = document.querySelector('#myGrid');
    new agGrid.Grid(gridDiv, gridOptions);

    // do http request to get our sample data - not using any framework to keep the example self contained.
    // you will probably use a framework like JQuery, Angular or something else to do your HTTP calls.
    var httpRequest = new XMLHttpRequest();
    httpRequest.open('GET', 'https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/olympicWinnersSmall.json');
    httpRequest.send();
    httpRequest.onreadystatechange = function() {
        if (httpRequest.readyState === 4 && httpRequest.status === 200) {
            var httpResult = JSON.parse(httpRequest.responseText);
            gridOptions.api.setRowData(httpResult);
        }
    };
});

 
.test-container {
    height: 100%;
    display: flex;
    flex-direction: column;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script> var __basePath = ''; </script>
<style>
    html, body {
        height: 100%;
        width: 100%;
        margin: 0;
        box-sizing: border-box;
        -webkit-overflow-scrolling: touch;
    }
    html {
        position: absolute;
        top: 0;
        left: 0;
        padding: 0;
        overflow: auto;
    }
    body {
        padding: 1rem;
        overflow: auto;
    }
</style>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/ag-grid-community.min.js"></script>    <link rel="stylesheet" href="styles.css">
</head>
<body>

<div class="test-container">

    <div id="myGrid" class="ag-theme-balham" style="height: calc(100% - 30px);"></div>
</div>

    <script src="main.js"></script>
</body>
</html>

Upvotes: 2

Views: 2430

Answers (1)

VectorX
VectorX

Reputation: 667

if you asking about alternative way , this is my suggestion .

you can try agSelectCellEditor in the columnDefs , user will still be able to change it using keyboard by pressing enter and select true or false using arrow key.

this.columnDefs = [
  {
    headerName: 'ID',
    field: 'id',
    width: 50
  },
    headerName: 'IsCompleted',
    field: 'isCompleted',
    editable: true,
    filter: true,
    sortable: true,
    cellEditor: "agSelectCellEditor",
    cellEditorParams:
      {
        values: ["True", "False"]
      },
    width: 105}
   ]

And to save your changes on the server side:

(cellEditingStopped)="UpdateTrainingData()" //as an example your ag-grid html tag.

Upvotes: 1

Related Questions