2

I am trying to show/hide columns based on selected picklist value from Picklist 3 filter.

Example:

Assuming that value is Type 1, table should be like this:

enter image description here

Assuming that value is Type 2, table should be like this:

enter image description here

If Picklist 3 value is changed to All, table should be like this:

enter image description here

There are no error messages upon saving and deploying codes to the org, but each time I select a Picklist 3 value, I encounter this message:

enter image description here

I also inspected browser's developer console for some javascript errors, and I got

OTS parsing error: invalid version tag

This doesn't make sense to me since I haven't encountered any errors when compiling it via Visual Studio Code.

Meanwhile, here are the current codes I have:

accountLWC.html

<template>  
    
    <div>
        <lightning-combobox
            class="slds-m-bottom_small slds-m-left_small"
            name="box2"
            label="Picklist 2"
            value={picklist2Value}
            placeholder="--None--"
            options={picklist2Options}
            onchange={findAccountResult} >
        </lightning-combobox>  
        <lightning-combobox
            class="slds-m-bottom_small slds-m-left_small"
            name="box3"
            label="Picklist 3"
            value={picklist3Value}
            placeholder="--None--"
            options={picklist3Options}
            onchange={displayCol}>
        </lightning-combobox>      
    </div>    
    
    <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_col-bordered">
        <thead>
            <tr class="slds-line-height_reset">
                <th scope="col">
                    <div class="slds-truncate" title="accountPicklist1">Picklist 1</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="accountName">Account Name</div>
                </th>  
                <th scope="col">
                    <div class="slds-truncate" title="accountPicklist2">Picklist 2</div>
                </th>  
                <th class="type1" scope="col">
                    <div class="slds-truncate" title="type1Header">Type 1</div>
                </th>  
                <th class="type2" scope="col">
                    <div class="slds-truncate" title="type2Header">Type 2</div>
                </th>  
            </tr>
        </thead>
        
        <tbody>
           
            <template if:true={mapData}>
                <template for:each={mapData} for:item="keyValue">
                    <tr key={keyValue.key} class="slds-hint-parent">
                        <th scope="col">
                            <div>{keyValue.key}</div>
                        </th>
                        <th scope="col">
                            <template for:each={keyValue.value} for:item="mapValue">
                                <div key={mapValue.Name}>
                                    {mapValue.Name}
                                </div> 
                            </template>
                        </th>
                        <th scope="col">
                            <template for:each={keyValue.value} for:item="mapValue2">
                                <div key={mapValue2.Picklist2}>
                                    {mapValue2.Picklist2}
                                </div> 
                            </template>
                        </th>
                        <th class="type1" scope="col">
                            <template for:each={keyValue.value} for:item="mapValue3">
                                <div key={mapValue3.CustomTextField}>
                                    {mapValue3.CustomTextField}
                                </div> 
                            </template>
                        </th>
                        <th class="type2" scope="col">
                            <template for:each={keyValue.value} for:item="mapValue3">
                                <div key={mapValue3.CustomTextField}>
                                    {mapValue3.CustomTextField}
                                </div> 
                            </template>
                        </th>
                    </tr>
                </template>
            </template> 
        </tbody>
        
    </table>
    
    <center>
        <template if:true= {noRecordsFound}>
            --No Account Records Found--
        </template>
    </center>
</template>

accountLWC.js

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

import getDataFromApex from '@salesforce/apex/AccountController.getAccountData';

export default class accountLWC extends LightningElement {

    @track mapData = [];

    @track noRecordsFound = true;

    @track picklist2Value = '--None--';

    @track picklist3Value = '--None--';

    @track picklist2Options = [
        {value: 'A', label: 'A'},
        {value: 'B', label: 'B'},
        {value: 'C', label: 'C'}
    ];

    @track picklist3Options = [
        {value: 'All', label: 'All'},
        {value: 'Type 1', label: 'Type 1'},
        {value: 'Type 2', label: 'Type 2'}
    ];

    findAccountResult(event) {
        const accPicklist2 = event.target.value;

        if(accPicklist2) {
            getDataFromApex ( {accPicklist2}) 
            .then(result => {
            
                if(result) {
                    for(var key in result) {
                        let tempMapData = [];
                        tempMapData.push({key:key,value:result[key]});
                        this.noRecordsFound = false;
                        
                    }   
                    this.mapData = tempMapData;      
                }
                                 
            })
        } 
        else {
            this.mapData = undefined;
            this.noRecordsFound = true;
        }
    }

    displayCol(event) {
        const picklist3 = event.detail.value;    

        if(picklist3 === 'Type 1') {
            this.template.querySelectorAll(".type1").style.display = "block";
            this.template.querySelectorAll(".type2").style.display = "none";
        }
        else if(picklist3 === 'Type 2') {
            this.template.querySelectorAll(".type1").style.display = "none";
            this.template.querySelectorAll(".type2").style.display = "block";
        else {
            this.template.querySelectorAll(".type1").style.display = "block";
            this.template.querySelectorAll(".type2").style.display = "block";
        }
    }

}

AccountController.cls

public class AccountController{

    @AuraEnabled

