[SalesForce] Building an efficient LWC form without record-edit-form

I'm new to Lightning web components (LWC) and I'm trying to find the best way to build an input form where I need to control the submit process – I need to do extra validation and then construct a contact object to submit to an Apex method then do my own record insert.

The form has some contact fields – first name, last name, email, etc. Some fields are required, some are not. We're starting from blank, there will be no existing data pre-filled.

When the user submits the form, I need to do some extra validation. Then I want to construct a contact from the data and call Apex to find any matching contacts (using duplicate rules). Based on those results, I'll insert a new contact or update an existing contact.

I started by looking at lightning-record-edit-form, but lightning-input-field doesn't have a required attribute and I didn't like the workarounds I found in web searches.

So instead, I'm using lightning-input fields with a lightning-button. When the user submits, I get the data for each input using querySelector and construct the contact object, then I call the Apex method,

I have two questions:

  1. Is there a way to mix lightning-input and lightning-input-field on lightning-record-edit-form so that I can use required attribute where I need it, yet still get the lightning-input data into the contact object instantiated by the form?

  2. If I can't do #1, is there a more efficient pattern than the one I'm doing below?

The HTML page:

<template>
    <lightning-input data-formfield="firstName" label="First Name" required></lightning-input>
    <lightning-input data-formfield="lastName" label="Last Name" required></lightning-input>
    <lightning-input data-formfield="mobile" label="Mobile" type="phone" class="spec-req"></lightning-input>
    <lightning-input data-formfield="email" label="Email" type="email" class="spec-req"></lightning-input>
    <lightning-button label="Submit" click={handleFirstSubmit}></lightning-button>
</template>

The JS code:

handleFirstSubmit() {
    ...
  let submittedContact = { 'sObjectType': 'Contact' };
  submittedContact.FirstName = this.template.querySelector('lightning-input[data-formfield="firstName"]').value;
  submittedContact.LastName = this.template.querySelector('lightning-input[data-formfield="firstName"]').value;
  submittedContact.MobilePhone = this.template.querySelector('lightning-input[data-formfield="mobile"]').value;
  submittedContact.Email = this.template.querySelector('lightning-input[data-formfield="email"]').value;
    ...
  // Call Apex method and pass submittedContact.
}

Best Answer

Since lightning-input-field now has a required attribute, I decided to use lightning-record-edit-form. I'm using both lightning-input-field and lightning-input because some of the form fields reside in different objects. I use an onsubmit handler to do the validation that I needed.