Manage custom fields

ūüďė

Much of the content on this page deals with a legacy feature of the <COMPANY_NICKNAME>> Identity Cloud (in this case, the JavaScript SDK). If you are currently an Identity Cloud customer and are using the JavaScript SDK, that SDK is still supported. However, if you’re new to the Identity Cloud the JavaScript SDK is no longer available. Instead, you should use Hosted Login for your login and registration needs. See Configure social login in Hosted Login to learn how to implement social login in Hosted Login.


Create a custom field

Fields are means of connecting data input from the user to the Capture database. Unlike forms, fields are defined in three places:

  1. The schema
  2. The slow
  3. The HMTL markup (as JTL tags)

To create a custom field, you need to make changes to the flow and the HTML markup. You might also need to modify the schema because fields need to map to an attribute in the schema.

To create a custom field:

  1. Identify the name of the schema attribute you want to associate with your new field. Multiple fields can reference the same schema attribute, so you have the option of using an existing schema attribute. Examples of this are the emailAddress and signInEmailAddress fields that appear on the default registration flow. These attributes both map to the email attribute in the schema. However, if you don't wish to map your data to an existing attribute you must create a new attribute instead. You can create a schema attribute by making a POST request to the /entityType.addAttribute operation.

    To delete a field, first make a GET call on the config/{app}/flows/{flow}/fields/{field} operation to confirm you are viewing the correct field. Then, make a DELETE call on the same operation to delete the field. Note that you will need to also add the force URL parameter to the DELETE call, with the value true.

  2. Add the new field to the Flow. There are many field types that can define a field. Regardless of the field type, however, you create a new field by making a POST request to the /config/{app}/Flows/{Flow}/locales/{locale}/fields Configuration API operation. We don't recommend using the /config/{app}/flows/{flow}/fields operation to create new fields; not all field types (such as drop-down fields) can be created using that operation.

    An example request body is shown below:

{
        "label": "foo",
         "name": "myCustomTextField",
         "placeholder": "foo",
         "schemaAttribute": "displayName",
         "tip": "foo",
         "type": "text",
         "validation": [
           {
             "rule": "required",
             "value": true,
             "message": "foo"
           }
         ]
    }
  1. Update the relevant form(s) to include the field. To make your new field visible to the user, you must add it to a form include that field’s JTL tag in that form’s markup. Please refer to the section on how to add a field to a form.

Remove a custom field

Removing a field can be a bit ambiguous, as fields can be ‚Äúremoved‚ÄĚ in two ways:

  • Updating a form to remove the field from the form.
  • Deleting the field completely, which automatically removes it from all forms.

Fields are defined as independent objects in the flow, and can optionally be included on forms. Thus, removing a field from a form doesn’t delete the field; it only removes that field from the form. 

However, if you want to completely remove a field definition you need to delete the field from the flow. 


ūüďė

This also removes the field from all forms. To delete a field, first make a GET call on the /config/{app}/flows/{flow}/fields/{field} operation to confirm you are viewing the correct field. Then, make a DELETE call on the same operation to delete the field. Note that you need to add the force URL parameter to the DELETE call, with the value true.


Add a field to, or remove a field from, a form

Forms are how a user interacts with your website and submits registration information. On the backend, forms function to group together fields (input elements), and are defined in two places:

  • The flow
  • The HTML markup (as JTL tags)

