JSF2 get JSON Data via AJAX from Backing Bean - ajax

I am using RichFaces 4. I am using flot as a JQuery Charting library and i want to implement a chart, that keeps refreshing itself via AJAX.
I get the data for the chart via JSON from my backing bean.
I am lost on how to get new data from a backing bean into a javascript variable. From what i understand i can't use <f:ajax> since there is no user interaction and no use of html input elements.
I think the solution would be the use of jsf.ajax.request. But i don't understand how to call that without an input-element either.
Following is a code snipped of how it should look like, but i don't know how to get the value from my backing bean into a javascript variable.
$(function() {
function update(){
//**dont know how this call should look like**
jsf.ajax.request('dev-form-input1', {render:'dev-form-output1'});
//'newAjaxData' would be the value from #{someBean.chartData}
plot.setData(newAjaxData);
// draw the chart with the new data
plot.draw();
//get an update every second
setTimeout(update, 1000);
}
I managed to send AJAX requests with jsf.ajax.request when using some input-element, but i didnt get the new value to render. And even if i could i wouldnt know hot to get it in a javascript variable (i dont have a lot of experience with javascript).
<h:form id="dev-form">
<h:inputText id="input1" value="#{someBean.chartData}"/>
<h:outputText id="output1" value="#{someBean.chartData}" />
</h:form>
note: i changed the javax.faces.SEPARATOR_CHAR to "-", because i need ":" for jquery.
Thanks for your help!

JSF is the wrong tool for the job. Use a webservice framework like JAX-RS, not a MVC framework like JSF. Then you can in the client end just use jQuery the usual way and so on.
See also:
Jersey (JAX-RS reference implementation) tutorial
Servlet vs RESTful

Related

How to Trigger an AJAX call in JSF from Javascript and avoid using global functions as callback handlers?

I want to move the JSF AJAX triggering code written with f:ajax, f:event and the h:commandLink (with its action attribute) to Javascript by using the jsf.util.ajax. - Why ? Because to avoid globally written handler functions to handle call backs. We are migrating the JS code to AMD Require JS and JSF isn't playing very well
Previously, the code to trigger AJAX calls from the view XHTML file in JSF was written like this :
<h:commandLink id="elemID" tabindex="-1" rendered="#{something.isEnabled ('showSomeLink')}">
<f:ajax render="#{someBean.getElemId('LinkID')}" onevent="renderAjax" />
<jsft:event type="ajax"> someBean.someMethod(); </jsft:event>
</h:commandLink>
The above markup gets rendered in HTML as follows:
Then, a click event was triggered on this link to execute the AJAX and the action.
The jsft:event was used which behaves similarly to its counterpart f:event.
I do not want to use this because it forces to define JS functions globally. In this case, renderAjax() in the onevent attribute of f:ajax
As you can see, This relies on a globally defined function called renderAjax() as the callback function to execute something and render on the UI side.
The trouble is we are moving into AMD and require JS and we have no scope of defining any globals in our code (we can but we do not want to). Even if we did, this ajax call gets triggered much before Require AMD loads
So I attempted to re-write this ajax call from the client side in JS, inside an AMD module, like this (from the generated HTML snippet's onclick mentioned above)
(Point to note, I did not know how to mention the action attribute in this JS code.)
jsf.util.chain(document.getElementById('elemID'), event,'jsf.ajax.request(\'elemID\',event,{render:\'LinkID\',onevent:renderAjax,\'javax.faces.behavior.event\':\'action\'})');
Once I wrote the above code in JS, I removed the f:ajax (since the render and the onevent attributes came inside the JS code itself ) and the jsft:event from the view, in the XHTML file. Once I removed this, it began causing a continuous reload of the page, as an infinite loop. I had to stop the server and put back the code to its old state.
Next, I thought h:commandLink was the issue and decided to replace h:commandLink with a normally rendered anchor tag via the h:outputLink.
Unfortunately this doesn't have an action attribute. The point is, although the element is rendered,
jsf.util.chain(document.getElementById('elemID'), event,'jsf.ajax.request(\'elemID\',event,{render:\'LinkID\',onevent:renderAjax,\'javax.faces.behavior.event\':\'action\'})');
Since my code with h:outputLink has no action attribute, it doesnt execute the method in the managed Bean.
Suppose I included the h:commandLink, without the jsft:event and the f:ajax, then it causes an infinite page reload.
I even added the action attribute to the h:commandLink after removing the jsft:event and f:ajax . I made it work with the below update.
<h:commandLink id="elemID" tabindex="-1" rendered="#{something.isEnabled ('showSomeLink')}" action="#{someBean.someMethod()}">
<f:ajax />
</h:commandLink>
and then using the following in JS:
jsf.util.chain(document.getElementById('elemID'), event,'jsf.ajax.request(\'elemID\',event,{render:\'LinkID\',onevent:renderAjax,\'javax.faces.behavior.event\':\'action\'})');
So far it works. But the problem is my renderAjax is still globally defined. Now i move my JS function into a require AMD module. The function renderAjax is no longer globally available and I move the jsf ajax code also into my module and access it as:
jsf.util.chain(document.getElementById('elemID'), event,'jsf.ajax.request(\'elemID\',event,{render:\'LinkID\',onevent:_t.renderAjax,\'javax.faces.behavior.event\':\'action\'})');
Note, _t.renderAjax() is now inside a module in Require JS. The Error i get now is _t is undefined. I guess it expects to see only global functions. The fun part is it automatically creates a wrapper function around the code. Is there any way to fix this?
(function(event
/**/) {
jsf.ajax.request('elemID',event,{render:'LinkID',onevent:_t.renderAjax,'javax.faces.behavior.event':'action'})
})
If someone could help me fix this, it would be extremely helpful.
Ok. I figured this out. I'm not sure if this is the right method. But it works.
Remove the following section as its not right to create a dummy link just for the sake of triggering a click event on it (in order to make JSF ajax work). It also forces to define global handler call backs as mentioned above which pollutes the global namespace, prevents the modularization of JS code, makes it imposs to move to AMD:
<h:commandLink id="elemID" tabindex="-1" rendered="#{something.isEnabled ('showSomeLink')}">
<f:ajax render="#{someBean.getElemId('LinkID')}" onevent="renderAjax" />
<jsft:event type="ajax"> someBean.someMethod(); </jsft:event>
</h:commandLink>
Now create a simple XHTML file called ajax.xhtml that serves as a template.
Create another file called needHelp.xhtml that uses the above file ajax.xhtml as the template
Both steps (1) and (2) have been shown in an image below:
http://i61.tinypic.com/2rgypsi.png
In the backing bean, do this:
http://i62.tinypic.com/1037bci.png
This completes the setup. Our Ajax response is now in the JSON format and written to the response stream.
Now, in the required AMD require Module,
define('checkChannel', ['jQuery', 'ajaxHandlers'], function($, ajaxHandlers){
(function checkChannel(){
$.ajax({
url : baseURL+"/needHelp.jsf",
dataType : "json",
type: "POST",
success : ajaxHandlers.renderAjax
});
})();
})
The success handler is used to update whatever DOM element needed, based on the response flags. In this case, it would update the element with id="LinkID", as defined in the original code snippet.
Now, the renderAjax is well wrapped inside an AMD module and is no longer required to be defined globally. Now there is no need to use the and or have dummy links created via to simulate a click and trigger AJAX in JSF. If the view state needs to be maintained, it can always be got and updated in a similar manner.
Also, baseURL is the basehref of your app. For example, if the page
was www.example.com/tool/index.jsf, then the baseUrl would be
www.example.com/tool/. So, the AJAX URL would be
www.example.com/tool/needHelp.jsf
PS: pardon the external image links as stackoverflow did not let me
post pics / more links as i needed atleast 10 reputation to post. I
had to use external images as I had some trouble formatting the code.

Refresh JSF component after custom javascript Ajax call

I have a custom javascript Ajax call in my jsf page. I capture and process the query string of the XMLHttpRequest in a filter. The filter adds a record to a table in the model.
Now I want the jsf page, without full page refresh, to reflect the updated model in one of the components (a Primefaces data table).
I guess what I need is a custom xmlHttpResponse...
Can anyone tell me how to do this? I'm scared it might be complicated, but I have no choice but to use the custom javascript...
The PrimeFaces <p:remoteCommand> is designed for this purpose.
Here's a basic kickoff example for your particular case:
<h:form>
<p:remoteCommand name="updateTable" action="#{bean.updateTable}"
process="#this" update="table" />
...
<p:dataTable id="table">...</p:dataTable>
</h:form>
It generates a JS function updateTable() which will invoke the #{bean.updateTable} method and update the component with (relative) client ID table. You just have to call the function updateTable() in JavaScript context.
updateTable();
You can even pass request parameters if necessary, it has to be sent as JS object:
updateTable({ name1: "value1", name2: "value2 });
No need to fiddle with homebrewed ajax requests and keeping the JSF state in sync.

Add ajax parameters from onstart function

A have primefaces commandButton with actionListener. On page I also have few dialogs, some of them are opened and others are closed. I need to dynamically find first closed dialog, call actionListener method, and pass parameters to that method with information which dialog is first closed. I use that information to update that dialog, and to call show() method to open dialog. I think that only possible place for that is onstart method, but I can't find the way to pass ajax parameter from onstart method. Is there any solution for this?
I'm using Primefaces 3.4, JSF 2.1.
If I understand you correct, you want to pass the value hold in a JavaScript variable along with the form submit as well. Easiest would be to set it as value of the HTML representation of a <h:inputHidden> component.
Given this JSF
<h:form id="form">
<h:inputHidden id="hidden" value="#{bean.hidden}" />
...
</h:form>
and this JS
var some = "some value";
you can set it by JS as follows
document.getElementById("form:hidden").value = some;
or, given that you're using PrimeFaces, by jQuery
$("#form\\:hidden").val(some);
Inside the JSF action method, it's just directly available as hidden property.

Ajax + Spring Webflow

First, I am using spring webflow and some spring javascript to make ajax calls easier.
As of right now, I am having ajax make a call into webflow to display the appropriate fragment.
So I am attempting to use Spring.AjaxEventDecoration for my ajax needs for my application. However, I am having some trouble with this method and webflow and from what I can tell, there are very few examples available to work with.
On a side note, I am not using a form or a select box. I thought I would mention this since every example I've found has used a form/form submit with onlick event or select box with onchange event.
Main question: if I have a method in my webflow that has parameters coming from my ajax, can I actually pass in the parameters from ajax to webflow?
Code:
<transition on="disassociateProperty" >
<evaluate expression="dService.disassociateProperty(requestParameters.currentPId ,currentD)" result="flowScope.currentD" />
<render fragments="PList" />
</transition>
So, when I look at the ajax call in firebug, it has the parameter I'm passing in (currentPId) and the correct eventId.
I put a debug point on the first line of the disassociateProperty method and it tells me currentPId is null.
So I would assume requestParameters.currentPId in webflow isn't pulling the currentPId from the ajax call.
Is this expected? Could anyone explain and give an example?
I would appreciate any help provided.
Adam
If you think that the problem comes from ajax call, it would be helpful if you write here the ajax call, so we could check if the call is being done correctly.
You could try to pass the form serialized in the data parameter when doing the ajax call. Also, do not forget to add the ajaxSource parameter in the URL. Hope this help.
HTML example:
<form id="formId" method="post" action="${flowExecutionUrl}&_eventId=disassociateProperty">
<input type="text" id="currentPId" />
</form>
jQuery Example:
$.ajax({
type: "POST",
data: $("#formId").serialize(),
url: $("#formId").attr("action") + "&ajaxSource=true",
...
});

JSF2 and custom components - how to call action from Javascript code?

I have adapted a Pie chart JS object to use with JSF; in order to do so, I've created a custom component that outputs the appropriate markup and JS calls on the page, rendering the graph correctly. For reference's sake, this is the link for the tutorial I've followed for the JS part.
The next step is listening to clicks on the slices, and calling an action from a backing bean. The JS object for the chart already contains a placeholder function that listens to such clicks, so I believe the JS part of it is good. However, the JSF side bugs me still; I've read the Java EE tutorial, Jim Driscoll's blog posts, and all over the internet, and still can't get my head around it.
So, could anyone be so kind as to give a little example, of how I could bind a JS function call to an event listener in JSF, so that my backing bean would be nicely informed of which slice index had been clicked by the user?
It would be something close to:
function myChartObject() {
function onSliceClick() {
// This will somehow trigger JSF ajax event listener with slice data
}
}
class MyCustomChart extends UIComponentBase implements ClientBehaviorHolder {
// Is the decode() method the place to bind JS calls to JSF actions?
}
The closest I've found to my problem is something like this. However, I'd like to have this support in my own component, using the standard JSF API. Something perhaps close to this?
Thank you all in advance!
The JSF Javascript API to do AJAX calls is itself standardized (resource library "javax.faces", resource name "jsf.js") but adding full AJAX support in your own Java based custom component is a little elaborate.
The quickest way I can think of is following the blog by Jim Driscoll that you cited, and re-use the existing AJAX machinery offered by the <f:ajax> tag by wrapping your own Java based custom component in a composite component.
In Jim's example, I guess the following code from line 22 in his example is what you should render inside your onSliceClick function:
String click = behaviors.get("click").get(0).getScript(behaviorContext);
It would then look a little like this:
<ui:component
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:cu="http://javaserverfaces.dev.java.net/demo/custom-taglib"
>
<cc:interface shortDescription="Some Description">
<cc:attribute name="render" required="false" />
<cc:attribute name="clickAction" method-signature="java.lang.Object action" required="true" shortDescription="The click action method" />
</cc:interface>
<cc:implementation>
<cu:custom id="customId">
<f:ajax render="#{cc.attrs.render}" listener="#{cc.attrs.clickAction}"/>
</cu:custom>
</cc:implementation>
</ui:component>
Note that I haven't tested this, but it's the general idea. Of course it's also possible to do all of it directly in Java code but that surely takes some more work.
It looks like you want the ability to encode ajax style behaviors in your java compiled code, while integrating this with a J2ee stack.
The framework that comes to mind is JBOSS's Seam
Seam integrates directly with JSF by design, (GWT is more of a lightweight, standalone, statefull web-application framework - it doesn't have a lot of embedded features for direct integration with JMS and other modern J2ee features)...
Seam directly supports GWT-style ajax enabled components.
There is a good tutorial here : http://www.ibm.com/developerworks/java/library/j-seam3/

Resources