3

I'm trying to use lightning:datatable component to render table of my custom data.

I do generate myData like:

JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartArray();

    for (all territories to populate country column){
        gen.writeStartObject();
        gen.writeStringField('country', territory);

        for (all dynamic fileds){
            if(yes condition){
                gen.writeStringField(b.id, 'Yes');
            }else{
                gen.writeStringField(b.id, 'No');
            }
        }
        gen.writeEndObject();
    }
    gen.writeEndArray();

so my JSON looks like:

[
   {country: "A" , id001: "Yes", id002: "No" ... id007: "Yes"},
   {country: "B" , id001: "No", id002: "Yes" ... id007: "Yes"}...]

so number of columns (id) can be different and yes/no values checked for all of them with some background logic.

in the helper I assign it like this:

component.set('v.columns', result.lstDataTableColumns);
component.set("v.dataTable", JSON.parse(result.JSONDataTable));

My table has proper Yes/No values in proper cells but how can I customize cell classes or add icons to cells? I need to add Green/Red background or Yes/No icons to data cells based on Yes/No values in them. Is it possible to assign cellAttributes to data attribute same way as to columns attribute of lightning:datatable?

Or it is easier just go with <aura:iteration>? lightning:datatable looks cool and has a lot of additional stuff to play with.

3

The best you could do right now would be to render the cell as a button type, which would allow you to specify an iconName in the typeAttributes property for each cell. This probably isn't a desirable solution, though, so you'll probably want to use the aura:iteration idea instead, or you could write your own data table component using the code from SLDS (it's not too complicated).

  • Thanks! Actually was able to add icons to cells. Your advice to try buttons actually helped, first I did it for buttons, and for text dataType works the same. Just had to change typeAttribute to cellAttribute. – Leonid Zadorozhnykh Jun 8 '18 at 14:26
3

I did figured this out! Found out that it is possible to provide cellAttributes properties like an Object.

cellAttributes: { iconName: `columnName` }

It is possible to assign values to iconName dynamically by providing column name to grab the vale from.

In my case number of columns can be dynamic and names are also dynamic. So I used Object ids for fieldName and just made another columns in format objectId_ico where I did assign different icon names.

I did the whole table structure on backend.

for(MyObject__c b:myCollection){
    Map<String, Object> btn = new Map<String, Object>(); //obj to hold cell
    Map<String, String> btnLabel = new Map<String, String>(); //obj to hold cell Label
    Map<String, String> btnIco = new Map<String, String>(); //obj to hold cell Icon

    btnLabel.put('fieldName', String.valueOf(b.id)); //here record ID assigned to column fieldName
    btnIco.put('fieldName', String.valueOf(b.id) + '_ico'); //here recordID_ico assigned to column fieldName will be used for cellAttribute
    btn.put('label', btnLabel);
    btn.put('iconName', btnIco); // here we put object to cellAttribute
...
}

I have added to my JSON generator code from original question 2 new lines to add this additional columns:

if(yesCondition){
                gen.writeStringField(b.id, 'DEAL');
                gen.writeStringField(b.id + '_ico', 'action:approval');
            }else{
                gen.writeStringField(b.id, 'NO DEAL');
                gen.writeStringField(b.id + '_ico', 'action:close');
            }

Well, in the end I have column b.id (which is just Object ID) where I have labl and column b.id + '_ico' where I have icon name to associate with the cell.

So far work in progress, can be optimized a bit. However, my 1200-1500 cells table generated and rendered pretty fast. As well it also has sorting and some other functionality. enter image description here

  • I used JSON and Map<... , ...> types to be more flexible. MAybe later will assign dataType for the cells dynamically, e.g. to show url/text/button in different cells of the same column based on the cell value. – Leonid Zadorozhnykh Jun 8 '18 at 14:30
  • Yes this is the same approach but you've used hidden columns (I assume) rather than hidden wrapper fields (my JS manipulated keys). Good stuff! – tsalb Jun 9 '18 at 0:10
  • yes, something similar. Took a while to figure out how this datatable actually works. Seems that we can pass dynamic values for cellAttribute/typeAttribute via hidden columns (as I did) or manipulate with data in JS. Haven't test it performance nut think whatever is preferable will work. – Leonid Zadorozhnykh Jun 9 '18 at 7:54
  • It works well performance wise. I am rendering somewhere like 8K (visible) to 50k (initially hidden) cells with an icon in each using treegrid – tsalb Jun 9 '18 at 18:35
2

You can do it, but it's quite troublesome. I've managed to do this with a data display wrapper and assigning the icon by hand clientside (I'm sure you could do it serverside, but I thought it was easier to manipulate the Object keys as you'll see below).

This trick leverages the fieldName reference in lightning:treeGrid but I'm sure lightning:datatable behaves the same way.

Given the following column cellAttributes configuration:

cellAttributes: { 
  alignment: "left",
  iconName: {
    fieldName: "icon_0",
    iconPosition: "left"
  },
  fieldName: "dataCell_0",
  label: "MAR 2018"
}

And then the Apex display wrapper, which is now a JS Object clientside:

dataCell_0: "4"

... other fields in flattened format my column fieldNames look for...

icon_0: "utility:success"

As an FYI, I do this in my JS Helper:

let _self = this;
for (let row of dataWrapperRows) {
  _self.applyIconToData(row);
}

.......

applyIconToData : function(row) {
  Object.keys(row).forEach(function(value, index, array) {
    // I go through the keys for each row to look for that column's fieldName
    // because for me, I care about matching the dataCell_INDEX to the icon_INDEX
    // For you it might be easier to evaluate
    let iconKey = "icon_0";

    // some logic to assign which icon
    // I use each row's data inside the wrapper to figure this out
    row[iconKey] = "utility:success";
  });
},

Add a dash of CSS:

.THIS .slds-icon-utility-success svg {
  fill: rgb(52,168,83);
}

And presto:

enter image description here

  • thanks @tsalb tied to implement this approach but couldn't. At least it gave me the right direction. – Leonid Zadorozhnykh Jun 8 '18 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.