I know what I am asking is capable using pure HTML; however, I need this capability within an ag-Grid cell.
I have a new requirement for my ag-Grid Angular application. The stakeholder would like me to display a hierarchical LOVs (list of values) dropdown inside of an ag-Grid cell. I am using a cellEditorSelector with a valueFormat to build up different type of cellEditors; i.e. agRichSelectCellEditor, datePicker, no editor (just a free form input field).
Here is an example screenshot of a hierarchical dropdown from my stakeholder:
Example of Stakeholder's LOV/dropdown
I tried to create a POC using an existing dropdown within my application:
I was hoping that I did not have to place hyphens to denote the levels (i.e. -, --). I wanted to place tab (‘\t’ for level one and ‘\t\t’ for level two, etc…) escape sequences.
I then tried adding hyphens with a font color of white to no avail with the following code:
return {
component: 'agRichSelectCellEditor',
params: {
values: valueArray,
formatValue: function(value) {
return '-----'.fontcolor('white') + value;
},
}
};
What was displayed for the LOV was something like this:
LOV with hyphens, but trimmed tabbed space
Here is the array object I created to work with. Level1 has a tab (\t) after the one hyphen and level2 has two tabs (\t\t) after two hyphens and are shown accordingly. For some reason the tabbed spaces are being removed at the time they are displayed by the grid; hence, the usage of the hyphens since they do not get trimmed.
Array object with hyphens and tabbed space
If I create the array object without the hyphens the tabs are still preserved:
I was able to come up with a solution for my proof of concept. Note, I use 'level1' and 'level2' as static level indicators. Eventually, my array object will contain the actual level so that it is not restricted to two levels.
In my grid component I created the following ag-Grid component reference:
this.components = { levelRenderer: levelRenderer }
as well as, the levelRenderer code:
// cell renderer class
function levelRenderer() {
}
// init method gets the details of the cell to be renderer
levelRenderer.prototype.init = function (params) {
this.eGui = document.createElement('select');
const hiddenLOVsElement: HTMLInputElement = document.getElementById('hiddenLOVs') as HTMLInputElement;
this.hiddenLOVs = hiddenLOVsElement;
const hiddenLOVsArray: any[] = this.hiddenLOVs.value.split(',');
for (let i = 0; i < hiddenLOVsArray.length; i++) {
const option = document.createElement('option');
option.value = hiddenLOVsArray[i];
option.text = hiddenLOVsArray[i];
const levelValue = option.value.substr(0, 6);
console.log('levelValue: ', levelValue);
switch (levelValue) {
case 'level1':
option.innerHTML = ' ' + hiddenLOVsArray[i];
break;
case 'level2':
option.innerHTML = ' ' +
' ' + hiddenLOVsArray[i];
break;
default:
option.innerHTML = hiddenLOVsArray[i];
}
this.eGui.appendChild(option);
}
};
levelRenderer.prototype.getGui = function() {
return this.eGui;
};
Here is how I call it from my cellEditorSelector:
return {
component: 'levelRenderer',
}
};
Note, the values I use are the results from a web service call (via a utility class) which returns a JSON object. From the JSON object I build an array named, valueArray. I hide that array inside the DOM:
<input id='hiddenLOVs' type='hidden' [value]="this.hiddenLOVs"/>
const hiddenListOfValues: HTMLInputElement = document.getElementById('hiddenLOVs') as HTMLInputElement;
hiddenListOfValues.value = JSON.parse(JSON.stringify(valueArray));
Here is the final result of my LOV:
Note, needed to add a getValue function:
levelRenderer.prototype.getValue = function() {
console.log('getValue');
return this.eGui.value;
};