lwcSalesforce

Maps and Filters in a LWC component, Part 2

Part 1 showed how to use the Map function to add new properties to the results of an apex call. Our current LWC is getting an account list and then showing a datatable of the results.

Our apex controller is a simple:

  @AuraEnabled(cacheable=true)
  public static List<Account> getAccountList() {
    return [SELECT Id, Name, BillingAddress FROM Account LIMIT 10];
  }
}

In this next post we will add some more information to the apex method and then work out how to show the detail if someone selects the row. So lets add a bit data to return:

public with sharing class mapsandfiltersController {
  @AuraEnabled(cacheable=true)
  public static List<Account> getAccountList() {
    return [
      SELECT
        Id,
        Name,
        BillingAddress,
        Rating,
        Phone,
        Type,
        Industry,
        NumberOfEmployees
      FROM Account
      LIMIT 10
    ];
  }
}

So we have more information coming in and we want a table on the left of the component and details on the right. We will need a grid layout (see https://www.lightningdesignsystem.com/utilities/grid/)

If we set our template to the following code then we can have two areas, one occupying 7/12th of the area and showing the table and another 5/12th of the area showing the details.

<template>
  <div style="width: 100%">
    <div class="slds-grid slds-gutters">
      <div class="slds-col slds-size_7-of-12">
        <lightning-card title="Maps and Filters">
          <div class="slds-m-around_small">
            <div style="height: 600px" class="slds-m-around_x-small">
              <lightning-datatable
                key-field="id"
                hide-checkbox-column="true"
                data={accountList}
                columns={columns}
              >
              </lightning-datatable>
            </div>
          </div>
        </lightning-card>
      </div>
      <div class="slds-col slds-size_5-of-12">
        <lightning-card title="Account Details"> </lightning-card>
      </div>
    </div>
  </div>
</template>

This will show as:

The key programming issue is how do we find what row is selected and then get back to our original data to present the extra details not shown by the datatable. In part 1 we did include the actions on the row but we have not hooked this up to anything:

const actions = [{ label: "Show details", name: "show_details" }];

const columns = [
  { label: "Name", fieldName: "Name" },
  { label: "Billing Address", fieldName: "CompleteBillingAddress" },
  { label: "Address Quality", fieldName: "AddressQuality" },
  {
    type: "action",
    typeAttributes: { rowActions: actions }
  }
];

So lets get this to call a function when we click:

<lightning-datatable
  key-field="id"
  hide-checkbox-column="true"
  data={accountList}
  columns={columns}
  onrowaction={handleRowAction}
>
</lightning-datatable>

We can add a function to handle the Row Action, this can find both the action that was fired (we only have one action called show_details) and the row selected:

  handleRowAction(event) {
    const actionName = event.detail.action.name;
    const row = event.detail.row;
    console.log("--- start handleRowAction---");
    console.log(actionName);
    console.log(JSON.stringify(row));
  }

The row will return all the data of the row, not just what was shown in the datatable. So we can easily then populate the detail side of the component by updating the javascript to add:


detailRating;
detailPhone;
detailType;
detailIndustry;
detailEmployees;

handleRowAction(event) {
    const actionName = event.detail.action.name;
    const row = event.detail.row;
    console.log("--- start handleRowAction---");
    console.log(actionName);
    console.log(JSON.stringify(row));

    this.detailRating = row.Rating;
    this.detailPhone = row.Phone;
    this.detailType = row.Type;
    this.detailIndustry = row.Industry;
    this.detailEmployees = row.NumberOfEmployees;
  }

and the template to add:

      <div class="slds-col slds-size_5-of-12">
        <lightning-card title="Account Details">
          <div><b>Rating :</b>{detailRating}</div>
          <div><b>Phone :</b>{detailPhone}</div>
          <div><b>Type :</b>{detailType}</div>
          <div><b>Industry :</b>{detailIndustry}</div>
          <div><b>Employees :</b>{detailEmployees}</div>
        </lightning-card>
      </div>

which will result in this:

The advantage of the datatable is that when the apex call is made all the data is stored in the datatable to be accessed within the component.

The final post will look at a method when this is not possible.

Leave a Reply

Your email address will not be published. Required fields are marked *