You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开发支持动态字段配置的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 like AccountId, 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)
  • Add records for your required fields first: Account, Contact, Type, Case Reason, Product, Subject, Description—set Is Required to 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 16:28:11