4

I have a JSF file that needs to get populated from the data I get from the JS function that I get from Ajax call to a web-service. The latter part works like a charm. I am able to retrieve the JSON data from the ajax call. I need to parse this json data and take data and use that to populate the JSF. I am unsure as to how I would access the JS variables from the JSF/xhtml.

Is is possible to do it in someway? I was going through some DWR stuff that would send ajax post from JS to the Java bean and I could use the bean variable from the JSF. But, I want to know if there is any other way of doing this.

I would greatly appreciate any help. I am using JSF 2.x btw.

Thanks, S.

reg_frenzy
  • 81
  • 1
  • 5
  • 13
  • JSF 1.x or 2.x? In 2.x this is certainly doable. Btw: you never responsed on that here as well.. http://stackoverflow.com/questions/5507823/updating-a-list-of-items-on-calling-setpropertyactionlistener-in-jsf It's pretty important to mention the JSF spec version because JSF 2.x offers builtin ajax functionality and the answer depends heavily on that. It would be a total waste of time to post an answer for JSF 2.x and you're after all using old 1.x. – BalusC May 13 '11 at 21:56
  • I apologize for not being specific. It is JSF 2.x – reg_frenzy May 13 '11 at 22:21

3 Answers3

8

You can use the following 'hack' to get JS to submit information to JSF.

Create an invisible JSF form with <f:ajax> hook:

<h:form prependId="false" style="display:none;">
    <h:inputText id="input" value="#{bean.input}">
        <f:ajax event="change" execute="@form" listener="#{bean.process}" render=":something" />
    </h:inputText>
</h:form>

Let JS update the input field and trigger the change event:

<script>
    function somefunction() {
        var input = document.getElementById('input');
        input.value = 'your JSON string';
        input.onchange();
    }
</script>

Do the Java/JSF job in the listener method:

private String input; // +getter +setter

public void process(AjaxBehaviourEvent event) {
    doSomethingWith(input);
}

Put the desired JSF markup in a <h:someComponent id="something"> which will be re-rendered by <f:ajax render=":something"> when the listener has done its job:

<h:panelGroup id="something">
    The JSON string was: <h:outputText value="${bean.input}" />
</h:panelGroup>

That said, I'd prefer to do the webservice call in the constructor or action method of the managed bean instead of in JS. Your approach is literally a roundabout.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks tons. That was pretty quick. I have another question as well. How do I access the input variable in the process() listener? I am not sure if this is something very simple that I am missing. – reg_frenzy May 14 '11 at 00:04
  • It's already set in the property behind the `value` of ``, the `input`. See, in my example I even demonstrated to do something with it. It's available by `input` in the listener method. This comment however indicates that you're totally new to JSF and it look like as you've never developed forms with JSF. I'd suggest you to invest some more time in to learn how JSF works. This tutorial might give new basic insights: http://balusc.blogspot.com/2011/01/jsf-20-tutorial-with-eclipse-and.html – BalusC May 14 '11 at 00:05
1

I think this is not possible.

  • JSF runs on server.
  • JavaScript runs on client (browser).

So, JSF runs BEFORE action in JS.

Of course, you can make a servlet that will be called from JavaScript, receiving information stored in JavaScript variables. But, this will be in next step:

  • JSF assembles the page
  • JavaScript call WebService, getting JSON data
  • JavaScript send JSON data to server (servlet)
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Topera
  • 12,223
  • 15
  • 67
  • 104
  • I need to render the JSF elements based on the JSON data basically say, if I get back 3 elements, I need to have a loop on my JSF to create those many div tags. So, I need the JSON to be fetched at the load of the JSF page and have the data populated accordingly. – reg_frenzy May 13 '11 at 21:54
  • @reg_frenzy: Ok, so you don't need to use javascript to read JSON information. The server can get this JSON data directly. – Topera May 14 '11 at 10:33
0

You could revisit the design a bit and probably accomplish what you're looking for. Rather than accessing the webservice via ajax on the client you could access it server side by communicating with it directly in an action method or a method that occurs before the view is created (prettyfaces actions handle this kind of work nicely). Then you can construct your view dynamically based on the results of the response from the web service.

I'm not 100% sure that will accomplish what you are looking for but that general idea might work for what is sounds like you're going for.

If you've already rendered a view and you want to do it with ajax you could use f:ajax with the same principle -- hit action method, communicate with webservice server side in that action method, change state of variables that determine the view layout and render the response.

Dave Maple
  • 8,102
  • 4
  • 45
  • 64