0
votes

I have a grid that I would like to use different editors for different rows in the same column. ag-Grid’s documentation discusses how to use and configure the colDef.cellEditorSelector as a function that allows for the use of different editors in the same column: https://www.ag-grid.com/javascript-grid-cell-editing/#many-editors-one-column

I have been successful in creating unique editors for numeric and text data types. Unfortunately, I was unable to get my date picker editor to fully work. I used the following plunker example as guidance; however, the date picker is not implement as a cellEditorSelector: https://next.plnkr.co/edit/Bi7MWBaeruuMEvE5?preview

Here is a code snippet that shows my date picker implementation using cellEditorSelector:

      {
        headerName: 'Values',
        field: 'value',
        onCellValueChanged: this.UpdateRowDataModel.bind(this),
        onCellClicked: this.ClickedConditionCell.bind(this),
        cellEditorSelector: function (params) {
          const alias = params.data.alias.alias;
          console.log('alias: ', alias);

          const myAttributesElement: HTMLInputElement = document.getElementById('myAttributes') as HTMLInputElement;
          const myAttributes = JSON.parse(myAttributesElement.value);
          console.log('myAttributes: ', myAttributes);

          const cU = new CriteriaUtilities();
          const dataType = cU.getDataType(alias, myAttributes);
          console.log('dataType: ', dataType);

          if (dataType === 'DT') {
            console.log('inside: dataType === DT');
            return {
              component: 'agDateInput',
              cellEditor: 'datePickerEditor',
              filterParams: {
                comparator: function (filterLocalDateAtMidnight, cellValue) {
                  const dateAsString = cellValue;
                  const dateParts = dateAsString.split('/');
                  const cellDate = new Date(Number(dateParts[0]), Number(dateParts[1]) - 1, Number(dateParts[2]));
                  if (filterLocalDateAtMidnight.getTime() === cellDate.getTime()) {
                    return 0;
                  }
                  if (cellDate < filterLocalDateAtMidnight) {
                    return -1;
                  }
                  if (cellDate > filterLocalDateAtMidnight) {
                    return 1;
                  }
                }
              },
            };

          }

          // Static cell editor - example
          if (params.data.alias.alias === 'Fiscal Period') {
            console.log('inside if - params.data.alias: ', params.data.alias);
            return {
              component: 'agRichSelectCellEditor',
              params: {
                values: ['01', '02', '03', '04',
                  '05', '06', '07', '08',
                  '09', '10', '11', '12'
                ]
              }
            };

          }

          // Static cell editor - example
          if (params.data.alias.alias === 'Fiscal Year') {
            console.log('inside if - params.data.alias: ', params.data.alias);
            return {
              component: 'agRichSelectCellEditor',
              params: {
                values: ['1997', '1998', '1999', '2000',
                  '2001', '2002', '2003', '2004',
                  '2005', '2006', '2007', '2008',
                  '2009', '2010', '2011', '2012',
                  '2013', '2014', '2015', '2016',
                  '2017', '2018', '2019', '2020',
                  '2021', '2022', '2023', '2024',
                ]
              }
            };

          }

          return null;
        },
        width: 225,
        editable: true
      },

I expect that after I select the date via the date picker that the date value will display in the cell where the date picker was called.

When I run the my code, the CustomDateComponent is throwing the following error:

core.js:1448 ERROR TypeError: this.params.onDateChanged is not a function at CustomDateComponent.push../src/app/common/utilities/custom-date-component/custom-date-component.component.ts.CustomDateComponent.onDateChanged

To better illustrate the issue, I modified the above plunker example to use a cellEditorSelector instead of a cellEditor. Here is the modified plunker that demonstrates the error being thrown; similar to the one in my application: https://next.plnkr.co/edit/sQdaj1ryYFnXYZZb?preview

1

1 Answers

0
votes

So I ran into this conundrum today and realized that the function that is called

.onDateChanged is happening "after the fact" in the code. For example

var item = thisFunction();
function thisFunction() {
    console.log('hello'); 
}

So that isn't actually accessible. What's kind of nuts is that ag-grid is using the custom component and setting up a function/class object with a .init ->

    CustomDateComponent.prototype.init = function (params) {
        // your code here

    }

So we are stuck in this catch-22 with Javascript. After playing around a bit today with the code from the ag-grid website I landed on this piece.

        CustomDateComponent.prototype.init = function (params) {

        let custom_date_component = this;

        var template =
            "<input type='text' data-input />" +
            "<a class='input-button' title='clear' data-clear>" +
            "<i class='fa fa-times'></i>" +
            "</a>";

        this.params = params;

        this.eGui = document.createElement('div');

        var eGui = this.eGui;

        eGui.setAttribute('role', 'presentation');
        eGui.classList.add('ag-input-wrapper');
        eGui.classList.add('custom-date-filter');
        eGui.innerHTML = template;

        this.eInput = eGui.querySelector('input');

        this.picker = flatpickr(this.eGui, {
            onChange: function (dateobj, datestr) {
                 custom_date_component.date = datestr;
            },
            // onChange: this.onDateChanged.bind(this),
            dateFormat: 'd/m/Y',
            wrap: true
        });

I declare a variable initially to store the root component "this"

   let custom_date_component = this;

And then to follow up, flatpickr has an onChange handler event where we can just write our own custom function to capture the event.

onChange: function (dateobj, datestr) {
             custom_date_component.date = datestr;
        },

And then using that variable declared before we can set properties as such following the ag-grid example code.

For references to the original code -> https://www.ag-grid.com/javascript-grid-date-component/