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.

Sunday, October 19, 2014

Quick Tip: Forcing a CSS override

If you are using OneUI in your XPages application, then you know sometimes it just doesn’t do what you want it to do. Trying to get it to behave can be frustrating, this tip will help when OneUI overides your custom style for reasons unknown.

The Problem

In my case, I was trying to make the labels of a radio button group appear disabled. Only the buttons themselves would look disabled, but the labels looked the same as when the control was enabled.
I don't feel that there is enough distinction between Enabled on the left, and Disabled on the right.
The radio button group control does attempt to make it easy by having a property to enter the styleClass for when the control is disabled or enabled.

XPages makes it easy for you to specify a disabled styleClass
This works fine for most of the CSS, except for some reason the color is overwritten as shown in the left picture below. I spent a lot of time playing with multiple CSS selectors with no success until I discovered how to force the CSS to override.
For some reason the "color" is overwritten by OneUI

The Solution

The way to override is to add “!important” after the attribute you don’t want to be overwritten. In my case, the only attribute that wasn’t behaving was the color. After I added !important, it worked exactly like I wanted. In the right picture above shows what this one change gives you.

Here is the Before code:

.radio-disabled {
font-size:14pt;
font-family:Calibri;
color: #AFAEB5;
}

Here is the After code:
.radio-disabled {
font-size:14pt;
font-family:Calibri;
color: #AFAEB5 !important;
}

The Finished Result

Enabled on the left, disabled on the right. It is easy to distinguish which is which.

Final Thoughts

Perhaps this is old news to some who read this. Though, in my office, none of the four XPages developers knew about this before. I hope that this helps other XPagers who wrestle with OneUI.

I will add that, this should be something that is used sparingly. In my case, only the specific class of “.radio-disabled” is using it. I can see that you could really mess your UI by overusing !important. Here is a related article called “Don’t Use !important” that explains some of the pitfalls.