I have a problem with a h:inputText and i don't know how to solve it.
I'm working on a xhtml page using JSF and RichFaces which contains fields as Calendar, SelectOneMenu, InputTextArea, Input. At the end of my form, there are two buttons Print and Save.
If one of the fields is modified (text, date, etc), i have to disable the Print button. In every field, i have add ajax event.
For example :
<rich:calendar datePattern="dd/MM/yyyy" timeZone="#{timeZone.timeZone}" value="#{myBean.date}">
<f:ajax event="change" listener="#{myBean.verifyModification}" render="myForm"/>
</rich:calendar>
If my date is changed, i call a method stored in my bean and it's ok.
But, i have a problem with my inputText and inputTextArea.
<h:inputText value="#{myBean.name}" maxlength="50">
<a4j:ajax event="keydown" render="myForm" listener="#{myBean.verifyName}" />
</h:inputText>
If i write fastly, for example i stay on the letter a to write aaaaaaaa in my field. The field will contain aaaaaaaa then aaaa. Is it because the ajax event is too slow? The problem doesn't come from my bean method because i only test a value.
Because of that, i can't test this field. I have tried the others events like blur, change. If i use these events, i have to click out of my field then my button is refresh.
Could you help me, please?
Thank you.
The problem is most likely that you render your complete form, not only the part of it that needs updating. JSF will then replace your form with the values you submitted on the first ajax request. Try:
<h:inputText value="#{bean.name}">
<f:ajax event="keydown" render="myButtonP" listener="#{bean.verifyName}" />
</h:inputText>
<h:panelGroup id="myButtonP">
<h:commandButton id="printBtn" value="Print" action="#{bean.printMe}"
disabled="#{bean.canPrint}" />
<h:commandButton id="saveBtn" value="Save" action="#{bean.save}" />
</h:panelGroup>
If you use disabled instead of rendered on the button, you can even reference printBtn directly in the render attribute.
Related
I am using jsf 2. One part of my code is this:
<h:panelGrid id="jobDetail" columns="3" cellpadding="7">
<p:outputLabel value="#{msg['content.jobList.JobName']}" />
<p:inputText id="jobName" styleClass="BIC_search_textbox" value="#{timerConfigurationBean.selectedTimerConfigurationJob.jobName}" required="true" requiredMessage="#{msg['content.jobNew.requiredfield.errormsg']}"/>
<p:message for="jobName" styleClass="error"/>
</h:panelGrid>
<p:commandButton id="update" value="Update_Button" action="#{timerConfigurationBean.updateExportJob}" styleClass="bottomButtonsAfterFirst" update="jobDetail" oncomplete="PF('updatejobpopup').show()"/>
This is only a section of the code. What happens is that when I click on the command button "Update_Button" one of the following two things happen:
1) I enter a value in inputText "jobName" and click the command button. First the function in action="#{timerConfigurationBean.updateExportJob}" runs and then the oncomplete="PF('updatejobpopup').show()" runs. This is how it was intended to be so that is okay.
2) I don't enter anything in inputtext (it is a required field), then click on the commandbutton. I see an error message on the webpage next to the Inputtext field (this happens because I have update="jobDetail" in my commandButton) and action="#{timerConfigurationBean.updateExportJob}" is not run however the oncomplete="PF('updatejobpopup').show()" still runs. This is a problem.
I want the oncomplete to only run when there are no errors on the page just like the function in action="#{timerConfigurationBean.updateExportJob}".
Can someone please help.
You can use the callback of primefaces to give a feedback to the view.
So, in your action method yo can do:
context.addCallbackParam("ok", true);
And in the onComplete:
oncomplete ="if ( args.ok ) { PF('updatejobpopup').show(); }"
I am using p:message for doing validations in p:dialog which opend on a button click on the form. So my main form has two dialog boxes which open on button click and these two dialog boxes have a h:form in it.
In the main form I have two fields username and password so when the user enter empty values and clicks on submit the error messages are shown on the main form and the dialog also pops up with the error messages which should not be the behavior. I want the validations for the main form to be shown on the form only and the validations for the fields in the p:dialog to be shown in the p:dialog only. Could you help me on this?
Let me know if any more information is required.
One of the possibilities is to have a separate <p:message> component for every input in every form. This way only the relevant messages will be shown. Example:
<h:form>
<h:inputText id="value" ... />
<p:message for="value>
...
</h:form>
<p:dialog>
<h:form>
<h:inputText id="value" ... />
<p:message for="value>
...
</h:form>
<p:dialog>
If you'd like to have global messages displayed as well you could consider using a 'hovering' component like <p:growl> with globalOnly="true".
I have a commandButton like this:
<p:commandButton value="Save" actionListener="#{bean.checkDetails}" action="#{bean.save}" />
My checkDetails() method checks some fields on the page and if they are not filled in, uses RequestContext to trigger a Javascript alert() which I want to use to block bean.save from being called until the user clicks "OK". The RequestContext piece looks like this:
RequestContext context = RequestContext.getCurrentInstance();
context.execute("alert('Details are not Complete.')");
My problem is I am not seeing the alert() dialog and bean.save is being called regardless of the state of the checkDetails() method.
Am I going about this completely the wrong way? I have spent three hours on this so far and I am plain stuck. If I remove the action method, the alert() pops up just fine.
Please, any input would be greatly appreciated.
My checkDetails() method checks some fields on the page and if they are not filled in...
As BalusC said, this can very easily be solved by adding required="true" to those fields, no need to write Java for this.
If you want to mix this up with the 'old-scool' alert() you can use the validationFailed callback parameter:
<h:form>
<p:inputText required="true" />
<p:commandButton value="submit" oncomplete="handleValidation(xhr, status, args)" />
</h:form>
<script type="text/javascript">
function handleValidation(xhr, status, args)
{
if(args.validationFailed)
{
alert('Details are not Complete.');
}
}
</script>
I have a form above which captures Contract records and displays them in a datatable which has a commandlink "Edit" tag. When I click “Edit” I would like the form populated with this contract data but with the Contract No field disabled. I’m trying to do this disabling in an Ajax onEvent tag and it is working (ie the disabling). However, the fields are not being populated/displayed in the form when the ajax is being used. If I remove it, everything is fine only that the Contract No will b editable.
These are my edit tags.
<h:commandLink id="editLink" value="#{bundle.ListUnitEditLink}" >
<f:ajax onevent="disablePK" listener="#{contractManager.updateContract}" />
</h:commandLink>
This is my backing bean.
public String updateContract() {
System.out.println("Now in UPDATECONTRACT method and serious debugging");
current = (Contract) items.getRowData();
this.newContractId=current.getContractid();
this.newContractDesc=current.getContractdesc();
this.newContractDt=current.getContractdt();
this.newContractAmt=current.getContractamt();
this.newContractStrtDt=current.getContractstrtdt();
this.newExpDuration=current.getExpduration();
this.newCtdBy=current.getCtdby();
this.newCtdOn=current.getCtdon();
this.lstUpdBy=current.getLstupdby();
this.lstUpdOn=current.getLstupdon();
return "contracts";
}
The properties in the bean are being given correct values but they are not appearing in the form to be edited.
I sorted out my problem by adding render=#all in the ajax tag
<h:commandLink id="editLink" value="#{bundle.ListUnitEditLink}"
actionListener="#{contractManager.updateContract}">
<f:ajax onevent="disablePK" render="#all" />
</h:commandLink>
I have a dataTable with a column named DELETE (it is a link) which has an listener . When I click it the first time (click 1) it deletes the row (as expected), but when I try it with another row after that nothing happened (click 2). In fact wherever I click next nothing happen. I should click another time (click 3) to get it work. I don't want that.
Attention: The "delete()" method in my_user is not reached after "click 2".
Here is the code for the column:
<h:column>
<f:facet name="header">#{lng.del}</f:facet>
<h:form>
<h:commandLink action="#">
<f:ajax event="click" listener="#{my_user.delete}" render="#all" />
<h:graphicImage name="delete.png" library="images" styleClass="tableIcon" />
</h:commandLink>
</h:form>
</h:column>
You've multiple forms inside the table. When you re-render another form from inside a form by ajax, then its view state will get lost and hence the 1st click will fail. This click however takes care that the form gets the view state back, so the 2nd click works.
Technically you need to re-render only the content of the other form, but this isn't possible in this particular use case. Better put the <h:form> outside the <h:dataTable> so that you have a single form with a shared view state.
<h:form>
<h:dataTable>
...
</h:dataTable>
</h:form>
If your page contains another forms as well, I'd suggest to render only the current form instead of all, otherwise any actions on those forms will fail as well.
<f:ajax event="click" listener="#{my_user.delete}" render="#form" />