To add or remove fields on a form, you need to make changes in both those places. You can find more information on the technical nature of forms and their relationship to screens in the JavaScript SDK screens reference. This is generally how you add/remove fields on forms:

  1. Identify the form you wish you modify. You can identify the name of the form by looking for the {* #formName *}...{* /formName *} JTL markup. In the forgotPassword screen example below, you can see the form name is forgotPasswordForm.
<divstyle="display:none;"id="forgotPassword">
       <div class="capture\_header">
           <h1>Create New Password</h1>
       </div>
       <h2>We'll send you a link to create a new password.</h2>
       {* #forgotPasswordForm *}
           {* signInEmailAddress *}
           {* someField *}
           <div class="capture\_footer">
               <div class="capture\_left">
                   {* backButton *}
               </div>
               <div class="capture\_right">
                   <input value="Send"type="submit"class="capture\_btn capture\_primary">
               </div>
           </div>
       {* /forgotPasswordForm *}
    </div>
  1. Add or remove the field from the form, using the Configuration API. Use the /config/{app}/flows/{flow}/forms/{form} operation to add or remove a field on a form.

  2. GET the form first, so that you have the form definition JSON. This is also a good opportunity to check if the field you wish to add or remove is already defined on the form. Below is an example response for a GET of the forgotPasswordForm:

{
     "_self": "/config/v86cchggr5cdvbfh7ydk8s63zz/Flows/myCoolFlow/forms/forgotPasswordForm",
     "fields": [
       {
         "_self": "/config/v86cchggr5cdvbfh7ydk8s63zz/Flows/myCoolFlow/fields/signInEmailAddress",
         "name": "signInEmailAddress",
         "required": false
       },
       {
         "_self": "/config/v86cchggr5cdvbfh7ydk8s63zz/Flows/myCoolFlow/fields/someField",
         "name": "someField",
         "required": false
       }
     ]
    }
  1. Make a PUT request, specifying the form JSON in the body of your request. You can exclude keys preceded by underscores (such as _self), however this is not required. If youremove a field (say, the someField field in the example), then the request body might look like this:

{
     "fields": [
       {
         "name": "signInEmailAddress"
       }
     ]
    }
    ```

    If you were *adding* a field to the form, then the request body might look like this:  

    ```
    {
     "fields": [
       {
         "name": "signInEmailAddress"
       },
       {
         "name": "someField"
       },
       {
         "name": "someNewField"
       }
      ]

If you add a field to the form then it must already exist in the flow. If it doesn't, then you need to create a new field first. 
  1. Update your markup to include/exclude the field JTL. Update your screen HTML to include or exclude the field’s JTL tag. For example, adding someNewField’s JTL tag to the forgotPasswordForm by adding the { someNewField } markup looks like this:
<div style="display:none;"id="forgotPassword">
       <div class="capture\_header">
           <h1>Create New Password</h1>
       </div>
       <h2>We'll send you a link to create a new password.</h2>
       {* #forgotPasswordForm *}
           {* signInEmailAddress *}
           {* someField *}
           {* someNewField *}
           <div class="capture\_footer">
               <div class="capture\_left">
                   {* backButton *}
               </div>
               <div class="capture\_right">
                   <input value="Send"type="submit"class="capture\_btn capture\_primary">
               </div>
           </div>
       {* /forgotPasswordForm *}
    </div>

Customize an existing field

To modify an existing field, use the /config/{app}/Flows/{Flow}/locales/{locale}/fields/{field} Configuration API operation. We don't recommend using the /config/{app}/Flows/{Flow}/fields/{field} operation to update a field definition. The behavior of that operation isn't consistent across all fields (such as for drop-down fields).

  1. Make a GET call to acquire the current field definition.

  2. Modify the field definition, and then make a PUT call with the modified field definition in the body of your request. You can exclude elements preceded by an underscore, such as _self.


Add a field that requires regex validation.

Fields such as email, phone number, zip code, etc. that require validation against a regular expression pattern can be implemented in two different ways:

  • Using a¬†pre-built Validation rule, or
  • Implementing¬†custom regex

Pre-built validation rule

Using a pre-built validation rule automatically provides both client and server-side validations to a field, and doesn't require you to write your own regular expression (we’ve done that for you). To implement a pre-built validation rule you only need to modify the flow, adding or updating a field to have a validation object with the format rule.

{
    "label": "Your Email",
    "name": "myCustomEmailField",
    "schemaAttribute": "email",
    "validation": [
        {
          "rule": "format",
          "value": "email",
          "message": "Your email was not formatted correctly"
        }
    ]
}

A pre-built validation rule can be ‚Äúemail‚ÄĚ, ‚Äúphone‚ÄĚ, ‚Äúalphanumeric‚ÄĚ or any number of other pre-built regular expressions. Remember to¬†add the new field to the relevant forms¬†in order to utilize it.

Custom regex

To implement custom regular expressions, you need to make three changes: a flow change , a client-side change, and a API client settings change. In your flow, add or a field such that it has a validations object with the following rules:

  • clientFunctionName. The name of the client-side JavaScript function that you will register with the Registration UI client-side.

  • serverRegexSetting. The name of the API client setting that contains the regular expression.

When a user fills out a form incorrectly but hasn't submitted it*,they'll instantly see an error message. The clientFunctionName corresponds to a JavaScript function defined client-side (see the next step), which enables this instantaneous feedback to the user.

On the other hand, if, after submitting a form. a field fails validation then the user sees an error message after the form is submitted. This is a slower mechanism for feedback, but it helps to ensure data integrity. The serverRegexSetting corresponds to this server-side feedback.

You can see this behavior by giving meaningful messages like in the example below, and trying to trigger each error. Note, however, that, in practice, both messages are typically the same. That's because the user doesn’t need to know which type of validation failed (only that it failed).

{
    "label": "Your Member Number"
    "name": "memberNumber",
    "schemaAttribute": "professionalInfo.memberNumber",
    "validation": [
        {
          "rule": "clientFunctionName",
          "value": "validateMemberNumber",
          "message": "Your member number fails client-side validation"
        },
        {
          "rule": "serverRegexSetting",
          "value": "member\_number\_regex",
          "message": "Your member number fails server-side validation"
        }
    ]
}

Generally speaking, we recommend implementing both clientFunctionName and serverRegexSetting rules to enforce both client-side and server-side validation. However, if you're implementing your own client-side validation then you can exclude the clientFunctionName validation rule.

In your client-side markup, you need to register the clientFunctionName with the Registration UI. Following is an example; you can find more information on this function in our Registration JavaScript API documentation.

functionjanrainCaptureRegistration UIOnLoad(){
    functionvalidateMemberNumber(name,value){
        varexpression = /\d{5,7}/;
        returnexpression.test(value);
    }
    //
    janrain.capture.ui.registerFunction('validateMemberNumber',validateMemberNumber);
    //
    janrain.capture.ui.start();
}

Add the name of the regexServerSetting to your API client setting. Note that you must exclude the leading or trailing forward-slash. Generally, we recommend adding these settings on a per-client basis, as depicted below. Please see Application and API client settings for more information on clients and settings.

Finally, remember to add the new field to the relevant forms in order to utilize it.


Add a dropdown list to a form

To create a drop-down field,¬†add¬†or¬†update¬†a ‚Äúselect‚ÄĚ field that has an¬†options¬†object containing a list of select options. See the example below. Remember to¬†add the new field to the relevant forms¬†in order to utilize it.

{
      "label": "Favorite Food",
      "name": "favoriteFood",
      "options": [
        {
          "selected": true,
          "label": "",
          "value": ""
        },
        {
          "label": "Hot Dogs",
          "value": "hotdogs"
        },
        {
          "label": "Hamburgers",
          "value": "hamburgers"
        }
      ]
      "schemaAttribute": "favorites.lunchFood",
      "type": "select"
    }

Add a multi-select field to a form

Currently, Akamai does not support a multi-select field type out-of-the-box. To implement this functionality, we recommend the following approach:

  1. Implement a field of¬†type¬†‚Äúhidden‚ÄĚ. You'll store a string representation of multi-select data in this hidden field, so make sure that the¬†schemaId¬†key maps to a schema attribute that is¬†type¬†‚Äústring‚ÄĚ. Additionally, your request must exclude¬† the label,¬†tip, and¬†placeholder¬†keys.
"favoriteBirds": {
           "schemaId": "favorites.birds",
           "type": "hidden"
       },
  1. Add the new field to the relevant forms in order to utilize it.

  2. Add markup to your HTML form for the hidden field and the select options.

{* #registrationForm *}
     {* favoriteBirds *}
     <div class="capture\_form\_item"id="favoriteBirds\_checkboxes">
         <label>Favorite Birds:</label>
         <label><input type="checkbox"value="penguin">Penguins</label>
         <label><input type="checkbox"value="parrot">Parrots</label>
         <label><input type="checkbox"value="pigeon">Pidgeons</label>
         <label><input type="checkbox"value="chicken">Chicken</label>
         <!-- Etc... -->
     </div>
    {* /registrationForm *}
  1. Register a JavaScript function to the onCaptureScreenShow event. This function is called whenever a screen is shown to the user.
janrain.events.onCaptureScreenShow.addHandler(function(result){
     initFavoriteBirds(result.screen);
    });

For example, this function iterates the input elements and attaches a listener function that‚Äďwhen the¬†onclick¬†DOM event fires‚Äďupdates the content of the hidden field.

functioninitFavoriteBirds(screenname){
     // Get the target elements
     varhiddenElement = document.getElementById('capture\_'+screenname+'\_favoriteBirds');
     varcheckboxesDiv = document.getElementById('favoriteBirds\_checkboxes');
     // Define a function to update the hidden field when the checkboxes are clicked
     varupdatefavoriteBirds = function(){
       varhiddenElement = document.getElementById('capture\_'+screenname+'\_favoriteBirds');
       varcheckboxesDiv = document.getElementById('favoriteBirds\_checkboxes');
       varnewValue = '';
       if(hiddenElement && checkboxesDiv){
           // build the newValue, be it a comma-delimited string, JSON string, etc.
           // then set the value of favoriteBirds to this updated value
           hiddenElement.value = /* some string */;
         }
       }
     // Attach the updater function to the input elements
     if(hiddenElement && checkboxesDiv){
         varcheckboxes = checkboxesDiv.getElementsByTagName('input');
         for(vari=0;i<checkboxes.length;i++){
             checkboxes[i].onclick = updatefavoriteBirds;
         }
     }
    }

The preceding example doesn’t need to check explicitly for screen names,due to the way the Registration UI renders id** attributes for field HTML. It renders id attributes with the pattern capture_'+screenname+'_'+fieldname. Because the conditional block only executes if it finds an HTML element with the id attribute capture_'+screenname+'_favoriteBirds, then the block will only be executed for screens containing the favoriteBirds field (e.g., capture_traditionalRegistration_favoriteBirds, capture_socialRegistration_favoriteBirds, and capture_editProfile_favoriteBirds**)


Add a date field to a form

To create a¬†dateselect¬†field,¬†add¬†or¬†update¬†a field that is¬†type¬†‚Äúdateselect‚ÄĚ. Before creating the field, ensure that the target schema attribute is type¬†dateTime¬†or¬†date.

{
  "label": "Birthday",
  "name": "birthday",
  "schemaAttribute": "birthday",
  "type": "dateselect"
}

After the field has been added to the flow, it will be populated with additional keys such as yearLabel, monthLabel, dayLabel, and monthNames. These do not need to be included in the initial request. Finally, remember to add the new field to the relevant forms in order to utilize it.

Usually date fields are created with intention to capture or enforce age gating. You can find information on how to implement this in Add validations and related logic.


Add a radio-button or checkbox to a form

Checkbox

To create a¬†checkbox¬†field,¬†add¬†or¬†update¬†a field that is¬†type¬†‚Äúcheckbox‚ÄĚ. Before creating the field, ensure that the target schema attribute is type¬†boolean¬†or¬†string¬†(depending on your use case). See the example below. Finally, remember to¬†add the new field to the relevant forms¬†in order to utilize it.

{
      "label": "I agree to receive emails and other communications",
      "name": "optIn",
      "preChecked": false,
      "schemaAttribute": "optIn.status",
      "submitValue": "yes",
      "type": "checkbox"
    }

In the preceding example, the preChecked and submitValue keys are optional. If preChecked is set to true, then the checkbox will be already checked when it is loaded on the form. The submitValue key is used to specify the submit value on a check box (that is, if a checkbox should submit a value other than on).
Radio-Button

To create a¬†radio¬†field,¬†add¬†or¬†update¬†a field that is¬†type¬†‚Äúradio‚ÄĚ and also has an¬†options¬†object containing a list of select options. Before creating the field, ensure that the target schema attribute is type¬†string. See the example below. Finally, remember to¬†add the new field to the relevant forms¬†in order to utilize it.

{
  "name": "gender",
  "options": [
    {
      "selected": true,
      "label": "Not Specified",
      "value": "Not Specified"
    },
    {
      "label": "Female",
      "value": "Female"
    },
    {
      "label": "Male",
      "value": "Male"
    },
    {
      "label": "Other",
      "value": "Other"
    }
  ],
  "schemaAttribute": "gender",
  "type": "radio"
}

Integrate third-party analytics into registration

With the Registration JavaScript API it's possible to track registration events and send data to third-party analytics sites such as Google Analytics. An administrator can use these analytical tools to gain greater insight into how users interact with the website.

To implement third-party analytics, register an event handler that makes a call to your analytics service. You can find more information about the data made available client-side in Modify the user experience flow. Some common events you might want to track are:

  • onCaptureLoginStart
  • onCaptureLoginSuccess

Following is an example integration with Google Analytics. This example registers a function with the onCaptureLoginSuccess event to send tracking information upon successful login. There are a few key pointers to keep in mind:

  • Ensure Google Analytics code is loaded before event handlers are registered.
  • Ensure event handlers are registered inside¬†janrainCaptureWidgetOnLoad
  • Ensure events handlers are registered before calling¬†janrain.capture.ui.start().

You can find a working example of third-party analytics in Capture on our Enterprise Demos site.

<script type="text/javascript">
    var_gaq = _gaq || [];
    _gaq.push(['\_setAccount','UA-38162009-1']);
    _gaq.push(['\_trackPageview']);
    (function(){
        varga = document.createElement('script');ga.type = 'text/javascript';ga.async= true;
        ga.src = ('https:'== document.location.protocol ? 'https://ssl':'http://www')+ '.google-analytics.com/ga.js';
        vars = document.getElementsByTagName('script')[0];s.parentNode.insertBefore(ga,s);
    })();
</script>
<script src=""></script>
<script type="text/javascript">
    functionjanrainCaptureWidgetOnLoad(){
        janrain.events.onCaptureLoginSuccess.addHandler(function(result){
            _gaq.push(['\_trackEvent','onCaptureLoginSuccess','fired']);
        });
        /* possibly more event handlers here */
        janrain.capture.ui.start();
    }
</script>