JSF 2, ajax input field behaves differently in firefox 10 and ie9 - ajax

When cursor is in input "test" and user press enter-key in a simplified form like
<h:form>
<h:inputText id="test" value="#{myModel.someValue}" >
<f:ajax event="blur" execute="#this" listener="#{myBean.calculateStuff}" render="myText"/>
</h:inputText>
<h:outputText id="myText" value="#{myModel.myText}" />
<h:commandButton value="send" action="#{myBean.calculatedNextPage} ">
</h:form>
firefox invokes 1 submit, ie invokes submit and partial-request.
Is this behaviour ok? From application side it is nuisance, because there is prevention/detection for multiple request on client/server side.
We don't know the page outcome beforehand if some field's validation/conversion has failed and we might not get updated "myText" rendered on both browsers. Enter-key check to prevent from submitting is not desirable and "blur" is good in normal cases. Any suggestions how to get both browser working the same way?

This behaviour is indeed not desired. But MSIE as whole browser at its own also not. That's what you have to deal with as being a web developer. Firefox/Chrome/Safari/etc correctly skip the blur event when the submit event has occurred.
If your sole purpose is to convert/validate someValue, then you should be doing that inside a normal converter and/or validator, not inside an ajax listener method.
<h:inputText id="test" value="#{myModel.someValue}">
<f:converter converterId="someValueConverter" />
<f:validator validatorId="someValueValidator" />
<f:ajax event="blur" execute="#this" listener="#{myBean.calculateStuff}" render="myText"/>
</h:inputText>
This way you can just safely ignore "unnecessary" ajax requests.
But if you really have a hard head in, you can in your particular example always add an onsubmit handler to skip the onblur.
<h:form id="form" onsubmit="document.getElementById('form:test').onblur=null">

Related

p:ajax blur event on p:inputText is not invoked when p:commandButton is clicked

I want to pass data to back bean through ajax call on command button click.
I have a form with couple of input text fields where each field is having ajax blur event.
Every thing is working fine in happy flow except in the flowing scenario.
Ajax blur event is invoking when i directly clicking on submit which is suppose to be happen before submit click, hence i should make another click on submit button to invoke ajax call to save my form.
Here is the code.
Input text fields:
<p:inputText id="txt_name"
value="#{partnerVO.partnerName}"
required="true" maxlength="30"
rendered="#{!partnerVO.isReadOnly}">
<p:keyFilter regEx="/[A-Za-z0-9#.,&- ]/i"
for="txt_name" preventPaste="false" />
<p:ajax update="txt_name" event="blur" />
</p:inputText>
<p:inputText id="txt_assigned"
value="#{partnerVO.assignedName}"
required="true" maxlength="30"
rendered="#{!partnerVO.isReadOnly}">
<p:keyFilter regEx="/[A-Za-z0-9#.,&- ]/i"
for="txt_assigned" preventPaste="false" />
<p:ajax update="txt_assigned" event="blur" />
</p:inputText>
Command Button:
<p:commandButton id="btn_save"
title="Save"
value="#{lbl['tpdetails.remove.additional.address']}"
update="#form" process="#this"
action="#{partnerDetailsController.save}">
</p:commandButton>
I'm using JSF 2.2
Please provide some suggestions to overcome this strange behavior.
Note: omitted form related code here.

f:ajax does not update t:dataTable on complete

I have a JSF search command button and a tomahawk dataTable that showing the result from a search. When clicking on the command button, the dataTable should output the search result. Anyway, since I use the JSF Ajax, the dataTable doesn't show. I am just wondering whether JSF Ajax cause the problem?
Here is the problematic code that cause the table now render:
<h:commandButton id="search" value="#{msg.Label_Search}" action="#{theBean.doSearch}">
<f:ajax render="searchStatus" execute="#form" />
</h:commandButton>
<h:outputText id="searchStatus" value="Loading data now..." rendered="#{theBean.searchingNow}" />
<h:panelGroup id="searchResultTable">
<t:dataTable ... />
</h:panelGroup>
*Take note on this. If the ajax code were removed. It is working fine.
You're only updating the searchStatus, not the searchResultTable when the ajax request completes. So the enduser will indeed never see a visual change in the HTML representation of the searchResultTable.
Fix the <f:ajax render> accordingly so that the searchResultTable is also really updated:
<f:ajax render="searchStatus searchResultTable" execute="#form" />

Deactivating commandButton functionality if inputText validation fails or ajax call starts

