spacer

 

Sunday, September 10, 2006

Internet Explorer Submit Button Bug




I've know about this problem for almost 3 years now. I guess It's time to put the blog out.

Affeted IE Version: 5 and 6
Firefox, Bon Echo: Not affected

The Bug
If we have a form where only one text field exists:
<form>
    First Name: <input type="text" name="firstName"/><br/>
    Roles:  
    admin: <input type="radio" name="role" value="admin" />
    user: <input type="radio" name="role" value="user"checked="checked"/><br/><br/>
    <input type="submit" name="submitButton" value="submit"/>
</form>

When the user enters a first name and hits the enter button, here's
the query string and by George the submitButton is missing!

ie_submit_button_form.htm?firstName=John&role=user   

I know what you're thinking: IE sucks! Microsoft is Evil! Son-of-a-$*#@@#&!
I know. I know. But nobody writes perfect code so I'll show you how to fix this problem.

What's suppose to happen by default is that the first declared submit button should be set. In our case it's the submitButton. In IE, this doesn't happen.

The Workaround
So the way to fix this bug is add another text field. In most cases where you don't have a choice and there's only 1 text field in the form, you can add an invisible text field (a hack):
<input type="text" style="display:none;"/>
Now let's try this again, given the following code:

<form>
    First Name: <input type="text" name="firstName"/><br/>
    Roles:  
    admin: <input type="radio" name="role" value="admin" />
    user: <input type="radio" name="role" value="user" checked="checked"/><br/><br/>
    <input type="submit" name="submitButton" value="submit"/>
</form>

Focus on the first name field and type a name, then press Enter key.
Here is the query string and the submitButton is set:
ie_submit_button_form.htm?firstName=George&role=user&submitButton=submit

Putting an invisible text field is not a bad hack and does not require code change when new versions of IE come out. It's also not going to affect the other browsers that are functioning properly...nevertheless, it's a hack!


A Spring MultiActionController with Command

The following is an example Spring code on how to create a handler methond within a Spring MultiActionController that includes a Command object. The MultiActionController implementation simple checks whether a method with an additional object in the handler method signature exists. If that's the case it assumes that it is a command object and binds the request parameters to the command object.

Here Are Some Code Examples

A typical Spring MultiActionController does not contain a command object in the method signature.

public ModelAndView myHandler(HttpServletRequest request, 
        HttpServletResponse response) {
    // handler methods here
}

A Spring MultiActionController with a Command object passed as an additional parameter in the method signature.

public ModelAndView myHandler(HttpServletRequest request, 
        HttpServletResponse response, Object command) {
    MyObjectCommand command = (MyObjectCommand) command; 
}

The creation of the command object can be overloaded as well.

protected Object newCommandObject(Class clazz) 
        throws Exception {
    return new MyObjectCommand();
}

Customizing Rico AJAX to process JavaScript Response Types

The Issue

Rico Ajax currently does not know how to process xml responses of type "text/javascript". In a situation when We want to be able to send a javascript ajax response back, we totally are out of option. An example use would be is an XML Reponse that updates the state of an image (i.e., highlighted version of an image).

Consider the Ajax XML Response:
<ajax-response>
    <response type="javascript" id="myResponseId">
         function testFunction() {
            alert('Hello World');
         }
    </response>
</ajax-response>
The Workaround

Basically what we need to do is create a function to process a javascript content type. This method should do nothing more than call the javascript "eval" built-in function. The modification code is commented with "// Add This" below.

_processAjaxResponse: function( xmlResponseElements ) {
  for ( var i = 0 ; i < xmlResponseElements.length ; i++ ) {
     var responseElement = xmlResponseElements[i];

     // only process nodes of type element.....
     if ( responseElement.nodeType != 1 )
        continue;

     var responseType = responseElement.getAttribute("type");
     var responseId   = responseElement.getAttribute("id");

     if ( responseType == "object" )
        this._processAjaxObjectUpdate( this.ajaxObjects[ responseId ], responseElement );
     else if ( responseType == "element" )
        this._processAjaxElementUpdate( this.ajaxElements[ responseId ], responseElement );
     // Add This
     else if ( responseType == "javascript" )
        this._processAjaxJavascript( this.ajaxElements[ responseId ], responseElement );
     else
        alert('unrecognized AjaxResponse type : ' + responseType );
  }
},

_processAjaxObjectUpdate: function( ajaxObject, responseElement ) {
    ajaxObject.ajaxUpdate( responseElement );
},

_processAjaxElementUpdate: function( ajaxElement, responseElement ) {
    ajaxElement.innerHTML = RicoUtil.getContentAsString(responseElement);
},

// Add this
_processAjaxJavascript: function( ajaxElement, responseElement ) {
    eval( RicoUtil.getContentAsString( responseElement ) );
}
Reference:

Friday, September 01, 2006

Refactoring the EJBHomeFactory in JDK 1.5


Here's nifty way of refactory the EJBHomeFactory. What I really wanted to do if it's possible is to do to make a call to the factory without having to pass the EJBHome class. I have that implemented here but with the expense of a JNDI Name to EJBHome class mapping. This is a code snippet of what I wish Java Templating could do. That's too bad that Java Templating doesn't support the T.class static property.

public <T extends EJBHome> T getRemoteHome(String jndiHomeName)
        throws RemoteException {
    T home = null;
    try {
        InitialContext ctx = new InitialContext().lookup(jndiHomeName);
        home = (T) PortableRemoteObject.narrow(objRef, T.class);
    } catch (NamingException e) {
        throw (new RemoteException("Failed lookup on jndi [" + jndiHomeName
                + "]", e));
    }
    return home;
}

The old way
try {
    AccountManagerHome remoteHome = (AccountManagerHome) EJBHomeFactory
            .getInstance().getRemoteHomeTheOldWay("ejb/AccountManager");
    AccountManager mgr = remoteHome.create();
    mgr.doSomething();
} catch (RemoteException e) {
    e.printStackTrace();
} catch (CreateException e) {
    e.printStackTrace();
}

Using JDK 1.5 Typesafety
The only difference here is that the typcasting is ommitted.


// Using JDK 1.5 Typesafety
try {
    AccountManagerHome remoteHome = EJBHomeFactory.getInstance()
            .getRemoteHome("ejb/AccountManager");
    AccountManager mgr = remoteHome.create();
    mgr.doSomething();
} catch (RemoteException e) {
    e.printStackTrace();
} catch (CreateException e) {
    e.printStackTrace();
}
To View the source code click: 
EJBHomeFactory.java
or simply just browse the
package
contents
.


Popular Posts

Featured Post

Encrypting Properties File Values with Jasypt

Encrypting Properties File Values with Jasypt What's the fuzz all about? Property files are text resources in your standard web applic...