Recently i have worked on " multi select picklist" component required for my project. Showing you how to create it using LWC and hopefully you can use this component as your need.
it looks great and work beautifully , Lets enjoy ..!
multiselectdropdown.html
it looks great and work beautifully , Lets enjoy ..!
multiselectdropdown.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <template> <div class="slds-form-element"> <label class="slds-form-element__label" for="combobox-id-5">Relate to</label> <div class="slds-form-element__control"> <div class="slds-combobox_container slds-size_small"> <section id="maindiv" class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open" aria-expanded="true" aria-haspopup="listbox" role="combobox"> <div onclick={handleClick} onmouseleave={handleMouseOut} 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-has-focus slds-combobox__input-value" id="combobox-id-5" aria-controls="listbox-id-5" role="textbox" placeholder={defaultText} readonly="" /> <span class="slds-icon_container slds-icon-utility-down slds-input__icon slds-input__icon_right"> <lightning-icon icon-name="utility:down" size="x-small" alternative-text="Approved"></lightning-icon> </span> </div> <template if:true={iswindowOpen}> <div onmouseenter={handlemouseOver} onmouseleave={handleMouseLeave} id="listbox-id-5" class="slds-dropdown slds-dropdown_length-5 slds-dropdown_fluid" role="listbox"> <ul class="slds-listbox slds-listbox_vertical" role="presentation"> <template for:each={_options} for:item="option"> <c-list-items key={option.value} value={option.value} label={option.label} selected={option.selected} onselected={handleSelectedClick}></c-list-items> </template> </ul> </div> </template> </section> </div> </div> </div> </template> |
multiselectdropdown.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | import { LightningElement, api, track } from 'lwc'; export default class Multiselectdropdown extends LightningElement { @api options = [{label:'Resource 1',value:'Resource 1',selected:false}, {label:'Resource 2',value:'Resource 2',selected:false}, {label:'Resource 3',value:'Resource 3',selected:false}, {label:'Resource 4',value:'Resource 4',selected:false}, {label:'Resource 5',value:'Resource 5',selected:false}, {label:'Resource 6',value:'Resource 6',selected:false}, {label:'Resource 7',value:'Resource 7',selected:false}, {label:'Resource 8',value:'Resource 8',selected:false}]; @api selectedValues=[]; @api label=' '; @track _options= []; @track iswindowOpen=false; /*Init() call..*/ connectedCallback() { this._options = JSON.parse(JSON.stringify(this.options)); //sort all array items befor display it to ui this._options=this._options.sort(function compare(a,b) { if (a.value == 'All'){ return -1; } else if (a.value < b.value){ return -1; } if (a.value > b.value){ return 1; } return 0; }); } get defaultText(){ if (this.selectedValues.length === 0) { return "Select an option..."; } if (this.selectedValues.length === 1) { return this.selectedValues[0].label; } else{ return this.selectedValues.length+" Options Selected"; } } handleClick(event){ console.log('query selector..'+this.template.querySelector("section")); this.iswindowOpen=true; this.template.querySelector("section").classList.add("slds-is-open"); } handleMouseOut(event){ if(this.iswindowOpen){ return; } this.template.querySelector("section").classList.remove("slds-is-open"); } handleMouseLeave(event){ this.iswindowOpen=false; this.template.querySelector("section").classList.remove("slds-is-open"); } handlemouseOver(event){ this.iswindowOpen=true; } handleSelectedClick(event){ var value; var selected; event.preventDefault(); event.stopPropagation(); const data = event.detail; value = data.value; selected = data.selected; //shift key ADDS to the list (unless clicking on a previously selected item) //also, shift key does not close the dropdown. if (data.shift) { this._options.forEach(function(option) { if (option.value === value) { option.selected = selected === true ? false : true; } }); } else { this._options.forEach(function(option) { if (option.value === value) { option.selected = selected === "true" ? false : true; } else { option.selected = false; } }); // this.closeDropdown(); } this.selectedValues = this.getOptionsArray(); } getOptionsArray(){ var pills = []; this._options.forEach(function(element) { var interator = 0; if (element.selected) { pills.push({label:element.label, name:element.value, key: interator++}); } }); return pills; } } |
Child Component :
listItems.html
1 2 3 4 5 6 7 8 9 10 11 12 | <template> <li onclick={eventHandler} class="slds-listbox__item" role="presentation" > <div class={listStyle} role="option"> <span class="slds-media__figure"> <lightning-icon icon-name="utility:check" size="x-small" alternative-text="selected" class="slds-icon-utility-check slds-current-color slds-listbox__icon-selected slds-icon_container"></lightning-icon> </span> <span class="slds-media__body"> <span class="slds-truncate no-selection" title={label}> {label}</span> </span> </div> </li> </template> |
listItems.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import { LightningElement,api,track } from 'lwc'; export default class ListItems extends LightningElement { @api key = ''; @api value = ''; @api label = ''; @api selected = false; get listStyle() { var initial = ' slds-media slds-listbox__option_plain slds-media_small slds-listbox__option '; return this.selected === true ? initial + ' slds-is-selected ' : initial ; } eventHandler(event) { event.preventDefault(); event.stopPropagation(); console.log('selcted value..'+this.selected); const selectedEvent = new CustomEvent('selected', { detail: {label:this.label,value:this.value,selected:this.selected,shift:event.shiftKey} }); this.dispatchEvent(selectedEvent); } } |
Explanation..
in code we are using Shift key to select multiple options from dropdown. on select option(s) , events is getting fired from child component and being handled on parent component
# handleSelectedClick(event)
one tricky part is handling showing and hiding of drop down list using below two events:
- onmouseenter
- onmouseleave
OutPut :
Lets see the output and hope you will like it.
its not working as like you shown in above vedio..
ReplyDeleteThis comment has been removed by the author.
ReplyDelete