开发支持动态字段配置的Salesforce Lightning Web Component Case录入组件需求
Hey there! Let's build this flexible Lightning Web Component for Case creation that checks all your boxes. Here's a complete, step-by-step solution:
Step 1: Set Up Custom Metadata Type for Dynamic Field Configuration
First, we need a way to configure Case fields without modifying code. Let's create a Custom Metadata Type:
- Go to Setup → Custom Metadata Types → New
- Label:
Case Field Configuration, Plural Label:Case Field Configurations, Object Name:Case_Field_Config - Add these custom fields:
- Field Label:
API Name, Type:Text, Length: 40 (stores Case field API names likeAccountId,Subject) - Field Label:
Display Label, Type:Text, Length: 40 (user-friendly label for the field) - Field Label:
Is Required, Type:Checkbox(marks fields as mandatory)
- Field Label:
- Add records for your required fields first: Account, Contact, Type, Case Reason, Product, Subject, Description—set
Is Requiredto true for each. You can add other fields later as needed, no code changes required!
Step 2: Apex Controller
We need an Apex class to fetch configured fields and create the Case record. Create this class with @AuraEnabled methods:
public with sharing class CaseCreationController { @AuraEnabled(cacheable=true) public static List<Case_Field_Config__mdt> getCaseFields() { return [SELECT API_Name__c, Display_Label__c, Is_Required__c FROM Case_Field_Config__mdt ORDER BY CreatedDate ASC]; } @AuraEnabled public static Id createCase(Map<String, Object> caseFields) { Case newCase = new Case(); // Populate Case fields from input map for (String fieldApiName : caseFields.keySet()) { if (Schema.sObjectType.Case.fields.getMap().containsKey(fieldApiName)) { newCase.put(fieldApiName, caseFields.get(fieldApiName)); } } insert newCase; return newCase.Id; } }
Step 3: LWC Component Files
Let's create the LWC with three core files:
caseCreator.html
Renders dynamic fields and action buttons:
<template> <lightning-card title="Create New Case"> <div class="slds-p-around_medium"> <!-- Dynamic Fields --> <template for:each={caseFields} for:item="field"> <div key={field.API_Name__c} class="slds-form-element"> <label class="slds-form-element__label" for={field.API_Name__c}> {field.Display_Label__c} <template if:true={field.Is_Required__c}> <span class="slds-required">*</span> </template> </label> <div class="slds-form-element__control"> <!-- Render appropriate input based on field type --> <template if:true={isLookupField(field.API_Name__c)}> <lightning-record-edit-form object-api-name="Case"> <lightning-input-field field-name={field.API_Name__c} required={field.Is_Required__c}></lightning-input-field> </lightning-record-edit-form> </template> <template if:true={isTextAreaField(field.API_Name__c)}> <lightning-textarea name={field.API_Name__c} label="" required={field.Is_Required__c}></lightning-textarea> </template> <template if:true={isPicklistField(field.API_Name__c)}> <lightning-record-edit-form object-api-name="Case"> <lightning-input-field field-name={field.API_Name__c} required={field.Is_Required__c}></lightning-input-field> </lightning-record-edit-form> </template> <template if:true={isTextField(field.API_Name__c)}> <lightning-input type="text" name={field.API_Name__c} label="" required={field.Is_Required__c}></lightning-input> </template> </div> </div> </template> <!-- Action Buttons --> <div class="slds-m-top_medium slds-align_absolute-center"> <lightning-button variant="brand" label="Submit Case" onclick={handleSubmit} class="slds-m-right_small"></lightning-button> <lightning-button variant="neutral" label="Cancel" onclick={handleCancel}></lightning-button> </div> </div> </lightning-card> </template>
caseCreator.js
Handles field fetching, validation, and Case submission:
import { LightningElement, wire } from 'lwc'; import getCaseFields from '@salesforce/apex/CaseCreationController.getCaseFields'; import createCase from '@salesforce/apex/CaseCreationController.createCase'; import { ShowToastEvent } from 'lightning/platformShowToastEvent'; import { NavigationMixin } from 'lightning/navigation'; export default class CaseCreator extends NavigationMixin(LightningElement) { caseFields; error; @wire(getCaseFields) wiredCaseFields({ error, data }) { if (data) { this.caseFields = data; this.error = undefined; } else if (error) { this.error = error; this.caseFields = undefined; } } // Helpers to identify field types isLookupField(fieldApiName) { return ['AccountId', 'ContactId'].includes(fieldApiName); } isTextAreaField(fieldApiName) { return fieldApiName === 'Description'; } isPicklistField(fieldApiName) { return ['Type', 'Reason', 'Product__c'].includes(fieldApiName); // Adjust Product API name if needed } isTextField(fieldApiName) { return fieldApiName === 'Subject'; } handleSubmit() { // Validate all required fields const allValid = [...this.template.querySelectorAll('lightning-input, lightning-textarea, lightning-input-field')] .reduce((validSoFar, inputCmp) => { inputCmp.reportValidity(); return validSoFar && inputCmp.checkValidity(); }, true); if (!allValid) { this.dispatchEvent( new ShowToastEvent({ title: 'Error', message: 'Please fill in all required fields.', variant: 'error' }) ); return; } // Collect field values const caseFields = {}; [...this.template.querySelectorAll('lightning-input, lightning-textarea, lightning-input-field')].forEach(input => { caseFields[input.name || input.fieldName] = input.value; }); // Call Apex to create Case createCase({ caseFields }) .then(result => { this.dispatchEvent( new ShowToastEvent({ title: 'Success', message: 'Case created successfully!', variant: 'success' }) ); // Navigate to the new Case record this[NavigationMixin.Navigate]({ type: 'standard__recordPage', attributes: { recordId: result, objectApiName: 'Case', actionName: 'view' } }); }) .catch(error => { this.dispatchEvent( new ShowToastEvent({ title: 'Error creating Case', message: error.body.message, variant: 'error' }) ); }); } handleCancel() { // Clear all input fields [...this.template.querySelectorAll('lightning-input, lightning-textarea, lightning-input-field')].forEach(input => { input.value = null; }); } }
caseCreator.css
Adds basic layout styling:
.slds-form-element { margin-bottom: 1rem; }
Step 4: Test and Configure
- Add the LWC to a Lightning Page (like an Account record page or standalone utility page)
- Update your Custom Metadata Type records anytime to add/remove fields—no code changes needed!
- Test submitting a Case to confirm required fields are enforced and the record is created correctly.
内容的提问来源于stack exchange,提问作者Mukul Gautam
相关产品推荐
相关产品推荐

