So you want to build forms?


Looking to build forms on the Salesforce Platform? You’ve got multiple options, spanning the entire low-code to pro-code continuum. Representing low-code, Dynamic Forms in Lightning App Builder and Screen Flows in Flow Builder. Hanging out in the middle of the continuum is the ability to extend Screen Flows with LWCs. And representing pro-code is the LWC framework and its ever-growing library of base components.

Options are great, but how do you determine which one (or which combination) is the right option? That’s where this doc comes in.

  • Takeaway #1:?For basic create/edit forms on a Lightning record page on desktop, use Dynamic Forms.
  • Takeaway #2:?Use Flow to build multi-screen forms. If you need to also meet precise UX requirements, layer in LWCs.
  • Takeaway #3:?If you need test automation, start with LWC. You can write unit tests for any LWC, regardless of where you plan to embed it.

A bit later, we’ll go into depth on these use cases and more, including how to choose between click-based tools and code-based tools (and when to combine them), but here are the major considerations to start with when choosing between these three options.

1Dynamic Forms is a feature of Lightning Pages. Lightning Pages are declaratively configured with the Lightning App Builder. As part of Summer ‘20, Dynamic Forms is a non-GA preview feature, and we aim to GA it in Winter ‘21.

  • Available:?works fine with basic considerations.
  • Not Ideal:?possible but consider an alternative tool
  • Roadmap:?estimated to support by Summer ’21 (targeted go-live mid-June 2021). Our?forward-looking statement?applies to roadmap projections.
  • Not Available:?no plans to support in the next twelve months.

Quickly, let’s elaborate on the takeaways and table above.

  • If Lightning Pages and Dynamic Forms meet your requirements, use them.?That means you need a create or edit form for exactly one object on desktop, and you need to control field visibility. Lightning App Builder may be a declarative tool, but this is where it excels. If your requirements aren’t met by those constraints, keep reading. Either Flow or LWC will be a better fit.
  • If you need additional logic or actions?behind the form, use Flow or LWC.?Both tools offer ways for your solution to do more than create or edit a single record. That “more” might be more advanced logic, such as branching or iteration, and it might be more actions like integrating with external systems, sending emails, or pushing notifications to a user’s mobile app.
  • If you’re building a multi-page form or a wizard, start with Flow.?Flow provides a linear navigation framework for orchestrating multiple forms together. You could use LWC to construct your own framework for navigating between forms, but we recommend letting Flow do the hard work for you, so that you can focus on the forms themselves.
  • Got sophisticated UX requirements? Need to dynamically handle more than visibility? Build that stuff in a LWC.?If your requirements can be achieved with simple theming and column-based layouts, you can build your forms directly in a low-code builder. For more fine-grained control over your form’s style, you’ll need the ultimate flexibility of LWC.

Keep in mind, your choice doesn’t have to be an either/or – you can combine the power of multiple options. For example, if you need both Flow’s built-in navigation system and the full styling flexibility that LWC offers, use them together.

What About Page Layouts?

You may notice that Page Layouts are missing from our comparison in this document. Moving forward, the recommended way to configure record detail pages is Dynamic Forms in Lightning App Builder using Lightning Pages. It’s been a long time since we enhanced page layouts, and that trend will continue. Here’s why.

  • Dynamic Forms are more flexible – you can place fields and sections wherever you want directly in Lightning App Builder, where you can take advantage of sections, tabs, and accordions. And just like you can do with components on the Lightning page, you can control the visibility of your fields and sections without defining multiple page layouts or record types.
  • With Accordion and Tab components, you can restrict the amount of fields that are displayed initially. Guess what that means? Faster page load times.
  • Layout management is simpler with Lightning Pages, since you can manage everything about your pages from Lightning App Builder – whether that’s the contents of the page or which users have access to the page. It’s no longer necessary to make updates in your page layout to make a change happen in your Lightning page. Not to mention, with the power of component visibility rules, you no longer have to create multiple pages (or page layouts) to control who sees which fields when. And that also means you only need to assign users a Lightning page rather than doing that and also assigning the page layout.

As of this non-GA preview, Dynamic Forms has a handful of limitations. We recommend using Dynamic Forms wherever possible, and falling back to Page Layouts only when necessary. For reference, here are the high-level gaps we’re aware of and when we plan to fill them.

