2010-10-07
 
Kategorie
 

Custom Elements – Part 3 – Writing Your First Custom Field

 

Let’s get down to business. This post will show you how to create your first simple custom element. We’ll focus on the custom field first, as it is simpler and used more often.

Our task is to implement a field that looks like a standard single line text field, but has a custom validation: it will check entered numbers for parity.

Add the custom field to your form like any other field. After you’ve embedded the custom field in the form, you will see something like this:

Properties tab of your custom field. You can set attributes known from other fields:

  • label,
  • identifier,
  • context help,
  • required or not,
  • default value,
  • maximum value length (the number of characters in the user response) + validation message.

The Source code under the attributes is where you actually specify how your custom field is supposed to work and look.

First, type HTML code (or upload a file) that will render your control.
Second, enter JavaScript code that will enable communication between your control and the ActiveForms engine.
Third, you can enter a CSS style sheet so that your control looks as it should.

Let’s begin from the HTML code. First of all, you need to know that the entered HTML code will be embedded in the form using an IFRAME. You can write anything in the HTML code assuming it is already within the <body> section.

You want your control to look like a regular single line text field, so enter something like this:

<input id="evenNumber" type="text" onchange="epoint_activeforms_customField.evenNumberChanged();" >

The resulting custom field looks like this:

I will present a few ways to make a custom field look like other fields below.

The most important and most difficult part of creating a custom field is writing the right JavaScript code. Click Edit next to JavaScript to open a code template to fill in.

A custom field has to provide a JavaScript object called epoint_activeforms_customField, which implements a number of methods. The object with empty methods is readily available in an empty custom field, all you need to do is to implement the methods. The methods of this object are briefly described below:

  • getValue() returns the value entered by the user in the field (a string).
  • setValue(val) sets a value in the control that is already present in the entry. This method is called on page load and is needed to set a default value for the control or when returning to the page from another one. It can also be used by the dependencies engine.
  • clear() sets an empty value for the control. This method is called when the dependencies engine finds that the field should be cleared.
  • enable() enables the control. The method is called when the dependencies engine finds that the field should be enabled.
  • disable() disables the control. The method is called when the dependencies engine finds that the field should be disabled.
  • onLoad() contains a code that should be executed after the page loads. You can specify some actions that initialise the control.
  • onValidation(afCallBackFunction) allows manual validation of the field value. The method is called when attempting to move to the next screen. We will write a code that will validate the entered value in this method. After the control completes its action, it has to call a function passed in the (afCallBackFunction) parameter.
  • getValidationResult() returns the validation status. If the validation was successful, it should return the ‘ok’ value, otherwise it should return ‘not_ok’.
  • getValidationMessage() returns a validation message. It is only relevant if the getValidationResult() method has returned ‘not_ok’.
  • onValidationTimeout() contains code that should be executed if validation takes too long, i.e. if the afCallBackFunction function is not called within 10 seconds.
  • getFieldNodes() returns an array of DOM nodes of an HTML document—these are form fields that should be visualised in a standard way for the form. The ActiveForms engine assigns them appropriate CSS classes depending on the element states.

If you want your custom field to work as planned, implement the above methods as follows:

var epoint_activeforms_customField = {
 
  value: "",
  validationStatus: 'ok',
 
  /*string*/ getValue: function() {
    return this.value;
  },
 
  /*void*/ setValue: function(/*string*/ val) {
    this.value = val;
    document.getElementById("evenNumber").value=val;
  },
 
  /*void*/ clear: function() {
    this.setValue("");
  },
 
  /*void*/ enable: function() {
  },
 
  /*void*/ disable: function() {
  },
 
  /*void*/ onValidation: function(afCallBackFunction) {
    if (isNaN(this.value) || (parseInt(this.value)%2 != 0)) {
      this.validationStatus = "not_ok";
    } else {
      this.validationStatus = "ok";
    }
  },
 
  /*string*/ getValidationResult: function() {
    return this.validationStatus;
  },
 
  /*string*/ getValidationMessage: function() {
    return "The value is not an even number";
  },
 
  /*void*/ onLoad: function() {
  },
 
  /*void*/ onValidationTimeout: function() {
    alert("It should not have happened");
  },
 
  /*HTMLCollection|HTMLElement[]*/ getFieldNodes: function() {
    var a = new Array();
    a[0] = document.getElementById("evenNumber");
    return a;
  },
 
  evenNumberChanged: function() {
    this.value = document.getElementById("evenNumber").value;
    this.onChange;
  }
}

A few comments:

  • In line 3 we declare a field of our object which will store the value entered in the field.
  • In line 4 we declare a field which will store the result of the last validation.
  • In line 7 we implement getValue() by returning the value from our attribute.
  • In lines 11 and 12 we implement setValue()—we write a value to a field and present it in our control.
  • In line 27 we implement the most important method of this custom field—our own validation. We check whether the value is an even number and store the result of the check in the validationStatus field. At the end of the validation process we have to call afCallBackFunction to notify the ActiveForms engine that the validation is completed (custom elements are validated asynchronously).
  • In line 42 we return always the same validation message, because we only validate one aspect (parity). If the validation is successful, this function is not called.
  • In line 46 we don’t do anything, because it isn’t necessary to initiate a control.
  • In line 56 we return (a single element) an array of HTML nodes which are to be visualised by the ActiveForms engine like the other form elements. Here, we specify our Input type field.
  • In line 59 we write a function that is called when the value in our control changes. This function is not part of the custom elements API; we simply use it to find out that someone typed something in the field. We made a reference to this function in the HTML code.
  • In line 61 we call a very important function: onChange(). It notifies the ActiveForms engine that the value in our control has changed. This way:
  • - the AF engine will store this value while submitting the entry;
  • - the AF engine can launch the dependencies engine (for example when a condition is based on the value of our custom field).

Now we have the custom field we needed. We could also work on its visual aspect, but let’s leave that for later.

 
 
recent posts
3rd Apr 2014
Faster than ever!
5th Dec 2013
Live validation!
2nd Dec 2013
Features distilled
12th Mar 2012
Flicking Channels
26th Jan 2012
Your Own Error Page
9th May 2011
Box Properties
15th Apr 2011
Grouping Fields
13th Apr 2011
Form Versioning
24th Feb 2011
Form Access Modes
22nd Feb 2011
Required Fields
4th Feb 2011
Stats!