•  

    Dynamic ComboBox In LWC

    Hi All,

    Please find my POC on building Dynamic Combobox in LWC which supports Data injection , hence it can be used within existing aura components for performance issues faced when using dealing with the larger dataset. It also supports Dynamic SOQL when the values are to be queried from the server. Lastly, it can replace all those apexes written to get picklist filters in the aura by using wire adapters in LWC. It is a plug and play model wherein based on the config passed it will perform either of the three operations.

    Author: Somnath Sharma

     

    In the container component all the three use cases are demonstrated.The lwcConfig  has properties to support where clause,limit clause and Order By clause.If the rowsdata array length is not greater than 0 or the lwcConfig.getDataFromServer is not set to true then picklist values are displayed based on the Sobject API name and picklist field.  

    <!--
    
      @File Name          : containerLWCTabComponent.html
    
      @Description        : 
    
      @Author             : Somnath Sharma
    
      @Group              : 
    
      @Last Modified By   : Somnath Sharma
    
      @Last Modified On   : 2/25/2020, 10:08:34 PM
    
      @Modification Log   : 
    
      Ver       Date            Author                  Modification
    
      1.0    2/25/2020   Somnath Sharma     Initial Version
    
    -->
    
    <template>
    
        <div class="slds-page-header">
    
            <div class="slds-page-header__row">
    
                <div class="slds-page-header__col-title slds-text-heading_large slds-text-align_center ">
    
                    {pageHeader}
    
                </div>
    
            </div>
    
        </div>
    
        
    
        <div class="slds-box slds-text-align_center slds-p-top_xx-small slds-m-top_xx-small">
    
            <div class="slds-page-header slds-page-header__col-title" style="font-size: large;
    
                font-weight: bold;font-style: italic;">Combo Box Query data from Server</div>
    
            <c-dynamic-filters-based-on-combo-box lwc-config={lwcConfig}></c-dynamic-filters-based-on-combo-box>
    
        </div>
    
    
        <div class="slds-box slds-text-align_center slds-p-top_xx-small slds-m-top_xx-small">
    
            <div class="slds-page-header slds-page-header__col-title" style="font-size: large;
    
                font-weight: bold;font-style: italic;">Data Injection To comboBox</div>
    
            <c-dynamic-filters-based-on-combo-box rowsdata={_dataInjection}></c-dynamic-filters-based-on-combo-box>
    
        </div>
    
    
        <div class="slds-box slds-text-align_center slds-p-top_xx-small slds-m-bottom_x-large">
    
            <div class="slds-page-header slds-page-header__col-title" style="font-size: large;
    
                font-weight: bold;font-style: italic;">wire adapter to get the picklist values for a specified field.</div>
    
            <c-dynamic-filters-based-on-combo-box objectapiname="Account" picklistfield="Account.Industry">
    
            </c-dynamic-filters-based-on-combo-box>
    
        </div>
    
    </template>
    
    
    /**
    
     * @File Name          : containerTabComponent.js
    
     * @Description        : 
    
     * @Author             : Somnath Sharma
    
     * @Group              : 
    
     * @Last Modified By   : Somnath Sharma
    
     * @Last Modified On   : 1/3/2020, 1:31:39 pm
    
     * @Modification Log   : 
    
     * Ver       Date            Author                 Modification
    
     * 1.0    2/25/2020   Somnath Sharma     Initial Version
    
     **/
    
    import {
    
        LightningElement
    
    } from 'lwc';
    
    
    export default class ContainerTabComponent extends LightningElement {
    
        pageHeader = 'Container LWC Tab Component';
    
        _dataInjection = ['Option 1', 'Option 2', 'Option 3', 'Option 4', 'Option 5'];
    
        connectedCallback() {
    
            //query data From Server
    
            this.lwcConfig = {
    
                getDataFromServer: true,
    
                sObjectApiName: 'Account',
    
                whereClause: 'Type =\'Prospect\'',
    
                orderByClause: 'ORDER BY LastModifiedDate ASC',
    
                limitClause: 0
    
            };
    
        }
    
    }
    
    <!--
    
      @File Name          : dynamicFiltersBasedOnComboBox.html
    
      @Description        : 
    
      @Author             : Somnath Sharma
    
      @Group              : 
    
      @Last Modified By   : Somnath Sharma
    
      @Last Modified On   : 2/25/2020, 9:33:55 PM
    
      @Modification Log   : 
    
      Ver       Date            Author                  Modification
    
      1.0    2/25/2020   Somnath Sharma     Initial Version
    
    -->
    
    <template>
    
        <div class="slds-dropdown-trigger slds-dropdown-trigger_click" if:true={renderComboBox}>
    
            <lightning-combobox name="progress" label={comboBoxLabel} value={value} placeholder={placeholderValue}
    
                options={options} onchange={handleChange} dropdown-alignment={dropdownAlignmentValue}>
    
            </lightning-combobox>
    
        </div>
    
        <div if:false={renderComboBox}>
    
            {comboBoxLabel}
    
        </div>
    
    </template>
    
    /**
    
     * @File Name          : dynamicFiltersBasedOnComboBox.js
    
     * @Description        : 
    
     * @Author             : Somnath Sharma
    
     * @Group              : 
    
     * @Last Modified By   : Somnath Sharma
    
     * @Last Modified On   : 2/25/2020, 10:21:11 PM
    
     * @Modification Log   : 
    
     * Ver       Date            Author                 Modification
    
     * 1.0    2/25/2020   Somnath Sharma     Initial Version
    
     **/
    
    
    import {
    
        LightningElement,
    
        api,
    
        wire,
    
        track
    
    } from 'lwc';
    
    import {
    
        getObjectInfo
    
    } from 'lightning/uiObjectInfoApi';
    
    import {
    
        getPicklistValues
    
    } from 'lightning/uiObjectInfoApi';
    
    //import method from the Apex Class
    
    import getDataBasedOnSobject from '@salesforce/apex/DynamicFilterController.getDataBasedOnSobject';
    
    
    export default class DynamicFiltersBasedOnComboBox extends LightningElement {
    
    
        value = '';
    
        @track options = [];
    
        /**Data To be passed to Combox Box */
    
        @api rowsdata = [];
    
        /** name of combobox*/
    
        @api comboBoxLabel = '';
    
        /** Alignment of drop down top or bottom*/
    
        @api dropdownAlignmentTop = false;
    
        /** palceholdervalue for combo Box*/
    
        @api placeholderValue = 'Select an Option';
    
        /** dropdown value derieved to align the drop down contents*/
    
        dropdownAlignmentValue;
    
        /** config params to query data from Server*/
    
        @api lwcConfig = {
    
            getDataFromServer: false,
    
            sObjectApiName: '',
    
            whereClause: '',
    
            orderByClause: '',
    
            limitClause: 0
    
        };
    
    
        /**************UI Wire Services Chained So as to get the picklist Values  */
    
        @api objectapiname;
    
        @api picklistfield;
    
        defaultRecordTypeId; //Master  Record Type Id
    
    
        @wire(getObjectInfo, {
    
            objectApiName: '$objectapiname'
    
        })
    
        wiredObjectInfo({
    
            error,
    
            data
    
        }) {
    
            if (data) {
    
                console.log('ObjectInfo' + JSON.stringify(data));
    
                this.record = data.recordTypeInfos;
    
                this.defaultRecordTypeId = data.defaultRecordTypeId;
    
                this.error = undefined;
    
            } else if (error) {
    
                this.error = error;
    
                this.record = undefined;
    
            }
    
        }
    
    
        @wire(getPicklistValues, {
    
            recordTypeId: '$defaultRecordTypeId',
    
            fieldApiName: '$picklistfield'
    
        })
    
        wiredPicklistInfo({
    
            error,
    
            data
    
        }) {
    
            if (data) {
    
                console.log('picklist' + JSON.stringify(data.values));
    
                this.processPicklistRawJSON(data.values);
    
            } else if (error) {
    
                console.log(JSON.stringify(error));
    
            }
    
        }
    
    
        /**************UI Wire Services Chained So as to get the picklist Values  */
    
    
        connectedCallback() {
    
    
            this.dropdownAlignmentValue = this.dropdownAlignmentTop ? 'bottom-left' : 'auto';
    
    
            if (this.lwcConfig.getDataFromServer) {
    
                window.console.log(this.comboBoxLabel);
    
                window.console.time("Std server lwc processing");
    
                this.processConfig();
    
                window.console.timeEnd("Std server lwc processing");
    
            } else if (this.rowsdata.length > 0) {
    
                window.console.log('DATA-INJECTION-FROM-CALLING-COMPONENT---->>>>>' + this.rowsdata.length);
    
                this.setOptions(this.rowsdata);
    
            }
    
    
        }
    
    
        /**query data from server if data is not passed from calling component */
    
        processConfig() {
    
            //if lwcConfig.getDataFromServer is set 
    
            this.queryRows();
    
    
        }
    
    
        queryRows() {
    
            //imperative callback to get data from server on demand
    
            getDataBasedOnSobject({
    
                    sobjectName: this.lwcConfig.sObjectApiName,
    
                    whereClause: this.lwcConfig.whereClause,
    
                    orderByClause: this.lwcConfig.orderByClause,
    
                    limitClause: this.lwcConfig.limitClause
    
                })
    
                .then(result => {
    
                    //window.console.log('LwcDataFromCallingCmpServer---->>>>>' + JSON.stringify(result));
    
                    this.setOptions(result);
    
                })
    
                .catch(error => {
    
                    this.error = error;
    
                });
    
        }
    
    
        setOptions(_rawData) {
    
            //  window.console.log('OptionsDataFromCallingCmp---->>>>>' + JSON.stringify(_rawData));
    
            let isQueryRows = false;
    
            if (this.lwcConfig.getDataFromServer) {
    
                isQueryRows = true;
    
            }
    
            this.options = _rawData.map(row => {
    
                return {
    
                    label: isQueryRows ? row.Name : row,
    
                    value: isQueryRows ? row.Id : row
    
                };
    
            });
    
            window.console.log('->>>>>>length of array-->>>>>>>' + this.options.length);
    
    
        }
    
    
        //render the component after all the processing is done
    
        get renderComboBox() {
    
            return this.options.length > 0 ? true : false;
    
        }
    
    
        /*fire event on change of drop down value and pass is to called component 
    
        where the event can be handled to capture the selected value*/
    
        handleChange(event) {
    
    
            let selectedOption = this.options.find(item => item.value === event.detail.value);
    
            window.console.log('dropdownlabel', selectedOption.label);
    
            window.console.log('dropdownValue', event.detail.value);
    
            let filters = {
    
                selectedvalue: event.detail.value,
    
                selectedLableValue: selectedOption.label,
    
                dropDownClicked: this.comboBoxLabel
    
            };
    
            const filterChangeEvent = new CustomEvent('filterchange', {
    
                detail: {
    
                    filters
    
                },
    
            });
    
            // Fire the custom event
    
            this.dispatchEvent(filterChangeEvent);
    
        }
    
    
        processPicklistRawJSON(_rawData) {
    
            this.options = _rawData.map(row => {
    
                return {
    
                    label: row.label,
    
                    value: row.value
    
                };
    
            });
            console.log('picklistprocessed' + JSON.stringify(this.options));
        }
    }
    
    
    public with sharing class DynamicFilterController {
    
    
    @AuraEnabled
    
        public static List<SObject> getDataBasedOnSobject(String sobjectName,String whereClause,
    
                                                          String orderByClause,Integer limitClause){
    
            List<SObject>  sObjectRowsList=new List<SObject>();
    
            String query='Select Name From';
    
            System.debug('sobjectName' +sobjectName);
    
            query=query+' '+sobjectName+' Where '+whereClause;
    
            if(String.isNotBlank(orderByClause)){
    
               query=query+' '+orderByClause+' ';
    
            }
    
           if(limitClause>0){
    
               query=query+' '+'Limit '+limitClause;
    
            } 
    
            system.debug('Final QUERY-->'+query);
    
            sObjectRowsList = Database.query(query);
    
            System.debug('Rows'+sObjectRowsList);
    
          return sObjectRowsList;
    
        }
    
      }

Comments

  •  
    icon

    Eric Smith says (Mar 2, 2020):

    I would like to test this out. Can you share the code for the Apex DynamicFilterController?

  •  
    icon

    Somnath says (Mar 11, 2020):

    I have shared the code.

  •  
    icon

    qe says (Jul 15, 2020):

    eqweeeeeeee

  •  
    icon

    B.J.Suraj says (Jul 15, 2020):

    how can we create to or more than two picklist in lwc

Post Comments