Timeline for Lightning Pages & Dynamic FormsSupport for standard objectsSpring '21Support on the Salesforce mobile appSummer '21Support in Community record pagesFar FutureConfigure tab visibilitySummer '21Show, hide, and collapse section headersSpring '21Conditional formatting of fieldsSummer '21Conditionally make a field requiredSummer '21Conditionally make a field read-onlySummer '21

What About Performance?

Any performance considerations related to Dynamic Forms, screen flows, and LWC center on what framework those technologies themselves sit on. The ones that are based in LWC (besides, of course, an LWC) are going to outperform ones that are based in Aura. The LWC framework offers better performance because core features are implemented natively in web engines instead of in JavaScript via framework abstractions. If you’re not familiar give?this blog post?a read.

Now, which framework are our form technologies using? In other words, which form technologies benefit from this superior performance?

  • Dynamic Forms, which is integrated in the Lightning pages metadata, are built on a brand new foundation that uses the LWC stack, which will enable us to implement some long-requested features. Building everything from ground up takes time, which is why Dynamic Forms currently has some limitations – like standard object and mobile experience support.
  • Screen flows are built on a mixed stack. Today, the flow runtime client uses an Aura container application, and most of the individual components you can display in a flow screen are Aura. A few have been converted to LWC so far: Text, Checkbox, Date, and DateTime. The Flow team is committed to converting the flow runtime client to use 100% LWC components instead of Aura, with the exception of customer-created (that’s you!) Aura components. We can’t convert those for you, but there is an excellent Trailhead module that explains how to do so:?Lightning Web Components for Aura Developers. It goes without saying: if you’re thinking about building a custom component for a screen flow or any other container, always go LWC.
  • LWC is built on ... LWC of course. This is a freebie. ??

Navigating The Low-Code To Pro-Code Continuum

Most of this doc focuses on helping you understand what functionality and level of customization is possible with Dynamic Forms, screen flows, and LWC.

  • LWC is the most customizable and robust option for building a form, but it has the fewest guardrails in place. It’s up to you to build a component in a way that ensures security and scalability.
  • Dynamic Forms is the least flexible, but there are far fewer opportunities for missteps.
  • Flow sits somewhere in the middle – more powerful than Dynamic Forms but not quite at the level of LWC. By the same token, it has fewer guardrails than Dynamic Forms but is harder to break than custom code.

If multiple tools fit the bill, the decision comes down to which tool is the right one for your team.?Introducing the Salesforce Architect Decision Guides?on the Salesforce Architects blog introduces some aspects to consider when making that decision.

We won’t go into the details of each of those aspects here, but what we will do is interpret them for the specific tools this doc is assessing.

Specialized Skills: What percentage of your team is already an expert in the tools you’re comparing? How many makers are well-versed and familiar with LWC or Javascript? How about makers who are experts in Flow Builder or have expressed an interest in dipping their toes? Generally speaking, Dynamic Forms and Flow are more attainable for a broader population of makers. Dynamic Forms is the most declarative form-building tool and will always be easier to learn than Flow. That said, the Flow team is committed to getting that bar as low as possible.

Delegation of Delivery: Just because part of your requirements require LWC doesn’t mean the entire solution needs to be built with LWC. Consider how you can build your solution modularly, such that the bits that require LWC are coded, and the bits that don’t are built in a low-code solution. Doing so maximizes the impact of a diverse team and ensures that makers are solving problems appropriate for their specialization.

Maintainability & Long-Term Ownership: If you anticipate this form will be maintained in the future by pro-code makers and your current team is highly familiar with Javascript frameworks, it makes sense to choose LWC as your solution of choice. If, on the other hand, low-code makers will be responsible for maintaining the form, consider how you can make the solution as configurable as possible for that audience.

Diving Deeper

As promised, we’re diving deep into a variety of comparison points and functional differences between Dynamic Forms, Screen Flows, Screen Flows with embedded LWCs, and the LWC framework itself.

Object Impact

What objects will the form operate against? Just one object? Multiple objects?

Dynamic FormsScreen FlowScreen Flow + LWCLWCSingle ObjectAvailable (Custom Objects)AvailableAvailableAvailableCross-ObjectNot AvailableAvailableAvailableAvailableObject-AgnosticNot AvailableAvailableAvailableAvailable