    public static Map<String, List<AccountWrapper>> getAccountData(String accPicklist2) 
    {
   
     Map<String, List<AccountWrapper>> mapPicklist1 = new Map<String, List<AccountWrapper>>();
     Map<String, Integer> accPicklist1CountMap = new Map<String, Integer>();
     

     List<Account> accountList = [SELECT Name, Picklist1__c, Picklist2__c, Custom_Text_Field__c
            FROM Account 
            WHERE Picklist1__c != null AND Picklist2__c =: accPicklist2 
            ORDER BY Picklist1__c];       
         

     for(Account accObj:accountList)
     {
      List<AccountWrapper> accWrapperList = new List<AccountWrapper>();
      
      if(mapPicklist1.containsKey(accObj.Picklist1__c))
      {
       
       accWrapperList = mapPicklist1.get(accObj.Picklist1__c);
       
       
       accWrapperList.add(new AccountWrapper(accObj));
       
       mapPicklist1.put(accObj.Picklist1__c, accWrapperList);
       
      
       accPicklist1CountMap.put(accObj.Picklist1__c, accWrapperList.size());
      }
      else
      {
       
       accWrapperList.add(new AccountWrapper(accObj));
       mapPicklist1.put(accObj.Picklist1__c, accWrapperList);
       
       
       accPicklist1CountMap.put(accObj.Picklist1__c, accWrapperList.size());
      }
     }
     
     return mapPicklist1;

    }
   
    public Class AccountWrapper {
     
     public AccountWrapper(Account acc)
     {
      this.Name = acc.Name;
      this.Picklist1 = acc.Picklist1__c;
      this.Picklist2 = acc.Picklist2__c;
      this.CustomTextField = acc.Custom_Text_Field__c;
     }
     
     @AuraEnabled
     public String Name {get;set;}
     @AuraEnabled
     public String Picklist1 {get;set;}
     @AuraEnabled
     public String Picklist2 {get;set;}
     @AuraEnabled
     public String CustomTextField {get;set;}
     
    }

    
   }

This is the first time I encountered such issue, even refreshing the page does not do anything about it. I hope anyone could help me on this.

5
  • please use this.template.querySelector(".type1") instead of document.getElementsByClassName('type1') using this is not a best practice. Commented Jun 17, 2020 at 16:22
  • @rahulgawale thanks for your response! Let me try your suggestion first. But may I know why this document.getElementsByClassName('type1') is not best practice at all? Does this have conflict when implemented with Salesforce lwc?
    – Ertyq
    Commented Jun 17, 2020 at 17:00
  • @rahulgawale I modified the code and replaced previous with this.template.querySelector(".type1") but upon clicking a picklist value, columns are not hidden. Also, columns that should be hidden are duplicated.
    – Ertyq
    Commented Jun 17, 2020 at 17:24
  • the reason you can find here. Also I just realized that you need all of the components so use querySelectorAll so you get the list of all elements. Commented Jun 17, 2020 at 18:02
  • @rahulgawale i replaced querySelector with querySelectorAll, [NoErrorObjectAvailable] Script error. displays again.
    – Ertyq
    Commented Jun 18, 2020 at 3:59

1 Answer 1

2

The common cause of this error is the null pointer exception. You need to use event.detail.value to get the value from the picklist. Also, you don't need to do this picklist3.value.

Also, you don't need to set visibility by manipulating the DOM. instead of that create reactive properties to show/hide the elements.

Setting display style will hide the element but it will leave empty space.

Follow the below steps.

Create reactive properties for the columns.

//...
showType1 = true;
showType2 = true;
//....

Refer them in HTML

<th class="type1" if:true={showType1} scope="col">
    <div class="slds-truncate" title="type1Header">Type 1</div>
</th>  
<th class="type2" if:true={showType2} scope="col">
    <div class="slds-truncate" title="type2Header">Type 2</div>
</th> 
 ...
 ...

<th if:true={showType1} class="type1" scope="col">
    <template for:each={keyValue.value} for:item="mapValue3">
        <div key={mapValue3.CustomTextField}>
            {mapValue3.CustomTextField}
        </div>
    </template>
</th>
<th if:true={showType2} class="type2" scope="col">
    <template for:each={keyValue.value} for:item="mapValue3">
        <div key={mapValue3.CustomTextField}>
            {mapValue3.CustomTextField}
        </div>
    </template>
</th>

Change the values based on picklist

displayCol(event) {
    const picklist3 = event.detail.value;
    if (picklist3 === 'Type 1') {
        this.showType1 = true;
        this.showType2 = false;
    } else if (picklist3 === 'Type 2') {
        this.showType1 = false;
        this.showType2 = true;
    } else {
        this.showType1 = true;
        this.showType2 = true;
    }
}

Here is the playgorund

8
  • I modified javascript file based on your answer, but same script error occurs. Code has been updated, please check,
    – Ertyq
    Commented Jun 18, 2020 at 13:23
  • can you please create a playground with some dummy data? @Ertyq Commented Jun 18, 2020 at 13:49
  • Will do. Let me prepare it first, then will let you know immediately. How can I share credentials to you?
    – Ertyq
    Commented Jun 18, 2020 at 14:14
  • 1
    @Ertyq I have updated the answer, also check the linked playground. Commented Jun 18, 2020 at 17:22
  • 1
    this.template.querySelectorAll works but not suitable for this scenario, also it returns a array of elements Commented Jun 18, 2020 at 18:00

You must log in to answer this question.

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