Saturday, February 21, 2015

Using Javascript RegExp Object to replace a XPages Contraint Validator


I had an occasion yesterday where I needed change a partial refresh to process data without validation in order to fix another problem. Despite this I still needed to validate the data the user enters based on a regular expression.  The previous developer was was using a <xp:validateContraint> to check the data, but this check would no longer trigger since I am skipping validation. The constraint validator uses a regular expression to determine whether the validation passes or not.

Even though the regular expression in this case was simplistic, I did not want to mirror what it does using string manipulation to validate it. 
I remembered from one of my Javascript books (Professional JavaScript for Web Developers) that Regular Expressions are built into the language.  It was very easy to duplicate the constraint functionality by just copying the RegExp string that already worked and then creating a RegExp javascript object.   

The code here lives in a button in the SSJS onclick event: 

        
var thisID = getComponent("inputID").getValue(); 
var pattern = /^([A-Za-z]{2}[A-Za-z0-9]{0,2})$/; 
        
if(!pattern.test(thisID)){ 
     return viewScope.infoMessage = "No Can Do";
} 

The built-in RegExp object can be created in one of two ways, you can either use the slash as I do in the above code or you can create it using new RegExp("....").  Either way that you choose, it works the same. The object has a method called test() which will return a true/false depending if the passed in string matches.  Of course, you can use this in any javascript, client or serverside.

Thursday, January 8, 2015

Using a Hidden Input to Validate if a Button was pushed

In one of my current projects, I came across an issue where I needed to validate a form using the XPages validators.  This is a mature application that only uses SSJS everywhere, and I have to work with the boundaries already in place. 

The Problem

This particular problem is hard to describe but I will try.  I wanted to prevent a page from advancing to the next step.  The "Next >" link uses validators to control whether it works or not. Because of this established pattern, I needed to continue to use validators.  My problem was that there were no editable fields left on the page.  Validators only work on editable input fields, not buttons, links or computed fields. 

I needed to validate whether a button was pushed and still allow the code behind the button to work and itself trigger validation. 
The Next button allows the user to continue only when all validation is passed.

The Solution

I am going to show how to use a hidden input to validate non-input clickable elements, in this case a button. Despite validition, the onclick event of the button will still work.  Normally, the validator will trip, and the onclick event will not work until validation is passed.

Since you can only use a validator with input controls, I decided to use a Hidden Input. This control shows up on the page, but is not displayed. The validation messages of a hidden input are displayed using the standard display error control. 


<xp:inputHidden id="inputHidden1" value="#requestScope.validateYN}" required="true"> 
      <xp:this.validators> 
           <xp:validateRequired 
                  message="Please use Validate with WU button before continuing"> 
            </xp:validateRequired> 
        </xp:this.validators> 
</xp:inputHidden> 

The key is to bind the control to a scoped variable with no initial value; this will cause the validator to trigger when the page is submitted. To make the button still work normal, I used the onfocus to set the scoped variable so that it passes validation. In that onfocus event, I must do a partial refresh on the hidden input, and 'The Process Data Without Validation' box must be checked.

This shows the onfocus event of the button you want to validate

Final Thoughts

There might be other ways to accomplish what I show here, but I spent a lot of time trying other ways before I got this one working. I do know this is a rather obscure use case, but google has nothing on it, and I really didn't want to forget this in case I need to use it again.

Note: If you are very experienced with XPages, you might ask why I didn't set the button's "disabledValidators" property to "true".  For some reason, this did not work; the main code in the onclick event did not execute regardless of the property being set.

Monday, December 29, 2014

Using Domino Designer's 'Sign Design' to solve strange Java exceptions

Today, I reached out to another XPages developer who works on the same project in order to help me get past a strange error I was getting. The issue was that Java code within an XPages application that previously worked fine started failing, even though it had not been altered. He had experienced this issue before and knew what to do to fix it. The fix I am about to describe was new to me, so I felt it was worth sharing here.

The exception I was getting was this:
javax.servlet.ServletException: java.lang.Error: Unresolved compilation problem:  

When I first got the error, I naturally thought that it was something that I had changed. I didn't know what to make of an unresolved compilation problem, it seemed a bit generic, like the check engine light on your car. Even after I was able to isolate the line causing the problem, it made no sense because it was run of the mill Java code, the kind of snippet you use and reuse. In this case, it was a variable resolver that gets a handle to the current session.  

My coworker suggested performing a "Sign Design" on the whole application. To do this, right click on the application name, then click "Application", and then "Sign Design". Sure enough, this fixed the issue, no more Java exceptions. This is one of those fixes that is worth trying when nothing else is making sense. Of course this issue is most likely to happen for applications where work is shared by a team of developers, as is the case here. The downside of this fix of course, is that you lose some of the history, and it looks like you touched every design element.
The way to find the option to Sign Design is to right-click on the application title, and choose Application, and then choose Sign Design.

PS:  I want to wish Best Wishes for 2015 to all who stumble across my ramblings.