0

I am trying to add filter buttons to my data table so the user can be able to filter the data table based on priority (closed, submitted, or active). The buttons show up in the lighting app builder but once I save the page, go to the app, and refresh the app the buttons do not show up on top of the data table as they do in the preview in the app builder. I inspected the app page and found the <c-filter-button ... </c-filter-button> element where it should be displayed on the template for this component. I threw in some text in the div tag that contains the custom button to make sure the div was working and the text showed up on the app page. Would anyone know what this LWC is showing up in the app builder but not on the active app page?

This is the reference I am using to help develop the filter buttons. I kept all the variables the same and put log statements to make sure I was getting the correct data (which I am) https://live.playg.app/play/using-buttons-as-list-filters-lwc

Datatable Component Template

<template>
    <div class="slds-box slds-theme_shade slds-theme_alert-texture">
        <div class="slds-align_absolute-center">
            <c-filter-button button-labels={carMakes} onchange={handleChange}>
            </c-filter-button>
        </div>
        <div class="slds-m-top_small">
            <lightning-datatable key-field="Id" data={contact.data} columns={columns} onsave={handleSave}
                draft-values={draftValues}></lightning-datatable>
        </div>
    </div>
</template>

Datatable Component JS

import { LightningElement, wire, track } from 'lwc';
import getCaseList from '@salesforce/apex/CasesController.getCaseList';
import { updateRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { refreshApex } from '@salesforce/apex'



const columns = [
    {label: 'Id', fieldName: 'Id', editable: false},
    {label: 'Case Number', fieldName: 'CaseNumber', editable: false},
    {
        label: 'Priority',
        fieldName: 'Priority',
        editable: true,
        actions: [{
                label: 'All',
                checked: true,
                name: 'all'
            },
            {
                label: 'Low',
                checked: false,
                name: 'Low'
            },
            {
                label: 'Medium',
                checked: false,
                name: 'Medium'
            },
            {
                label: 'High',
                checked: false,
                name: 'High'
            }
        ]
    },
    {
        label: 'Status',
        fieldName: 'Status',
        editable: true,
        actions: [{
                label: 'All',
                checked: true,
                name: 'all'
            },
            {
                label: 'Submitted',
                checked: false,
                name: 'Submitted'
            },
            {
                label: 'Active',
                checked: false,
                name: 'Active'
            },
            {
                label: 'Closed',
                checked: false,
                name: 'Closed'
            }
        ]
    },
    {label: 'Type', fieldName: 'Type', editable: true},
    {label: 'Subject', fieldName: 'Subject', editable: true},
    {label: 'Contact Email', fieldName: 'ContactEmail', type: 'email', editable: true},
]

export default class RefreshLWC extends LightningElement {

    // Initialize variables
    columns = columns;
    draftValues = [];
    // ALL_CASES = [];
    // cases = [];
    // contactResult = null;

    @track carMakes;
    @track allCars;
    @track selectedValues;
    @track hasProcessed = false;
    @track selectedCars;
    

    // Wire the getCaseList() method from Apex Controller
    @wire(getCaseList)
    contact;
    
    // // Use getCaseList to assign data to cases and ALL_CASES to be used when filtering
    // @track data;
    // @wire(getCaseList)
    // wiredCases({ error, data }) {
    //     if (data) {
    //         this.ALL_CASES = data;
    //         this.cases = data;
    //         console.log(this.cases)
    //         this.error = undefined;
    //     } else if (error) {
    //         this.error = error;
    //         this.contacts = undefined;
    //     }

    // }

    @wire(getCaseList)
    wiredCases({ error, data }) {
        if (data) {
            this.allCars = [];
            this.allCars = data;
            console.log(JSON.stringify(this.allCars));
            this.carMakes = [];
            this.carMakes.push('Active')
            this.carMakes.push('Submitted')
            this.carMakes.push('Closed')
            console.log(JSON.stringify(this.carMakes));
            this.filterCars();
            this.error = undefined;
        } else if (error) {
            this.error = error;
            this.allCars = undefined;
        }
    }

    handleChange(event) {
        this.selectedValues = event.detail;
        this.filterCars();
    }

    filterCars() {
        this.selectedCars = [];
        if(this.selectedValues) {
            for(var index in this.allCars) {
                var car = this.allCars[index];
                if (this.selectedValues.indexOf(car.make) >= 0) {
                    this.selectedCars.push(car);
                }
            }
        }
    }


    // Handle save event
    handleSave(event) {
        console.log(event.detail.draftValues);

        // Slice the draft values array
        const recordInputs = event.detail.draftValues.slice().map(draft => {
            const fields = Object.assign({}, draft)
            return {fields}
        })
        console.log("recordInputs", recordInputs)

        // Map recordInput to using the updateRecord method from uiRecordApi
        const promises = recordInputs.map(recordInput => updateRecord(recordInput))
        Promise.all(promises).then(result => {
            // On success show success message
            this.showToastMsg('Success', 'Cases Updated')
            // Clear out draft values
            this.draftValues = [];
            // Use refreshApex to update list view w/o refreshing the page
            return refreshApex(this.contact)
        }).catch(error => {
            // On error show error message
            this.showToastMsg('Error Updating Case', error.body.message, error)

        })
    }

    // Simple toast message to signals sucess or error
    showToastMsg(title, message, variant) {
        this.dispatchEvent(
            new ShowToastEvent({
                title: title,
                message: message,
                variant: variant || 'success'
            })
        )
    }

Filter Button Component Template

<template>
    <lightning-button-group>
        <template for:each={buttons} for:item="btn">
            <lightning-button 
                label={btn.label} 
                key={btn.label} 
                onclick={handleClick} 
                variant={btn.variant}
                >
            </lightning-button>
        </template>
    </lightning-button-group>
</template>

Filter Button Component JS

import { LightningElement, track, api } from 'lwc';

export default class FilterButton extends LightningElement {

    @api buttonLabels;
    @track buttons;
    @track hasRendered = false;
    @track selectedLabels;

    connectedCallback() {
        if (this.hasRendered == false) {
            this.hasRendered = true;
            this.selectedLabels = [];
            this.buttons = [];

            for (var index in this.buttonLabels) {
                var item = this.buttonLabels[index];
                this.buttons.push({
                    'label': item,
                    'variant': 'neutral',
                });
            }
        }
    }

    handleClick() {
        var selectedLabels = [];
        for(var index in this.buttons){
            var item = this.buttons[index];
            if (item.label == event.target.label){
                item.variant = (
                    item.variant == 'neutral'
                ) ? 'success' : 'neutral'
            }

            if(item.variant == 'success') {
                selectedLabels.push(item.label);
            }
        }

        this.selectedLabels = selectedLabels;
        this.dispatchEvent(new CustomEvent(
            'change', {
                detail: this.selectedLabels
            }
        ));
    }
}

App Builder View

My App Page names Custom List View

Inspecting the page and finding my filter button component

2
  • 1
    After saving the lightning page, have you activated it (either for the entire org or for relevant apps/ profiles)?
    – arut
    Commented Dec 21, 2020 at 14:45
  • @arut yes I activate and save the page after I add the data table with the filter buttons Commented Dec 21, 2020 at 15:36

1 Answer 1

0

on Load of the child (filterButton) component, buttonLabels variable will be null. since carMakes variable in the parent (Datatable) component will be null on load and is populated dynamically inside the wire property.

So, update the code inside the child component to handle changes for buttonLabels. Sample code below:

  _buttonLabels;

  @api 
  get buttonLabels() {
    return this._buttonLabels;
  }
  set buttonLabels(value) {
    this._buttonLabels = value;
    this.handleButtonLabels();
  }

  handleButtonLabels() {
    this.buttons = [];
    for (var index in this._buttonLabels) {
      var item = this._buttonLabels[index];
      this.buttons.push({
        'label': item,
        'variant': 'neutral',
      });
    }
  }
2
  • Also, update the code inside connectedCallBack method accordingly. Commented Dec 21, 2020 at 15:45
  • @H R so are you replacing my @api buttonLabels; with @api _buttonLabels; ? Commented Dec 21, 2020 at 16:19

You must log in to answer this question.

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