Working with User Input Elements, Pg. 2

Working with User Input Elements

Logi Info
v12.6 - Oct 2018

Page 2

1 | 2

User Input elements allow users to interact with applications, most often to provide reporting criteria. This document discusses a variety of techniques for working with these elements. Topics on this page include:


Validating Input

When it comes to validating data entered by users, we highly recommend it! It takes some additional development work up front, but can save so many heartaches (and time) later. Validating data is one of the most important tasks associated with processing user input.

The browser environment presents some validation challenges and there are generally three opportunities to do validation. The first is related to events and occurs when the focus changes from one Input element to another element or when the Input element contents change. Validation in this case is accomplished using Event Handlers.

The second opportunity occurs when the page is submitted. If the validation fails, then the submission is aborted. Logi Studio provides a variety of Validation elements for this purpose.

This document concerns itself with these first two validation opportunities but there is a third: it occurs in the next Report page or Process task, after submission has completed. That falls outside the scope of this document but is highly encouraged, especially if you're updating a database.

The Action.Pre-Action Javascript element, a child of many Action elements, can be used to validate input and control whether its parent Action element executes. For more information, see our document Working with Scripting.

  Back to the top

 

Using Validation Elements

Validation elements are provided to allow you to validate the data users enter. All of them have some behaviors and attributes in common. For example, if validation fails, the page submission is aborted, an error message is displayed, and, optionally, the offending user input element can be highlighted by applying a different style class to it (coloring its background, for example). Multiple validation elements can also be used in combination under a single Input element.

  You must give each Input element being validated a unique ID. This allows the validation process to correctly identify the element in case validation fails; failing to do this will result in validation being ignored.

Some validation elements are not appropriate (nor available in Studio) for some user input elements. For example, it makes no sense to try to validate a numeric entry for the Input Radio Buttons element.

 

  A very important step, one that developers often overlook when working with Validation elements, is enabling input validation. As shown above, the Action element used to submit the page has a Validate Input attribute which must be set to True or else none of the Validation elements will do anything.
 

Validation.Date

The Validation.Date element allows the developer to validate several things about dates entered in an Input Date element. The Validation.Date element's attributes include those discussed above for the Validation.Required element and also adds Range Start and Range End attributes.

Validation.Date will ensure that the date was entered in a format that matches the mask in the Input Date element's Format attribute. So, if the Input Date element's Format value is "MM/dd/yyyy" and the user enters "12/25/15", an error message will be displayed because a 4-digit year was not entered.

Validation.Date can also ensure that the date entered falls within the date range specified by its Range Start and Range End attributes. To be validated, the date entered must be on or after the Range Start date, and be on or before the Range End date. For this validation to work correctly, the format of the Range Start and Range End values entered must match the format described in the Input Date element's Format attribute.

If you use @Date tokens for the Range attributes, be aware that their default format, "yyyy-M-d", is not very user-friendly and might not match a more normal format you establish for Input Date. To reconcile this, in your _Settings definition, add a Globalization element and set its Default Input Date Reformat attribute to the same user-friendly format as your Input Date element. This will change the format of the @Date tokens, they'll match the Input Date element's Format attribute, and the validation will work correctly.
 

Validation.Email

The Validation.Email element allows the developer to validate the value entered in an Input Email element.

Validation.Email ensures that a properly formatted email address value has been entered. The address is validated for the "@" symbol and a domain name. Certain special characters forbidden in email addresses are not allowed.

The validation elements provide a quick, easy method of implementing simple validation and can catch many data entry errors.
 

Validation.JavaScript

The Validation.JavaScript element allows you to validate the value entered by using a custom JavaScript function.

To use this element, enter a call to a custom function (found in the report definition) in its Javascript Function attribute. Usually this call will include the ID of the Input element as argument. Here's an example of the complete attribute value:

    validateMustBeX(document.getElementById('inpText'));

The function itself can be included in your report definition using any of the elements that run script in the browser, such as Include Script or Include Script File.

When the page is submitted, the custom function will be run by the browser. If the function detects an error, it should call throw(<errorMessage>) to trigger display of an error message.