If your form operates against a single Salesforce object, any of the tools we’re comparing will work. Things get a little more complicated with cross-object or object-agnostic forms. By?object-agnostic, we mean inputs that don’t map to any Salesforce object. Perhaps your form represents a data structure that you’ll send to an external service, like Stripe or Docusign. Or perhaps you’re using several inputs in your form to calculate a value, and then committing that value to the database.

For both cross-object and object-agnostic forms, Flow is a solid option. The components available in flow screens are agnostic by nature, so you can choose what to do with that data behind the scenes. For example, use the data entered in one form to create multiple records behind the scenes, or use the data to perform other actions like generating Chatter posts, sending emails, or connecting to external services.

For simple cases, using existing LWC components like?lightning-record-form?can be a simple way to lower code needed to provide a robust solution. However, for scenarios where multiple objects are involved, Flow provides cohesive control for all objects and removes complexities of developers having to traverse complex relationships and dependencies.

Form Scope

Do you need a single screen, or will the user need to navigate between multiple screens to complete a task?

Dynamic FormsScreen FlowScreen Flow + LWCLWCSingle-Screen FormAvailableAvailableAvailableAvailableMulti-Screen FormNot AvailableAvailableAvailableNot Ideal

If you can get all of your user’s inputs from a single-screen form, start with Dynamic Forms. If you need more functionality than what Dynamic Forms offers, the choice between Flow and LWC depends on a few other questions.

  • What skills does your team have? For a more admin-heavy organization, we recommend starting with Flow. For a more developer-heavy organization, start with LWC.
  • Is it OK to display a navigation bar at the bottom of your form? If the flow navigation bar is undesirable UX, swing towards LWC.
  • What needs to happen behind the form? If you need the behavior to be configurable by an admin, build a flow. Otherwise, build a LWC.
  • If you choose Flow, you may need to build a LWC anyway to achieve the right UX. If you’re already building a LWC to style your form correctly, consider whether?embedding that component in a flow?is overkill.

If, on the other hand, your solution looks like a wizard, where the user navigates between multiple screens, think Flow. Flows come with a built-in navigation model, so you don’t have to build and maintain that yourself. The navigation is linear in nature, with forward-moving actions (Next and Finish), backward-moving actions (Previous), and a mechanism for saving the form for later (Pause). You can also build a form with non-linear navigation if it suits your purposes. For a great example of that, check out this Salesforce Labs package:?Digital Store Audit.

Location

Where do you want to embed the form?


1?Flows and LWCs are supported in the Salesforce mobile app, but the Salesforce mobile app doesn’t support all the ways you can embed flows and LWCs. For example, object-specific actions are supported in mobile, but utility bar items are not.

Since they require a record context, Dynamic Forms are supported only in Lightning Record pages. However, Dynamic Forms aren’t supported in Lightning Community pages. This limitation is in place because Lightning communities don’t use the underlying framework that Dynamic Forms depends on: Lightning Pages. We are definitely evaluating this as we do often hear feedback of wanting Dynamic Forms in Communities.

Roadmap!?Today, Dynamic Forms are supported only for custom objects on desktop, but Salesforce is actively working on supporting them for standard objects and the Salesforce mobile app as well.

You can build flows that require a record context or flows that work globally. As such, you can embed flows in a variety of locations. For the record-contextual flows, that might be a Lightning record page, a Community record page, an object-specific action, or an Actions & Recommendations deployment. For the global flow, that might be the utility bar, other Lightning or Community pages, a snap-in, or an external application. Flows aren’t currently supported as global actions, but as a workaround you can wrap the flow in an Aura component.

LWC supports a high degree of reusability, since you are creating components and able to associate with targets via metadata across Salesforce, Communities, and even in?Open Source Projects. LWC components can also be embedded inside of your own website via?Lightning Out. LWCs aren’t currently supported as quick actions (object-specific or global), but – much like you can with flows – as a workaround you can wrap the LWC in an Aura component.

None of the form technologies covered in this doc are officially supported in Mobile SDK templates today. If Mobile SDK is paramount to your use case, you’re better off building your form in natively in your mobile application or building a Visualforce page.

Roadmap!?The Mobile SDK team is actively working on supporting LWCs within Visualforce pages.

Controller

What actions or logic do you want to be performed behind the scenes?

Dynamic Forms is perfect if you need to use the values in your form to create or update a record. For anything beyond that capability, you’ll need to leverage Flow or LWC. That might be a layer of decisioning or iteration, or you might generate Chatter posts or emails using the inputs from the form.

