-1

I have jQuery modal div which displays on an on-click event....

<div id="time_scheduler" style="display: none;" title="Change Event Time"   class="dialog">
    <div class="block">
        <h:form>
            <span>Select Shift</span>
            <p></p>
            <h:selectOneMenu value="#{fieldController.shift}">
                <f:selectItems itemLabel=" #{s.shiftName}  &nbsp; &nbsp; &nbsp;   #{s.startTime} to #{s.endTime}" var="s" value="#{fieldController.allShiftUnfiltered}" /> 
                <f:converter converterId="shconvert" />
            </h:selectOneMenu> 
            <p></p>  
            <h:commandButton onclick="getShift('#{request.contextPath}/changeEvent?','#{fieldController.shift.startTime}','#{fieldController.shift.endTime}');" styleClass="btn btn-small" value="change" />
        </h:form>
    </div>
</div>

and also a javascript function in a js file which gets called in a commandButton , the problem is each time the page displays , i get a null on the selectOneMenu after i click, then later i get the value, although its inconsistent,

function getShift(url,start_time,end_time){
    console.log('starttime is '+start_time); //start time is null on page first load
    console.log('endtime is '+end_time);     //end time is null on first page load

    $.ajax({
        url: url + 'event_id=' + event_id + '&start_time=' + start_time + '&end_time=' + end_time,
        cache: false,
        success: function(value) {
            console.log(value);  
        }
    });
}

I have a converter class

@FacesConverter(value = "shconvert")
public class ShiftConverter implements Converter {
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        AdminEJB adm;
        try {
            adm = (AdminEJB) new InitialContext().lookup("java:global/ffm/AdminEJB");
            return adm.findShift(value);
        } catch (NamingException ex) {
            return null;
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
      return value.toString();
    }
}

which pretty much does the conversion at a postconstruct level, what could really be the best way to pass this values to the javascript function each time the is changed ?

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Johnson Eyo
  • 113
  • 1
  • 9

1 Answers1

0

The way the commandButton is set up will make it use the last submitted values to call the javascript function. Before addressing this issue, we may want to understand the relationship between EL, JSF, and Javascript. JSF takes the facelet code and turns it into HTML. Any EL statements are resolved on the server side at that time. So, when it's all said and done, we have an HTML page that we can inspect in our favorite browser. Now comes Javascript, which has no awareness of JSF, so it works solely on the rendered HTML page.

With that in mind, we can see why the code above wouldn't work. The EL statements used as argument to the getShift Javascript function will only be resolved when that part of the page is rerendered by the server.

It look like the objective here is to call a non-JSF servlet asynchronously when the button is clicked. I would go about this a little differently. Have the commandButton call a JSF method asynchronously, and the method can reach out to the custom servlet.

<div id="time_scheduler" style="display: none;" title="Change Event Time"   class="dialog">
<div class="block">
    <h:form>
        <span>Select Shift</span>
        <p></p>
        <h:selectOneMenu value="#{fieldController.shift}">
            <f:selectItems itemLabel=" #{s.shiftName}  &nbsp; &nbsp; &nbsp;   #{s.startTime} to #{s.endTime}" var="s" value="#{fieldController.allShiftUnfiltered}" /> 
            <f:converter converterId="shconvert" />
        </h:selectOneMenu> 
        <p></p>  
        <h:commandButton styleClass="btn btn-small" value="change">
           <f:ajax execute="@form" listener="#{someBean.callServlet()} />
        </h:commandButton>
    </h:form>
</div>

Then, create a backing bean with a method to call the servlet

@Named
public class SomeBean {
    @Inject FieldController fieldController;
    public String callServlet() {
      Object startTime = fieldController.shift.startTime;
      Object endTime = fieldController.shift.endTime;

      //Call the servlet here

      return null;
    }
}

Here's an example on calling a servlet from java.

Community
  • 1
  • 1
Ali Cheaito
  • 3,746
  • 3
  • 25
  • 30
  • Thanks @Ali cheaito, actually the idea is to pass managed bean values to a javascript client side, which in turn makes an ajax server side call. im trying to achieve it this way because the javascript stores a global variable initialized by a jquery component if you notice in the javascript method there is a variable called event_id , this variable is actually initialized by a custom jquery component, any head way in this? or is there a way a jquery /js initialized value can be retrieved in a managed or cdi bean? – Johnson Eyo Dec 17 '14 at 08:18
  • I can't tell how the event_id is being created with the code provided. It looks specific to your application. If you must use that, assign it to an h:inputHidden and tie that to a field in the backing bean to read it from the JSF side and include it in the servlet request. – Ali Cheaito Dec 17 '14 at 16:40