Customizing the Information Gathered During Registration

How do I create a custom field, in general?

Fields are means of connecting data input from the user to the Capture database.

Therefore, unlike forms, fields are defined in three places:

  1. The Schema
  2. The Flow
  3. The HMTL/Markup (as JTL tags)

To create a custom field, you need to make changes not just the Flow and HTML/Markup, but also possibly in the Schema because fields need to map to an object in the database (Schema). You can learn more about the Schema in our documentation on Data Management.

  1. Identify the name of the schema attribute you want to associate with your new field Multiple fields are allowed to 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 come with the default registration Flow; both map to the email attribute in the schema. However, if you do not wish to map your data to an existing schema attribute, then you must create it first. You can create a schema attribute by making a POST request to the a/entityType.addAttribute Janrain Entity API endpoint.
     
  2. Add the new field to the Flow There are many field types and validations 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 endpoint. 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"
        }
      ]
    }
    We do not recommend using the /config/{app}/flows/{flow}/fields endpoint to create new fields; not all field types (such as drop-down fields) support being created at that endpoint.
     
  3. 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 in the Flow and then include that field’s JTL tag in that form’s markup. Please refer to this document’s section on how to generally add a field to a form.

How do I remove a custom field, in general?

“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. 

If, however, you want to completely remove a field definition then you will need to delete the field from the Flow. 

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

How do I add/remove a field on a form, in general?

Forms are how your 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:

  1. The Flow
  2. The HMTL/Markup (as JTL tags)

Therefore, 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 Screens Technical Overview. This is how generally 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>
  2. Add or remove the field from the form, using the Configuration API. You will be using the /config/{app}/flows/{flow}/forms/{form} endpoint to add or remove a field on a form.
     
  3. 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/remove isn’t 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
        }
      ]
    }
    
    
  4. Make a PUT request, specifying the form JSON in the body of your request. You can exclude keys preceeded by underscores (such as _self), however this is not required. If you were removing a field (say, the someField field in the example), then the request body may 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 are adding a field to the form then it must already exist in the Flow. If it does not, then you need to create a new field first. 
     
  5. Update your markup to include/exclude the field JTL Update your screen HTML to include or exclude the field’s JTL tag. For example, addingsomeNewField’s JTL tag to the forgotPasswordForm by adding the {* someNewField *} markup:
<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 *}
        {* 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>

How do I customize an existing field?

To modify an existing field, you will utlize the /config/{app}/Flows/{Flow}/locales/{locale}/fields/{field} Configuration API endpoint. We do not recommend using the /config/{app}/Flows/{Flow}/fields/{field} endpoint to update a field definition; behavior is not 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.

How do I add a field for email, phone number, etc. requiring 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 does not require you to write your own regular expression (we’ve done that for you). Plus, to implement a Pre-Built Validation Rule, you only need to implement a Flow change, adding or updating a field to have a validationobject 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. You can browse the validations section of our Configuration API documentation to find definitions that fit your use case. Finally, 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 update a field such that it has a validations object with the following rules:

  • clientFunctionName - This will be the name of the client-side JavaScript function that you will register with the Registration UI client-side.
  • serverRegexSetting - This will be the name of the API client setting that contains the regular expression.

When an user is filling out a form incorrectly and has not yet submitted it, they will instantly see an error message displayed. The clientFunctionNamecorresponds to a JavaScript function defined client-side (see the next step), which is what enables this instantaneous feedback to the user.

On the other hand, if after submitting a form a field fails validation then the user will see an error message displayed after the form is submitted. This is a slower mechanism for feedback, but 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 set of validation rules below, and trying to trigger each separately. Note, however, that in practice both messages will be the same because the user doesn’t need to know which type of validation that it 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"
        }
    ]
}

Note that, generally speaking, we recommend implementing both clientFunctionName and serverRegexSetting rules to enforce both client-side and server-side validation. If, however, you are implementing your own client-side validation then you can exclude the clientFunctionName validation rule.

In your client-side markup, you will need to register the clientFunctionName with the Registration UI. Below is an example; you can find more information on this function in our 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 settingsNote that you must exclude the leading/trailing forward-slash. Generally, we recommend adding these settings on a per-client basis, as is depicted below. Please see Clients and Settings for more information on clients and settings.

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

How do I add a drop-down/list-of-values field to a form?

To create a drop-down field, add or update a field such that is type “select” and has an options object containing a list of select options. See the example below. Finally, 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"
    }

How do I add a multi-select field to a form?

Currently, Janrain 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 will 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, in your request exclude 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 JS function to the onCaptureScreenShow event; this function will be called whenever a Janrain screen is shown to the user.
janrain.events.onCaptureScreenShow.addHandler(function(result){
  initFavoriteBirds(result.screen);
});

For example, this function may iterate over the input elements and attach 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 above 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 idattributes with the pattern 'capture_'+screenname+'_'+fieldname. Since the conditional block only executes if it finds an html element with 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)

How do I 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"
}

Once 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 also created with intention to capture/enforce age gating; you can find information on how to implement this in this section.

How do I 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 above 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"
}

How do I integrate third-party analytics into Registration?

With the Janrain Registration JavaScript API, it is possible to track registration events and send data to popular third-party analytics sites, such as Google Analytics and Adobe SiteCatalyst. 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 this section. Some common events you may want to track are:

Below is an example integration with Google Analytics, which 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="scripts/janrain-init.js"></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>

Note: If you want to implement third-party analytics for Social-Login, please see our documentation on Customizing Social Login, as it utilizes a different JavaScript API.