Here's an example of a custom validation function that requires the letter "x" to be entered:
 

function validateMustBeX(eleInput){
    if (eleInput.value != 'x') {
        throw('The input value is: "' + eleInput.value + '". But it must be "x".')
    }
}


If the validation fails, the text in the Validation element's Error Message attribute gets displayed in a message box. If the attribute's value contains the special string variable {error} it will be replaced with the custom function's throw( ) argument, providing a customizable error message. For example, the attribute value could be:

    Did not pass script validation. The error was: {error}

When used with the custom function shown earlier, the resulting message box would look like this (assuming a the letter "d" was entered):
 


     

Here's a particularly good example of Validation.JavaScript in use: when using Input Date with a date range, ensuring that the Start date is not later than the End date. Assuming the input element is configured so that its ID is inpDateStart and its End Date Range ID attribute is set to inpDateEnd, here are the Validate.JavaScript element's attributes:

Error Message: Did not pass validation! {error}

JavaScript Function: validateMe(document.getElementById('inpDateStart'), document.getElementById('inpDateEnd'));

As you can see, the function call above uses the element IDs to pass the input objects as parameters to the validating function.


And, in an Include Script element at the end of the definition, here's the code for the "validateMe" function:

function validateMe(objStart, objEnd) {
    var sDate = new Date(objStart.value);
    var eDate = new Date(objEnd.value);

    /* development only */
    alert(sDate);
    alert(eDate);

    if (sDate > eDate) {
        throw('The Start Date must be earlier than the End Date');
    }
}

JavaScript makes it easy to compare the Date objects directly, without having to parse them.
 

Validation.Length

The purpose of the Validation.Length element is to ensure that a minimum and/or maximum number of characters has been entered.
 

The Validation.Length element's attributes include those discussed above for the Validation.Required element and also adds Maximum Length and Minimum Length attributes, which are optional (though you should enter something for at least one of them or why bother with the element at all?)
 

Validation.Numeric

The purpose of the Validation.Numeric element is to ensure that all of the characters entered in the text box are numbers. If any of the characters entered are letters or symbols, the validation fails, the error message is displayed, and the text box can have an optional style class applied to it. Page submission is aborted.

The Validation.Numeric element's attributes are the same as those discussed above for the Validation.Required element.
 

Validation.Required
 

The purpose of the Validation.Required element, as shown above, is to ensure that the user enters something in the control. If the text box is left blank and the page is submitted,
 

     

a popup error message window will appear displaying the text set in the Error Message attribute. If the optional Class attribute is set, then the offending user input element will be set to that style class (allowing the developer to color its background). After the OK button in the popup error message window is clicked, submission of the page is aborted.
 

Validation.Time

The Validation.Time element allows the developer to validate the time value entered in an Input Time element. The Validation.Time element's attributes include those discussed above for the Validation.Required element and also adds Range Start Time and Range End Time attributes.

Validation.Time ensures that a time value has been entered. The format of the time entered must conform to that in the Format attribute of the parent Input Time element. Validation.Time can also ensure that the time falls within a time range, specified with the Range Start Time and Range End Time attributes. To pass the validation, the time entered must be on or after the Range Start Time, and be on or before the Range End Time.
 

  Back to the top

 

Using Event Handlers

Another popular method of validating user input is through the use of event handlers. The Validation elements use this same technique but shield you from the underlying details. For better control and more validation variety, you can create your own Event Handlers, as shown in the following examples.
 

Event Handler Mechanics

The Event Handler element is used for this purpose and it responds to DHTML events. If you're unfamiliar with these events, information about them is available here from Microsoft.

 


     

The example above shows a typical arrangement and configuration of elements. The Placeholder text is displayed inside the Input control but disappears if text is entered (it also re-appears if the text entered is deleted).

 

Next, as shown above, an Event Handler element has been added beneath the first Input Text element ("inpLoginID"). Its DHTML Event property has been set to "onChange".

The onChange event only runs ("fires") when the cursor moves to another control and if a change has been made to the data in inpLoginID. In that case, processing is passed to any elements beneath the Event Handler.

