p:commandButton only works with two clicks (JSF 2.2 Bug?) - javascript

i'm trying to update (merge) a field from a ListDataModel and I'm experiencing what I think is a bug in Jsf (Mojara) 2.2. The update only works if the PrimeFaces command button is clicked twice. I've read a number of posts on here and tried the solutions but nothing seems to be working:
h:commandButton/h:commandLink does not work on first click, works only on second click
commandButton only works on the second click
p:commandButton with p:fileDownload and no ajax only works in second click
The list comes from
<h:form>
<p:dataTable value="#{proDocFolBean.selectedProDocs}" var="docs">
<p:column headerText="Document Name:">
<h:outputText value="#{docs.docName}"/>
</p:column>
<p:column headerText="Description">
<h:outputText value="#{docs.description}"/>
</p:column>
<p:column headerText="Date Created">
<h:outputText value="#{docs.dateCreated}">
<f:convertDateTime pattern="dd-MMM-yyyy" />
</h:outputText>
</p:column>
<p:column headerText="Classification">
<h:outputText value="#{docs.classification}"/>
</p:column>
<p:column>
*** <p:commandLink value="Update" action="#{proDocFolBean.prepareUpdateDoc}"/> ***
</p:column>
<p:column>
<p:commandLink id="downLoadLink" value="Download" ajax="false">
<p:fileDownload value="#{proDocFolBean.downloadFromFolders}"
contentDisposition="attachment"/>
</p:commandLink>
....
</h:form>
Clicking the Update link in the above form calls a preparedUpdate method in the bean:
public String prepareUpdateDoc() {
docToUpdate = selectedProDocs.getRowData();
selectedId = docToUpdate.getProjectDocId();
docsFacade.find(selectedId);
return "UpdateProDoc";
}
The above method populates the update form:
<h:outputScript name="js/formbugfix.js" target="head" />
<p:inputTextarea rows="30" cols="60" value="#{proDocFolBean.docToUpdate.description}" immediate="true"/>
<p>
<p:commandButton value="Change" action="#{proDocFolBean.updateProjectDoc}">
<!-- <f:ajax execute="#form"/> -->
</p:commandButton>
I included a js script although I realize that PF has already fixed view state through embedded js. I thought possibility including a script as stated in this question.
might solve the problem but it results in the same behavior.
Finally, the form calls the following merge method in the bean:
public String updateProjectDoc() {
docsFacade.update(docToUpdate);
return "ProSysHome";
}
If I try to use an h:commandbutton or set ajax to false using the p:commandButton (without the js script), the form is simply refreshed and the updated value is not merged into the database. If i use the p:commandButton on its own, I am able to get the operation working but only after two clicks. This is very odd behavior and would appreciate any help. Thanks in advance!

Well I think I solved this with Vsevolod's help. First it's totally unnecessary to use a separate js script because as Vsevolod says PF has its own fix.
Using p:commandButton alone I was getting a javascript error
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
VM94:25 Uncaught TypeError: Cannot read property 'debug' of undefined
It seems that this error comes from the original list form at the point I click the UPDATE link to call the prepareUpdateDoc method and populate the update form. Setting the ajax to false on this column solved the problem:
<p:column>
<p:commandLink value="Update" action="# {proDocFolBean.prepareUpdateDoc}" ajax="false"/>
</p:column>
The form now works after a single click but I would still like to know if the cause was due to two repeated ajax calls (one from the list form p:commandLink and the second from the actual update call by the p:commandButton) and why the js error disappears after setting ajax to false?

I had this "2 click" problem as well. In my case the solution was to use
<p:commandLink value="Update" id="sButton" action="#{myBean.myAction}" update=":myForm"/>
and not
<p:commandLink value="Update" id="sButton" action="#{myBean.myAction}">
<p:ajax event="click" update=":myForm"/>
</p:commandLink>

I had this problem, but in my case there was ajavax.faces.application.ViewExpiredException
Here is a good article about it javax.faces.application.ViewExpiredException: View could not be restored

Related

Closing popup only if the form is valid

