Cell Editors

A cell editor component is the UI that appears, normally inside a cell, that takes care of the edit operation.

Editor Types

An editor can be in a popup or in cell.

In Cell

The contents of the cell will be cleared and the editor will appear inside the cell. The editor will be constrained to the boundaries of the cell, so if it is larger than the provided area it will be clipped. When editing is finished, the editor will be removed and the renderer will be placed back inside the cell again.

Popup

The popup will appear over the cell, however it will not change the contents of the cell. Behind the popup the cell will remain intact until after editing is finished which will result in the cell being refreshed.

const columnDefs = [
    {
        field: 'name',
        editable: True,
        # uses the provided Text Cell Editor (which is the default)
        cellEditor: 'agTextCellEditor'
    },

        # show this editor in a popup
        cellEditorPopup: True,
        # position the popup under the cell
        cellEditorPopupPosition: 'under'
    }
]
import dash_ag_grid as dag
from dash import Dash, html, dcc

app = Dash(__name__)

columnDefs = [
    {
        "headerName": "Make",
        "field": "make",
        "cellEditorPopup": True,
        "cellEditorPopupPosition": "under",
    },
    {
        "headerName": "Model",
        "field": "model",
        "cellEditorPopup": True,
        "cellEditorPopupPosition": "over",
    },
    {"headerName": "Price", "field": "price"},
]

rowData = [
    {"make": "Toyota", "model": "Celica", "price": 35000},
    {"make": "Ford", "model": "Mondeo", "price": 32000},
    {"make": "Porsche", "model": "Boxster", "price": 72000},
]


app.layout = html.Div(
    [
        dcc.Markdown(
            "In this grid, the __Make__ column has a popup below the cell,  the __Model__ has a popup above the cell, and the __Price__ has the default (in cell) editor."
        ),
        dag.AgGrid(
            id="cell-editors-basic-example",
            columnDefs=columnDefs,
            rowData=rowData,
            columnSize="sizeToFit",
            defaultColDef={"editable": True},
        ),
    ],
    style={"margin": 20},
)

if __name__ == "__main__":
    app.run(debug=False)

In this grid, the Make column has a popup below the cell, the Model has a popup above the cell, and the Price has the default (in cell) editor.

Dynamic Parameters

Parameters for cell editors can be dynamic to allow different selections based on what cell is being edited. For example, you might have a ‘City’ column that has values based on the ‘Country’ column. To do this, provide a function that returns parameters for the property cellEditorParams.

This function is defined in the dashAgGridFunctions.js file in the assets folder:


var dagfuncs = window.dashAgGridFunctions = window.dashAgGridFunctions || {};

dagfuncs.dynamicOptions = function(params) {
    const selectedCountry = params.data.country;
    if (selectedCountry === 'United States') {
        return {
            values: ['Boston', 'Chicago', 'San Francisco'],
        };
    } else {
        return {
            values: ['Montreal', 'Vancouver', 'Calgary']
        };
    }
}
import dash_ag_grid as dag
from dash import Dash, html, dcc

app = Dash(__name__)


columnDefs = [
    {
        "field": "country",
        "editable": False,
    },
    {
        "headerName": "Select Editor",
        "field": "city",
        "cellEditor": "agSelectCellEditor",
        "cellEditorParams": {"function": "dynamicOptions(params)"},
    },

]

rowData = [
    {"country": "United States", "city": "Boston"},
    {"country": "Canada", "city": "Montreal"},
    {"country": "Canada", "city": "Vancouver"},
]


app.layout = html.Div(
    [
        dcc.Markdown(
            "This grid has dynamic options for city based on the country.  Try editing the cities."
        ),
        dag.AgGrid(
            id="cell-editor-grid-2",
            columnDefs=columnDefs,
            rowData=rowData,
            columnSize="sizeToFit",
            defaultColDef={"editable": True},
        ),
    ],
    style={"margin": 20},
)


if __name__ == "__main__":
    app.run(debug=False)

This grid has dynamic options for city based on the country. Try editing the cities.

Custom Datepicker Component

The example below demonstrates how to use a custom date picker as a cell editor. The ‘Date’ column uses a component
cell editor that allows you to pick a date using jQuery UI Datepicker.