The onChange event fires at different times for different Input elements. For Input Text and related elements, it fires if a change has been made and the cursor leaves the control. For Input Select List, it fires when the selection is changed.

For the Input Radio Buttons and Input Checkbox elements, use the onClick event, which fires when a radiobutton or checkbox is clicked.

 The use of Event Handlers that "intercept" the onChange event will prevent the Change Flag Element scheme, described with Input Hidden and available to all user input elements, from working so you can't use both.

Now let's see some specific Event Handler use-case examples.


Using Event Handlers and Dependent Controls

Developers often encounter requirements to have the contents of one Input Select List change dynamically based on user selections in another Input Select List. The second control is said to be "dependent" on the first one. Event Handlers provide an easy method of enabling this dependency.

The following example depicts a web page that allows users to get information about automobiles. This is a classic example of Input Select List dependency: once users select from a list of car brands, then a second list, of car models, is populated with choices based on the brand selection.
 


Here's how it works: when a car brand is selected, the page is submitted and the next page is called. The selected brand is passed to the next page as a request variable. The "next" page, however, will be the same report definition (the page calls itself or "refreshes") but now the selected brand will be available to it in a @Request token. This token is then used to populate the list of car models that match the selected brand.

Here's the example data, a simple XML file, that we'll use:
 

CarInfo>
   <Car Brand="Alfa Romeo" Model="174 Hatchback" Code="1"/>
   <Car Brand="Aston Martin" Model="Spider Open" Code="2"/>
   <Car Brand="Audi" Model="Spider Open" Code="3"/>
   <Car Brand="Bentley" Model="Spider Open" Code="4"/>
   <Car Brand="BMW" Model="3 Series Convertible" Code="5"/>
   <Car Brand="BMW" Model="3 Series Coupe" Code="6"/>
   <Car Brand="BMW" Model="5 Series Saloon" Code="7"/>
   <Car Brand="BMW" Model="5 Series Touring" Code="8"/>
   <Car Brand="BMW" Model="7 Series Touring" Code="9"/>
   <Car Brand="BMW" Model="M3 Coupe" Code="10"/>
   <Car Brand="Cadillac" Model="Spider Open" Code="11"/>
</CarInfo>


For the purposes of this example, BMW is the only manufacturer that's been given multiple models.

 

 

The example report definition, shown above, contains two Input Select List elements.

 


The attribute values for the car brands Input Select List are shown above. Note these two key attributes:

  • Value Column - This attribute has been set to the same value as the Caption Column attribute, ensuring that the selected brand name is passed as a request variable.
  • Default Value - This attribute is set to the request variable with the same ID as the Input Select List element, ensuring that the selected brand name will remain selected when the page refreshes.

In addition, datalayer and Group Filter elements have been added below the Input Select List. The Group Filter's Group Column attribute is set to the "Brand" column, ensuring that there are no duplicate entries in the list of brands.

 

As shown above, an Event Handler element has also been added beneath the car brands Input Select List. Its DHTML Event attribute has been set to "onChange". In the case of an Input Select List, this event will fire as soon as a selection has been made. Action.Report and Target.Report child elements have also been added and the target definition file has been set to the name of the current report definition, "newReport2".

  Do not use the CurrentReport option available in the list of choices for this attribute - Request variables are not passed when this is used.
 


 The attribute values for the car models Input Select List are shown above; its attributes are pretty straightforward.
 

 As shown above, datalayer and Compare Filter elements have been added below the Input Select List. The filter is the key to setting the second Input Select List to the models of the chosen brand: its attributes are set to filter the Model data based on the @Request token containing the Brand selection.
 

Finally, the interaction between the two select lists is shown above. The entire page will not repaint itself when a brand selection is made, so there'll be no annoying page flicker, due to the use of AJAX technology in Logi products.

In summary, this example has shown how an event handler can be tied to a change in a user input control and how it can trigger other actions based on that change.

  Back to the top

 

Using Event Handlers with JavaScript

A very powerful feature of Logi Info is the ability to execute JavaScript when an event occurs.
 

Developers can use the Action.Javascript element, shown above, beneath an Event Handler element. JavaScript code can be entered directly into the Javascript attribute; multi-line code is supported.