Flow offers standard actions for posting to Chatter, sending email, and interacting with Quip documents, so you don’t have to write code for the same operations. LWC offers rich interactions with single records and related objects through the use of wire adapters that interact with UI API. LWC can also interact with multiple records when using the wire for?getListUi.

Both Flow and LWC integrate with Apex, so you can easily close the gaps in whichever solution you choose. For example, if you require filtering records from an LWC you can always use the wire adapter for Apex to create complex SOQL queries. If you’re swayed by the click-based story, consider Flow as a viable alternative to an Apex controller for your server-side needs.

A secondary question to answer here about the actions is whether you want to immediately commit them, or defer them to a particular part of your form. This is especially relevant if you’re in a multi-page form. Flow makes it easy to combine inputs from multiple forms (flow screens) and use them much later in the wizard (flow) to perform some operations. In fact, we recommend designing flows in just that way – perform actions at the end – in case the user bounces back and forth between screens, thereby changing their answers.

Do you need to control which operations occur in which transaction?

Transactions and?governor limits?are a way of life on the Salesforce Platform. If your use case is fairly simple, it may not be as important to control what transaction a particular operation occurs in. However, there are a few use cases where you might want to combine multiple operations into a single transaction rather than performing those across multiple transactions. Some examples:

  • To Rollback Or Not to Rollback: That is the question. Let’s say your form creates multiple records behind the scenes. If the third record fails to be created, should the first two records be rolled back? If each of your actions are independent of each other, feel free to execute them in separate transactions. If they’re dependent, however, and you want the failure of one to also rollback the others, implement them in a single transaction.
  • Downstream Impact on Governor Limits: Especially when your form creates or updates a record, consider what the downstream implications of that operation are. What processes, workflow rules, flow triggers, Apex triggers, or other items in the save order are going to fire based on this record change? And how do those collective changes impact the governor limits being consumed in that transaction? If a particular record change will result in a lot of downstream changes that impact your limits, consider isolating that record change into its own transaction.
  • Batch Processing: Even in a UI context, you may need to batch multiple updates together. Let’s say your multi-screen form iterates over a large group of records. Rather than committing a record update after each screen, wait until you’ve collected the updates for all of the records and then submit one request to update all the records.

When you use a Dynamic Form to create or edit a record, you’re only ever performing one operation, and that operation is always the start of a net-new transaction.

When building a screen flow, you have significant control over what happens in a given transaction. Screens and Local Actions act as boundaries between transactions. Here’s a high-level summary of how transactions are managed in the screen flow architecture.

  1. The end user interacts with a screen, and then clicks?Next.
  2. The client posts a request to the API with the inputs.
  3. The API receives the request, and a transaction and database connection are opened. The API then then calls the Flow engine to invoke the request.
  4. The Flow engine takes over and follows the appropriate path in the flow definition – until it hits a Screen or Local Action node. The engine then returns information about that node to the API.
  5. The API creates a response object that contains the details of the next screen to render, and returns that object to the client. At this point, database changes are committed (cue the save order execution), and the database connection and transaction are closed.
  6. The client uses the API response to render the next screen for the user to interact with.
  7. Rinse and repeat.

In other words, screens “break” transactions. When that happens, any pending actions or DML are committed, the prior transaction is closed, and a new transaction is started. The right design – which operations you group into a given transaction – is your call.

On the left, you can see a flow that collects inputs across multiple screens, and then performs several actions in one transaction.


The flow on the right performs each operation in a separate transaction.

For more details, check out these resources on?Salesforce Help:?Flows in Transactions?and?Flow Bulkification in Transactions.

Your ability to control the transaction from an LWC comes down to the underlying services that LWC is using to perform its operations. If you’re using the?lightning-record-form?base component, the underlying operation (creating or updating the record) happen in a standalone transaction as soon as the form is submitted. In general, these rules apply:

  • Each UI API call is isolated into its own transaction.
  • If you need to perform multiple operations within a single transaction, send the inputs off to a server-side technology like an Apex controller or a flow. The regular transaction rules for that technology apply.

Do you need to integrate with external systems?

