Skip to content

This module provides a way for admins to build an application/form using LWC's.

License

Notifications You must be signed in to change notification settings

effordDev/sf-application

Repository files navigation

sf-application

Deploy to Salesforce

Demo :todo

Table of Contents

Overview

This module provides a way for admins to build an application/form using LWC's. This is accomplished by building a skeleton structure of your application using the custom objects:

Reference_Application__c
Reference_Application_Language__c
Reference_Application_Section__c
Reference_Application_Section_Language__c
Reference_Application_Detail__c
Reference_Application_Detail_Language__c

The individual instances of an application are represented using the following custom objects:

Application__c
Application_Language__c
Application_Section__c
Application_Section_Language__c
Application_Detail__c
Application_Detail_Language__c

Below is a link to the ERD of the objects involved.

View on canvas

Component Hierarchy:

View on canvas

Getting Started

If you'd like an example application, not a problem, we have you covered.

  1. First clone the repository
git clone https://github.com/effordDev/sf-application
  1. cd into sf-application
cd sf-application
  1. Authenticate into salesforce org you want to deploy (click for help)
sf org login web --alias my-hub-org --instance-url https://exciting.sandbox.my.salesforce.com
  1. Once authenticated, you run the following command to deploy an example Reference Application. The data tree structure can be found documentation/example-application.json
sf data import tree -f documentation/example-application.json   

The output should ressemble:

OutputDataTreeDeployment

Navigate to the App Reference Application Helper To create an application, simply create a Application__c record and populate the lookup Reference_Application__c to the application you want your instance modeled after. This is will trigger a process to write the following mapping:

Reference_Application__c => Application__c
Reference_Application_Language__c => Application_Language__c
Reference_Application_Section__c => Application_Section__c
Reference_Application_Section_Language__c => Application_Section_Language__c
Reference_Application_Detail__c => Application_Detail__c
Application_Detail_Language__c => Reference_Application_Detail_Language__c

Creating Inputs / Display Text

The record type of Reference_Application_Detail__c Determines the type of input.

The following are the currently supported input fields / display types (Record Types):

  • Display Rich Text
  • Display Text
  • Input Checkbox Group
  • Input Currency
  • Input Date
  • Input Date Time
  • Input File
  • Input Flow
  • Input Number
  • Input Picklist
  • Input Radio Group
  • Input Record List
  • Input Text
  • Input Text Area Long
  • Custom Component

To Customize Inputs :

  • Required__c - Determines if the input must be completed before saving the section.

  • Field_Label__c - Label of the input to show on application.

  • Sort_Order__c - Order of which the field should display.

  • Small_Device_Size__c - Determines how the width of the input on a small device.

  • Medium_Device_Size__c - Determines how the width of the input on a medium device.

  • Large_Device_Size__c - Determines how the width of the input on a large device

  • Reference_Parent_Application_Detail__c - Determines parent dependant question

  • Parent_Dependent_Answer__c - Specifies the answer to show child component (when parent is = to answer → child will show)

  • Alignment__c - Configures alignment (Left, Center, Right)

  • Required__c - Specfies if the input should require a value before save (Only available for inputs)

  • Field_Label__c - Label of the input

  • Sort Order - Specifies the order of the details

  • Target Field API Name to do

See SLDS Grid Doc Example

Display Rich Text

Display Text

Input Address

Input Checkbox

Input Checkbox Group

Input Currency

  • Saves value to Input_Currency__c
  • Displays base lightning-input - type="currency"
  • Maximum - Specifies maximum value
  • Minimum - Specifies minimum value
  • Step - The value of step constrains the numbers that users can enter. If you don't specify step, the default value of 1 allows users to enter only integers. To enable decimal number entry, specify a value for step that represents the number of decimal places accepted and the increment. For example, specifying step=".01" permits numbers such as 0.99 and 123456.78. Specifying step=".20" permits numbers such as 18.60 but not 18.61 or 18.70.

Input Date

  • Saves value to Input_Date__c
  • Displays base lightning-input - type="date"
  • Default_Value__c - For Date/Datetime use "TODAY" so set the default to the current date.

Input Date Time

  • Saves value to Input_Datetime__c
  • Displays base lightning-input - type="datetime"
  • Default_Value__c - For Date/Datetime use "TODAY" so set the default to the current date.

Input Email

  • Saves value to Input_Text__c
  • Displays base lightning-input - type="email"
  • Pattern__c - Regex pattern to validate input
  • Message_When_Pattern_Mismatch__c - When using pattern, you can provide a custom validation error message using the message-when-pattern-mismatch attribute.

Input File

  • Displays base lightning-file-upload
  • File_Rename__c - The name that will be set as the file that was uploaded
  • Accepted_File_Types__c - Set valid file types

Input Flow

  • Displays base lightning-flow
  • Flow_API_Name__c - The name that will be set as the file that was uploaded
  • Pass_Application_Id_into_Flow__c - If checked, will pass the Application Id into the flow - recordId (text variable - available for input)
  • To require a flow, Set Require__c = true. Create an output variable called isComplete and set it to true once the flow is valid

Input Lookup

  • Saves value to Input_Text__c
  • Displays base lightning-input - type="search"
  • Object_Label__c - Specifies the label of the object to search
  • Object_API_Name__c - Specifies the object to search
  • Primary_Search_Field_API_Name__c - Specifies the field to search Ex. 'Name' WHERE Name LIKE =: inputString
  • Other_Field_API_Name__c - Specifies another field to show when searching
  • SLDS_Icon_Name__c - Specifies the slds icon to display

