如何使用带有ag-grid的布尔数据的复选框

时间:2017-01-17 20:57:09

标签: ag-grid ag-grid-react

我现在已经搜索了一段时间,并且没有看到任何真实的例子。

我正在使用ag-grid-react,我想要一个包含布尔值的列来表示带有复选框的布尔值,并在更改时更新rowData中的对象。

我知道有了checkboxSelection,我尝试使用它,就像我在下面所做的那样,但是当它是一个复选框时,它没有链接到数据,只是用于选择一个单元格。

var columnDefs = [
        { headerName: 'Refunded', field: 'refunded', checkboxSelection: true,}
  ]

那么有没有办法用ag-grid和ag-grid-react做我正在寻找的东西?

20 个答案:

答案 0 :(得分:19)

您应该使用cellRenderer属性

const columnDefs = [{ headerName: 'Refunded', 
    field: 'refunded', 
    editable:true,
    cellRenderer: params => {
        return `<input type='checkbox' ${params.value ? 'checked' : ''} />`;
    }
}];

我遇到了同样的问题,这是我能想到的最好的但是我无法将值绑定到此复选框。

我将单元格属性设置为true,现在如果要更改实际值,则必须双击单元格并键入true或false。

但这就是我去了,我决定帮助你,我知道它并没有100%全部解决,但至少它解决了数据展示部分。

如果您发现了如何与我们分享您的答案。

答案 1 :(得分:7)

以下代码有助于解决此问题。缺点是gridOptions中的正常事件不会被触发(onCellEditingStarted,onCellEditingStopped,onCellValueChanged等)。

var columnDefs = [...
           {headerName: "Label", field: "field",editable: true,
                cellRenderer: 'booleanCellRenderer',
                cellEditor:'booleanEditor'

            }
        ];
//register the components
$scope.gridOptions = {...
                components:{
                    booleanCellRenderer:BooleanCellRenderer,
                    booleanEditor:BooleanEditor
                }
            }; 

  function BooleanCellRenderer() {
  }

  BooleanCellRenderer.prototype.init = function (params) {
      this.eGui = document.createElement('span');
      if (params.value !== "" || params.value !== undefined || params.value !== null) {
          var checkedStatus = params.value ? "checked":"";
          var input = document.createElement('input');
          input.type="checkbox";
          input.checked=params.value;
          input.addEventListener('click', function (event) {
              params.value=!params.value;
              //checked input value has changed, perform your update here
              console.log("addEventListener params.value: "+ params.value);
          });
          this.eGui.innerHTML = '';
          this.eGui.appendChild( input );
      }
  };

  BooleanCellRenderer.prototype.getGui = function () {
      return this.eGui;
  };

  function BooleanEditor() {
  }

  BooleanEditor.prototype.init = function (params) {
      this.container = document.createElement('div');
      this.value=params.value;
      params.stopEditing();
  };
  BooleanEditor.prototype.getGui = function () {
      return this.container;
  };

  BooleanEditor.prototype.afterGuiAttached = function () {
  };

  BooleanEditor.prototype.getValue = function () {
      return this.value;
  };

  BooleanEditor.prototype.destroy = function () {
  };

  BooleanEditor.prototype.isPopup = function () {
      return true;
  };

答案 2 :(得分:6)

这个怎么样?它是在Angular而不是在React上,但你可以明白这一点:

        { headerName: 'Enabled', field: 'enabled', cellRendererFramework: CheckboxCellComponent },

这是checkboxCellComponent:

@Component({
selector: 'checkbox-cell',
template: `<input type="checkbox" [checked]="params.value" (change)="onChange($event)">`,
styleUrls: ['./checkbox-cell.component.css']
}) 
export class CheckboxCellComponent implements AfterViewInit, 
ICellRendererAngularComp {

@ViewChild('.checkbox') checkbox: ElementRef;

public params: ICellRendererParams;

constructor() { }

agInit(params: ICellRendererParams): void {
  this.params = params;
}

public onChange(event) {
  this.params.data[this.params.colDef.field] = event.currentTarget.checked;
  }
}

让我知道

答案 3 :(得分:2)