I want to validate my inputText field, which is in a popupPanel. It should contains only numbers.
<h:form>
<h:outputText value="Input:"/>
<h:inputText id="myID" value="#{myBean.field}"
validatorMessage="Only numbers">
<f:validateRegex pattern="([0-9])*$" />
<rich:validator />
<a4j:ajax event="change" render="msgValidator" />
</h:inputText>
<h:message id="msgValidator" for="myID" styleClass="text_colorRed" />
</h:form>
After all I want to save all with button. If the input is correct I want to close the popup, otherwise I want to re-insert the correct input without closing popup.
<a4j:ajaxButton type="submit" value="Save" styleClass="text_weigthBold"
action="#{myBean.save()}" render="myTable"
oncomplete="#{rich:component('myPopup')}.hide();" execute="#this">
</a4j:ajaxButton>
Unfortunately when I type wrong input and click two times on the button, it save the request and close the popup without requesting to input the correct text.
I also used a Java validator but the behavior is still the same.
What can I do to correct this bug?
This is because you're closing popup unconditionally. You must check yourself if validation was OK. In JSF 2.0 you can use FacesContext#isValidationFailed().
<a4j:commandButton execute="#form" value="Save" styleClass="text_weigthBold"
oncomplete="if (!#{facesContext.validationFailed}) {#{rich:component('myPopup')}.hide();}"
action="#{myBean.save}" render="myTable" />
To check also other errors you can use facesContext.maximumSeverity.ordinal gt 0 or facesContext.maximumSeverity != null.
I don't know RF 3.X (and you didn't tell if you're using RF 3 or 4) but it looks like it never had component named a4j:ajaxButton, did you mean a4j:commandButton? Also note that I've changed action="#{myBean.save()}" to action="#{myBean.save}" which is corrent.
Resolved. In the form there were some h:checkbox, I remove the checkboxes and now it works fine. I dont know why the Richfaces checkbox doesn't work correctly but I replace them with HTML checkbox.

Avoid onRowClick event in certain column of rich:dataTable

I have a rich:dataTable which contains 4 columns.
The first one is a selectBooleanCheckBox, which fires an event called "CheckEvent" (just for the example) into the bean.
Meanwhile, the dataTable also supports the onRowClick event, which fires "onRowClick" on the bean.
The problem I'm facing is that when I click on the first column (the check one), the onRowClick also fires. This certainly is a problem in this situation: if a row has the check selected and I just want to deselect it, the onRowClick highlights the row, a behaviour I don't want.
I've tried to define the oOnRowClick event inside the other three rich:columns, but what I achieve this way is nothing; that the event doesn't even trigger, so there's no onRowClick for the datatable.
Trying to make the logic via the bean doesn't work either, since I don't know which column is pushed when I enter the onRowClick() method.
I'm really desperate about this. Any help would be kindly appreciated.
onrowclick adds onclick on the table row, if you don't want it to fire you have to prevent the click event on the checkbox from bubbling up to the row, e.g.:
<h:selectBooleanCheckbox onclick="event.stopPropagation()" … />
I can see that this
<h:selectBooleanCheckbox onclick="event.stopPropagation()" … />
works perfectly for solving the QA's Problem with the selectBooleanCheckbox.
Would something similar work, if the Column that is not supposed to react to the onclick Event contains a clickable Icon, that is supposed to execute a different function? See the example below:
<rich:panel headerClass="panelHeader" styleClass="panel">
<f:facet name="header">Header</f:facet>
<rich:dataTable id="myTable" value="#{myModel}" var="k">
<a4j:support event="onRowClick" action="#{myAction.selectItem(k, facesContext.viewRoot.viewId)}"
reRender="myTable"/>
<rich:column>
<f:facet name="header">
<h:outputText value="Normal Column - should be clickable"/>
</f:facet>
<h:outputText value="#{k.name}"/>
</rich:column>
<rich:column >
<f:facet name="header">
<h:outputText value="Only Click on Icon should react to Mouseclick"/>
</f:facet>
<s:graphicImage value="/img/bin_closed.gif">
<a4j:support event="onclick"
action="#{myAction.deleteItem(k)}"
reRender="myTable"
ajaxSingle="true" limitToList="true"
onsubmit="if(!confirm('Really?')) { return false; }" />/>
</s:graphicImage>
</rich:column>
</rich:dataTable>
</rich:panel>