Both Flow and LWC support API integrations with an assist from Apex. Additionally, Flow supports External Services – which enables you to declaratively generate process integration building blocks. Anyone can integrate with legacy systems or web apps, as long as those services can be described with an OpenAPI-compliant schema. For example, you can generate actions for integrating with Slack or Google Sheets, and then configure your flow to post to a Slack channel or add a row to a particular Google Sheet. The end-to-end solution involves touching zero lines of code.

Regardless of whether you do so with custom Apex or an External Service, a callout is a callout. Here’s what you need to know.

  1. A callout can take a long time.
  2. When a callout is executed synchronously, it's performed while a database transaction is open.
  3. Salesforce doesn't let you keep a database transaction open if you've got pending database operations.

The main limitation to keep in mind is the danger of what we call a?dirty transaction, where you perform a create, update, or delete operation and then, in the same transaction, execute a callout. This pattern isn’t allowed because of consideration #3, which of course exists because of considerations #1 and #2.

You can work around this limitation by breaking the transaction. As we mentioned above, screens and local actions both reintroduce the browser context, which breaks the transaction. Use a Screen to break a transaction if it makes sense to display a new form to the user prior to making the external callout. If it doesn’t, we recommend a no-op local action, like?this one available to install from?UnofficialSF. Not familiar with local actions? They’re Aura components with no markup; the flow executes the?invoke()?method in the component’s Javascript controller. They’re the only actions available in Flow that aren’t performed server-side. In addition to being useful for breaking transactions, local actions are great for performing browser-level actions like firing toasts or force navigating the user.

On the left is a flow that updates a record, then uses a callout to request a list of Slack channels. This flow fails at runtime, because the callout occurs in the same transaction after a pending database operation (the record update).


To the right is a flow that updates a record, executes a no-op local action, and then uses a callout to request a list of Slack channels. This flow succeeds at runtime, because the callout is performed in a separate transaction from the record update.

The impact of callouts on the transaction is less complicated with LWC. Generally speaking, you’ll perform your data operations using the Lightning Data Service, and then use an Apex controller to make the external callout. This design protects you from dirty transactions, since the LDS call is isolated in its own transaction separate from the Apex callout.

What are your requirements for reusability and modularity?

Dynamic Forms doesn’t support reuse. Each Dynamic Form is tied to a specific Lightning record page for a specific object. Though you can assign that Lightning record page to multiple apps, profiles, and so on.

Much like you can write libraries, utilities, and components that are intended to be used across multiple other components, you can apply similar design patterns when creating flows with the power of?subflows. Save your flows in smaller, more modular buckets, and then call them from other flows by using the Subflow element. If your design calls for it, you can build a flow that both stands on its own and is useful as a subflow of another one.

Flow and LWCs can both be built for reuse, such that you can embed them in a variety of locations including external sites and Lightning Out applications.

Validation

What are your validation requirements?

Dynamic FormsScreen FlowScreen Flow + LWCLWCRespect System-Level ValidationAvailableAvailableAvailableAvailable

All technologies that attempt to create or update a record adhere to system-level validation – whether those are classic validation rules or custom validation built into an Apex trigger. No matter what technology you use to perform a record change, every change goes through the save order. That means in addition to validation rules, the record change is processed by any number of before- or after-save flows, before or after triggers, escalation rules, assignment rules, and more. If you haven’t already, now’s a good time to bookmark and familiarize yourself with the?Order of Execution.

Inputs on a flow screen are by nature unbound, so the screen itself doesn’t natively adhere to system-level validation associated with a particular object. Whatever values you use to Create or Update records, however, are processed by the save order, which means they pass through the object’s system-level validation.

Dynamic FormsScreen FlowScreen Flow + LWCLWCCustom Field-Level Validation Specific to this FormAvailable*AvailableAvailableAvailableCustom Form-Level ValidationNot AvailableNot AvailableAvailableAvailable

Just like page layouts, Dynamic Forms let you set requiredness and read-only state at the page level. However, you can’t override system-level settings.

Flow provides flexibility for customizing validation on a form’s inputs. While some checks are performed in the client (like flagging missing required fields or incompatible values), none of the client-side validation blocks the user from trying to navigate. The real stuff happens on the server. When a user clicks?Next, Flow sends the inputs to the server for validation. If any inputs are returned as invalid, navigation is blocked and the appropriate error is displayed. The server validates the inputs by checking:

  1. The input’s requiredness setting, or whether the entered value is compatible with the underlying data type.
  2. Custom validation on that input: Several standard components (Checkbox, Currency, Date, Date/Time, Long Text Area, Number, Password, and Text) support custom validation on a per-screen basis. Supply a Boolean formula expression and an error message to display when the formula expression isn’t met.
  3. Custom validation on the underlying component: If you’re building a custom LWC for a flow, add your own validation code to the?validate()?method.