这是一个老问题,但如果您将 AdapTable 与 AG Grid 结合使用,则会有一个新的答案。 只需将列定义为复选框列,AdapTable 就会为您完成所有操作——创建复选框,检查单元格值是否为真,并在每次检查时触发一个事件: 请参阅:https://demo.adaptabletools.com/formatcolumn/aggridcheckboxcolumndemo

答案 4 :(得分:2)

框架-React / Angular / Vue.js

通过将单元格渲染器创建为本机框架组件,您可以轻松地将单元格渲染器与用于渲染ag-Grid的任何JavaScript框架集成在一起。

请参见下面的代码段,这在React中实现:

export default class extends Component {
  constructor(props) {
    super(props);
    this.checkedHandler = this.checkedHandler.bind(this);
  }
  checkedHandler() {
    let checked = event.target.checked;
    let colId = this.props.column.colId;
    this.props.node.setDataValue(colId, checked);
  }
  render() {
    return (
      <input 
        type="checkbox" 
        onClick={this.checkedHandler}
        checked={this.props.value}
      />
    )
  }
}

注意:将单元格渲染器创建为框架组件时,没有必需的生命周期方法。

创建渲染器后,我们将其注册到gridOptions.frameworkComponents的ag-Grid中,并在所需的列上进行定义:

