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. – rahul gawale Jun 17 '20 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 Jun 17 '20 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 Jun 17 '20 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. – rahul gawale Jun 17 '20 at 18:02
  • @rahulgawale i replaced querySelector with querySelectorAll, [NoErrorObjectAvailable] Script error. displays again. – Ertyq Jun 18 '20 at 3:59
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 Jun 18 '20 at 13:23
  • can you please create a playground with some dummy data? @Ertyq – rahul gawale Jun 18 '20 at 13:49
  • Will do. Let me prepare it first, then will let you know immediately. How can I share credentials to you? – Ertyq Jun 18 '20 at 14:14
  • 1
    @Ertyq I have updated the answer, also check the linked playground. – rahul gawale Jun 18 '20 at 17:22
  • 1
    this.template.querySelectorAll works but not suitable for this scenario, also it returns a array of elements – rahul gawale Jun 18 '20 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.