Manually implement Customer Account Fields using an existing registration form

Custom Account Fields has two ways to integrate with customer registration and profile editing. The easiest and most reliable way is to utilize the quick install which uses an embedded javascript form that works perfectly with all field types.

The second way to integrate with the app is to create your customer registration form in liquid, and tie your registration form together with the fields you define in the app.

The "manual" method does not support file or image upload field types since we utilize advanced security measures for transfer of files into and out of the account that are not compatible with basic file input fields.

Some app features will work differently when using this manual integration method. Features such as field validation and conditions should continue to work (although it's possible that the way your form is structured could cause issue with conditions).

Field settings such as the field width, default values, placeholder text, additional classes and field descriptions will not work (although they will work in the admin interface within the app itself). Those features can be set manually in your registration form through standard HTML attributes.

Step 1. Create new liquid snippet "customer-fields-js.liquid"

Copy in the contents from the link below. The javascript supports several "callback" methods that will allow you to edit the functionality of the form when there are errors and messages to be displayed to the user.

https://gist.github.com/donutdan4114/ed3a7745c07bc2c8e596880fc07640dc

Step 2. Create your custom fields in the app

Create the new custom fields you want in the app. If you already have a customized user registration form you can name the new fields the same name. Image and file upload fields are not supported using this method.

Step 3. Create your customer registration form in "customers/register.liquid"

Fields need the name attribute of "customer[machine_name]", where "machine_name" is the field machine_name as defined through the app. See examples below of how various field types HTML could be formatted:

  <div>
     <label for="Accepts">Sign-up for our email newsletter</label>
     <input type="checkbox" name="customer[accepts_marketing]" id="Accepts">
   </div>
    <label for="text">Textfield</label>
   <input type="text" name="customer[text]" id="text">
    <label for="textarea">Textarea</label>
    <textarea name="customer[textarea]" type="textarea" id="textarea"></textarea>
    <label for="dropdown">Dropdown</label>
   <select name="customer[dropdown]" type="select" id="dropdown">
     <option value="">none</option>
     <option value="one">one</option>
     <option value="two">two</option>
     <option value="three">three</option>
     <option value="four">four</option>
   </select>
    <label>Radios</label>
    <label>
      <input name="customer[radios]" type="radio" value="">none   </label>
    <label>
     <input name="customer[radios]" type="radio" value="one">one   </label>
    <label>
     <input name="customer[radios]" type="radio" value="two">two   </label>
    <label for="number">Number</label>
    <input name="customer[number]" type="number" id="number">
    <label>Checkboxes</label>
    <label>
     <input type="checkbox" value="one" name="customer[checkboxes][]">
     <span>one</span>   </label>
    <label>
     <input type="checkbox" value="two" name="customer[checkboxes][]">
     <span>two</span>   </label>
    <label for="date">Date</label>   <input name="customer[date]" type="date" id="date">

Ideally your fields configuration in the app should mimic what you have coded in the register template. For example, dropdown, checkboxes, and radios fields should have the same options and default value.

Step 4. Include "customer-field-js" snippet on your register page

{% include 'customer-fields-js' %}

This should be placed before your form.

Step 5. Customize messages and errors

There are several key callbacks you can implement in the javascript to control how form messages and field errors are displayed.

Example of callbacks and data passed to them.

 // Callback whenever a message should be displayed to the user.
onDisplayMessage: function(data) {
   data (object) {
     form: form#create_customer (form element),
     message: "Please correct the errors below and try again.",
     message_type: "error" (can be "success" or "error")
   }

// Example of how to display a form error.
   $(data.form).prepend(data.message);
 }

// Callback when a field has an error.
onFieldError: function(error) {
   error (object) {
     error: "Value must not contain "bad_string".",
     error_type: "not_contains",
     field: "first_name",
     label: "First Name",
     value: "m3_bad_string"
   }

  // Example of how to display a field error:
  $('[data-machine-name="' + error.field + '"]').after(error.error);

  // We can use the data-machine-name selector because the javascript sets
  // those attributes on form elements for us.
}


// Callback when a field is loaded and data attributes applied to the element.
 onFieldLoaded: function(data) {
   data (object) {
     field_name: "text", // Field machine_name.
     $el: (element), // jQuery element.
     field: (object) 
{ 

       // Field info.
       type: "text",
       value: "customer entered value",
     }
   }
 }