aspose file tools*
The moose likes JSF and the fly likes Calling a4j: jsFunction from a .js file Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » JSF
Bookmark "Calling a4j: jsFunction from a .js file" Watch "Calling a4j: jsFunction from a .js file" New topic
Author

Calling a4j: jsFunction from a .js file

J Miller
Ranch Hand

Joined: Oct 21, 2010
Posts: 67
I have an application that uses JSF 1.2 and RichFaces 3.3.3. I need to be able to, from within a javascript file, call an a4j:jsFunction, but when I try, it's saying "Object required" in the javascript console. The jsFunction essentially calls a method in my backing bean that will add an error to JsfUtilities.addErrorMessage.

Is there some limitation that prevents us from doing this? I am able to call functions in my .js file from a jsFunction tag, but this is the first time I'm having to do the reverse. When I view the source code, the function does exist.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

Javascript functions cannot "call methods" in backing beans. That's because the backing beans are on the server and the JavaScript executes on the client.

In order to access server resources, you have to make server requests. JSF doesn't do RMI, just plain old HTTP. So that means that the JavaScript has to create and process an AJAX request/response.

The a4j:jsFunction facilitates that by defining the AJAX call as a named javascript-callable method. The richfaces Live Demo merely updates the backing bean and re-renders based on that update. If you code the "action=" attribute on it, you can also fire an action processor, which is what you'd normally want to do if you're adding to the JSF messages object, since otherwise you'd have to commit an offence such as giving side-effects to a property setter method.

One caveat, however. The JSF messages object is rather volatile. It's based on the last request/response cycle, so don't expect to be able to just stack up messages as you edit values on the page or do similar things. If that's what you want, you're better off making a message collection of your own. And DEFINITELY don't expect good things from Request Scope backing bean objects.


Customer surveys are for companies who didn't pay proper attention to begin with.
J Miller
Ranch Hand

Joined: Oct 21, 2010
Posts: 67
sooo... how do I do this? I understand pretty well how the a4j jsFunction works, we've used it quite a bit. And if I define the jsFunction and put the javascript in the same xhtml file, it they can call each other no problem. What I don't uderstand is why I can't call it from an included .js file. I tied the jsFunction to a backing bean that does nothing but prints a line to the console, just to see if it's getting called, and it's not. The javascript console is giving me an Object required, so as far as my included .js file goes, the jsFunction doesn't exist.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

I think that the "missing object" is the JSF form that contains the generated JSF function. And that it isn't in the namespace or DOM of the .js file.

I'm taking it for granted that you're not actually moving the a4j:support definition into the .js file. That would be hopeless, since the js file isn't processed by the xhtml processor.

It's important to remember that when you reference a .js file via a link tag, that this isn't an "include" operation where the js gets copied in as though it was inline. Instead the js is fetched via a completely separate server request and held independently by the client - often cached by the client. So the js can only refer to external resources at the source level and not the binary level.
J Miller
Ranch Hand

Joined: Oct 21, 2010
Posts: 67
I think you might be right, I think it has to do with the form. It's currently not in a form. However, if I put it in a form, I get Expected ')' and it points to the line for the a4j jsFunction. I've tried it with an h:form and an a4j:form, with an ID, without an ID, same thing. I even created a new function in javascript on the same xhtml as the jsFunction, that only calls the a4j jsFunction. So from the .js file, I call that javascript function, which then calls the jsFunction. It makes it to the javascript function, but I'm STILL getting that error, even though they're on the same page. I've done this on other pages and it's worked fine, cannot figure out the problem here. I've never this much trouble with something so seemingly simple.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

JSF AJAX works by doing partial-page postbacks. So under the covers, the jsFunction is doing an HTTP POST, and POST requires a form to post from. Therefore you have to declare the jsFunction within a JSF form (and not a raw HTML form or in a non-form area of the page).

There's no material difference between a4j:form and h:form these days, so that wouldn't help. If you don't explicitly specify an ID on the form, then JSF will synthesize an ID. Either way, an xhtml ID becomes a parameter to the jsFunction submitter. However, that ID references the DOM of the JSF view definition. When your calling javaScript is outside of that DOM, I think that's where your problem lies. In large part it's because the view form ID is passed as an ID string rather than as the actual DOM object itself. If the jsFunction passed the actual object, I think that an external javascript code could deal with that.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Calling a4j: jsFunction from a .js file