1

I want to invoke a modal from a button click in a lightning-datatable that will display the contents of the account description (because this can sometimes be a large amount of text that renders in a sub-optimal way from a UX perspective, even with setting the lightning-datatable wrapping attribute to true).

The lightning-datatable looks like so from the below code:

enter image description here

and upon clicking the button, that looks like a hyperlink because of the button variant, the modal appears:

enter image description here

However, I want the modal to display the data from the Description field, for example 'This is account 134' if the button from the first row in the lightning-datatable was selected.

I am reviewing the docs here and here but I think I need stronger coffee to understand it better.

My code so far is below:

<template>
  <lightning-card title="Account Table">
    <div class="slds-m-around_medium">
      <template if:true={accounts}>
        <lightning-datatable
          key-field="Id"
          data={accounts}
          columns={columns}
          hide-checkbox-column="true"
          onrowaction={handleOpenModal}
        >
        </lightning-datatable>
      </template>
      <template if:true={error}>
        <div class="slds-text-color_error">{error}</div>
      </template>
    </div>
  </lightning-card>
</template>
import { LightningElement, wire } from 'lwc';
import getAccountList from '@salesforce/apex/AccountDataTable.getAccountList';
import MyModal from "c/myModal";
const columns = [
    { label: 'Name', fieldName: 'Name', type: 'text' },
    { label: 'Description', fieldName: 'Description', type: 'text' },

    {
        label: 'Description',
        type: 'button',
        typeAttributes: {
            label: { fieldName: 'Description' },
            name: 'view_description',
            title: 'Click to see the full description',
            iconPosition: 'center',
            variant: 'base'
        }
    }
];

export default class AccountTable extends LightningElement {
    accounts;
    error;
    columns = columns;

    connectedCallback() {
        this.fetchAccounts();
    }

    fetchAccounts() {
        getAccountList()
            .then(result => {
                this.accounts = result;
                this.error = undefined;
            })
            .catch(error => {
                this.error = error;
                this.accounts = undefined;
            });
    }

    // ...
    // Process the select event from within the modal
    handleSelectEvent(detail) {
        const { id, value } = detail;
        console.log(`select event fired elem with id ${id} and value: ${value}`);
    }

    // ...
    // Trigger visibility of the modal
    handleOpenModal() {
        MyModal.open({
            label: 'Modal Title',
            size: 'large',
            description: 'Modal Title with brief description',
            // event triggered when new CustomEvent('select', {detail: {}});
            // occurs *from within* LightningModal.
            // see dispatchSelectEvent() in c/myModal.js above
            onselect: (e) => {
                // stop further propagation of the event
                e.stopPropagation();
                // hand off to separate function to process
                // result of the event (see above in this example)
                this.handleSelectEvent(e.detail);
                // or proxy to be handled above by dispatching
                // another custom event to pass on the event
                // this.dispatchEvent(e);
            }
        });
    }
}
    <template>
      <lightning-modal-header label="My Modal Heading"></lightning-modal-header>
      <lightning-modal-body> Content: {content} </lightning-modal-body>
      <lightning-modal-footer>
        <lightning-button label="OK" onclick={handleOkay}></lightning-button>
      </lightning-modal-footer>
    </template>
import { api } from 'lwc';
import LightningModal from 'lightning/modal';

export default class MyModal extends LightningModal {
    @api content;


    handleOkay() {
        this.close('okay');
    }

    dispatchSelectEvent(e) {
        console.log('dispatchSelectEvent called' + e);
        // e.target might represent an input with an id and value
        const { id, value } = e.target;
        const selectEvent = new CustomEvent('select', {
            detail: { id, value }
        });
        this.dispatchEvent(selectEvent);
    }
}
public with sharing class AccountDataTable {
    @AuraEnabled(cacheable=true)
    public static List<Account> getAccountList() {
        return [SELECT Id, Name, Description FROM Account LIMIT 5];
    }
}

1 Answer 1

1

You're just missing the part where you add the event parameter to your function, and then passing the content to the modal:

handleOpenModal(event) {
    MyModal.open({
        label: 'Modal Title',
        size: 'large',
        description: 'Modal Title with brief description',
        // Parameter name must be an @api property, which you've already done.
        content: event.detail.row.Description,
        // event triggered when new CustomEvent('select', {detail: {}});
        // occurs *from within* LightningModal.
        // see dispatchSelectEvent() in c/myModal.js above
        onselect: (e) => {
            // stop further propagation of the event
            e.stopPropagation();
            // hand off to separate function to process
            // result of the event (see above in this example)
            this.handleSelectEvent(e.detail);
            // or proxy to be handled above by dispatching
            // another custom event to pass on the event
            // this.dispatchEvent(e);
        }
    });
}
2
  • Thank you, sir! :) Commented Apr 13 at 23:08
  • @AndyHitchings You're welcome!
    – sfdcfox
    Commented Apr 14 at 1:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .