Closed rodriggj closed 2 years ago
So this process will occur in 2 parts:
carTileList
component and display the data that is filtered. To execute these 2 Steps we will utilize 2 files within the carFilter
component.
carFilter.html
file will implement the 4 elementscarFilter.js
file will contain handlers (aka Functions) that implement the desired bahaviorWhile executing Step 1, we are concentrating on adding HTML Tags, and Tag attributes that will later support the Data Binding, or Javascript Functionality.
We will keep the 2 steps separate as much as possible so if there is a JS portion of the HTML file, we will jump over to the carFilter.js
file to add a "placeholder" and we will circle back to the HTML.
Keyword Search
Functionalitylightning-card
element which will act as the container. Within the container add a lightning-input
element that will received the users Search Word. Use attributes in the lighting-input
element to provide a label name, specify the type of input (Search), and a javascript placeholder that will manage the "onChange" behavior that occurs when a user inputs a Search Word. carFilter.html
<template>
<lightning-card title="Filters" icon-name="standard:calibration">
<div class="slds-m-horizontal_medium">
<!-- Search Key Input -->
<lightning-input
label="Search Key"
type="search"
value={}
onchange={handleSearchKeyChange}>
</lightning-input>
</div>
</lightning-card>
</template>
carFilter.js
import { LightningElement } from 'lwc';
export default class CarFilter extends LightningElement {
handleSearchKeyChange(){
// Logic for search function to be written here
}
}
Slider Bar
Functionalitylightning-card
element which will act as the container. Within the container add a lightning-input
element that will received the users Search Word. Use attributes in the lighting-input
element to provide a label name, specify the type of input (Search), and a javascript placeholder that will manage the "onChange" behavior that occurs when a user inputs a Search Word. carFilter.html
<template>
<lightning-card title="Filters" icon-name="standard:calibration">
<div class="slds-m-horizontal_medium">
<!-- Search Key Input -->
<lightning-input
label="Search Key"
type="search"
value={}
onchange={handleSearchKeyChange}>
</lightning-input>
</div>
<!-- Slider Section -->
<section>
<lightning-slider
label="Max Price"
step="100"
min="0"
max="99999"
value={}
onchange={onMaxPriceChange}>
</lightning-slider>
</section>
</lightning-card>
</template>
carFilter.js
import { LightningElement } from 'lwc';
export default class CarFilter extends LightningElement {
handleSearchKeyChange(){
// Logic for search function to be written here
}
onMaxPriceChange(){
}
}
Now we need to implement Data Binding
between the HTML and the JS.
carFilter
class. Here we create an Object called filters
which will contain the attributes we want to maintain State
in our application. Template
utilizing the {}
(Interpolation Syntax) to receive the State
of our attributes and pass it to the front-end HTML. Javascript will maintain this state with the class properties and update as needed. The slider bar needs to maintain 2 pieces of data as the user interacts with this filter. These are the SearchKey
, and the MaxPrice
. Because these will change with the user interaction and because they are used by Javascript to query the right tiles we need to retain this input. This is referred to as State
. The state of these 2 variables will change, and be used by Javascript to execute its behavior. To ensure that the HTML input can be shared with Javascript file, we need to create a place for the state to be stored. To do this we create a class property
, called filters. This property is an Object, which has 2 attributes, searchKey and maxPrice. We will initiate searchKey with a null
value and maxPrice with the Max Price in filter range. We will finally call the filter
Object using dot notation
, through a process called data binding
between the HTML and JS files. The syntax for data binding
is the curly braces { }
.
carFilter.html
<template>
<lightning-card title="Filters" icon-name="standard:calibration">
<div class="slds-m-horizontal_medium">
<!-- Search Key Input -->
<lightning-input
label="Search Key"
type="search"
value={filters.searchKey}
onchange={handleSearchKeyChange}>
</lightning-input>
<!-- Slider Section -->
<section>
<lightning-slider
label="Max Price"
step="100"
min="0"
max="99999"
value={filters.maxPrice}
onchange={onMaxPriceChange}>
</lightning-slider>
</section>
</div>
</lightning-card>
</template>
carFilter.js
import { LightningElement } from 'lwc';
export default class CarFilter extends LightningElement {
filters={
searchKey: '',
maxPrice: 99999
}
handleSearchKeyChange(){
// Logic for search function to be written here
}
onMaxPriceChange(){
}
}
carFilter
parent folder and Deploy to Source Org
Picklist
FunctionalityWe have 2 Picklist
selections we are placing in the Filter Component
- these are Category
& Make Type
. Both have effectively the same coding construct, so we will simply explain the Category Picklist
and then show the details for the Make Type
.
Category
filter, you will need to collect thier input
- so we start by creating a new <section>
and adding a lightning Input
component with identifying attributes. We also add our onchange attribute so we can assign behavior in our javascript file for when a box is checked. carFilter.html
<!-- Category Checkboxes -->
<section>
<h2>Categories</h2>
<lightning-input
type="checkbox"
name="category"
checked
onchange={handleCheckbox}/>
</lightning-input>
</section>
carFilter.js
handleCheckbox(){
}
Category__c
field when we created our Cars__c
Object. Recall that we're trying to bring back a picklist for the Category__c
field that contains 4 selection items.To do this we need to import some functionality from Salesforce, specifically the getObjectInfo
and getPicklistValues
API from the Lightning Data Service (LDS), which is packaged in a module called lightning/uiObjectInfoApi
. We will also be using the @wire()
service to fetch this data from the LDS. We will use the @wire
service to first fetch the Car__c
Object Info, then we will again use the @wire()
service on the retrieved Car__c
Object to retrieve the Category__c
info.
NOTE: the
Lightning Data Service
and the methods used to retrieve data from the LDS is another major difference between React, Vue, Angular, etc. Development that requires specialized tooling to utilize. (Elaborate more later)
carFilter.js
import { LightningElement, wire } from 'lwc';
import { getObjectInfo, getPicklistValues } from 'lightning/uiObjectInfoApi';
// Importing Car__c and associated fields via @salesforce/schema API
import CAR_OBJECT from '@salesforce/schema/Car__c'
import CATEGORY_FIELD from '@saleforce/schema/Car__c.Category__c'
export default class CarFilter extends LightningElement {
filters={
searchKey: '',
maxPrice: 99999
}
// fetching Car__c Object Info
@wire(getObjectInfo, {objectApiName: CAR_OBJECT})
carObjectInfo
// fetching Category__c referencing the property carObjectInfo (Car__c)
@wire(getPicklistValues, {
recordTypeId: '$carObjectInfo.data.defaultRecordTypeId',
fieldApiName: CATEGORY_FIELD
}) categories
handleSearchKeyChange(){
// Logic for search function to be written here
}
onMaxPriceChange(){
}
handleCheckbox(){
}
}
categories
property that we assigned using the wire Service. We can now go back to the carFilter.html
file and use the picklist values. We will have to use the <template>
tag to execute some iteration to list all 4 values in the pick list. <!-- Category Checkboxes -->
<section>
<h2>Categories</h2>
<template if:true={categories.data}>
<template for:each={categories.data.values} for:item="category">
<lightning-input
key={category.value}
label={category.label}
type="checkbox"
name="category"
checked
onchange={handleCheckbox}/>
</lightning-input>
</template>
</template>
<template if:true={categories.error}>
<div>Error loading categories</div>
</template>
</section>
carFilter
folder and Deploy Source to Org
. Refresh or Open your DevOrg and you should see something like thisMake Type
. Your code should look like this. carFilter.html
<!-- Make Type Checkboxes -->
<section>
<h2>Make Type</h2>
<template if:true={makeTypes.data}>
<template for:each={makeTypes.data.values} for:item="make">
<lightning-input
key={make.value}
label={make.label}
type="checkbox"
name="makeType"
checked
onchange={handleCheckbox}/>
</lightning-input>
</template>
</template>
<template if:true={makeTypes.error}>
<div>Error loading categories</div>
</template>
</section>
carFilter.js
// ...
import MAKE_FIELD from '@salesforce/schema/Car__c.Make__c'
// ...
// fetching Make__c referencing the property carObjectInfo (Make__c)
@wire(getPicklistValues, {
recordTypeId: '$carObjectInfo.data.defaultRecordTypeId',
fieldApiName: MAKE_FIELD
})makeTypes
carFilter
folder and Deploy Source to Org
. We may want to test to see if the filters we put in place do respond to front-end interaction. To do this we can print something to the console when any of the filters are engaged. This will invole writing a console.log()
statement in our Javascript - handler
functions that we've left empty so far. This isn't the completion of STEP 2 ; that logic will be much more specific. This is simply a test to see that the interaction between the front end components we built will receive input and react to it.
carFilter.js file
// Handle Search Key
handleSearchKeyChange(event){
console.log(event.target.value)
this.filters = {...this.filters, "searchKey": event.target.value}
}
// Handle Slider Price Change
onMaxPriceChange(event){
console.log(event.target.value)
this.filters = {...this.filters, "maxPrice": event.target.value}
}
<!-- Category Checkboxes -->
<section>
<h2>Categories</h2>
<template if:true={categories.data}>
<template for:each={categories.data.values} for:item="category">
<lightning-input
key={category.value}
label={category.label}
type="checkbox"
data-name="category"
data-value={category.value}
checked
onchange={handleCheckbox}/>
</lightning-input>
</template>
...
</section>
<!-- Make Type Checkboxes -->
<section>
<h2>Make Type</h2>
<template if:true={makeTypes.data}>
<template for:each={makeTypes.data.values} for:item="make">
<lightning-input
key={make.value}
label={make.label}
type="checkbox"
data-name="makeType"
data-value={make.value}
checked
onchange={handleCheckbox}/>
</lightning-input>
...
</section>
handleCheckbox(event){
const {name, value} = event.target.dataset
console.log("name", name)
console.log("value", value)
}
We saw the interaction between our Javascript (Behavior/Logic) and the Front-End UI (Templates or HTML)
<template>
tags which are unique to Salesforce<template>
tags have an unique syntax for handling logic like Conditionals, Iteration, and Data Binding and require testing at Unit and System levelTest Automation Locators
in the DOM. We saw the interaction in our Javascript to the Lighting Data Service (LDS)
Here we will implement some "functionality" for our
carFilter
component.Here we will support 4 business requirements for our Filter Functionality.
You're Product or UI/UX department provide you with a Mock Up that looks something like this.
Plan of Attack