Submit Query? What Query?

You've just built a web form. Users type in a message in a text area, then click on a Submit button to send the message. You run the application, and .... what? The browser has changed your Submit button into "Submit Query"! What Query? There's no query here!

We've had some bugs filed against Creator on this. In some browsers (notably Mozilla and Firefox), submit buttons change their labels into "Submit Query".

Form built in Creator Form deployed and shown in Firefox

This is a symptom of a much deeper problem, which I'd like to discuss in this blog entry.

Let's say you drop a button. This will create a button, but no label has been set on the button - look at its text property in the property sheet. A button component with no label set will render to this HTML:

    <input type="submit" />

This will not display a blank button (which you can achieve by adding value="") - all browsers will pick a default label! Internet Explorer, Safari, and most other browsers use the label "Submit". Mozilla/Firefox on the other hand, uses "Submit Query" - which I think is an odd choice. Creator has to choose something - it cannot show the "right" thing since that will depend on which browser the application is viewed with - and there could be a different browser for each user accessing the same web page!

There is an easy fix to this - go and set the value of the button to a specific string, like "Submit" (or Send or Order or Lookup or whatever makes sense on the current page.) In recent dev-builds of Creator, we've made some changes such that you don't end up in the scenario of an unset button as easily.

But this raises the question of why we don't set the text to some default value automatically. For a button, we probably could (and have - see above). But for components like Static Text, we can't. The reason for that is that it would make it very hard to set the text value from code!

Let's say you've dropped a Static Text component on the page, and you've set its text attribute to "Hello World", so your JSP contains this:

    <ui:staticText text="Hello World" binding="#{Page1.staticText1}" />

Now you're trying to do something clever in your Java code, for example setting the text to include the name of the logged in user:

    // In Page1's constructor
    staticText1.setText("Hello " + getUserName());

This won't work! Note that there is a conflict of definitions here - the JSP says that the text should be "Hello World", and the page constructor says that the text should be "Hello Tor". And the JSF spec says:

The JSP attribute wins.

You might try to move the above code into the new init() method, or even the prerender() method, but that won't help - the JSP attribute setting will still win the first time the page is displayed.

The only way to get your Java code to be able to set the static text, is to remove the attribute setting from the JSP.

And this is precisely why, when you drop a Static Text component on a page, we don't automatically set it to some "default" value. We could (and in early devepment versions did), but most users are not aware of the JSP vs Java conflict, and did not understand why their Java code which set labels didn't work. Granted, in most cases you don't want to set the label from code - you'll use value binding expressions instead. But it's an important enough scenario that we don't want to get people too frustrated when they run into this.

So, the solution we've settled on is using what we call shadow text\*. When a component is rendered at designtime, and it's missing a value that's vital (but one we don't want to set to avoid conflicts), we render the component text in bold italics instead, using a default label such as the type of the component. This shows you that there is a component here (since otherwise a static text with no actual text is rather hard to read...) and allows you manipulate it. But it's also obvious, or at least we hope so, that the component is not configured with normal text. As soon as you set a specific value for the property, it's rendered in the usual way.

Here's how this looks for buttons, static texts and hyperlinks - the first row shows components with shadow text:

\*: I don't think this is "official" terminology - it was simply called that in a recent bug report, and once I realized what they were describing I figured it's as good a name as any. Before that I had called it "uninitialized/bold/italic text" which is a mouthful...


I was testing this. I added the statement: staticText1.setText("Hello " + getUserName()); to my constructor. When I clicked on the Design: Preview in Browser button - I still saw the shadow text. I agree with you, bindings are the way to go, but I was just curious on how this worked. Thanks.

Posted by Todd Patrick on April 11, 2006 at 03:11 PM PDT #

"Preview In Browser" is special - it does NOT do a deployment. That's why it's nearly instant. It's great for tweaking visual design stuff. But it's showing you things like shadow text, as well as "123" and "abc" in databound controls rather than actual data. The whole issue around JSP versus values set from the page bean constructor only comes up with actual deployment, when a true JSF lifecycle is performed.

Posted by Tor Norbye on April 11, 2006 at 03:19 PM PDT #

Post a Comment:
Comments are closed for this entry.

Tor Norbye


« June 2016