// ./index.jsx

 this.frameworkComponents = {
   checkboxRenderer: CheckboxCellRenderer,
 };

 this.state = {
      columnDefs: [
        // ...
        {
          headerName: 'Registered - Checkbox',
          field: 'registered',
          cellRenderer: 'checkboxRenderer',
        },
        // ...
      ]
      // ....

请参见下面在最受欢迎的JavaScript框架(React,Angular,Vue.js)中实现的实时示例:

React demo

Angular demo
注意:使用Angular时,还必须将自定义渲染器传递给@NgModule装饰器,以允许依赖项注入。

Vue.js demo

香草JavaScript

您还可以使用JavaScript来实现复选框渲染器。

在这种情况下,复选框渲染器是使用JavaScript类构造的。在ag-Grid init生命周期方法(必需)中创建了一个input元素,并将其checked属性设置为将在其中呈现的单元格的基础布尔值。click事件侦听器添加到该复选框中更新每当输入选中此基础单元格值/未选中状态。

getGui(必需)生命周期挂钩中返回创建的DOM元素。我们还在可选的destroy生命周期挂钩中进行了一些清理,在其中删除了点击侦听器。

function CheckboxRenderer() {}

CheckboxRenderer.prototype.init = function(params) {
  this.params = params;

  this.eGui = document.createElement('input');
  this.eGui.type = 'checkbox';
  this.eGui.checked = params.value;

  this.checkedHandler = this.checkedHandler.bind(this);
  this.eGui.addEventListener('click', this.checkedHandler);
}

CheckboxRenderer.prototype.checkedHandler = function(e) {
  let checked = e.target.checked;
  let colId = this.params.column.colId;
  this.params.node.setDataValue(colId, checked);
}

CheckboxRenderer.prototype.getGui = function(params) {
  return this.eGui;
}

CheckboxRenderer.prototype.destroy = function(params) {
  this.eGui.removeEventListener('click', this.checkedHandler);
}

创建渲染器后,我们只需将其注册到gridOptions.components对象中的ag-Grid中即可。

gridOptions.components = {
  checkboxRenderer: CheckboxRenderer
}

并在所需列上定义渲染器:

gridOptions.columnDefs = [
  // ...
  { 
    headerName: 'Registered - Checkbox',
    field: 'registered',
    cellRenderer: 'checkboxRenderer',
  },
  // ...

请在下面的演示中查看该实现:

Vanilla JavaScript

website上阅读完整的博客文章,或查看我们的documentation,了解可以使用ag-Grid实施的多种方案。

Ahmed Gadir |开发人员@ ag-Grid

答案 5 :(得分:2)

以下是在Angular中创建agGrid单元格渲染器以将您的其中一列绑定到复选框的方法。

此答案很大程度上基于上述 user2010955 的出色答案,但有更多解释,并采用了最新版本的agGrid和Angular(I在添加以下更改之前,使用他的代码接收到错误)。

是的,我知道这个问题与agGrid的 React 版本有关,但是我敢肯定我不是唯一一个偶然发现此问题的 Angular 开发人员StackOverflow网页无奈之下,试图找到针对该问题的Angular解决方案。

(顺便说一句,我不敢相信这是2020年, agGrid for Angular 没有默认包含复选框渲染器。严重吗?!)

首先,您需要定义一个渲染器组件:

import { Component } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { ICellRendererParams } from 'ag-grid-community';

@Component({
    selector: 'checkbox-cell',
    template: `<input type="checkbox" [checked]="params.value" (change)="onChange($event)">`
})
export class CheckboxCellRenderer implements ICellRendererAngularComp {

    public params: ICellRendererParams; 

    constructor() { }

    agInit(params: ICellRendererParams): void {
        this.params = params;
    }

    public onChange(event) {
        this.params.data[this.params.colDef.field] = event.currentTarget.checked;
    }

    refresh(params: ICellRendererParams): boolean {
        return true;
    }
}

接下来,您需要将其告知@NgModule:

import { CheckboxCellRenderer } from './cellRenderers/CheckboxCellRenderer';
. . .
@NgModule({
  declarations: [
    AppComponent,
    CheckboxCellRenderer
  ],
  imports: [
    BrowserModule,
    AgGridModule.withComponents([CheckboxCellRenderer])
  ],
  providers: [],
  bootstrap: [AppComponent]
})

在显示agGrid的组件中,您需要导入渲染器:

import { CheckboxCellRenderer } from './cellRenderers/CheckboxCellRenderer';

让我们为网格定义一个新列,其中一些将使用此新渲染器:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
    @ViewChild('exampleGrid', {static: false}) agGrid: AgGridAngular;

    columnDefs = [
        { headerName: 'Last name', field: 'lastName', editable: true },
        { headerName: 'First name', field: 'firstName',  editable: true },
        { headerName: 'Subscribed', field: 'subscribed', cellRenderer: 'checkboxCellRenderer' },
        { headerName: 'Is overweight', field: 'overweight', cellRenderer: 'checkboxCellRenderer' }
    ];
    frameworkComponents = {
      checkboxCellRenderer: CheckboxCellRenderer
    }
}

现在,当您创建agGrid时,需要向您说明所使用的自制框架组件:

<ag-grid-angular #exampleGrid 
    style="height: 400px;" 
    class="ag-theme-material" 
    [rowData]="rowData"
    [columnDefs]="columnDefs" 
    [frameworkComponents]="frameworkComponents" >
</ag-grid-angular>

Ph!

是的。。。我花了一段时间才弄清楚如何使所有零件组合在一起。 agGrid自己的网站确实应该包含这样的示例……

答案 6 :(得分:2)

具体解决方案

在将React(16.x)功能组件与React Hooks一起使用时,可以轻松编写cellRenderer。这是pnunezcalzado先前发布的功能的等效项。

单元格渲染器的反应组件

function AgGridCheckbox (props) {
  const boolValue = props.value && props.value.toString() === 'true';
  const [isChecked, setIsChecked] = useState(boolValue);
  const onChanged = () => {
    props.setValue(!isChecked);
    setIsChecked(!isChecked);
  };
  return (
    <div>
      <input type="checkbox" checked={isChecked} onChange={onChanged} />
    </div>
  );
}

在您的网格中使用

调整列定义(ColDef)以使用此单元格渲染器。

{
  headerName: 'My Boolean Field',
  field: 'BOOLFIELD',
  cellRendererFramework: AgGridCheckbox,
  editable: true,
},

答案 7 :(得分:1)

这是一个反应挂钩版本,请将columnDef.cellEditorFramework设置为此组件。

import React, {useEffect, forwardRef, useImperativeHandle, useRef, useState} from "react";

export default forwardRef((props, ref) => {
    const [value, setValue] = useState();

    if (value !== ! props.value) {
        setValue(!props.value);
    }

    const inputRef = useRef();
    useImperativeHandle(ref, () => {
        return {
            getValue: () => {
                return value;
            }
        };
    });

    const onChange= e => {
        setValue(!value);
    }

    return (<div  style={{paddingLeft: "15px"}}><input type="checkbox" ref={inputRef} defaultChecked={value} onChange={onChange}  /></div>);
})

我也有以下不错的单元格渲染器

       cellRenderer: params => {
            return `<i class="fa fa-${params.value?"check-":""}square-o" aria-hidden="true"></i>`;
        },

答案 8 :(得分:1)

我们可以使用cellRenderer在网格中显示复选框,当您还想编辑该字段时,该复选框将起作用。网格将不会直接更新gridoption-rowdata中的复选框值,直到您不使用节点对象可以访问的对象中的相应字段更新节点为止。

  

params.node.data.fieldName = params.value;

此处“ fieldName”是该行的字段。

{
                    headerName: "display name",
                    field: "fieldName",
                    cellRenderer: function(params) {

                        var input = document.createElement('input');
                        input.type="checkbox";
                        input.checked=params.value;
                        input.addEventListener('click', function (event) {
                            params.value=!params.value;
                            params.node.data.fieldName = params.value;
                        });
                        return input;
                    }
                }

答案 9 :(得分:1)

尽管这是一个老问题,但我开发了一个可能很有趣的解决方案。

您可以为复选框创建cell renderer component,然后将其应用于必须根据 boolean 值呈现复选框的列。

检查以下示例:

/*
  CheckboxCellRenderer.js
  Author: Bruno Carvalho da Costa (brunoccst)
*/

/*
 * Function to work as a constructor.
 */
function CheckboxCellRenderer() {}

/**
 * Initializes the cell renderer.
 * @param {any} params Parameters from AG Grid.
 */
CheckboxCellRenderer.prototype.init = function(params) {
  // Create the cell.
  this.eGui = document.createElement('span');
  this.eGui.classList.add("ag-icon");

  var node = params.node;
  var colId = params.column.colId;
  
  // Set the "editable" property to false so it won't open the default cell editor from AG Grid.
  if (params.colDef.editableAux == undefined)
      params.colDef.editableAux = params.colDef.editable;
  params.colDef.editable = false;

  // Configure it accordingly if it is editable.
  if (params.colDef.editableAux) {
    // Set the type of cursor.
    this.eGui.style["cursor"] = "pointer";

    // Add the event listener to the checkbox.
    function toggle() {
      var currentValue = node.data[colId];
      node.setDataValue(colId, !currentValue);

      // TODO: Delete this log.
      console.log(node.data);
    }
    this.eGui.addEventListener("click", toggle);
  }

  // Set if the checkbox is checked.
  this.refresh(params);
};

/**
 * Returns the GUI.
 */
CheckboxCellRenderer.prototype.getGui = function() {
  return this.eGui;
};

/**
 * Refreshes the element according to the current data.
 * @param {any} params Parameters from AG Grid.
 */
CheckboxCellRenderer.prototype.refresh = function(params) {
  var checkedClass = "ag-icon-checkbox-checked";
  var uncheckedClass = "ag-icon-checkbox-unchecked";

  // Add or remove the classes according to the value.
  if (params.value) {
    this.eGui.classList.remove(uncheckedClass);
    this.eGui.classList.add(checkedClass);
  } else {
    this.eGui.classList.remove(checkedClass);
    this.eGui.classList.add(uncheckedClass);
  }

  // Return true to tell the grid we refreshed successfully
  return true;
}

/*
  The code below does not belong to the CheckboxCellRenderer.js anymore.
  It is the main JS that creates the AG Grid instance and structure.
*/

// specify the columns
var columnDefs = [{
  headerName: "Make",
  field: "make"
}, {
  headerName: "Model",
  field: "model"
}, {
  headerName: "Price",
  field: "price"
}, {
  headerName: "In wishlist (editable)",
  field: "InWishlist",
  cellRenderer: CheckboxCellRenderer
}, {
  headerName: "In wishlist (not editable)",
  field: "InWishlist",
  cellRenderer: CheckboxCellRenderer,
  editable: false
}];

// specify the data
var rowData = [{
  make: "Toyota",
  model: "Celica",
  price: 35000,
  InWishlist: true
}, {
  make: "Toyota 2",
  model: "Celica 2",
  price: 36000,
  InWishlist: false
}];

// let the grid know which columns and what data to use
var gridOptions = {
  columnDefs: columnDefs,
  defaultColDef: {
    editable: true
  },
  rowData: rowData,
  onGridReady: function() {
    gridOptions.api.sizeColumnsToFit();
  }
};

// wait for the document to be loaded, otherwise
// ag-Grid will not find the div in the document.
document.addEventListener("DOMContentLoaded", function() {
  // lookup the container we want the Grid to use
  var eGridDiv = document.querySelector('#myGrid');

  // create the grid passing in the div to use together with the columns & data we want to use
  new agGrid.Grid(eGridDiv, gridOptions);
});
<!DOCTYPE html>
<html>

<head>
  <script src="https://unpkg.com/ag-grid/dist/ag-grid.js"></script>
</head>

<body>
  <div id="myGrid" style="height: 115px;" class="ag-fresh"></div>
</body>

</html>

请注意,在结束 init 函数之前,我需要先禁用 editable 属性,否则AG Grid将呈现该字段的默认单元格编辑器,具有怪异的行为

答案 10 :(得分:0)

这是对我有用的解决方案。必须使用箭头功能来解决上下文问题。

组件:

import React from "react";

class AgGridCheckbox extends React.Component {

  state = {isChecked: false};

  componentDidMount() {
    let boolValue = this.props.value.toString() === "true";
    this.setState({isChecked: boolValue});
  }

  onChanged = () => {
    const checked = !this.state.isChecked;
    this.setState({isChecked: checked});
    this.props.setValue(checked);
  };

  render() {
    return (
      <div>
        <input type={"checkbox"} checked={this.state.isChecked} onChange={this.onChanged}/>
      </div>
    );
  }
}

export default AgGridCheckbox;

columnDefs数组内的列定义对象:

{
  headerName: "yourHeaderName",
  field: "yourPropertyNameInsideDataObject",
  cellRendererFramework: AgGridCheckbox
}

JSX调用ag-grid:

<div
    className="ag-theme-balham"
  >
    <AgGridReact
      defaultColDef={defaultColDefs}
      columnDefs={columnDefs}
      rowData={data}
    />
</div>

答案 11 :(得分:0)

您可以保持显示复选框,并进行如下编辑:

headerName: 'header name',
field: 'field',
filter: 'agTextColumnFilter',
cellRenderer: params => this.checkBoxCellEditRenderer(params),

然后创建一个渲染器:

checkBoxCellEditRenderer(params) {
   const input = document.createElement('input');
   input.type = 'checkbox';
   input.checked = params.value;
   input.addEventListener('click', () => {
      params.value = !params.value;
      params.node.data[params.coldDef.field] = params.value;
      // you can add here code

    });
      return input;
}

答案 12 :(得分:0)

gridOptions = {
  onSelectionChanged: (event: any) => {
    let rowData = [];
    event.api.getSelectedNodes().forEach(node => {
      rowDate = [...rowData, node.data];
    });
    console.log(rowData);
  }
}

答案 13 :(得分:0)

答案 14 :(得分:0)

您可以使用布尔值(对或错)

我尝试了,这是可行的:

var columnDefs = [
  {
    headerName: 'Refunded', 
    field: 'refunded',
    editable: true,
    cellEditor: 'booleanEditor',
    cellRenderer: booleanCellRenderer
  },
];

功能复选框编辑器

function getBooleanEditor() {
    // function to act as a class
    function BooleanEditor() {}

    // gets called once before the renderer is used
    BooleanEditor.prototype.init = function(params) {
        // create the cell
        var value = params.value;

        this.eInput = document.createElement('input');
        this.eInput.type = 'checkbox'; 
        this.eInput.checked = value;
        this.eInput.value = value;
    };

    // gets called once when grid ready to insert the element
    BooleanEditor.prototype.getGui = function() {
        return this.eInput;
    };

    // focus and select can be done after the gui is attached
    BooleanEditor.prototype.afterGuiAttached = function() {
        this.eInput.focus();
        this.eInput.select();
    };

    // returns the new value after editing
    BooleanEditor.prototype.getValue = function() {
        return this.eInput.checked;
    };

    // any cleanup we need to be done here
    BooleanEditor.prototype.destroy = function() {
        // but this example is simple, no cleanup, we could
        // even leave this method out as it's optional
    };

    // if true, then this editor will appear in a popup
    BooleanEditor.prototype.isPopup = function() {
        // and we could leave this method out also, false is the default
        return false;
    };

    return BooleanEditor;
}

然后是booleanCellRenderer函数

function booleanCellRenderer(params) {
    var value = params.value ? 'checked' : 'unchecked';

    return '<input disabled type="checkbox" '+ value +'/>';
}

让网格知道要使用哪些列和哪些数据

var gridOptions = {
    columnDefs: columnDefs,
    pagination: true,
    defaultColDef: {
        filter: true,
        resizable: true,
    },
    onGridReady: function(params) {
        params.api.sizeColumnsToFit();
    },
    onCellValueChanged: function(event) {
        if (event.newValue != event.oldValue) { 
            // do stuff
            // such hit your API update
            event.data.refunded = event.newValue; // Update value of field refunded
        }
    },
    components:{
        booleanCellRenderer: booleanCellRenderer,
        booleanEditor: getBooleanEditor()
    }
};

页面加载完成后设置网格

document.addEventListener('DOMContentLoaded', function() {
    var gridDiv = document.querySelector('#myGrid');
    // create the grid passing in the div to use together with the columns & data we want to use
    new agGrid.Grid(gridDiv, gridOptions);

    fetch('$urlGetData').then(function(response) {
        return response.json();
    }).then(function(data) {
        gridOptions.api.setRowData(data);
    })
});

答案 15 :(得分:0)

当前部分的布尔数据:

    function booleanCellRenderer(params) { 
        var valueCleaned = params.value;
        if (valueCleaned === 'T') {
            return '<input type="checkbox" checked/>';
        } else if (valueCleaned === 'F') {
            return '<input type="checkbox" unchecked/>';
        } else if (params.value !== null && params.value !== undefined) {
            return params.value.toString();
        } else {
            return null;
        }
    }

    var gridOptions = { 
        ...
        components: {
            booleanCellRenderer: booleanCellRenderer,
        }
    };

    gridOptions.api.setColumnDefs(
      colDefs.concat(JSON.parse('[{"headerName":"Name","field":"Field", 
        "cellRenderer": "booleanCellRenderer"}]')));

答案 16 :(得分:0)

ALTER PROCEDURE [dbo].[SPInsert]
@prm1 varchar(30),
@prm2 varchar(20),
@prm3 varchar(20),
@prm3 varchar(max),
@ID output,
AS
BEGIN
Insert into tbl2 (student_no, reason_txt, created_by, created_date)Values(@prm1 ,@prm2 ,@prm3 , GETDATE())
Select @ID = Scope_Identity()
END

答案 17 :(得分:0)

字符串值的数组对我不起作用,但是[true,false]的数组正在工作。

{
    headerName: 'Refunded',
    field: 'refunded',
    cellEditor: 'popupSelect',
    cellEditorParams: {
        cellRenderer: RefundedCellRenderer,
        values: [true, false]
    }
},

function RefundedCellRenderer(params) {
    return params.value;
}

答案 18 :(得分:0)

在columnDefs中,添加一个复选框列。不需要将cell属性设置为true

columnDefs: [ { headerName: '', field: 'checkbox', cellRendererFramework: CheckboxRenderer, width:30}, ...]

CheckboxRenderer

export class CheckboxRenderer extends React.Component{
    constructor(props) {
        super(props);
        this.state={
            value:props.value
        };
        this.handleCheckboxChange=this.handleCheckboxChange.bind(this);
    }

    handleCheckboxChange(event) {
        this.props.data.checkbox=!this.props.data.checkbox;
        this.setState({value: this.props.data.checkbox});
    }

    render() {
        return (    
        <Checkbox
            checked={this.state.value}
            onChange={this.handleCheckboxChange}></Checkbox>);
    }
}

答案 19 :(得分:-4)

所以最后我有点得到了我想要的东西,但是以稍微不同的方式,我使用了popupSelect和cellEditorParams的值:[&#39; true&#39;,&#39; false&#39;]。当然,我没有像我想要的那样有一个实际的复选框,但它的表现足以满足我的需要

{
    headerName: 'Refunded', 
    field: 'refunded',
    cellEditor: 'popupSelect',
    cellEditorParams: {
        cellRenderer: RefundedCellRenderer,
        values: ['true', 'false']
    }
},

function RefundedCellRenderer(params) {
    return params.value;
}