JSF render component ajax radio button selection

This Question is a follow up to JSF Primefaces Radio Button show/hide/enable a textarea
One of the two problems were solved from that Post by wrapping the inputTextArea in a panelGroup, however I still need to figure out how to not show the inputTextArea on form load when the status is a 2 (=No), but only show when the radio under column 2 is being toggled.
<p:column ...>
<p:selectOneRadio ...>
...
<p:ajax update="reason" />
</p:selectOneRadio>
</p:column>
<p:column headerText="Reason For Attribute Failure">
<h:panelGroup id="reason">
<h:inputTextarea value="#{qAndA.fail_reason}" rendered="#{qAndA.toggle_value == '2'}" />
</h:panelGroup>
<h:outputText value="" rendered="#{qAndA.toggle_value == '1' or qAndA.toggle_value == '3'}" />
<h:outputText value="#{qAndA.fail_reason}" rendered="#{qAndA.toggle_value == '2' or qAndA.toggle_value == '4'}" />
</p:column>
perhaps the status codes are flawed:
0 = no input yet
1 = yes
2 = no, with a reason
3 = Not Applicable
4 = the No was eventually resolved
I'd rather not have to modify the status codes but adding another intermediate code, something like this would probably work:
2 = show reason box
2.5 means no with a reason
Any other options besides modifying status code?
Well the real answer is to not have the value at 2 when the bean is loaded if you want to not display it. But you already know that. What you are asking is subjective to you and how you wanna do things. You have no issue and this is more a design question. Having said that here is one:
Maybe you'd like to have 2 conditions :
<h:inputTextarea value="#{qAndA.fail_reason}" rendered="#{qAndA.toggle_value == '2' and bean.AnotherCondition}" />
If you wanna get fancy make a #ViewScoped bean that listen for the click you were talking about in your post ( not sure what the click does). Listen for the click and have a boolean property you can set to true once the click has been registered (maybe with an action listener). This way the textarea will only show when clicked.

Damaged parameter of javascript function in selectBooleanCheckbox

We have table with h:selectBooleanCheckbox in each row (checkbox represents boolean). We want to call backing bean action on change the checkbox value (in any row).
Following code works in funny way: if ID number (parameter from 1st column - String - used as parameter for javascript) is short (10 characters) then javascript parameter is correct, if ID number is longer (18 characters) then javascript parameter is not - value is partially destroyed (first 16 characters are the correct, 17 and 18 characters are replaced by 0).
XHTML:
<rich:dataTable id="loyaltyIdTable"
rows="#{referenceData.recordsPerPage}"
rowClasses="oddrow, evenrow"
var="pi"
value="#{chProfile.loyaltyPIs}">
<rich:column>
<f:facet name="header">
<h:outputText value="ID Number" />
</f:facet>
<h:outputText value="#{pi.idNumber}" />
</rich:column>
<rich:column styleClass="centeralign">
<f:facet name="header">
<h:outputText value="Can Redeem" />
</f:facet>
<h:selectBooleanCheckbox value="#{pi.canRedeem}"
onclick="alert(#{pi.idNumber});"
onchange="alert('ID number: ' + #{pi.idNumber}); return false;" />
</rich:column>
<rich:column styleClass="centeralign">
<f:facet name="header">
<h:outputText value="Delete" />
</f:facet>
<a4j:commandLink execute="#this" render="deleteConfirmationPanel"
oncomplete="#{rich:component('confirmPopup')}.show()">
<h:graphicImage value="/images/delete.gif" style="border:none;" />
<a4j:param value="#{pi.idNumber}" assignTo="#{loyaltyIdForm.deleteId}" />
</a4j:commandLink>
</rich:column>
</rich:dataTable>
In this code my javascript function was replaced by trivial alert.
It doesn't matter from which attribute onclick or onchange is javascript called - result is the same: last 2 characters of the #{pi.idNumber} are replaced by 0 when string length is 18.
Exact the same mess with parameter I had when h:commandButton was used for deleting row. After replacing h:commandButton to a4j:commandLink with a4j:param this part works fine (parameter is correct). Following is incorrect working code:
<h:commandButton value="#{msg.delete}"
action="#{chAction.deleteAltId(pi.idNumber)}"
onclick="return confirm('#{msg.deleteAltId} #{pi.idNumber}?')"
render="loyaltyIdTable" />
Environment: JSF 2.1 and RichFaces 4.3.
In this environment neither from a4j:ajax, f:ajax, h:selectBooleanCheckbox has action attribute. It means javascript should be called.
Can somebody explain me how to call javascript properly (per onclick or onchange in h:selectBooleanCheckbox) with parameter (different than checkbox object) in repeating structure (row of table or list)?
I can easily solve this problem with additional command button or replacing h:selectBooleanCheckbox with command link (with 2 images check/uncheck inside). But I am wondering if there is working solution with h:selectBooleanCheckbox.
Here,
onclick="alert(#{pi.idNumber});"
onchange="alert('ID number: ' + #{pi.idNumber}); return false;"
You're printing it as a JavaScript number type variable. Like the Java int, it has also a technical limit. For JavaScript it is 253 (9007199254740992).
Better print it as a string.
onclick="alert('#{pi.idNumber}');"
onchange="alert('ID number: #{pi.idNumber}'); return false;"
Note that EL runs in server side (while generating HTML/JS output), not in client side, so there's no need to "string-concatenate" it into a JavaScript variable.

