Last active
May 8, 2022 15:50
-
-
Save jotraverso/124e46ddd8a5caa0bc5a3b5bdc18adc0 to your computer and use it in GitHub Desktop.
LWC autocomplete combobox
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="slds-form-element"> | |
<label class="slds-form-element__label" for="combobox-id-16" id="combobox-label-id-138"><template | |
if:true={required}> | |
<abbr class="slds-required" title="required">* </abbr> | |
</template>{label}</label> | |
<div class="slds-form-element__control"> | |
<div class="slds-combobox_container"> | |
<div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open"> | |
<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" id="combobox-id-16" | |
value={selectedLabel} aria-activedescendant="option1" aria-autocomplete="list" | |
aria-controls="listbox-id-12" aria-expanded="true" aria-haspopup="listbox" | |
required={required} autocomplete="off" role="combobox" placeholder="Search..." | |
onkeyup={handleChangeSearchTerm} onfocus={handleFocus} onblur={handleBlur} /> | |
<span | |
class="slds-icon_container slds-icon-utility-search slds-input__icon slds-input__icon_right"> | |
<svg class="slds-icon slds-icon slds-icon_x-small slds-icon-text-default" | |
aria-hidden="true"> | |
<use xlink:href="/_slds/icons/utility-sprite/svg/symbols.svg#search"></use> | |
</svg> | |
</span> | |
</div> | |
<template if:true={showOptions}> | |
<div id="listbox-id-12" class="slds-dropdown slds-dropdown_length-5 slds-dropdown_fluid" | |
role="listbox"> | |
<ul class="slds-listbox slds-listbox_vertical" role="presentation"> | |
<template for:each={filteredOptions} for:item="option"> | |
<li key={option.value} role="presentation" class="slds-listbox__item" | |
onclick={handleSelect} data-rowid={option.value} data-rowlabel={option.label}> | |
<div aria-selected="true" | |
class="slds-media slds-listbox__option slds-listbox__option_plain slds-media_small" | |
role="option"> | |
<span class="slds-media__figure slds-listbox__option-icon"></span> | |
<span class="slds-media__body"> | |
<span class="slds-truncate" | |
title="Burlington Textiles Corp of America">{option.label}</span> | |
</span> | |
</div> | |
</li> | |
</template> | |
</ul> | |
</div> | |
</template> | |
</div> | |
</div> | |
</div> | |
</div> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable @lwc/lwc/no-async-operation */ | |
import { api, LightningElement } from "lwc"; | |
export default class AutocompleteCombobox extends LightningElement { | |
@api label; | |
@api required; | |
@api placeholder; | |
@api options; | |
filteredOptions = []; | |
toggleOptions = false; | |
selectedValue; | |
selectedLabel; | |
handleFocus() { | |
this.toggleOptions = true; | |
} | |
handleBlur() { | |
const cmp = this; | |
setTimeout(function () { | |
cmp.toggleOptions = false; | |
// if the selected label is empty must trigger the change event | |
if (cmp.selectedLabel === "") { | |
cmp.selectedValue = ""; | |
cmp.dispatchEvent(new CustomEvent("change", { bubbles: false, detail: { value: "", target: cmp.name } })); | |
} | |
}, 200); | |
} | |
handleSelect(event) { | |
let selectedValue = event.currentTarget.dataset.rowid; | |
let selectedLabel = event.currentTarget.dataset.rowlabel; | |
this.selectedValue = selectedValue; | |
this.selectedLabel = selectedLabel; | |
this.toggleOptions = false; | |
this.dispatchEvent(new CustomEvent("change", { bubbles: false, detail: { value: this.selectedValue, target: this.name } })); | |
} | |
handleChangeSearchTerm(event) { | |
clearTimeout(this.searchTO); | |
const searchTerm = event.target.value; | |
const cmp = this; | |
this.selectedLabel = searchTerm; | |
this.selectedValue = ""; | |
this.searchTO = setTimeout(() => { | |
cmp.filteredOptions = cmp.options.filter((option) => cmp.selectedLabel === "" || option.label.toLowerCase().includes(searchTerm.toLowerCase())); | |
}, 400); | |
this.toggleOptions = true; | |
} | |
connectedCallback() { | |
this.filteredOptions = this.options?.slice(0) ?? []; | |
this.selectedLabel = ""; | |
this.selectedValue = ""; | |
} | |
get showOptions() { | |
if (this.selectedLabel === "") { | |
this.filteredOptions = this.options?.slice(0); | |
} | |
return this.toggleOptions && this.filteredOptions?.length > 0; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" ?> | |
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata"> | |
<apiVersion>54.0</apiVersion> | |
<isExposed>false</isExposed> | |
<description>Autocomplete Combobox</description> | |
</LightningComponentBundle> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<lightning-card> | |
<div class="slds-p-around_medium" style="width: 800px;"> | |
<label>Selected Contact Id: {contactId}</label> | |
<c-autocomplete-combobox options={options} onchange={handleChange} label="Select a contact" | |
placeholder="Search..."> | |
</c-autocomplete-combobox> | |
<lightning-card if:true={showContact} title={contactName} icon-name="standard:contact"> | |
<lightning-record-form record-id={contactId} layout-type="Compact" object-api-name={sobjectName} | |
mode="readonly" columns="2"> | |
</lightning-record-form> | |
</lightning-card> | |
</div> | |
</lightning-card> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { LightningElement, wire } from "lwc"; | |
import { getRecord, getFieldValue } from "lightning/uiRecordApi"; | |
import getContacts from "@salesforce/apex/MyAppController.getContacts"; | |
import CONTACT_NAME from "@salesforce/schema/Contact.Name"; | |
import CONTACT_PHONE from "@salesforce/schema/Contact.Phone"; | |
import SOBJECT_CONTACT from "@salesforce/schema/Contact"; | |
export default class MyApp extends LightningElement { | |
@wire(getContacts) | |
contacts; | |
fileds = [CONTACT_NAME, CONTACT_PHONE]; | |
@wire(getRecord, { recordId: "$contactId", fields: [CONTACT_NAME, CONTACT_PHONE] }) | |
selectedContact; | |
contactId; | |
sobjectName = SOBJECT_CONTACT; | |
get options() { | |
return this.contacts?.data?.map((contact) => { | |
return { value: contact.Id, label: contact.Name }; | |
}); | |
} | |
handleChange(event) { | |
this.contactId = event.detail.value; | |
} | |
get showContact() { | |
return this.contactId ? true : false; | |
} | |
get contactName() { | |
return getFieldValue(this.selectedContact.data, CONTACT_NAME); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment