Search code examples
javascripthtmlsalesforcesalesforce-lightninglwc

How can I configure fields in a custom lightning record form as an admin?


I am very new to Salesforce and am currently trying to create a custom LWC for a project that has specific capabilities.

I have created a custom LWC, which is a lightning-record-form to be able to view and edit specific user information/fields. The form works fine in Salesforce, in the sense that I can view and edit all of the fields that I have included.

My next dilemma is that one of the requirements, requires the System Admin to be able to configure which fields are available AND editable for logged in users.

At this stage I'm not quite sure if I have used the right base component (lightning-record-form) for these requirements. I'm also not sure if I am knowledgeable enough yet with the Salesforce platform to know how to configure these fields as an Admin, or if this is even do-able to start with.

Another requirement is to make this form optimized for both Desktop AND Mobile. I understand the lightning-record-form is already optimized for mobile, but is there any way to override the styling if needed? (I haven't played with styling in LWC as of yet).

I have included my code below for reference:

userProfileForm.js

import { LightningElement } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

import Id from '@salesforce/user/Id';
import USER_OBJECT from '@salesforce/schema/User';
import FIRSTNAME_FIELD from '@salesforce/schema/User.FirstName';
import LASTNAME_FIELD from '@salesforce/schema/User.LastName'
import ALIAS_FIELD from '@salesforce/schema/User.Alias';
import EMAIL_FIELD from '@salesforce/schema/User.Email';
import USERNAME_FIELD from '@salesforce/schema/User.Username';
import NICKNAME_FIELD from '@salesforce/schema/User.CommunityNickname';
import TITLE_FIELD from '@salesforce/schema/User.Title';
import COMPANY_FIELD from '@salesforce/schema/User.CompanyName';
import DEPARTMENT_FIELD from '@salesforce/schema/User.Department';
import ADDRESS_FIELD from '@salesforce/schema/User.Address';
import PHONE_FIELD from '@salesforce/schema/User.Phone';
import MOBILE_FIELD from '@salesforce/schema/User.MobilePhone';
import TIMEZONE_FIELD from '@salesforce/schema/User.TimeZoneSidKey';
import LOCALE_FIELD from '@salesforce/schema/User.LocaleSidKey';
import LANGUAGE_FIELD from '@salesforce/schema/User.LanguageLocaleKey';

export default class UserProfileForm extends LightningElement {
    modeName = 'view'; // Sets mode to view in lightning-record-form
    objectApiName = USER_OBJECT;
    userId = Id; // Gets current user id from salesforce

    // Exposes fields to be made available in the form template
    fields = [
        FIRSTNAME_FIELD,
        LASTNAME_FIELD, 
        ALIAS_FIELD, 
        EMAIL_FIELD, 
        USERNAME_FIELD, 
        NICKNAME_FIELD, 
        TITLE_FIELD, 
        COMPANY_FIELD, 
        DEPARTMENT_FIELD, 
        ADDRESS_FIELD, 
        PHONE_FIELD, 
        MOBILE_FIELD,
        TIMEZONE_FIELD, 
        LOCALE_FIELD, 
        LANGUAGE_FIELD
    ];

    handleSubmit(event) {
        event.preventDefault(); // Stops form from submitting
        const fields = event.detail.fields;
        this.template.querySelector('lightning-record-form').submit(fields);
    }
    
    handleSuccess() {
        const toastEvent = new ShowToastEvent({
            title: "Updated Successfully",
            message: "User information has successfully been updated",
            variant: "success"
        });
        this.dispatchEvent(toastEvent);
    }

    handleError() {
        const toastEvent = new ShowToastEvent({
            title: "Update Unsuccessful",
            message: "Something went wrong, please try again",
            variant: "error"
        })
        this.dispatchEvent(toastEvent);
    }
}

userProfileForm.html

<template>
    <lightning-card title="User Information" icon-name="action:user">
        <lightning-record-form
            object-api-name={objectApiName}
            record-id={userId}
            fields={fields}
            mode={modeName}
            onsubmit={handleSubmit}
            onsuccess={handleSuccess}
            onerror={handleError}>
        </lightning-record-form>
    </lightning-card>
</template>

Solution

  • Very nice question and half the battle is knowing what to Google for...

    Many ways to solve it, depending on what you actually need. A purist would tell you could look into fieldsets but they aren't very "native" for LWC yet, you'd need some helper Apex code to pull their definitions. Which is a shame because we can do pretty neat things with fieldsets in Visualforce.

    Before you deep dive into coding it's sometimes worth poking the requirement a bit more. User object is probably bad choice for this because you don't get to control a lot with Profile/Permission Sets. But any other object - sometimes the right answer is to not do it, not make code changes. Make admin show/hide fields properly, in the profile. That way they'll be hidden everywhere, in normal layouts, listviews, reports, not just custom pieces.

    Anyway.

    Probably easiest for your admins is if you expose some parameters they could pass to your component. They could be passed from another component that's calling it but also from the App Builder (the drag&drop page editor), they'd drop your component and then configure it in right side menu.

    If you have time

    If you don't have time

    Jump straight to exercise 7 and there's ready component at the bottom.

    Just notice that this way of doing this (field names as strings, not as @salesforce/schema/...) doesn't come with protection against deleting and renaming. For standard fields on User you're safe, they're unlikely to go away. But for custom objects sometimes a compile time check/deployment error/error when somebody tries to delete the field is a nasty surprise but better than component not running for end users because you forgot to change it...