RichFaces 4 - <a4j:ajax ...> Javascript "RichFaces not found"

Sorry for the question title, but I couldn't figure out a better one.
I'm using JSF 2.0 (MyFaces 2.0.2) and added RichFaces 4 (4.0.0.20101004-M3) to my project.
I found an example with RichFaces 4 (http://java.sys-con.com/node/1098139) and created a xhtml-page with the following code:
<ui:define name="webpage_main_body">
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Text:" />
<h:inputText value="#{echoBean.text}">
<a4j:ajax event="keyup" render="text,count"
listener="#{echoBean.countListener}" />
</h:inputText>
<h:outputText value="Echo:" />
<h:outputText id="text" value="#{echoBean.text}" />
<h:outputText value="Count:" />
<h:outputText id="count" value="#{echoBean.count}" />
</h:panelGrid>
</h:form>
</ui:define>
As this is a Facelets page, it uses a template which defines a header (including a logo and the main navigation).
If i'm opening the page in my browser, it gets rendered correctly. The resulting HTML code of the inputbox is as follows:
<input type="text"
onkeyup="RichFaces.ajax("j_id1176210999_514e0f6c:j_id1176210999_514e0fad",event,{"parameters":{"javax.faces.behavior.event":"keyup"} } )" value="" name="j_id1176210999_514e0f6c:j_id1176210999_514e0fad" id="j_id1176210999_514e0f6c:j_id1176210999_514e0fad">
The problem is, if I enter something into the textbox, it should fire an ajax-reqest on every keyup using a Javascript-function called "RichFaces.ajax(...)". However everytime the event is fired, the Firefox Error-Console prints an Error:
Error: RichFaces is not defined
Source File: http://localhost:8080/project/richEchoTest.xhtml
Line: 1
To my question: Has anyone have an idea where this RichFaces-Javascript-Object is defined? Or is there anything i have to include within the xhtml-pages? I only included the "xmlns:a4j="http://richfaces.org/a4j", do i have to add the "xmlns:rich...." too?
Thanks in advance, I'd really appreciate any help, cause I already wasted 3 days looking into the problem.
//EDIT:
I forgot to mention that if I use the built-in jsf2 ajax-tag it works like a charm:
<f:ajax event="keyup" execute="#form" render="text count"
listener="#{echoBean.countListener}" />
This problem was solved and commented in this link. Here's an extract of relevance:
Cause:
The browser can't find references to JS and CSS libraries of RichFaces.
Solution:
Add the following tag to your JSF code:
<h:head/>

Categories