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
}
));
}
}