import dash_ag_grid as dag
from dash import Dash, html, dcc
import pandas as pd

app = Dash(__name__, external_scripts=["https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js", "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"], external_stylesheets=["https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css"],)


df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)


columnDefs = [
    {"field": "date", "cellEditor": {"function": "DatePicker"}},
    {"field": "athlete"},
    {"field": "country"},
]

defaultColDef = {"flex": 1, "minWidth": 150, "editable": True}

app.layout = html.Div(
    [
        dcc.Markdown("Custom Date Picker Cell Editor Example"),
        dag.AgGrid(
            id="custom-date-picker-cell-editor-example",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            defaultColDef=defaultColDef,
        ),
    ],
    style={"margin": 20},
)

if __name__ == "__main__":
    app.run(debug=True)

To run this example, add the following to your dashAgGridFunctions.js file in your app’s assets folder:

var dagfuncs = window.dashAgGridFunctions = window.dashAgGridFunctions || {};

dagfuncs.DatePicker = class {

    // gets called once before the renderer is used
  init(params) {
    // create the cell
    this.eInput = document.createElement('input');
    this.eInput.value = params.value;
    this.eInput.classList.add('ag-input');
    this.eInput.style.height = 'var(--ag-row-height)';
    this.eInput.style.fontSize = 'calc(var(--ag-font-size) + 1px)';

    // <a href="https://jqueryui.com/datepicker/">https://jqueryui.com/datepicker/</a>
    $(this.eInput).datepicker({
      dateFormat: 'dd/mm/yy',
      onSelect: () => {
        this.eInput.focus();
      },
    });
  }

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

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

  // returns the new value after editing
  getValue() {
    return this.eInput.value;
  }

  // any cleanup we need to be done here
  destroy() {
    // 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
  isPopup() {
    // and we could leave this method out also, false is the default
    return false;
  }

}

Custom date picker

Custom Number Input Component

The example below demonstrates how to use a custom number input as a cell editor. The ‘Price’ column uses a component
cell editor that is an HTML input with type=”number”.

Notice the following:

import dash_ag_grid as dag
from dash import Dash, html
import pandas as pd

data = {
    "item": ["A", "B", "C", "D"],
    "price": [1154.99, 268.65, 100.00, 96.75],
}
df = pd.DataFrame(data)

columnDefs = [
    {"field": "item"},
    {
        "field": "price",
        "type": "rightAligned",
        "valueFormatter": {"function": """d3.format("($,.2f")(params.value)"""},
        "editable": True,
        "cellEditor": {"function": "NumberInput"},
        "cellEditorParams" : {"placeholder": "Enter a number"}
    },
]


grid = dag.AgGrid(
    id="custom-number-input-example-1",
    columnDefs=columnDefs,
    rowData=df.to_dict("records"),
)


app = Dash(__name__)

app.layout = html.Div(grid,style={"margin": 20})


if __name__ == "__main__":
    app.run(debug=True)

To run this example, add the following to the dashAgGridFunctions.js file in your app’s assets folder:


var dagfuncs = window.dashAgGridFunctions = window.dashAgGridFunctions || {};

dagfuncs.NumberInput = class {
    // gets called once before the renderer is used
  init(params) {
    // create the cell
    this.eInput = document.createElement('input');
    this.eInput.value = params.value;
    this.eInput.style.height = 'var(--ag-row-height)';
    this.eInput.style.fontSize = 'calc(var(--ag-font-size) + 1px)';
    this.eInput.style.borderWidth = 0;
    this.eInput.style.width = '95%';
    this.eInput.type = "number";
    this.eInput.min = params.min;
    this.eInput.max = params.max;
    this.eInput.step = params.step || "any";
    this.eInput.required =  params.required;
    this.eInput.placeholder =  params.placeholder || "";
    this.eInput.name = params.name;
    this.eInput.disabled = params.disabled;
    this.eInput.title = params.title || ""
  }

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

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

  // returns the new value after editing
  getValue() {
    return this.eInput.value;
  }

  // any cleanup we need to be done here
  destroy() {
    // 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
  isPopup() {
    // and we could leave this method out also, false is the default
    return false;
  }
}

Cell Editing can also be done with Cell Editor Components. See: