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.
<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 *}
           <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 you remove 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">Pigeons</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.

function initFavoriteBirds(screenname){
     // Get the target elements
     var hiddenElement = document.getElementById('capture_'+screenname+'_favoriteBirds');
     var checkboxesDiv = document.getElementById('favoriteBirds_checkboxes');
     // Define a function to update the hidden field when the checkboxes are clicked
     var updatefavoriteBirds = function(){
       var hiddenElement = document.getElementById('capture_'+screenname+'_favoriteBirds');
       var checkboxesDiv = document.getElementById('favoriteBirds_checkboxes');
       var newValue = '';
       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){
         var checkboxes = 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().
<script type="text/javascript">
    var _gaq = _gaq || [];
    _gaq.push(['\_setAccount','UA-38162009-1']);
    _gaq.push(['\_trackPageview']);
    (function(){
        var ga = 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">
    function janrainCaptureWidgetOnLoad(){
        janrain.events.onCaptureLoginSuccess.addHandler(function(result){
            _gaq.push(['_trackEvent','onCaptureLoginSuccess','fired']);
        });
        /* possibly more event handlers here */
        janrain.capture.ui.start();
    }
</script>