0

I have an HTML table, where there a row column that renders on condition,

<table class="slds-table slds-table--bordered">
    <head>
        <tr>
            <th>Title</th>
            <th>File Type</th>
            <th>Uploaded on</th>
        </tr>
    </thead>
    <tbody>
        <template for:each={files} for:item="f">
            <tr key={f.Id}>
                <td>
                    <a href="javascript:void(0)" data-id={f.Id} onclick={previewFile}> {f.Title} </a>
                </td>
                <td>
                    {f.FileExtension}
                </td>
                <td>
                    <lightning-formatted-date-time value={f.CreatedDate}
                    year="numeric"
                    month="numeric"
                    day="numeric"
                    hour="2-digit"
                    minute="2-digit">
                    </lightning-formatted-date-time>
                </td>
                <td>
                    <div if:true={allowDelete}>
                        <a onclick={handleConfirmDialog} data-id={f.Id} data-name={f.Title}>
                            <lightning-button-icon icon-name="utility:delete" alternative-text="delete"></lightning-button-icon>
                        </a>
                    </div>
                </td>
            </tr>
        </template>
    </tbody>
</table> 

Which renders this way:

HTML Table

As you can see, the delete element is conditional and the title is actually a "link" that should show a preview of the file.

I would like to migrate this piece of the code to use the lightning datatable instead of an HTML table or have the HTML table refreshed each time a new element is added or removed (using lightning-datatable and refreshApex() is way easier to achieve this) - (gonna post another question for this).

So far this is what I have done:

HTML

<lightning-card title="Datatable Example" icon-name="custom:custom63">
    <div class="slds-m-around_medium">
        <template if:true={files.data}>
            <lightning-datatable
                key-field="Id"
                data={files.data}
                columns={columns}
                onsave={handleSave}
                draft-values={draftValues}
                hide-checkbox-column>
            </lightning-datatable>
        </template>
        <template if:true={files.error}>
            <!-- handle Apex error -->
        </template>
    </div>
</lightning-card>

JS

const COLUMNS = [
    {
        label: 'Title', fieldName: 'Title'
    },
    {
        label: 'File type', fieldName: 'FileExtension'
    },
    {
        label: 'Updated on', fieldName: 'CreatedDate', type: 'date', typeAttributes: {
            year: "numeric",
            month: "numeric",
            day: "numeric",
            hour: "2-digit",
            minute: "2-digit"
        }
    },
    {
        label: 'Delete', type: 'button-icon', typeAttributes: {
            iconName: "utility:delete",
            title: 'Delete'
        }
    }
]

Which renders this way:

Lightning-datatable

I guess I could do some CSS toggle or something to hack this delete icon condition, but I feel like it's gonna be an "ugly" solution.

If I manage to refresh the HTML table that will be enough for my goal, but since I'm using LWC, shouldn't I try to implement LWC elements?

So, this is what I'd like to learn to do:

  1. Refresh an HTML table from the JS controller. *Edit #1
  2. Use a button-icon/button, inside lightning datatable and show it conditionally.
  3. Make the title/text to show the file preview, by using the NavigationMixin preview file method from the docs.

I don't want you to think I pretend to get the straight solutions from here, rather than that if you can guide me in the right direction, point me the documentation that I should be reading, I'll really appreciate it.

Best,

Edit #1

I was able to make the two tables refresh (lightning-datatable refresh as per the documentation stands for the element). But most importantly, the HTML table would be enough for the use case of the component, but I'd like to learn how to achieve this using the lightning-datatable element.

By using a wired Apex method to a property:

JS

@wire(getFiles, { recordId: '$recordId', documentPrefix: '$documentPrefix' })
files;

HTML

<table class="slds-table slds-table--bordered">
    <thead>
        <tr>
            <th>Title</th>
            <th>File Type</th>
            <th>Uploaded on</th>
        </tr>
    </thead>
    <tbody>
        <template if:true={files.data} for:each={files.data} for:item="file">
            <tr key={file.Id}>
                <td>
                    <a href="javascript:void(0)" data-id={file.Id} onclick={previewFile}> {file.Title} </a>
                </td>
                <td>
                    {file.FileExtension}
                </td>
                <td>
                    <lightning-formatted-date-time value={file.CreatedDate}
                    year="numeric"
                    month="numeric"
                    day="numeric"
                    hour="2-digit"
                    minute="2-digit">
                </lightning-formatted-date-time>
                </td>
                <td>
                    <div if:true={allowDelete}>
                        <a onclick={handleConfirmDialog}
                            data-id={file.Id}
                            data-name={file.Title}>
                            <lightning-button-icon icon-name="utility:delete" alternative-text="delete">
                            </lightning-button-icon>
                        </a>
                    </div>
                </td>
            </tr>
        </template>
    </tbody>