On the LWC side, most base components perform their own client-side validations. For example,?lightning-record-form?respects system-level requiredness, but not page-level requiredness. For your custom components, you can build your own validation mechanisms.

Security

What are your security requirements? Should the form check the user’s access before performing certain operations??(Especially important when building for guest users)

Dynamic FormsScreen FlowScreen Flow + LWCLWCElevate User PermissionsNot AvailableAvailable*AvailableRequires Apex

Do your users have field-level security to see this field? Do they have permission to create records for this object? What about access to this specific record, based on your org’s sharing rules? When something runs in?user context, we enforce those access checks. Users can run a case update form only if they have the ability to update cases, the appropriate field-level security, and access to the record in question.

But what if you don’t want to grant users a particular permission? What if you want users to be able to perform a particular operation when they're using?your?form, but not through any other form or interaction? That’s where?system context?comes in. System context is a way to elevate the running user’s permissions for the duration of the session, so that the user doesn’t need Update access to the Case object to successfully complete your case update form. This is especially useful for unauthenticated communities. Instead of granting guest users dangerous abilities, set your form to run in system context. Of course, system context is a double-edged sword and you should use it only when necessary. When a form runs in system context,?every?single CRUD operation bypasses object- and field-level security & sharing – not just the specific operation you care about.

Note that system context has no bearing on who Salesforce considers the actor – the name you see in the Last Modified By field. For each operation that your form performs, such as the case update, the actor is the running user even if the form runs in a different context.

  • Dynamic Forms always run in user context, and there’s no way to override this behavior.
  • Screen flows run in user context by default, but you can set them to run in system context. It’s your choice whether the flow should grant access to all data or if it should still enforce record-level access like sharing.
  • If you embed a Lightning component in a flow that runs in system context, the flow doesn’t override the component’s context. If you need to bypass user access checks, we recommend using the flow to perform those operations and pass the appropriate data into or out of the Lightning component.
  • If your flow calls Apex actions, there are some more nuances to understand. If the Apex class is set to?inherited sharing, it runs in system context with sharing no matter what the flow is set to. If the class has no explicit sharing declaration, it runs in system context without sharing no matter what the flow is set to. If the class is set to?with sharing?or?without sharing, it does so and overrides the flow's context.

Best practices:

  • Leave the flow to run in its default context unless you need to elevate the running user’s access for a specific operation.
  • If the flow performs a variety of operations and not all of them require elevated access, use a subflow to isolate the operations that should run in system context.
  • LWCs run in user context by default, but you can override that in an Apex controller.
  • Operations performed through the UI API are run in user context.
  • Operations performed through an Apex controller depend on that class. To perform those operations in system mode, set the Apex class to?with sharing?or?without sharing.

Do you want to control who can access the form?

Dynamic FormsScreen FlowScreen Flow + LWCLWCRestrict Who Can AccessAvailableAvailableAvailableAvailable

To address this requirement, often you can look to the container you’re embedding your form in. For example, you can assign Lightning pages to be available for particular apps, record types, or profiles. If particular inputs in your form are sensitive, use visibility rules to further control what is displayed to who – this feature applies to both Dynamic Forms and screen flows.

You can?restrict a flow?to particular profiles or permission sets, much like you can an Apex class or Visualforce page. By default, flows are unrestricted, which means that any user with the Run Flows user permission can run it.

Best Practices:

  • If you’re exposing a flow to guest users, grant the guest user profile access to only the flows they need. You can add Run Flows to the guest user profile but we consider that a dangerous practice.
  • Be especially careful with flows that operate in system context. We highly recommend you restrict those flows to a particular set of users, since they have fewer checks and balances in place to protect your data.

For LWCs, you can check the running user’s permission assignments to confirm if they have a particular standard or custom permission. Directly from Javascript, you can import Salesforce permissions from the?@salesforce/userPermission?and?@salesforce/customPermission?scoped modules. Or you can use Apex to check the same.

Do you want to control where the form can be embedded?

