I have JSF text box like this
<p:outputLabel value="#{msgs['label.responsible']}:" for="printingResponsibleEdit"
rendered="#{b2cOrderDetailBean.b2cActionOrderView.canChangePrintingInfo() and
b2cOrderDetailBean.b2cActionOrderView.showExecutionInfo}" />
<h:panelGroup id="printresponsible"
rendered="#{b2cOrderDetailBean.b2cActionOrderView.canChangePrintingInfo() and
b2cOrderDetailBean.b2cActionOrderView.showExecutionInfo}">
<p:inputText id="printingResponsibleEdit" value="#{b2cOrderDetailBean.b2cActionOrderView.printingResponsiblePersNr}" size="4"
valueChangeListener="#{b2cOrderDetailBean.changeListenerString}" required="true" immediate="true"
requiredMessage="#{msgs['msg.required']}" binding="#{printingResponsibleBinding}" maxlength="4">
<f:attribute name="historyTypeCode" value="PR" />
</p:inputText>
<h:outputText value=" " />
<p:commandButton value="#{msgs['button.ok']}" immediate="true" process="printingResponsibleEdit"
actionListener="#{b2cOrderDetailBean.requestPrintingResponsible}" escape="false"
update="printingResponsibleName printingResponsibleEditMsg">
<f:attribute name="printingResponsible" value="#{printingResponsibleBinding.localValue}" />
<f:param name="responsiblePersonName" value="#{b2cOrderDetailBean.b2cActionOrderView.printingResponsiblePersNr}"></f:param>
</p:commandButton>
<h:outputText id="printingResponsibleName" value=" #{b2cOrderDetailBean.b2cActionOrderView.printingResponsible}" />
</h:panelGroup>
<p:message id="printingResponsibleEditMsg" for="printingResponsibleEdit" />
And i have my managed beans method like this
public void requestPrintingResponsible(ActionEvent actionEvent) {
try {
b2cActionOrderView.setPrintingResponsible(null);
b2cActionOrderView.setPrintingResponsibleName(null);
b2cActionOrderView.setPrintingResponsiblePersNr(null);
String persNr = (String) actionEvent.getComponent().getAttributes().get("printingResponsible");
if (persNr != null) {
Account account = accountDelegate.findByPersNr(persNr, localeView.getLocale());
b2cActionOrderView.setPrintingResponsible(account.getAccountId());
b2cActionOrderView.setPrintingResponsibleName(account.getName());
b2cActionOrderView.setPrintingResponsiblePersNr(account.getPersNr());
validatedPrintingResponsible = account.getPersNr();
} else {
b2cActionOrderView.setPrintingResponsible(null);
}
} catch (NoDataFoundException e) {
LOG.warn("PersNr not found.", e);
b2cActionOrderView.setPrintingResponsible(null);
b2cActionOrderView.setPrintingResponsibleName(null);
b2cActionOrderView.setPrintingResponsiblePersNr(null);
MessageUtil.addFacesMessage("msg.notFound", colruyt.giftactionmgmt.util.Constants.MSG_PACKAGE, FacesMessage.SEVERITY_ERROR,
false, "form:tabView:printingResponsibleEdit", null);
}
}
My problem is when i enter a value that is there in the db and after that if i press ok button the corrensponding user name and user id is displayed but after that if i clear the value in the text box and if i press ok button must be filled error message is coming but the previous lable is not getting cleared.
ie(username,user id).
I have tried in many ways to achieve this can you guys help me
Your problem is clear immediate="true"
When you put immediate="true" on your commandButton you simply say to JSF please skip any validation on form (including printingResponsibleEdit) and process this action (requestPrintingResponsible)
So how can JSF validate printingResponsibleEdit and render an updated p:message(printingResponsibleEditMsg) if you have already skipped the validation phase , See More on JSF lifecycle
Put on your mind you have to render(update) every single component you want it to be updated after Ok button is pressed or simply you can make h:panelGroup container to your component and give it an ID and update it ex: <p:commandButton ... update='containerId'/>.
Related
I am using Java EJB with JSF.
What I doing is just a simple search result from database and display it on a table using JSF with ajax. But why when first submitting, the result is not appear. And second time only the result will appear.
Below is my JSF page code
<h:form id="wholeForm">
<p:panelGrid id="resultTable" styleClass="result_table1" >
<p:row>
<p:column>
<div align="center" id="font-size1">
<h:selectOneRadio value="#{scanResult.typeOfScan}">
<f:selectItem itemValue="Carrier" itemLabel="Carrier"></f:selectItem>
<f:selectItem itemValue="Slot" itemLabel="Slot"></f:selectItem>
<f:selectItem itemValue="HD" itemLabel="HD"></f:selectItem>
<p:ajax event="change"></p:ajax>
</h:selectOneRadio>
Scan: <p:inputText styleClass="searchField" id="counter" value="#{scanResult.serialNumber}" a:autofocus="true">
<p:ajax event="keydown" update="wholeForm" onstart="if (event.keyCode != 13) { return false;}" listener="#{scanResult.checkResult()}" />
</p:inputText>
<br/><br/>
</div>
</p:column>
</p:row>
</p:panelGrid>
<p:panelGrid id="resultTable1" styleClass="result_table1" rendered="#{not empty scanResult.scanResultCarrier}" >
<c:forEach items="#{scanResult.scanResultCarrier}" var="result" >
<!-- ..do something and call out result -->
</p:column>
</p:row>
</c:forEach>
</p:panelGrid>
</h:form>
And my managed bean is as below
#Named(value = "scanResult")
#SessionScoped
public class scanResult implements Serializable {
//Some code here
public void checkResult() {
scanResultCarrier = new ArrayList<>();
scanResultSlot = new ArrayList<>();
System.out.println("checking");
if (typeOfScan.equals("Carrier")) {
System.out.println("Serial " + serialNumber);
scanResultCarrier = scanresultcarrierFacade.searchResultCarrier(serialNumber);
System.out.println(scanResultCarrier.size());
} else if (typeOfScan.equals("Slot")) {
scanResultSlot = scanresultslotFacade.searchResultSlot(serialNumber);
} else if (typeOfScan.equals("HD")) {
} else {
}
serialNumber = "";
}
}
I use System.out.println(lsitofresult.size()); to print out my result and the result is not blank. Mean that I successful retrieve my result from database.
But my result table not able to show out after I click on enter.
Then I notice that my url is as below
http://localhost:8080/outgoingScanSystem-war/faces/index.xhtml;jsessionid=8b6cefa932ff60984607ee38ec13
And after I refresh my page, the result will appear again.
And my url change to :
http://localhost:8080/outgoingScanSystem-war/faces/index.xhtml
May I know why? Is it related to URL? I have no idea where should I start my troubleshoot. Anyone can give me some guideline?
I see some problems here. First of all, you're using the session scope while your managed bean should be view scoped (there's no reason to use the session here, see the link below). That's the cause why your results are getting displayed when you refresh the page.
Second, I'd rather put the search results out from the form. I see no reason for them to be in the same form of the search itself. Then, when performing a searh you should only update the result list:
<p:ajax event="keydown" update="resultTable1" onstart="if (event.keyCode != 13) { return false;}" listener="#{scanResult.checkResult()}" />
Third, as you're using Primefaces, I encourage you to take a look to its p:remoteCommand tool in order to perform ajax-based calls to the beans from your JS code directly. This way you should avoid your second problem, which seems to be that you're preventing the standard form sending on the ajax start event (which might not even get called). You could do something like this:
<p:remoteCommand name="search" update="resultTable1" actionListener="#{scanResult.checkResult}" />
<p:inputText styleClass="searchField" id="counter" value="#{scanResult.serialNumber}"
a:autofocus="true" onkeypress="if (event.keyCode != 13) {search(); return false;}">
<!-- Update the input text value in the bean for each pressed key -->
<p:ajax event="keydown" />
</p:inputText>
See also:
How to choose the right bean scope?
Jsf calling bean method from input text when pressing enter
I am attempting to create a dialog that will serve the purpose of both creating objects and updating them. So if I happen to click the 'new' button I will be presented a dialog containing empty fields to be filled or if I click on an edit button for an entry, that entry's data will presented in the dialog for update.
Following the example in the primefaces showcase for version 5.2, I can present the data in a read only outputText form, however when I change it to an inputText, the field remains empty. The following code is an example of what I have:
<h:form id="form">
<p:dataGrid id="guestList" var="guest" value="${guestList.guests}" columns="3" paginator="true" rows="20">
<f:facet name="header">
Guest List
</f:facet>
<p:panel>
<h:outputText value="${guest.name}" />
<br />
<h:outputText value="${guest.street}" />
<br />
<h:outputText rendered="#{guest.street2.length() gt 0}"
value="${guest.street2}" />
<h:panelGroup rendered="#{guest.street2.length() gt 0}">
<br />
</h:panelGroup>
<h:outputText value="${guest.city}, " />
<h:outputText value="${guest.state} " />
<h:outputText value="${guest.zipCode}" />
<p:commandButton update="#form:newGuestDetail" oncomplete="PF('newGuestDialog').show()" icon="ui-icon-edit" styleClass="ui-btn-inline">
<h:outputText styleClass="ui-icon ui-icon-edit" style="margin:0 auto;" />
<f:setPropertyActionListener value="#{guest}" target="#{guestList.selectedGuest}" />
</p:commandButton>
</p:panel>
</p:dataGrid>
<p:dialog header="#{guestList.hasSelected() ? 'Edit Guest' : 'New Guest'}" widgetVar="newGuestDialog" modal="true" showEffect="fade" hideEffect="fade">
<p:outputPanel id="newGuestDetail">
<h:outputText value="'#{guestList.selectedGuest.name}'"/>
<p:inputText id="guestName" value="#{guestList.hasSelected() ? '' : guestList.selectedGuest.name}" pt:placeholder="Name"/>
<p:commandButton value="#{guestList.selectedGuest == null ? 'Create Guest' : 'Update Guest'}"/>
</p:outputPanel>
</p:dialog>
</h:form>
The hasSelected() method evaluates whether the selected guest is null or not, returning true if not null. The selectedGuest should be set when the commandButton is clicked so that an object is available for retrieval by the dialog, however, with tracers in the get/set for selectedGuest, I am not seeing the setter called with the above snippet. If I remove the inputText, then even though the hasSelected is still returning false, and thus the 'New Guest' is heading the dialog, the outputText is filled with a value.
I found this great post talking about the order of execution with respect to the action, action listener, etc., but don't think this quite my issue: Differences between action and actionListener.
So the ultimate question is why will my setter get called with the command button when I only have an outputText, but with an inputText, I never see it called in the log?
I appreciate the time and help anyone can provide.
Even if we fix your problem, this construct
<p:inputText value="#{guestList.hasSelected() ? '' : guestList.selectedGuest.name}">
is not ever going to work. It needs to reference a model property, not an empty string.
You'd best just reuse the edit form and let the create button precreate an empty entity. This would simplify a lot in the view side. It'd be more easy if the entity has an #Id property which is only present when it's persisted in the database.
Here's a kickoff example:
<h:form id="entitiesForm">
<p:dataTable id="entitiesTable" value="#{bean.entities}" var="entity">
<p:column>#{entity.foo}</p:column>
<p:column>#{entity.bar}</p:column>
<p:column>
<p:commandButton id="edit" value="Edit"
process="#this" action="#{bean.edit(entity)}"
update=":entityDialog" oncomplete="PF('entityDialog').show()" />
<p:commandButton id="delete" value="Delete"
process="#this" action="#{bean.delete(entity)}"
update=":entitiesForm:entitiesTable" />
</p:column>
</p:dataTable>
<p:commandButton id="add" value="Add"
process="#this" action="#{bean.add}"
update=":entityDialog" oncomplete="PF('entityDialog').show()" />
</h:form>
<p:dialog id="entityDialog" widgetVar="entityDialog"
header="#{empty bean.entity.id ? 'New' : 'Edit'} entity">
<h:form id="entityForm">
<p:inputText id="foo" value="#{bean.entity.foo}" />
<p:inputText id="bar" value="#{bean.entity.bar}" />
<p:commandButton id="save" value="#{empty bean.entity.id ? 'Create' : 'Update'} entity"
process="#form" action="#{bean.save}"
update=":entitiesForm:entitiesTable" oncomplete="PF('entityDialog').hide()" />
</h:form>
</p:dialog>
With this #ViewScoped bean:
private List<Entity> entities; // +getter
private Entity entity; // +getter
#EJB
private EntityService entityService;
#PostConstruct
public void load() {
entities = entityService.list();
entity = null;
}
public void add() {
entity = new Entity();
}
public void edit(Entity entity) {
this.entity = entity;
}
public void save() {
entityService.save(entity); // if (id==null) em.persist() else em.merge()
load();
}
public void delete(Entity entity) {
entityService.delete(entity); // em.remove(em.find(type, id))
load();
}
See also:
Creating master-detail pages for entities, how to link them and which bean scope to choose
Keep p:dialog open when a validation error occurs after submit
In my JSF application, here's a simplified version of part of my form:
<h:form id="loginFormId">
<h:panelGrid columns="3">
<h:outputText value="Login :" />
<h:inputText label="Login" id="loginId" />
<rich:message for="loginId" ajaxRendered="true"/>
<f:facet name="footer">
<a4j:commandButton value="OK" action="#{authentifierUtilisateurBean.authentifierUtilisateur}">
<f:ajax execute="#form" render="#form" />
</a4j:commandButton>
</f:facet>
</h:panelGrid>
</h:form>
and here's a simplified version of my Managed Bean method authentifierUtilisateur() :
public String authentifierUtilisateur() {
try {
utilisateurEnBase = utilisateurDao.chercherParLogin( utilisateur.getLogin() );
}
...
if ( utilisateurEnBase == .... ) {
message = new FacesMessage(FacesMessage.SEVERITY_ERROR, bundle.getString("authentifier.utilisateur.login.inconnu"),"" );
FacesContext.getCurrentInstance().addMessage("loginFormId:loginId", message );
}
I'd like to assign an error to the rich:message tag associated with the h:inputText based on something happening in the authentifierUtilisateur() method.
A validator is not possible, because the method that will deliver results from the DB is run in the authentifierUtilisateur() method.
When I try the above code, the page doesn't display message in front of the h:inputText.
If I insert in the form, the code
<rich:messages />
(messages with an s) above the button as follows:
<f:facet name="footer">
<rich:messages />
<a4j:commandButton value="OK" action="#{authentifierUtilisateurBean.authentifierUtilisateur}">
<f:ajax execute="#form" render="#form" />
</a4j:commandButton>
</f:facet>
then I can see the message so I am sure that the server sends correctly message to the client.
So why the client doesn't display h:message in front of the h:inputText?
Is there something wrong in the Managed Bean?
addMessage("loginFormId:loginId", message)
A FacesMessage consists of a summary and a detail, rich:message will display the detail by default. That's the one you're leaving empty so there's nothing to display. Either fill in the detail or set #showSummary="true"
Insert an id to the h:panelGrid i.e
<h:panelGrid columns="3" id="grid">
Then in java code try this
FacesContext.getCurrentInstance().addMessage("loginFormId:grid:loginId", message );
Let me know if this helps
I have created a simplified version of my app below.
<h:form>
<p:commandButton value="ADD NEW" action="#{sampleBean.onAddNew}" oncomplete="PF('addDialog').show()" update=":addForm"/>
</h:form>
The below dialog opens when the button is clicked.
<p:dialog widgetVar="addDialog">
<h:form id="addForm">
<p:messages autoUpdate="true" closable="true"/>
<p:outputLabel value="Name :"/>
<p:inputText value="#{sampleBean.name}" required="true" requiredMessage="Name is a required field"/>
<p:outputLabel value="Address :"/>
<p:inputText value="#{sampleBean.address}"/>
<p:commandButton value="Save" action="#{sampleBean.save}" oncomplete="if (args && !args.validationFailed) PF('addDialog').hide();"/>
<p:commandButton value="Cancel" action="#{sampleBean.cancel}" immediate="true" oncomplete="PF('addDialog').hide()" update="addForm"/>
</h:form>
</p:dialog>
Here is the backing bean code:
public void onAddNew()
{
name = "";
address = "";
}
public void save()
{
System.out.println("Saving ... " + name + " : " + address);
name = "";
address = "";
}
public void cancel()
{
System.out.println("Cancelling ... " + name + " : " + address);
name = "";
address = "";
}
The problem i'm facing is:
If i encounter a required field validation error on name field and if address is entered and after that if i hit cancel, i'm invoking the action method "sampleBean.cancel"(to reset both name and address to blank) and then updating the form before hiding the dialog box.
However after hiding the dialog and if i click on ADD NEW again, Its still holding the old state(address value what i entered before).
My need is to clear and display the dialog without any old values.
Could someone point out the issue in my above code?
I'm using Primefaces 5.0
Found one solution to address it however i'm not sure if that's the right way to fix.
<p:commandButton value="Cancel" action="#{sampleBean.cancel}" immediate="true" oncomplete="PF('addDialog').hide()" update="addForm">
<p:resetInput target="addForm"/>
</p:commandButton>
Regards.
We have a similar dialog cancel button build up like this:
<p:commandButton value="#{bundle['common.action.cancel']}"
icon="#{bundle['common.icon.cancel']}"
action="#{bean.cancel}"
process="#this"
update="#none"
oncomplete="PF('dialog').hide();"/>
Where bean.cancel sets the dialog input values to null so we neither need further process nor update of other input elements.
I have a h:inputText with valueChangeListener, when the user type some code another h:inputText display data from MySQL about that code, the valueChangeListener works but the second h:inputText not displayed the value and only do it when I set the readonly attribute or I change the component to h:outputText
my facelets page is:
<h:form id="idFacturacion">
<rich:panel>
<f:facet name="header">
<h:outputText value="FACTURACION AL CLIENTE" />
</f:facet>
<h:panelGrid columns="4">
<h:outputText value="Cedula: " />
<h:inputText value="#{facturaBean.encFactura.cedula}" onchange="submit();" valueChangeListener="#{facturaBean.processValueChange}" />
<h:outputText value="Nombre: " />
<h:inputText value="#{facturaBean.encFactura.nombre_cli}" />
</h:panelGrid>
</rich:panel>
</h:form>
facturaBean is:
#ManagedBean
#SessionScoped
public class FacturaBean {
private EncFactura encFactura = new EncFactura();
//getter and setter
public void processValueChange(ValueChangeEvent event){
String ced = event.getNewValue().toString();
try{
//do the database thing
if(resultSet.next()){
encFactura.setNombre_cli(resultSet.getString("nombre_cli"));
}else{
encFactura.setNombre_cli("");
}
}catch(SQLException error){
facesContext.addMessage(null, new FacesMessage("Hubo un error SQL."));
}
}
}
Please see
Change inputText value from listener method… and
Possible to execute `valueChangeListener` for `p:inputText` without hitting `enter` key?
May I suggest using ajax?
Here is a primefaces example but you could apply to richfaces..
<h:inputText value="#{facturaBean.stringOne}" >
<p:ajax event="change" listener="#{facturaBean.processValueChange}" update="strTwo"/> </h:inputText> <h:outputText value="Nombre: " />
<h:inputText id="strTwo" value="#{facturaBean.stringTwo}" />
</h:panelGrid>
private String stringOne= "";
private String stringTwo= "";
public void processValueChange(){
stringTwo = stringOne;
}
With getters etc.. basically on change, fires off to ajax, you do your database call etc, then it returns the response and updates your other input field, it's a much cleaner way than trying to submit forms etc..
Also are you sure you want session scope?