Salesforce Lightning Web Component - Dual List Box with Search

Today in this post, we are going to learn that how we can use Search Functionality in Dual List Box from Salesforce Lightning Web Component. The use case could be, I have 2 custom objects. One is Job Posting Site OR Company & another is Position. Now as per the request of HR department, we have created one Junction Object Posting, which will have Lookup relation with Job Posting Site as well as Position. So, one Job Posting Site can have multiple Open Positions. We can easily add or remove mapping/junction based on Job Position is open or closed.
Step 1/5: Create Custom Objects & Fields
1. Create Custom Object: 'Job_Posting_Site__c'
Create Field 'Name' & Datatype: 'Text'
Create Field 'Name' & Datatype: 'Text'
2. Create Custom Object: 'Position__c'
Create Field 'Name' & Datatype: 'Text'
You can add multiple fields based on requirements such as Salary, Description, Role etc.
You can add multiple fields based on requirements such as Salary, Description, Role etc.
3. Create Custom Object: 'Job_Posting__c'
Create Field 'Name' & Datatype: 'Text'Create Field 'Job_Posting_Site__c' & Datatype: 'Master-Detail(Job Posting Site)'
Create Field 'Position__c' & Datatype: 'Master-Detail(Position)'
Step 2/4: Create Apex Class
CustomLookupDualController.apxc
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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | public with sharing class CustomLookupDualController { public CustomLookupDualController() { } //First search field - Job_Posting_Site__c @AuraEnabled public static List<SObJectResult> getResults(String ObjectName, String fieldName, String value) { List<SObJectResult> sObjectResultList = new List<SObJectResult>(); system.debug(fieldName+'::'+ObjectName+'::'+value); if(String.isNotEmpty(value)) for(sObject rec : Database.Query('Select Id,'+fieldName+' FROM '+ObjectName+' WHERE '+fieldName+' LIKE \'%' + value + '%\'')) { String fieldvalue = (String)rec.get(fieldName); sObjectResultList.add(new SObjectResult(fieldvalue, rec.Id)); } return sObjectResultList; } //wrapper public class SObJectResult { @AuraEnabled public String recName; @AuraEnabled public Id recId; public SObJectResult(String recNameTemp, Id recIdTemp) { recName = recNameTemp; recId = recIdTemp; } } //to get available Position__c - left & right data @AuraEnabled public static positionInfoWrapper findPositions(Id siteId) { positionInfoWrapper positionInfoWrap = new positionInfoWrapper(); System.debug('Inside findPositions::'); System.debug('input parameter - siteId::'+siteId); List<ID> alreadyMappedPositionIdList = new List<ID>(); List<Position__c> positionHolderList = new List<Position__c>(); //map to show at left Map<Id,String> totalPositionIdToPositionNameMap = new Map<Id,String>(); // map to show at right Map<Id,String> positionIdToPositionNameRightMap = new Map<Id,String>(); List<Job_Posting__c > accUserList = new List<Job_Posting__c >(); accUserList = [SELECT Id, Job_Posting_Site__c, Position__c FROM Job_Posting__c WHERE Job_Posting_Site__c =:siteId]; for(Job_Posting__c positionRecord : accUserList) { alreadyMappedPositionIdList.add(positionRecord.Position__c); } positionHolderList = [SELECT Id, Name FROM Position__c where Id IN: alreadyMappedPositionIdList]; for(Position__c positionRecord: positionHolderList){ positionIdToPositionNameRightMap.put(positionRecord.Id,positionRecord.Name); } positionHolderList = [SELECT Id, Name FROM Position__c]; for(Position__c positionRecord: positionHolderList){ totalPositionIdToPositionNameMap.put(positionRecord.Id,positionRecord.Name); } positionInfoWrap.toShowAtLeft = totalPositionIdToPositionNameMap; positionInfoWrap.toShowAtRight = positionIdToPositionNameRightMap; return positionInfoWrap; } //To save postings @AuraEnabled public static Boolean saveSiteToPositionJunction(Id siteId,List<Id> positionInfoData) { system.debug('Inside saveSiteToPositionJunction::'); system.debug('siteId::'+siteId); system.debug('positionInfoData::'+positionInfoData); try{ Map<Id,String> positionIdToPositionNameMap = new Map<Id,String>(); Database.deleteResult[] drList; Database.saveResult[] srList; List<Id> existingPositionList = new List<Id>(); List<Id> positionListToDeletePosting = new List<Id>(); List<Id> positionListToCreatePosting = new List<Id>(); List<Job_Posting__c> toDeletePosting = new List<Job_Posting__c>(); Job_Posting__c createPostingInstance; List<Job_Posting__c> createPostingList = new List<Job_Posting__c>(); List<Job_Posting__c> existingPostingList = [select Id, Job_Posting_Site__c, Position__c from Job_Posting__c where Job_Posting_Site__c =:siteId]; for(Job_Posting__c postingRecord : existingPostingList){ existingPositionList.add(postingRecord.Position__c); } for(Id positionId: existingPositionList){ if(!positionInfoData.contains(positionId)){ positionListToDeletePosting.add(positionId); } } List<Position__c> tempPositionList = [select Id, Name from Position__c where id in:positionListToDeletePosting]; for(Position__c p:tempPositionList){ positionIdToPositionNameMap.put(p.Id,p.Name); } for(Id positionId : positionListToDeletePosting){ for(Job_Posting__c postingToDelete : existingPostingList){ if(postingToDelete.Position__c == positionId){ if(!toDeletePosting.contains(postingToDelete)){ toDeletePosting.add(postingToDelete); } } } } for(Id pId: positionInfoData){ if(!existingPositionList.contains(pId)){ positionListToCreatePosting.add(pId); } } List<Position__c> tempPosList = [select Id, Name from Position__c where id in:positionListToCreatePosting]; for(Position__c u:tempPosList){ positionIdToPositionNameMap.put(u.Id,u.Name); } for(Id posIdRecord : positionListToCreatePosting){ createPostingInstance = new Job_Posting__c(); createPostingInstance.Position__c = posIdRecord; createPostingInstance.Job_Posting_Site__c = siteId; createPostingList.add(createPostingInstance); } if(createPostingList != null && !createPostingList.isEmpty()){ srList = database.insert(createPostingList,false); } if(toDeletePosting != null && !toDeletePosting.isEmpty()){ drList = database.delete(toDeletePosting, false); } return true; }catch(Exception e){ system.debug('Inside Exception::'+e); return false; } } //wrapper public class positionInfoWrapper{ @AuraEnabled public Map<Id,String> toShowAtLeft; @AuraEnabled public Map<Id,String> toShowAtRight; } } |
Step 3/5: Create Lightning Web Components
1. lwcCustomLookup
2. dualListBoxV1
3. testJunction
lwcCustomLookup.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
36
37
38
39
40
41
42
43
44
45
46
<template>
<div>
<div class="slds-form-element">
<div class="slds-form-element__control">
<div class="slds-combobox_container">
<div class={txtclassname} data-id="resultBox" aria-expanded="false" aria-haspopup="listbox" role="combobox">
<div class="slds-form-element__control slds-input-has-icon slds-input-has-icon slds-input-has-icon_right" role="none">
<lightning-input placeholder="Search Job Posting Site" required={required} read-only={inputReadOnly} data-id="userinput" label={Label} name="searchText" onchange={searchField} value={selectRecordName} class="leftspace"></lightning-input>
<div if:true={iconFlag}>
<span class="slds-icon_container slds-icon-utility-search slds-input__icon slds-input__icon_right iconheight">
<lightning-icon class="slds-icon slds-icon slds-icon_small slds-icon-text-default" icon-name="utility:search" size="x-small" alternative-text="icon" ></lightning-icon>
</span>
</div>
<div if:true={clearIconFlag}>
<button class="slds-input__icon slds-input__icon_right slds-button slds-button_icon iconheight" onclick={resetData}>
<lightning-icon class="slds-icon slds-icon slds-icon_small slds-icon-text-default" icon-name="utility:clear" size="x-small" alternative-text="icon" ></lightning-icon>
<span class="slds-assistive-text">Clear</span></button>
</div>
</div>
<!-- Second part display result -->
<div id="listbox-id-1" class="slds-dropdown slds-dropdown_length-with-icon-7 slds-dropdown_fluid" role="listbox">
<ul class="slds-listbox slds-listbox_vertical" role="presentation">
<template for:each={searchRecords} for:item="serecord">
<li role="presentation" class="slds-listbox__item" key={serecord.recId}>
<div data-id={serecord.recId} data-name={serecord.recName} onclick={setSelectedRecord} class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta" role="option">
<span class="slds-media__body">
<span class="slds-listbox__option-text slds-listbox__option-text_entity">{serecord.recName}</span>
</span>
</div>
</li>
</template>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
lwcCustomLookup.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
import { LightningElement,api,track } from 'lwc';
import getResults from '@salesforce/apex/CustomLookupDualController.getResults';
export default class LwcCustomLookup extends LightningElement {
@api objectName = 'Job_Posting_Site__c';
@api fieldName = 'Name';
@api selectRecordId = '';
@api selectRecordName;
@api Label;
@api searchRecords = [];
@api required = false;
@api LoadingText = false;
@track txtclassname = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click';
@track messageFlag = false;
@track iconFlag = true;
@track clearIconFlag = false;
@track inputReadOnly = false;
searchField(event) {
var currentText = event.target.value;
this.LoadingText = true;
getResults({ ObjectName: this.objectName, fieldName: this.fieldName, value: currentText })
.then(result => {
this.searchRecords= result;
this.LoadingText = false;
this.txtclassname = result.length > 0 ? 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open' : 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click';
if(currentText.length > 0 && result.length === 0) {
this.messageFlag = true;
}
else {
this.messageFlag = false;
}
if(this.selectRecordId != null && this.selectRecordId.length > 0) {
this.iconFlag = false;
this.clearIconFlag = true;
}
else {
this.iconFlag = true;
this.clearIconFlag = false;
}
})
.catch(error => {
window.console.log('-------error-------------'+error);
window.console.log(error);
});
}
setSelectedRecord(event) {
var currentText = event.currentTarget.dataset.id;
window.console.log('ID::'+currentText);
this.txtclassname = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click';
this.iconFlag = false;
this.clearIconFlag = true;
this.selectRecordName = event.currentTarget.dataset.name;
// eslint-disable-next-line vars-on-top
var selectName = event.currentTarget.dataset.name;
window.console.log('Name::'+selectName);
this.selectRecordId = currentText;
this.inputReadOnly = true;
const selectedEvent = new CustomEvent('selected', { detail: {recordName : selectName, recordId : currentText}});
// Dispatches the event.
this.dispatchEvent(selectedEvent);
}
resetData() {
this.selectRecordName = "";
this.selectRecordId = "";
this.inputReadOnly = false;
this.iconFlag = true;
this.clearIconFlag = false;
const selectedEvent = new CustomEvent('remove', { detail: {recordId : null}});
// Dispatches the event.
this.dispatchEvent(selectedEvent);
}
}
lwcCustomLookup.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
div input[readonly] {
padding-left: 1.75rem !important;
}
.slds-input{
padding-left: 1.75rem !important;
}
.slds-input-has-icon .slds-input__icon {
top: 56% !important;
}
.slds-icon_small, .slds-icon--small {
width: 1.5rem;
height: 1.5rem;
line-height: 2;
}
2. dualListBoxV1
3. testJunction
lwcCustomLookup.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 36 37 38 39 40 41 42 43 44 45 46 | <template> <div> <div class="slds-form-element"> <div class="slds-form-element__control"> <div class="slds-combobox_container"> <div class={txtclassname} data-id="resultBox" aria-expanded="false" aria-haspopup="listbox" role="combobox"> <div class="slds-form-element__control slds-input-has-icon slds-input-has-icon slds-input-has-icon_right" role="none"> <lightning-input placeholder="Search Job Posting Site" required={required} read-only={inputReadOnly} data-id="userinput" label={Label} name="searchText" onchange={searchField} value={selectRecordName} class="leftspace"></lightning-input> <div if:true={iconFlag}> <span class="slds-icon_container slds-icon-utility-search slds-input__icon slds-input__icon_right iconheight"> <lightning-icon class="slds-icon slds-icon slds-icon_small slds-icon-text-default" icon-name="utility:search" size="x-small" alternative-text="icon" ></lightning-icon> </span> </div> <div if:true={clearIconFlag}> <button class="slds-input__icon slds-input__icon_right slds-button slds-button_icon iconheight" onclick={resetData}> <lightning-icon class="slds-icon slds-icon slds-icon_small slds-icon-text-default" icon-name="utility:clear" size="x-small" alternative-text="icon" ></lightning-icon> <span class="slds-assistive-text">Clear</span></button> </div> </div> <!-- Second part display result --> <div id="listbox-id-1" class="slds-dropdown slds-dropdown_length-with-icon-7 slds-dropdown_fluid" role="listbox"> <ul class="slds-listbox slds-listbox_vertical" role="presentation"> <template for:each={searchRecords} for:item="serecord"> <li role="presentation" class="slds-listbox__item" key={serecord.recId}> <div data-id={serecord.recId} data-name={serecord.recName} onclick={setSelectedRecord} class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta" role="option"> <span class="slds-media__body"> <span class="slds-listbox__option-text slds-listbox__option-text_entity">{serecord.recName}</span> </span> </div> </li> </template> </ul> </div> </div> </div> </div> </div> </div> </template> |
lwcCustomLookup.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 | import { LightningElement,api,track } from 'lwc'; import getResults from '@salesforce/apex/CustomLookupDualController.getResults'; export default class LwcCustomLookup extends LightningElement { @api objectName = 'Job_Posting_Site__c'; @api fieldName = 'Name'; @api selectRecordId = ''; @api selectRecordName; @api Label; @api searchRecords = []; @api required = false; @api LoadingText = false; @track txtclassname = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click'; @track messageFlag = false; @track iconFlag = true; @track clearIconFlag = false; @track inputReadOnly = false; searchField(event) { var currentText = event.target.value; this.LoadingText = true; getResults({ ObjectName: this.objectName, fieldName: this.fieldName, value: currentText }) .then(result => { this.searchRecords= result; this.LoadingText = false; this.txtclassname = result.length > 0 ? 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open' : 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click'; if(currentText.length > 0 && result.length === 0) { this.messageFlag = true; } else { this.messageFlag = false; } if(this.selectRecordId != null && this.selectRecordId.length > 0) { this.iconFlag = false; this.clearIconFlag = true; } else { this.iconFlag = true; this.clearIconFlag = false; } }) .catch(error => { window.console.log('-------error-------------'+error); window.console.log(error); }); } setSelectedRecord(event) { var currentText = event.currentTarget.dataset.id; window.console.log('ID::'+currentText); this.txtclassname = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click'; this.iconFlag = false; this.clearIconFlag = true; this.selectRecordName = event.currentTarget.dataset.name; // eslint-disable-next-line vars-on-top var selectName = event.currentTarget.dataset.name; window.console.log('Name::'+selectName); this.selectRecordId = currentText; this.inputReadOnly = true; const selectedEvent = new CustomEvent('selected', { detail: {recordName : selectName, recordId : currentText}}); // Dispatches the event. this.dispatchEvent(selectedEvent); } resetData() { this.selectRecordName = ""; this.selectRecordId = ""; this.inputReadOnly = false; this.iconFlag = true; this.clearIconFlag = false; const selectedEvent = new CustomEvent('remove', { detail: {recordId : null}}); // Dispatches the event. this.dispatchEvent(selectedEvent); } } |
lwcCustomLookup.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | div input[readonly] { padding-left: 1.75rem !important; } .slds-input{ padding-left: 1.75rem !important; } .slds-input-has-icon .slds-input__icon { top: 56% !important; } .slds-icon_small, .slds-icon--small { width: 1.5rem; height: 1.5rem; line-height: 2; } |
dualListBoxV1.html
dualListBoxV1.js
testJunction.html
testJunction.js
testJunction.css
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 | <template> <div class="backgroundDiv"> <div> <div class="slds-p-around--medium slds-p-right_x-large slds-m-right_xx-large" style="padding-top: 0; padding-right: 632px;"> <div class="slds-grid slds-wrap"> <div class="slds-col slds-size_1-of-2 slds-align_absolute-center" style="font-weight: bold; font-size: medium;"> <label class="slds-form-element__label" for="unique-id-of-input">Select Job Posting Site</label> </div> <div class="slds-col slds-size_1-of-2"> <c-lwc-custom-lookup onremove={selectedRecord} onselected={selectedRecord}></c-lwc-custom-lookup> </div> </div> <div class="slds-col slds-p-left_x-large slds-m-left_x-large"> <lightning-input value={userSearchKey} onchange={onUserSearch} type="search" placeholder="Search Position"></lightning-input> </div> <div class="slds-col slds-p-left_x-large slds-m-left_x-large"> <lightning-dual-listbox name="languages" disable-reordering="True" source-label="Available" selected-label="Selected" options={mapData} value={availableMapData} onchange={handleChange}></lightning-dual-listbox> </div> <div class="slds-list_horizontal slds-align_absolute-center slds-p-top_medium slds-p-left_xx-large"> <lightning-button variant="brand" class="slds-m-horizontal--x-small" label="Save" onclick={onSave}></lightning-button> </div> </div> </div> </div> </template> |
dualListBoxV1.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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | /* eslint-disable no-alert */ /* eslint-disable no-mixed-spaces-and-tabs */ /* eslint-disable vars-on-top */ import { LightningElement, track, api } from "lwc"; import { NavigationMixin } from "lightning/navigation"; import findPositions from "@salesforce/apex/CustomLookupDualController.findPositions"; import saveSiteToPositionJunction from "@salesforce/apex/CustomLookupDualController.saveSiteToPositionJunction"; export default class dualListBoxV1 extends NavigationMixin(LightningElement) { @track _selected = []; @api searchKey; @track mapData = []; @track availableMapData = []; @track userMapDataArray = []; @track userMapDataArray2 = []; @track tempCatchArray = []; @track finalCatchTempArray = []; @track filteredUsers = []; @api userSearchKey; @track searchFlag = false; @track tempInSearchRightArray = []; @track newTempArrayData = []; @track newTempArrayData2 = []; connectedCallback() { window.console.log("Inside ConnectedCallback::"); } afterSelectionFindRecords(a) { findPositions({ siteId: a }) .then(result => { if (result !== null || result !== undefined) { window.console.log("result::" + result); var availableUserInfoMap = result.toShowAtLeft; for (let key in availableUserInfoMap) { if (availableUserInfoMap.hasOwnProperty(key)) { this.mapData.push({ label: availableUserInfoMap[key], value: key }); this.userMapDataArray.push({ label: availableUserInfoMap[key], value: key }); this.userMapDataArray2.push({ label: availableUserInfoMap[key], value: key }); } } if (this.mapData != null) { var selectedUserInfoMap = result.toShowAtRight; window.console.log("Right wrapper - " + selectedUserInfoMap); for (let key in selectedUserInfoMap) { if (selectedUserInfoMap.hasOwnProperty(key)) { this.availableMapData.push(key); } } } window.console.log( "onfetchdata::availableMapData::" + this.availableMapData ); } }) .catch(error => { window.console.log("THis is the error: " + error); }); } // Called on site record selection from lookup, this is the selected site record selectedRecord(event) { window.console.log("SelectedAtLast::" + event.detail.recordId); if (event.detail.recordId != null) { window.console.log("Inside selected Record"); this.searchKey = event.detail.recordId; this.afterSelectionFindRecords(this.searchKey); window.console.log("SelectedAtLast::" + this._selected); } else { window.console.log("Inside else selected Record"); this.searchKey = ""; this.mapData = []; this.availableMapData = []; this.userMapDataArray = []; this.userMapDataArray2 = []; this.userSearchKey = ""; } } handleChange(e) { this.mapData = []; this.mapData.push(...this.userMapDataArray2); if (!this.searchFlag) { window.console.log( "Inside Handle Change IF, searchFlag::" + this.searchFlag ); this.availableMapData = e.detail.value; window.console.log( "Inside Handle Change IF, availableMapData::" + this.availableMapData ); } else { // eslint-disable-next-line vars-on-top var tempAvailableMapFromSearch = e.detail.value; window.console.log( "in else handle, e.detail.value::" + tempAvailableMapFromSearch ); window.console.log("this.filteredUsers::" + this.filteredUsers); window.console.log("this.availableMapData::" + this.availableMapData); // eslint-disable-next-line vars-on-top for (var i = 0; i < this.availableMapData.length; i++) { // eslint-disable-next-line vars-on-top for (var k = 0; k < this.filteredUsers.length; k++) { window.console.log( "this.filteredUsers[i].value::" + this.filteredUsers[k].value ); if (this.filteredUsers[k].value.includes(this.availableMapData[i])) { window.console.log( "this.availableMapData[i]::" + this.availableMapData[i] ); this.tempCatchArray.push(this.availableMapData[i]); } } } window.console.log("this.tempCatchArray::" + this.tempCatchArray); this.finalCatchTempArray = arr_diff( this.tempCatchArray, this.availableMapData ); window.console.log( "this.finalCatchTempArray::" + this.finalCatchTempArray ); // eslint-disable-next-line no-inner-declarations function arr_diff(a1, a2) { var a = [], diff = []; for (var j = 0; j < a1.length; j++) { a[a1[j]] = true; } for (var l = 0; l < a2.length; l++) { if (a[a2[l]]) { delete a[a2[l]]; } else { a[a2[l]] = true; } } // eslint-disable-next-line guard-for-in for (var z in a) { diff.push(z); } return diff; } this.availableMapData = e.detail.value; for (var k2 = 0; k2 < this.finalCatchTempArray.length; k2++) { if (!this.availableMapData.includes(this.finalCatchTempArray[k2])) { window.console.log( "this.finalCatchTempArray[k2]::" + this.finalCatchTempArray[k2] ); this.newTempArrayData.push(...this.finalCatchTempArray[k2]); this.newTempArrayData2.push(this.finalCatchTempArray[k2]); } } window.console.log("this.newTempArrayData::" + this.newTempArrayData); window.console.log("this.newTempArrayData2::" + this.newTempArrayData2); this.availableMapData.push(...this.newTempArrayData2); window.console.log("this.availableMapData::" + this.availableMapData); this.finalCatchTempArray = []; this.tempCatchArray = []; this.newTempArrayData = []; this.newTempArrayData2 = []; this.searchFlag = false; } } //To save mapping data onSave() { saveSiteToPositionJunction({ siteId: this.searchKey, positionInfoData: this.availableMapData }) .then(result => { window.console.log("This is result: " + JSON.stringify(result)); if (result === true) { alert("Job Posting Junction is saved"); window.console.log("Job Posting Junction Saved"); } else { alert("Application error occured. Please contact help desk."); } }) .catch(error => { alert("Application error occured. Please contact help desk."); window.console.log("THis is the error: " + error); }); } //function to filter positions onUserSearch(event) { this.tempInSearchRightArray = this.availableMapData; this.searchFlag = true; if (this.mapData != null) { this.userSearchKey = event.target.value; if (event.target.value !== "") { this.filteredUsers = this.userMapDataArray.filter((value, index) => { var userLowerCaseValue = this.userMapDataArray[ index ].label.toLowerCase(); return userLowerCaseValue.includes(this.userSearchKey.toLowerCase()); }); window.console.log("filtyer Left data::" + this.filteredUsers); this.mapData = []; this.mapData.push(...this.filteredUsers); } else { this.nullUserSearch(this.tempInSearchRightArray); } } } nullUserSearch(tempInSearchRight) { window.console.log("1:: " + this.availableMapData); this.mapData = []; this.mapData.push(...this.userMapDataArray2); window.console.log("mapDAta2:: " + this.mapData); this.availableMapData = []; window.console.log("after null2:: " + this.availableMapData); this.availableMapData.push(...tempInSearchRight); window.console.log("3:: " + this.availableMapData); this.searchFlag = false; } } |
testJunction.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 | <template> <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open"> <div class="backgroundDiv slds-m-top_large"> <div> <div class="slds-modal__header"> <b><h2 id="header43" class="slds-text-heading--medium">Job Posting</h2></b> </div> <div class="slds-p-around--medium slds-p-right_xx-large slds-m-right_xx-large" style="padding-right: 632px;"> <!--slds-modal__content removed--> <div class="slds-grid slds-wrap"> <div class="slds-col slds-size_1-of-2 slds-align_absolute-center" style="font-weight: bold; font-size: medium;"> <label class="slds-form-element__label" for="unique-id-of-input">Select Option</label> </div> <div class="slds-col slds-size_1-of-2"> <select class="slds-select" name = "junctionOption" onchange={onJunctionOptionChange}> <option value="Junction">Job Posting Site and Position Junction</option> </select> </div> </div> </div> </div> <div> <template if:false={isjunctionSelected}> <c-dual-list-box-v1></c-dual-list-box-v1> </template> </div> </div> </section> </template> |
testJunction.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 | import { LightningElement, api } from "lwc"; import { NavigationMixin } from "lightning/navigation"; export default class TestJunction extends NavigationMixin(LightningElement) { @api selectedJunctionOption; @api isjunctionSelected; connectedCallback() { this.pnumHomePageRef = { type: "standard__objectPage", attributes: { objectApiName: "Job_Posting__c", actionName: "home" } }; } onJunctionOptionChange(event) { const field = event.target.name; if (field === "junctionOption") { this.selectedJunctionOption = event.target.value; if (event.target.value === "Junction") { this.isjunctionSelected = false; } } } } |
testJunction.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | .selectOneAlignCenter{ margin-left: 40%; margin-right: 40%; margin-top: 1rem; } .selectOneDiv{ /*margin-left: 39rem; margin-right: 39rem;*/ margin-left: 35rem; margin-right: 30rem; margin-top: 1rem; } .backgroundDiv{ /*outline: auto;*/ /* background-color: aliceblue;*/ /*background: rgb(250, 250, 249);*/ background:White } .dualListBoxDiv{ margin-left: 35rem; margin-right: 30rem; } |
Step 4/5: Create Lightning App to preview our Lightning Web Component
DualBoxDemo.app
1 2 3 | <aura:application extends="force:slds"> <c:testJunction/> </aura:application> |
Step 5/5:
Now we are almost done! Just create some records:
Position Object Records: Super Sales Rep;
Super Sales Rep 2;
Awesome Sales Rep.
Now just preview the DualBoxDemo.App. Hence we can search the dual list box & insert or delete multiple mapping at one shot!
You can add Exception Handing & Toast Messages!
Please contact for any Ideas/Suggestions/Collaborations: krishna1096@gmail.com | 9921034154
It is so nice article thank you for sharing this valuable content
ReplyDeleteWorkday Studio Online Training India
Workday Studio Online Training Hyderabad
how to insert records from .xlsx file to sf?
ReplyDelete