Once a screen flow is activated, it’s available in all the locations that screen flows are supported, regardless of whether you intended it to be available everywhere or not. That said, Flow Builder supports multiple types of flows that have screens. The bread-and-butter type is Screen Flow, but there are a few other specialized types that are restricted to specific locations. For example, only Field Service Mobile Flows are supported in ... you guessed it, the Field Service mobile app. The same story goes for Contact Request Flows, which are supported only in communities.

Regardless of the flow type, the individual making the flow has no control over where the flow can be embedded. The flow will be available in every location supported for that flow type.

LWCs, on the other hand, are available in a given location only when it’s been added as a valid?target. So you can make a component available on Record pages and not available as a utility bar item.

Interaction Design

Should your form react dynamically to interactions or conditions?

Static forms are a thing of the past. Today, it’s all about dynamically updating the form with the right properties and values for this user, this time, this place. Let’s talk about what’s possible in this vein for Salesforce’s form-building tools.

Visibility can be dynamically controlled in all three tools. Both Dynamic Forms and Flow Builder address this with features called Component Visibility. With this, you can declaratively show or hide fields based on other values on the form or whether the user is on a mobile device or not.

  • With Dynamic Forms, you’re limited to fields on the associated object and there are some?limitations?on the supported field types and operators.
  • With Flow, you can base a visibility rule on other inputs on the screen, as well as other resources populated earlier in the flow like formulas or values from other records.
  • Device-based Rules:?It’s not obvious from the get-go, but you can use a formula to show or hide a particular field when the user is on a mobile device. Write a flow formula that checks the value of the?$User.UIThemeDisplayed?global variable. If the value is?Theme4t, the user is on the Salesforce mobile app.
  • Evaluating Other Resources:?Manual variable and formula references are evaluated only on the server. So whatever value that resource has when the screen first renders is the value it will have until you navigate to another screen. On navigation, the flow runtime submits a request to the flow engine (the server) and gets back the latest values of the manual variables and formulas. If you expect your visibility rule to update as the user passes through a single screen (aka?onblur), make sure that you’re referencing only values from the other components on the screen.

If you need to dynamically control any other properties, such as whether a field is required or read-only, your best bet in the short term is LWC, where you get full control. That’s especially true if you have bespoke requirements for what to do?onblur?or?onclick.

Roadmap!?For Lightning Pages, which includes Dynamic Forms, we anticipate enabling conditional requiredness, conditional formatting, and conditionally setting an input to read-only in the next 12 months.

Dynamic FormsScreen FlowScreen Flow + LWCLWCStandard Event Handling (such as `onblur`, `onfocus`)Not AvailableNot AvailableAvailableAvailableCustom Event HandlingNot AvailableNot AvailableAvailableAvailable

Now for custom events. If some of your inputs or the entire form need to communicate with something else in the page, LWC is your only option.

For more details, check out?Communicate with Events?and?Communicate Across the DOM?in the?Lightning Components Dev Guide.

Styling

How sophisticated is your desired styling and CSS?

Both Dynamic Forms and flows respect declarative theming features. If you need control beyond what?Salesforce Themes?or?Community Branding Sets?support, you need the wide open spaces of LWC.

Reminder: You can embed Lightning components in flows. So if you need pixel-perfect control over the look-and-feel of your form but want to use the other benefits of flows, like the navigation model, you can have the best of both worlds.

Layout

What are the layout requirements for your form?

Dynamic Forms supports two-column layouts. Dynamic Forms can be broken up into individual sections with fields. These sections can be placed in components such as tabs and accordions to create easy to use and organized layouts.

Flows can be rendered using a two-column layout. This feature is supported only when you add a flow to a Lightning or Community page, or when you use a direct flow URL, such as for a custom button. Due to our near-term roadmap, we recommend not using this feature.

Roadmap!?Salesforce is actively working on multi-column screens for Flow Builder. When this feature ships, you’ll be able to declarative configure screens with up to 4 columns.

With LWC, you can use?lightning-record-[edit|view]-form?and the supporting?lightning-[input|output]-field?to control layout. The only layout restrictions are those from HTML/CSS.?lightning-record-form?respects the section configuration in the associated page layout – if a section is two-column in the page layout, it’s two-column in this component.

Translation

Does your form need to be localized to other languages?

Dynamic FormsScreen FlowScreen Flow + LWCLWCLabels Entered in the BuilderRoadmapAvailableAvailable*Not AvailableLabels in the CodeNot AvailableNot AvailableAvailableAvailable