Input Number

  • Saves value to Input_Number__c
  • Displays base lightning-input - type="number"
  • Maximum - Specifies maximum value
  • Minimum - Specifies minimum value
  • Step - The value of step constrains the numbers that users can enter. If you don't specify step, the default value of 1 allows users to enter only integers. To enable decimal number entry, specify a value for step that represents the number of decimal places accepted and the increment. For example, specifying step=".01" permits numbers such as 0.99 and 123456.78. Specifying step=".20" permits numbers such as 18.60 but not 18.61 or 18.70.

Input Picklist

  • Saves value to Input_Number__c
  • Displays base lightning-combobox
  • Picklist_Values__c - Semicolon separated list of values (EX. 'Yes; No; Maybe')

Input Radio Group

  • Saves value to Input_Number__c
  • Displays base lightning-input type="radio"
  • Radio_Group_Values__c - Semicolon separated list of values (EX. 'Yes; No; Maybe')

Input Record List

  • Provides a way to add child records to the application
  • Child_sObject_API_Name__c - API name of SObject related to Application__c
  • Child_sObject_Field_Set_API_Name__c - Field set displayed when creating records
  • Child_sObject_Table_Field_Set_API_Name__c - Columns in table showing child records
  • Child_To_Parent_Relationship_Api_Name__c - Lookup/MD API name to Application__c (typically Application__c)

Input Long Text Area

  • Saves value to Input_Text_Long__c
  • Displays base lightning-textarea
  • Radio_Group_Values__c - Semicolon separated list of values (EX. 'Yes; No; Maybe')

Custom Components

To add a custom component to the application choose the record type Custom_Component. Populate Component_Name__c and if you need to pass information to the component you can do using Custom_Component_JSON__c.

In the LWC applicationDetailType.lwc set up a getter to display your component.

This repo comes with two custom components that are ready to be used. Follow the architecture below to add other custom components.

  • c-application-contact-info
  • c-application-account-info

Make sure in your custom component, make sure you have a public property called complete that returns a truthy or falsy value based on if the component is considered complete.

An example can be found in applicationAccountInfo.lwc

This adds a components called applicationAccountInfo.lwc

drawing

You will need to add your component with the appropriate getters in applicationDetailType.html

<template lwc:if={isCustomComponent}>
  <template lwc:if={isApplicationContactInfo}>
    <c-application-contact-info
      lwc:ref="input"
      record-id={recordId}
      section-id={sectionId}
      detail={detail}
      contact={contact}
      language={language}
      languages={languages}
      read-only={readOnly}
      class={inputDisplayClass}
    ></c-application-contact-info>
  </template>

  <template lwc:if={isApplicationAccountInfo}>
    <c-application-account-info
      lwc:ref="input"
      record-id={recordId}
      section-id={sectionId}
      detail={detail}
      account={account}
      language={language}
      languages={languages}
      read-only={readOnly}
      class={inputDisplayClass}
    ></c-application-account-info>
  </template>
</template>

applicationDetailType.js

get isCustomComponent() {
  return this.recordTypeName === "Custom_Component"
}
get customCmpName() {
  return this.detail?.Component_Name__c
}
get isApplicationContactInfo() {
  return this.customCmpName === "c-application-contact-info"
}
get isApplicationAccountInfo() {
  return this.customCmpName === "c-application-account-info"
}
Example of getting JSON.

applicationAccountInfo.js

get customJson() {
  if (isJSON(this.detail.Custom_Component_JSON__c)) {
    return JSON.parse(this.detail.Custom_Component_JSON__c)
    }
  return {}
}

const isJSON = (string) => {
  try {
    JSON.parse(string);
    return true;
  } catch (error) {
    return false;
  }
}

Application Response Flattener

Flatten Application Responses is an invokable Apex method that can be used in a Record-Triggered Flow to write responses from Application Detail records into specific fields on a target object.

  • A Record-Triggered Flow will control when the automation runs to write the responses.
  • Target fields are defined on the Reference Application Detail records.
  • Field data-types are handled by the Apex and are based on the Reference Application Detail record type.
    • The data type of your target field should match, otherwise errors may occur.

Configuration

Target Field Definition

For any application responses that you wish to write to a field, you must first populate the Target_Field_API_Name__c on the Reference Application Detail record.

The Target_Field_API_Name__c should be the API name of the field you wish to write the resonse to on the target object. (The target object will be specified in a Record-Triggered Flow) For Input_Address types use:

  • Street_Target_Field_API_Name__c
  • City_Target_Field_API_Name__c
  • Province_Target_Field_API_Name__c
  • Postal_Code_Target_Field_API_Name__c
  • Country_Target_Field_API_Name__c

Record-Triggered Flow

To allow for configurability of the criteria that trigger the responses to be flattened, a Record-Triggered flow should be created on the Application object, and fire based on your desired criteria (such as Status changing to Submitted)

  1. Create a Record-Triggered Flow on Application
  2. Invoke the Flatten Application Responses Apex method, passing in:
    • Application Id which is the record Id of the Application that triggered the flow
    • Target Object Record Id which is the Id of the specific record you want to write the responses to (where the Target Object Field API Names will be populated with their respective responses.

Coded while petting tokyo🐱‍👤