0

Below is the screenshot of my component on which i have a search lookup for account,when i select any account it should be added and displayed on the datatable. But after selecting any one account record when i select the second record or more they are added to my this.data variable but not displaying on the lightning datatable. Please help!

enter image description here

enter image description here

Lookup.js

 import { LightningElement, api, track } from 'lwc';
import retrieveRecords from '@salesforce/apex/MultiSelectTypeAheadController.fetchLookUpValues';

export default class InsurersLookup extends LightningElement {

    @api selectAll = false ;
    @track globalSelectedItems = []; //holds all the selected checkbox items
    @api picklistlabel ;
    @api objectApiName = '';
    @api iconName = 'standard:account';
    @track items = []; //holds all records retrieving from database
    @track selectedItems = []; //holds only selected checkbox items that is being displayed based on search

    //since values on checkbox deselection is difficult to track, so workaround to store previous values.
    //clicking on Done button, first previousSelectedItems items to be deleted and then selectedItems to be added into globalSelectedItems
    @track previousSelectedItems = []; 
    @track value = []; //holds checkbox values (Ids) which will be shown as selected
    searchInput ='';    //captures the text to be searched from user input
    isDialogDisplay = false; //based on this flag dialog box will be displayed with checkbox items
    isDisplayMessage = false; //to show 'No records found' message   
    @api values = [];
    @api fetchkey ='';
    @api customimplementationname ='';

    @track accountData = []; //will store selected accounts data
    @track data;
    @track accountColumns = [
        { label: 'Account Name', fieldName: 'Name' },
        {label : 'Industry', fieldName : 'Industry'},
        {label : 'Phone', fieldName : 'Phone'}
    ];
    
    //This method is called when user enters search input. It displays the data from database.
    onchangeSearchInput(event){
        const excludingIds = [];
        this.searchInput = event.target.value;
        console.log('this.searchInput : '+this.searchInput);
        if(this.accountData.length){
            this.accountData.forEach((item) => {
                excludingIds.push(item.Id);
            });
        }
        if(this.searchInput.trim().length>0){
            retrieveRecords({
                datasetName: this.customimplementationname,
                key: this.fetchkey,
                searchKeyWord: this.searchInput,
                lstExcludeitems: excludingIds
                })
            .then(result=>{
                console.log('result: '+JSON.stringify(result));
                
                this.items = []; //initialize the array before assigning values coming from apex
                this.value = [];
                this.previousSelectedItems = [];
                if(result.length>0){
                    this.items = result;
                    this.isDialogDisplay = true; //display dialog
                    this.isDisplayMessage = false;
                }
                else{
                    //display No records found message
                    this.isDialogDisplay = false;
                    this.isDisplayMessage = true;
                }
            })
            .catch(error=>{
                this.error = error;
                this.items = undefined;
                this.isDialogDisplay = false;
            })
        }else{
            this.isDialogDisplay = false;
            this.items = [];
        }                
    }

    // Event on Lookup record Selection
    onRecordSelection(event){
        console.log('Inside');
        
        //remove previous selected items first as there could be changes in checkbox selection
        for(var index = 0; index < this.items.length; index++){
            if(this.items[index].Id === selectedRecordId){
                this.accountData.push(this.items[index]);
                this.items.splice(index, 1);
            }
        }
        this.data = this.accountData;
        console.log('this.data : '+JSON.stringify(this.data));
    }

    // Event on Lookup record Remove
    onRecordRemove(event){
        const selectedRecordId = event.currentTarget.dataset.id;
        //console.log('Account Id that need to be Remove from the Table: '+selectedRecordId);
        var index=0;
        //remove previous selected items first as there could be changes in checkbox selection
        this.accountData.forEach((acc) => {
            if(acc.Id === selectedRecordId) {
                if (index > -1) {
                    this.accountData.splice(index, 1);
                }
            }
            index++;
        });
    }

    /**
    *@description: Below all methods are not using in the JS file
    */
    @api
    selectAllValues(selectAllValue){
        this.selectAll = selectAllValue;
        const selectAll = this.selectAll;

        //initialize values again
        this.initializeValues();
        this.value =[];
        this.globalSelectedItems = [];
        this.template.querySelectorAll('[data-id="selectall"]')[0].checked = selectAll;
        const evtCustomEvent = new CustomEvent('selectall', {   
            detail: {selectAll}
        });
        this.dispatchEvent(evtCustomEvent);
    }