</table>
1

3 - To open one or more file records in Lightning Experience and the Salesforce app, use the navigation service, lightning/navigation. The navigation service opens the preview of one or more files in a modal dialog in Lightning Experience or triggers a file download in the Salesforce app on mobile devices. For implementation details refer to this Blog.

2 - Instead of conditionlally hiding the Delete button, you can disable it, using disabled attribute of the Button. Pass the allowDelete value like this disabled: { fieldName: 'allowDelete'}

HTML

<template>
    <div style="height: 300px;">
        <lightning-datatable
                key-field="id"
                data={data}
                columns={columns}>
        </lightning-datatable>
    </div>    
</template>

JS

import { LightningElement } from 'lwc';

const COLUMNS = [
    {
        label: 'Title', fieldName: 'Title'
    },
    {
        label: 'File type', fieldName: 'FileExtension'
    },
    {
        label: 'Updated on', fieldName: 'CreatedDate', type: 'date', typeAttributes: {
            year: "numeric",
            month: "numeric",
            day: "numeric",
            hour: "2-digit",
            minute: "2-digit"
        }
    },
    {
        label: 'Delete', type: 'button-icon', typeAttributes: {
            iconName: "utility:delete",
            title: 'Delete',
            disabled: { fieldName: 'allowDelete'}
        }
    }
];

const DATA = [
    {
        "Title":"Title1",
        "FileExtension":"pdf",
        "CreatedDate":"2019-02-14T05:19:57.000+0000",
        "allowDelete": true
    },
    {
        "Title":"Title2",
        "FileExtension":"pdf",
        "CreatedDate":"2019-02-14T05:19:57.000+0000",
        "allowDelete": false
    },
    {
        "Title":"Title3",
        "FileExtension":"pdf",
        "CreatedDate":"2019-02-14T05:19:57.000+0000",
        "allowDelete": true
    },
    {
        "Title":"Title4",
        "FileExtension":"pdf",
        "CreatedDate":"2019-02-14T05:19:57.000+0000",
        "allowDelete": false
    }    

];


export default class BasicDatatable extends LightningElement {
    data = DATA;
    columns = COLUMNS;

    // eslint-disable-next-line @lwc/lwc/no-async-await
    connectedCallback() {
    }
}

Screengrab enter image description here

2
  • Since I'm getting my data from a wired property, how could I append, add the allowDelete property to the array? And also, make the first column a clickable action? so I call the preview file method?
    – AjFmO
    May 21 at 4:22
  • In your HTML implementation, how you are getting the value of allowDelete?
    – Saroj Bera
    May 21 at 11:28
4

You can utilize Lwc Datatable - disabled attribute. like shown here.

You can also use custom rowActions (in your case a button type) and add them to the columns when condition satisfy. Check out this.

It would be better if you can use Lightning-datatable since it gives you control of handling actions, standard style sheet, auto sorting, column expanding etc. in my opinion, nothing wrong utilizing html table as well if you want to have more control over your design, but keep in mind of the things you would have to implement on your own.

  1. To refresh HTML table,
  2. To preview file in LWC using navigation mixin you can refer this SF documentation.

Updated code based on comment : Let's say you get data returned from Wired method, you can add properties like this :

//Keep a boolean whenever you want to show the delete button based on your condition:

            this.datatoshowinLWCdataTable = result.map(row=>{
                            
                if(row.fieldName != 'value'){ //show delete button condition
                    this.showDelete = true;
                    
                }else{
                    this.showDelete = false;
                }
                return{...row, disaplyDelete: showDeleteButton }
            });

and update your Columns Delete button like this :

{
    label: 'Delete', type: 'button-icon', typeAttributes: {
                    iconName: "utility:delete",
                    title: 'Delete'
                },
                disabled: { fieldName: disaplyDelete}
            }

I havn't tested this but you will get an idea from this. You can also Refer this.

Hope this helps, happy to help you further.

3
  • I was able to make the HTML table refresh, this would be enough for my goal, but I want to implement using lightning-datatable, to do this, I need to two things, one, show the file preview when the user clicks on the title, that means I have to make the column title a clickable action like this <a href="javascript:void(0)" data-id={f.Id} onclick={previewFile}> {f.Title} </a>. The other would be about the delete button-icon, I have an idea on how to do it, but not sure how can I add a property to an array since I'm getting the data through a wired property.
    – AjFmO
    May 21 at 4:30
  • 1
    @AjFmO I updated my answer with code. May 21 at 4:42
  • Thank you, gonna test and let you know the outcome. 👍🏼
    – AjFmO
    May 21 at 4:48

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.