If you’ve localized your custom fields, those translated labels are respected on Dynamic Forms. However, localization isn’t supported for labels that you add to components in the same Lightning page. For example, the label for a tab in the Tabs component.

Roadmap!?Salesforce is actively working on filling this gap. Soon, you’ll be able to reference?Custom Labels?for any string or rich text property in Lightning App Builder, such as to localize a custom Tab or Accordion label or the title you added to a Report component.

With the power of Translation Workbench, Flow supports translation of user-facing labels for some, but not all, of the available screen components. For the following screen components, you can localize the label, help text, and error message: Text, Long Text Area, Number, Currency, Checkbox, Radio Buttons, Picklist, Multi-Select Picklist, Checkbox Group, Password, Date, and Date/Time.

The other components don’t yet support translation, because they’re Lightning components under the hood and we don’t have a way of identifying which Lightning component attribute should map to label vs. help text vs. error message. The same issue applies for our out-of-the-box actions, like Send Email or Post to Chatter. However, there is a workaround! If you define the translated labels with a?Custom Label, you can reference that custom label in the action or component when you configure it in Flow Builder. Create a flow formula that references the custom label, and reference that formula in the appropriate places in your flow.

Now for LWC. Certain base components automatically inherit translations of the associated object’s fields, help text, and validation messages if they’ve been configured in Translation Workbench. For example?lightning-record-form?.

If you need to introduce novel translatable labels in your code, Custom Labels are still the unsung hero. Declare the custom label you need, and then import it into your component from the?@salesforce/label?scoped module.

UI Test Automation

Do you need automated testing?

Consider your requirements for UI test automation.

Unit tests?enable more granular automation and validation that works with industry standard CI/CD systems and tools, which can test the components business logic, its Javascript controller, and its outputs. Going exclusively with low-code you will not be able to self author tests, but Salesforce rigorously tests our end-to-end offerings.

If your component’s methods are complex enough that you want them to be tested individually, put the methods into dedicated JS files. That way you can import them into a LWC and into a Jest test with something like?import { sort } from 'c/utils';.

With?end-to-end (Selenium) automation,?you can simulate how the user interacts with your form. However, these tests can't verify the outputs of each method being performed. You can write these tests for any standard or custom UI – Lightning pages and screen flows inclusive.

This recent blog post?UI Test Automation on Salesforce?compares the various options you have for building end-to-end automation on Salesforce. Included are considerations for when to use a no-code solution from an ISV, build your own custom test automation solution, or use an open source test framework like Selenium WebDriver or WebdriverIO. These solutions are valid for any UI interaction in Salesforce, whether that’s a Dynamic Form in a Lightning page, a screen flow in a utility bar, or an LWC in a flow in a quick action.

Metrics

Do you need to track usage of your form?

If you need to track overall usage and adoption of your form, start with the low-code tools. Both Dynamic Forms and Screen Flows are trackable using out-of-the-box custom report types, though you’ll get more granularity from the Screen Flow tracking reports. If you need to track usage of a LWC, out-of-the-box availability depends on where you’re using that LWC. If it’s on a Lightning page, whatever is available for tracking Lightning page usage applies to your LWC. The same story goes for LWCs that are embedded in flows.

Dynamic Forms themselves aren’t trackable out-of-the-box, though you can track the usage of the parent Lightning page through?Lightning usage objects. To track the standard Lightning pages, use the?Users with Lightning Usage by Page Metrics?custom report type. For the same on custom Lightning pages, use the?Users with Lightning Usage by FlexiPage Metrics?custom report type.

For tracking adoption of your specific form (not just the page it lives in), Flow’s got you covered. Use the “Sample Flow Report: Screen Flows” to answer questions like:

  • What’s the completion rate for this form? Is it being well-adopted?
  • How long does it take users to complete this form?
  • Which screen do users spend the most time on?
  • How often do users navigate backwards?
  • How often do errors occur?

If the standard report doesn’t meet your needs, clone it to make your own changes or build your own from scratch by using the?Screen Flows?report type.

To track the same for an LWC that isn’t embedded in a screen flow or Lightning page, there’s no out-of-the-box option. You can build a DIY solution by using Apex.

要查看或添加评论,请登录

Jack Li的更多文章

社区洞察

其他会员也浏览了