    handleSelectAll(event){
        this.selectAllValues(event.target.checked);
    }

    //This method is called during checkbox value change
    handleCheckboxChange(event){
        let selectItemTemp = event.detail.value;
        //all the chosen checkbox items will come as follows: selectItemTemp=0032v00002x7UE9AAM,0032v00002x7UEHAA2
        this.selectedItems = []; //it will hold only newly selected checkbox items.        
        
        /* find the value in items array which has been prepared during database call
           and push the key/value inside selectedItems array           
        */
        selectItemTemp.map(p=>{            
            let arr = this.items.find(element => element.value == p);
            if(arr != undefined){
                this.selectedItems.push(arr);
            }  
        });
    }

    //this method removes the pill item
    handleRemoveRecord(event){        
        const removeItem = event.target.dataset.item;        
        //this will prepare globalSelectedItems array excluding the item to be removed.
        this.globalSelectedItems = this.globalSelectedItems.filter(item => item.value  != removeItem);
        const arrItems = this.globalSelectedItems;

        //initialize values again
        this.initializeValues();
        this.value =[]; 

        //propagate event to parent component
        const evtCustomEvent = new CustomEvent('remove', {   
            detail: {removeItem,arrItems}
        });
        this.dispatchEvent(evtCustomEvent);
    }

    //Done dialog button click event prepares globalSelectedItems which is used to display pills
    handleDoneClick(event){
        //remove previous selected items first as there could be changes in checkbox selection
        this.previousSelectedItems.map(p=>{
            this.globalSelectedItems = this.globalSelectedItems.filter(item => item.value != p.value);
        });
        
        //now add newly selected items to the globalSelectedItems
        this.globalSelectedItems.push(...this.selectedItems);        
        const arrItems = this.globalSelectedItems;
        //store current selection as previousSelectionItems
        this.previousSelectedItems = this.selectedItems;
        this.initializeValues();      
        
        //propagate event to parent component
        const evtCustomEvent = new CustomEvent('retrieve', { 
            detail: {arrItems}
        });
        this.dispatchEvent(evtCustomEvent);
    }

    @api
    setSelectedValues(selectedOptions) {
        this.globalSelectedItems = [];
        selectedOptions.forEach(elem => {
            this.globalSelectedItems.push(elem);
        });
        const arrItems = this.globalSelectedItems;
        //store current selection as previousSelectionItems
        this.previousSelectedItems = selectedOptions;
        this.selectedItems  = selectedOptions;
        this.initializeValues();
    }

    //Cancel button click hides the dialog
    handleCancelClick(event){
        this.initializeValues();
    }

    //initialize values after performing operations
    initializeValues(){
        this.searchInput = '';        
        this.isDialogDisplay = false;
    }
    
    @api
    validateInputs(){
        var inputCmp = this.template.querySelector(".validate");
        var selectAllCmp = this.template.querySelector(".validateCheckbox");
        if (this.globalSelectedItems.length > 0 || selectAllCmp.checked ) {             
            inputCmp.setCustomValidity("");
            inputCmp.reportValidity();
            return true;
        } else {
            inputCmp.setCustomValidity("Please select atleast one option");
            inputCmp.reportValidity();
            return false;
        }
    }
}

Lookup.html