I have the following piece of code inside a form:
<p:panel id="panel" header="lalalala">
<h:panelGrid columns="5">
<h:outputLabel value="Enter name" for="name" />
<p:inputText id="name" value="#{userBean.name}"
required="true" label="name" maxlength="15"
validatorMessage="oops"
requiredMessage="ooopps">
<f:validateRegex
pattern="^somepattern$">
</f:validateRegex>
<p:ajax event="blur" update="inputValidationMessage" />
</p:inputText>
<p:message id="inputValidationMessage" showSummary="false"
for="name" />
<p:watermark for="name" value="eg. John" />
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" update="panel"
actionListener="#{userBean.save}"
onclick="handleOnclick"
oncomplete="handleAjaxResponse(xhr, status, args)">
</p:commandButton>
<p:messages autoUpdate="true" globalOnly="true" showDetail="true" />
</p:panel>
So the validation messages work well on the inputText element. But the submit button is still making an Ajax request when clicked, even though the input is invalid. I want the Ajax request to be sent iff the inputText is valid.
How do I do that?
Furthermore; there is another case I'd like to deactivate the button. This is the case where inputText is validated and the user clicks the button. The reason for this one is, I don't want the user to mistakenly flood requests. (i.e repeatedly press the submit button)
Currently, the handleOnclick javascript function only shows a modal dialog box saying "wait". Since that dialog is modal, the background is inaccessible. However, that still doesn't prevent the user from pressing it repeatedly because 1 second passes between onclick and modal dialog showing. Furthermore; this approach doesn't prevent submitting invalid data. What can you suggest?
I use JSF2.0 and Primefaces 3.0.
Any help appreciated.
You can use the button's disabled attribute for it. Just set it to true whenever FacesContext#isPostback() returns false (so, it's an initial request), or when it's true (so, a form submit has occurred), then check if FacesContext#isValidationFailed() returns true (so the validation has failed in general).
<p:commandButton ... disabled="#{not facesContext.postback or facesContext.validationFailed}" />
You only need to ensure that you update the button on ajax requests as well, so that it will reappear either enabled or disabled when necessary.
<p:ajax event="blur" update="inputValidationMessage submitButton" />

How to inject one JSF2 page into another with jQuery's AJAX

I'm using jQuery's .load function to load one JSF page into another.
This works really well until the loaded JSF page uses some AJAX functionality. When this happens, the parent JSF page's AJAX stops working. In fact, after the two pages are combined whichever page has its AJAX called next is the one that continues to work. The other page stops working. If I use the parent page first, the child breaks. If I use the child first, the parent breaks.
Am I doing something wrong? I'm guessing JSF isn't designed for this sort of behaviour and that's fine but then how do I go about doing what I want?
Basically, we have a report page. When the user clicks the link to a report we would like the report to load dynamically into the existing page. That way, the user doesn't experience a page refresh. It's a pretty slick behaviour BUT obviously isn't ideal due to the pages breaking.
I suppose I could do this with a page that contains every report in an outputpanel and then determine which one is rendered based on a value in the backing bean but I can see lots of occasions where I'd like to be able to "inject" one page into another (for dynamic dialogs for instance) and it would suck to have to keep everything in one giant template.
Has anyone else come across this sort of problem? How did you solve it?
Do not use jQuery.load(). It does not take JSF view state into account at all, so all forms will fail to work. Rather make use of <f:ajax> and rendered attribute instead. Here's a basic example:
<h:form id="list">
<h:dataTable value="#{bean.reports}" var="report">
<h:column>#{report.name}</h:column>
<h:column>
<h:commandLink value="Edit" action="#{bean.edit(report)}">
<f:ajax render=":edit" />
</h:commandLink>
</h:column>
</h:dataTable>
</h:form>
<h:form id="edit">
<h:panelGrid columns="3" rendered="#{not empty bean.report}">
<h:outputLabel for="name" value="Name" />
<h:inputText id="name" value="#{bean.report.name}" required="true" />
<h:message for="name" />
...
<h:panelGroup />
<h:commandButton value="save" action="#{bean.save}" />
<h:messages globalOnly="true" layout="table" />
</h:panelGrid>
</h:form>
You can if necessary split off the content into an <ui:include>.

Ajax, conditional rendering and backing beans

I am trying to display a page where the user, by the appropriate selection using a radio button, sees either a textbox or a combo box. This is relatively easy and I managed to do that by the following code:
<h:selectOneRadio id="selection" value="#{inputMethod.choice}">
<f:selectItem itemValue="#{inputMethod.TEXT}" itemLabel="textbox"/>
<f:selectItem itemValue="#{inputMethod.COMBO}" itemLabel="combobox" />
<f:ajax event="click" execute="#this" render="#form" />
</h:selectOneRadio>
<h:panelGroup id="Textbox" rendered="#{inputMethod.choice==inputMethod.TEXT}">
<h:outputLabel>Textbox:</h:outputLabel>
<h:inputText value="#{myBean.somevalue}" />
</h:panelGroup>
<h:panelGroup id="Combobox" rendered="#{inputMethod.choice==inputMethod.COMBO}">
<h:outputLabel Combobox:/>
<h:selectManyListbox id="CommunityListbox" value="#{myBean.choices}">
<f:selectItems value="#{myBean.selections}" var="u" itemValue="#{u.id}" itemLabel="#{u.name}"/>
</h:selectManyListbox>
</h:panelGroup>
The problem I have is that the setter for the combo box is never called.
In fact, the setter is only called for the component that is rendered by default (in this case whenever inputMethod.choice==inputMethod.TEXT). If I remove the conditional rendering, all setters are called as one would expect.
Any ideas or answers will be greatly appreciated!
PS: I am using jsf2.0, Glassfish 3.1, Netbeans 7.0 (in case this is of any importance)
You need to ensure that #{inputMethod.choice} evaluates exactly the same during the request of processing the form submit as it did during the request of displaying the form. Easiest is to put the bean in the view scope or to move the initialization logic into the (post)constructor of the request scoped bean.

Resources