Mike Gledhill
Mike Gledhill

Reputation: 29161

agGrid with Angular, using agRichSelectCellEditor

I have an agGrid populated with Employee records in JSON format from my web service.

[
   { 
     id: 123,
     firstName: 'Mike',
     lastName: 'Jones',
     countryId: 1001,
     DOB: '1980-01-01T00:00:00',
     . . .
   }

I have a second web service returning a list of country codes:

[ 
    { id: 1000, name: 'France' },
    { id: 1001, name: 'Spain' },
    { id: 1002, name: 'Belguim' }
]

What I'm trying to do is get my agGrid to have a column showing the user's details, including the name of their country, and when they edit this cell, a list of country codes will appear, where they can select one, and it'll update the record with the id of that country.

Basic stuff, no ?

But has anyone managed to get agGrid to successfully use the "agRichSelectCellEditor" to do this successfully ?

  { headerName: 'Country', width: 120, field: 'countryId', editable: true, 
      cellEditor:'agRichSelectCellEditor',

      cellEditorParams: { 
          // This tells agGrid that when we edit the country cell, we want a popup to be displayed
          // showing (just) the names of the countries in our reference data
          values: listOfCountries.map(s => s.name)
      },

      //  The "cellRenderer" tells agGrid to display the country name in each row, rather than the
      //  numeric countryId value
      cellRenderer: (params) => listOfCountries.find(refData => refData.id == params.data.countryId)?.name,

      valueSetter: function(params) {
        //  When we select a value from our drop down list, this function will make sure 
        //  that our row's record receives the "id" (not the text value) of the chosen selection.
        params.data.countryId = listOfCountries.find(refData => refData.name == params.newValue)?.id;
        return true;
    }  
  },

My code seems to be almost correct.. it manages to:

The only problem is that at the top of the popup, it shows the countryId value, rather than the user's current country name.

enter image description here

Has anyone managed to get this to work ?

The only workaround I could come up with was to override the CSS on this popup and hide that top element:

.ag-rich-select-value
{
    display: none !important;
}

It works... but you no longer get to see what your previously selected value was.

enter image description here

(I really wish the agGrid website had some decent, real-life, working Angular examples... or at least let developers post comments on there, to help each other out.)

Upvotes: 5

Views: 11864

Answers (4)

A. Parolini
A. Parolini

Reputation: 369

Much simpler solution: use cellEditorParams formatValue, along with valueFormatter

        {
        field: 'foo',
        cellEditor: 'agRichSelectCellEditor',
        cellEditorParams: {
            values: [1,2,3, 4, other ids... ],
            formatValue: (id: number): string => this.getLabelFromId(value)
        },
        valueFormatter: (params: ValueFormatterParams): string => this.getLabelFromId(params.value as number)
    }

Upvotes: 0

Mayur Parmar
Mayur Parmar

Reputation: 264

Here Is Example Of agRichSelectCellEditor...

{
            headerName: 'Dropdown', field: 'dropdown',
            cellEditor: 'agRichSelectCellEditor',
            width: 140,          
            editable: true,

            cellEditorParams: (params) => {
            values: Get All Dropdown List Like ["Hello","Hiii","How Are You?"]
            },

            valueSetter: (params) => {
              if (params.newValue) {
               params.data.dropdown= params.newValue;
                return true;
              }
              return false;
            }
 }

Upvotes: 0

Simon Dando
Simon Dando

Reputation: 1

I was able to get my similar situation (id:name pairs in a list, but not using Angular though) working without the problem you mentioned above, and without a valueGetter/valueSetter and only a renderer. The benefit is that you don't need to double click the cell to see the list, the cell appears as a selection box always, and you avoid a bug should the user double click the cell when the list is displayed.

The renderer is a lot clunkier than I was wanting (one line like yours) and it didn't seem that aggrid had built in support for this pretty basic function (and I already have spent enough time on this).

Anyway, this is what I had, which at least works, but keen to see further improvements on it. (You will need to at least change 2 lines for the option related code since my defaultValue object is specific to me).

The column definition:

{field: 'defaultValueID', headerName: "Default Value", cellEditor:'agRichSelectCellEditor', cellRenderer: defaultValueRenderer}

And the renderer code:

    function defaultValueRenderer(params) {
        var input = document.createElement("select");
        // allow it to be cleared
        var option = document.createElement("option");
        option.innerHTML = '[None]';
        option.value = null;
        input.appendChild(option);

        for (var i=0; i < defaultValueList.length; i++) {
            var option = document.createElement("option");
            option.innerHTML = defaultValueList[i].name;
            option.value = defaultValueList[i].gltID;
            input.appendChild(option);
        }

        input.value = params.value;
        input.onchange = function() {
            params.setValue(this.value);
            params.data.defaultValueID = this.value;
        }
        input.style="width: 100%; height: 100%"; // default looks too small
        return input;
    }

Upvotes: 0

Mike Gledhill
Mike Gledhill

Reputation: 29161

The solution was to use a valueGetter, rather than a cellRenderer:

 { 
    headerName: 'Country', width: 120, field: 'countryId', editable: true, 
    cellEditor:'agRichSelectCellEditor',

    cellEditorParams: { 
        // This tells agGrid that when we edit the country cell, we want a popup to be displayed
        // showing (just) the names of the countries in our reference data
        values: listOfCountries.map(s => s.name)
    },

    valueSetter: function(params) {
        //  When we select a value from our drop down list, this function will make sure
        //  that our row's record receives the "id" (not the text value) of the chosen selection.
        params.data.countryId = listOfCountries.find(refData => refData.name == params.newValue)?.id;
        return true;
    }, 

    valueGetter: function(params) {
        //  We don't want to display the raw "countryId" value.. we actually want 
        //  the "Country Name" string for that id.
        return listOfCountries.find(refData => refData.id == params.data.countryId)?.name;
    }
},

I hope this is useful...

Upvotes: 4

Related Questions