<template>
    <div class="slds-form-element">
        <label class="slds-form-element__label" for="combobox-id-4">Insurers</label>
        <div class="slds-form-element__control">
            <div class="slds-combobox-group slds-has-selection">
                <div class="slds-combobox_object-switcher slds-combobox-addon_start">
                    <div class="slds-form-element">
                        <label class="slds-form-element__label slds-assistive-text" for="combobox-id-5"></label>
                        <div class="slds-form-element__control">
                            <div class="slds-combobox_container">
                                <div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click"
                                    aria-controls="primary-combobox-id-4" aria-expanded="false" aria-haspopup="listbox"
                                    role="combobox">
                                    <div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right"
                                        role="none">
                                        <input type="text"
                                            class="slds-input slds-combobox__input slds-combobox__input-value"
                                            id="combobox-id-5" aria-controls="objectswitcher-listbox-id-01"
                                            autocomplete="off" role="textbox" placeholder=" " value="Accounts" />
                                        <span
                                            class="slds-icon_container slds-icon-utility-down slds-input__icon slds-input__icon_right">
                                            <svg class="slds-icon slds-icon slds-icon_xx-small slds-icon-text-default"
                                                aria-hidden="true">
                                                <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#down"></use>
                                            </svg>
                                        </span>
                                    </div>
                                    <div id="objectswitcher-listbox-id-01"
                                        class="slds-dropdown slds-dropdown_length-5 slds-dropdown_x-small slds-dropdown_left"
                                        role="listbox">
                                        <ul class="slds-listbox slds-listbox_vertical" role="group"
                                            aria-label="Suggested for you">
                                            <li role="presentation" class="slds-listbox__item">
                                                <div aria-checked="true" id="object1"
                                                    class="slds-media slds-listbox__option slds-listbox__option_plain slds-media_small slds-is-selected"
                                                    role="option">
                                                    <span class="slds-media__figure slds-listbox__option-icon">
                                                        <span
                                                            class="slds-icon_container slds-icon-utility-check slds-current-color">
                                                            <svg class="slds-icon slds-icon_x-small" aria-hidden="true">
                                                                <use
                                                                    xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#check">
                                                                </use>
                                                            </svg>
                                                        </span>
                                                    </span>
                                                    <span class="slds-media__body">
                                                        <span class="slds-truncate" title="Accounts">Accounts</span>
                                                    </span>
                                                </div>
                                            </li>
                                        </ul>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="slds-combobox_container slds-combobox-addon_end">
                    <div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open"
                        aria-expanded="true" aria-haspopup="listbox" id="primary-combobox-id-4" role="combobox">
                        <div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right" role="none">
                            <lightning-input class="validate" id="input" disabled={selectAll}
                                value={searchInput} onchange={onchangeSearchInput} variant="label-hidden" aria-autocomplete="list" role="textbox"
                                autocomplete="off" placeholder="Search..." type="search">
                            </lightning-input>
                            <span
                                class="slds-icon_container slds-icon-utility-search slds-input__icon slds-input__icon_right"
                                title="Description of icon when needed">
                                <svg class="slds-icon slds-icon slds-icon_x-small slds-icon-text-default"
                                    aria-hidden="true">
                                    <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#search"></use>
                                </svg>
                                <span class="slds-assistive-text">Description of icon when needed</span>
                            </span>
                        </div>
                        <div class="slds-dropdown slds-dropdown_length-with-icon-7 slds-dropdown_fluid" role="listbox">
                            <template if:true={isDialogDisplay}>
                                <ul class="slds-listbox slds-listbox_vertical" role="presentation">
                                    <template for:each={items} for:item="item" key={item}>
                                        <div key={item} data-key={item} >
                                            <c-re-Usable-Multi-Select-Lookup-Result objrec={item} onrecordselection={onRecordSelection} onselectall={handleOnChange} picklistlabel="Insurers" onretrieve={addSelectedItems} onremove={removeSelectedItems}></c-re-Usable-Multi-Select-Lookup-Result>
                                        </div>
                                    </template>
                                </ul>
                            </template>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div>
        <!--Show Selected Account records-->
        <template if:true={accountData}>
            
            <!--Lightning DataTable-->
            <lightning-card>
                <lightning-datatable 
                key-field="Id"
                data={data} 
                columns={accountColumns}>
            </lightning-datatable>
            </lightning-card>
        </template>
    </div>
</template>
2

In the method onRecordSelection you add the elements to accountData then you have this line:
this.data = this.accountData; Both accountData and data hold the reference to the same array, so now matter which one you modify, you'll see the changes in the other one too because there is only one array.
That's why the second time you run this.data = this.accountData; nothing changes.
You're replacing the value (the reference) stored in data with itself.

In order to update the table you have to change that value (the reference). You can do that creating a new array with the same content.
Instad of this.data = this.accountData; you should write this.data = [...this.accountData];

1
0

Update key-field attribute to 'Id' from 'id'.

The key-field attribute is required for correct table behavior. It associates each row with a unique identifier.

3
  • I did it but still no luck. – Indresh Bhargav Jan 4 at 16:08
  • @IndreshBhargav could you please update the question with complete code. – H R Jan 4 at 16:14
  • I have edited the question. You can check now! – Indresh Bhargav Jan 4 at 16:19

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.