I have a data table of Contacts on an Account Record Page and I am trying to use the modal component as a file uploader. Basically, you would select a contact or contacts, click the modal button, and then upload file/files to selected contact/contacts.
Is the file uploader component only a one-to-one relationship (i.e. one selected Contact Record Id to one batch of file/batch of file) or can you pass in a set of Contact Record Ids to the file uploader component and upload a file/batch of files to those passed Contact Record Ids?
To handle selecting/deselecting Contacts on the data table, I am using a set since I need a data structure to handle dynamically selecting/deselecting Contacts on that data table and it should be a unique set of Contact Record Ids being sent to the file uploader to upload file/batch of files.
I try and pass the selectedContacts Set into my modal but I an error that the selectedContacts set is undefined when clicking my modal button. Should I use @track on the selectedContacts?
contactListView.html
<template>
<lightning-card title="Contacts List View" icon-name="custom:custom63">
<div class="slds-m-around_medium">
<template if:true={contact}>
<lightning-button label="Upload File(s)" onclick={handlePopup}></lightning-button>
</template>
<div class="chart slds-m-around_medium" lwc:dom="manual"></div>
<section
id="modal"
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 slds-hide"
>
<div class="slds-modal__container">
<header class="slds-modal__header">
<button
class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse"
title="Close"
>
<svg
class="slds-button__icon slds-button__icon_large"
aria-hidden="true"
>
<use
xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#close"
></use>
</svg>
<span class="slds-assistive-text">Close</span>
</button>
<h2 id="modal-heading-01" class="slds-modal__title slds-hyphenate">
File Uploader
</h2>
</header>
<div
class="slds-modal__content slds-p-around_medium"
id="modal-content-id-1"
>
<div class="slds-p-bottom_large slds-p-left_large" style="width:500px">
<lightning-record-edit-form
id="recordViewForm"
record-id={contact}
object-api-name="Contact"
>
<lightning-messages></lightning-messages>
<lightning-input-field field-name="FirstName"> </lightning-input-field>
<lightning-input-field field-name="LastName"> </lightning-input-field>
<!-- <lightning-button
type="submit"
label="Update record"
class="slds-m-top_medium"
onclick={handleSaveFiles}
>
</lightning-button> -->
<lightning-file-upload
label="Attach File(s)"
name="fileUploader"
accept={acceptedFormats}
record-id={contact}
onuploadfinished={handleUploadFinished}
multiple>
</lightning-file-upload>
</lightning-record-edit-form>
</div>
</div>
<footer class="slds-modal__footer slds-modal__footer_directional">
<button class="slds-button slds-button_neutral" onclick={handleSkip}>
Close
</button>
</footer>
</div>
</section>
<div
class="slds-backdrop slds-backdrop_open slds-hide modalBackdrops"
id="modalBackdrops"
></div>
<!-- <c-file-upload-modal contact={selectedRecord}>
</c-file-upload-modal> -->
<template if:true={contact.data}>
<lightning-datatable
key-field="Id"
data={contact.data}
columns={columns}
onrowselection={getSelectedContact}
onsave={handleSave}
draft-values={draftValues}>
</lightning-datatable>
</template>
<template if:true={contact.error}>
<!-- handle Apex error -->
</template>
</div>
</lightning-card>
</template>
contactListView.js
import { LightningElement, track, wire, api } from 'lwc';
import getContacts from '@salesforce/apex/ContactController.getContacts';
import { refreshApex } from '@salesforce/apex';
import { updateRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import FIRSTNAME_FIELD from '@salesforce/schema/Contact.FirstName';
import LASTNAME_FIELD from '@salesforce/schema/Contact.LastName';
import TITLE_FIELD from '@salesforce/schema/Contact.Title';
import ID_FIELD from '@salesforce/schema/Contact.Id';
const COLS = [
{ label: 'Id', fieldName: 'Id' },
{ label: 'First Name', fieldName: 'FirstName', editable: true },
{ label: 'Last Name', fieldName: 'LastName', editable: true },
{ label: 'Title', fieldName: 'Title', editable: true},
{ label: 'Phone', fieldName: 'Phone', type: 'phone' },
{ label: 'Email', fieldName: 'Email', type: 'email' }
];
const columns = [{
label: 'Title',
fieldName: 'FileName',
type: 'url',
typeAttributes: {
label: {
fieldName: 'Title'
},
target: '_blank'
}
}];
export default class contactListView extends LightningElement {
@track selectedRecord;
selectedRecords = [];
// @track selectedRows;
showLoadingSpinner = false;
@track fileNames = '';
@track filesUploaded = [];
@track data;
@track cols = columns;
@api recordId;
columns = COLS;
draftValues = [];
record = {};
@wire(getContacts, { accId: '$recordId' })
contact;
handleSave(event) {
const fields = {};
fields[ID_FIELD.fieldApiName] = event.detail.draftValues[0].Id;
fields[FIRSTNAME_FIELD.fieldApiName] = event.detail.draftValues[0].FirstName;
fields[LASTNAME_FIELD.fieldApiName] = event.detail.draftValues[0].LastName;
fields[TITLE_FIELD.fieldApiName] = event.detail.draftValues[0].Title;
const recordInput = {fields};
updateRecord(recordInput)
.then(() => {
this.dispatchEvent(
new ShowToastEvent({
title: 'Success',
message: 'Contact updated',
variant: 'success'
})
);
return refreshApex(this.contact).then(() => {
this.draftValues = [];
});
}).catch(error => {
this.dispatchEvent(
new ShowToastEvent({
title: 'Error updating or reloading record',
message: error.body.message,
variant: 'error'
})
);
});
}
getSelectedContact(event){
const selectedContacts = new Set();
const selectedRows = event.detail.selectedRows;
for(let i = 0; i < selectedRows.length; i++){
// console.log("You selected: " + selectedRows[i].Id)
selectedContacts.add(selectedRows[i].Id);
}
console.log("Selected Contacts: " + selectedContacts);
}
handlePopup() {
console.log("Selected Contacts: " + this.selectedContacts);
// console.log("Selected Contact: " + this.contact.Id)
this.template.querySelector("section").classList.remove("slds-hide");
this.template
.querySelector("div.modalBackdrops")
.classList.remove("slds-hide");
}
handleSkip() {
this.template.querySelector("section").classList.add("slds-hide");
this.template
.querySelector("div.modalBackdrops")
.classList.add("slds-hide");
}
get acceptedFormats() {
return ['.pdf', '.png'];
}
handleUploadFinished(event) {
// Get the list of uploaded files
const uploadedFiles = event.detail.files;
alert("No. of files uploaded : " + uploadedFiles.length);
this.contact = null;
}
}