Now we're able to use the power of JavaScript and the DHTML object model for activities such as validation. The Attribute Zoom window comes in handy when entering code (double-click the Attribute name). Here are some use-case examples:
 

Example 1: Ensure that some data is entered

It's beyond the scope of this document to delve too deeply into JavaScript or the object model, but essentially the following code assigns the data in the inpLoginID control to a variable, then tests the length of that variable's value, and displays a message box if the length is zero.

 

var myStr = document.getElementById('inpLoginID').value;
if (myStr.length == 0 ) alert('You must enter some message text.');
if (myStr.length == 0 ) return false;
return true;

 

This is very similar to the Validation.Required element's functionality. The Document object's getElementById method is very handy in this situation. Remember: JavaScript is case-sensitive.

Note that while you may enter multi-line Javascript, you may not include code blocks that are set off by curly brackets. This means structures like If...Then...Else blocks are not usable. As shown in these examples, you can get around this by using multiple lines of code, each with a single If statement.
 

Example 2: Ensure some data is entered but not more than 4,000 characters

The example script that follows does something special: it limits the length of data that can be entered into an Input Text Area element.
 

var myStr = document.getElementById('inpTextArea1').value;
if (myStr.length > 4000) alert('Your message is too long (' + myStr.length + ' chars) - maximum length is 4,000 characters.');
if (myStr.length > 4000 ) return false;
if (myStr.length == 0 ) alert('You must enter some message text.');
if (myStr.length == 0 ) return false;
return true;

 

Input Text Area does not have a "maximum length" attribute. The code above sets a limit and if the text entered is too long, it reports the actual number of characters currently entered. It also requires that some data be entered.
 

Example 3: Replace all occurrences of '@' with '#'

This example demonstrates a method for replacing certain characters in the data entered, using a JavaScript Regular Expression.
 

var myStr = document.getElementById('inpTextArea1').value;
myStr = myStr.replace(/[@]/g, '#');
document.forms[0].inpTextArea1.value = myStr;
return true;

 

In the example, any @ characters that were entered by the user are replaced with the # character, and then the altered data is substituted for the data that was entered. Regular Expressions are very powerful, can be quite complex, and can perform actions such as adding, replacing, or removing characters, changing character case, and expanding or contracting phrases.

As you can see, the ability to run JavaScript whenever data changes in user input elements provides developers with a very powerful validation tool.
 

Example 4: Handling Links within Tables

This is a slightly different kind of example that deals with a common problem. Suppose you have a data table and each row has a column in it that contains a link or button; for instance, an "Edit" button. When the link or button is clicked, you want to send data from that row to another report or process task. Internally, the Logi engine adds a row designator - "_Row1, _Row2, etc." - to the datalayer column names, so addressing the correct data using tokens (@Request.myCol_Row#~) in the receiving Report or Process task is difficult.

However, there's an easy solution: add an Event Handler and an Action element beneath the link or button. The Event Handler will assign the data from the current table row to one or more Input Hidden elements (depending on how many columns you need to send) and the Action element submits the page and calls the next Report or Process task. The next report or task can then work with the values in the @Request token for the Input Hidden elements.
 

The example above shows the elements that might be used in this situation.

First, an Input Hidden element is added at the top of definition, outside of the table and its columns. We'll put the value we want to work with in this element, getting around the @Request.myCol_Row# issue.

Inside one of the table columns, beneath the Label element (which is the "Edit" link) an Event Handler is added and its DHTML Event attribute is set to onMouseDown. Beneath the Event Handler, ActionJavascript is added and its code set to:
 

document.getElementById('inpHidden').value = @Data.ProductID~;
return true;


So, when the mouse button is depressed on the link, the data from the ProductID column for the current row will be assigned to the Input Hidden element.

And then another Event Handler, for the actual mouse-click, is added with child Action.Report and Target.Report elements. These submit the page and calls the next Report or Process task, where the Product ID value will be available as @Request.inpHidden~.

This is a common and useful technique that allows you to perform multiple actions based on what seems like one mouse click.

  Back to top

  Prev

 


© Copyright 2007-2019 Logi Analytics, Inc. All Rights Reserved