Migrating from WAS6.1+JSF1.1+richfaces.3.1.5 to WAS7+JSF1.2+facelets1.1.14+richfaces3.3.3.
Error/Status messages are not rendering using h:messages, even though on debugging the facescontext.getMessages() contains the messages.
On submitting a form, I am validating an input. If the validation fails I am adding an error msg to the facescontext. It can be for multiple inputs. Each error msg is added to the facescontext
FacesMessage message = new FacesMessage();
message.setDetail(msg);
message.setSummary(msg);
message.setSeverity(FacesMessage.SEVERITY_ERROR);
getFacesContext().addMessage(componentID, message);
and on the xhtml I am displaying it using h:messages
I was using jsp in WAS6.1 and JSF1.1 and this used to work fine
Thanks
Adding more details
My xhtml
<ui:composition template="/template.xhtml">
<ui:define name="content">
<div id="content-nosidebar">
<h:form id="uploadDoc1" >
<h:messages/>
<h:panelGrid id="panelGridContact" headerClass="standardPageHeader" width="100%" cellpadding="5">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="Upload Contact Info" />
<hr/>
</h:panelGroup>
</f:facet>
<h:panelGroup id="msgId">
<xyz:errorMessages />
<xyz:statusMessages />
</h:panelGroup>
<h:panelGrid style="text-align: center;font-weight: bold;">
<h:outputText value="Click on Browse button to identify CSV file with contact information for upload."/>
<h:outputText value="File size limit is 10MB."/>
<h:panelGroup>
<rich:fileUpload id="fileuploader" fileUploadListener="#{uploadContactCntrl.onSubmit}"
acceptedTypes="csv" allowFlash="true" listHeight="50" addControlLabel="Select File" uploadControlLabel="Submit" clearControlLabel="clear"/>
</h:panelGroup>
<h:outputText value=" "/>
</h:panelGrid>
</h:panelGrid>
</h:form>
</div>
</ui:define>
</ui:composition>
errorMessages and statusMessages are common tags to display error(validation error) and status((like Update complete) messages
In the the backingbean on submit if an error is encountered (like "File not found" or "Database is down" I call a common method with the error/status message from the resource file.
WebUtils.addCustomErrorMessage("global.error.ContactInfo-DuplicateRecords-UserID", new String[]{userid,Integer.toString(j+1)}, Constants.RESOURCE_BUNDLE_NAME);
or
WebUtils.addCustomStatusMessage("global.error.ContactInfo-successMessage", new String[]{Integer.toString(noOfRowsInserted)}, Constants.RESOURCE_BUNDLE_NAME);
public static void addCustomErrorMessage(String msg, String componentID) {
FacesMessage message = new FacesMessage();
message.setDetail(msg);
message.setSummary(msg);
message.setSeverity(FacesMessage.SEVERITY_ERROR);
getFacesContext().addMessage(componentID, message);
}
public static void addCustomStatusMessage(String msg, String componentID) {
if (errorCodeParameters != null && errorCodeParameters.length > 0)
msg = MessageFormat.format(msg, (Object[])errorCodeParameters);
FacesMessage message = new FacesMessage();
message.setDetail(msg);
message.setSummary(msg);
message.setSeverity(FacesMessage.SEVERITY_INFO);
getFacesContext().addMessage(componentID, message);
}
We also use the same tags to display an error message when an error is encountered on an input field. For e.g. a Firstname field has invalid characters.
As mentioned earlier, this was working fine before we migrated to JSF1.2
Your answer need to have xhtml code too, any way i'm giving u sample for using validation in JSF 1.2...
The xhtml code should be like..
<h:inputText id="txt_project_name"
value="#{FIS_Project_Master.txt_project_name_value}"
validator="#{FIS_Project_Master.txt_project_name_validator}"/>
<h:message id="msg_txt_project_name" for="txt_project_name" />
The java code should be like...
public void txt_project_name_validator(FacesContext context, UIComponent component, Object value) {
if (bmwpProjectMstFacade.ispmProjName_exists(value.toString().toUpperCase().trim())) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, "Warning", "Project Name Already Exist");
throw new ValidatorException(message);
}
}
Related
Initially, sorry for my English.
Well, I have dialogs in my application that work individually very well each of them, but when I need one dialog to call another, I have problems closing this second dialog opened on top of the first one. I am creating them by the java API from the primefaces. What would solve this problem?
EDIT:
Right, I call my first dialog here:
<h:outputLabel value="#{bundle.CreateProfissionalLabel_idRegraComissao}" />
<h:panelGroup>
<h:inputText readonly="true" value="#{profissionalController.selected.idRegraComissao.descricao}" id="nomeRegraComissao"/>
<p:commandButton value="#{bundle.Pesquisar}" action="#{searchRegraComissaoController.abrirDialogo()}" process="#this" update="#none">
<p:ajax event="dialogReturn" listener="#{profissionalController.regraComissaoSelecionada}" process="#this" update="nomeRegraComissao"/>
</p:commandButton>
</h:panelGroup>
My openDialog method (searchRegraComissaoController.abrirDialogo()) for the first dialog is:
public void abrirDialogo() {
Map<String, Object> opcoes = new HashMap<>();
opcoes.put("modal", true);
opcoes.put("resizable", false);
opcoes.put("contentHeight", 470);
RequestContext.getCurrentInstance().openDialog("/webapp/lovs/SearchRegraComissao", opcoes, null);
}
Now I have an xhtml file (/webapp/lovs/SearchRegraComissao.xhtml) that is rendered in this first dialog and is responsible for opening the second. Here's how it does it:
<p:outputLabel value="#{bundle.CreateRegraComissaoLabel_idClinica}" />
<p:panel>
<h:inputText readonly="true" value="#{searchRegraComissaoController.filtro.clinica.nome}" id="nomeClinica"/>
<p:commandButton value="#{bundle.Pesquisar}" actionListener="#{searchClinicaController.abrirDialogo()}" process="#this" update="#none">
<p:ajax event="dialogReturn" listener="#{searchRegraComissaoController.clinicaSelecionada}" process="#this" update="nomeClinica"/>
</p:commandButton>
</p:panel>
Right Here, it also has the method that opens this second dialog:
public void abrirDialogo() {
Map<String, Object> opcoes = new HashMap<>();
opcoes.put("modal", true);
opcoes.put("resizable", false);
opcoes.put("contentHeight", 450);
RequestContext.getCurrentInstance().openDialog("/webapp/lovs/SearchClinica", opcoes, null);
}
Well, So far, everything works fine, the problem is in the next step. Now I have the method that should close the second dialog. This method is called after the user select one row into dataTable in the second dialog:
<p:column headerText="#{bundle.Acao}">
<p:commandButton value="#{bundle.Escolher}" process="#this" action="#{searchClinicaController.selecionar(clinica)}"/>
</p:column>
And the final method is:
public void selecionar(Clinica clinica) {
clinicas = new ArrayList<>();
//todasClinicas = false;
// isCPF = "CPF";
//nome = "";
RequestContext.getCurrentInstance().closeDialog(clinica);
}
The end of this method is reached without errors but the second dialog isn't closed. Anyone can help?
SOLUTION: I was reading the guide of primefaces 6 and using primefaces 5. In primefaces 5 nested dialogs aren't supported. I just updated my version to 6 and now is working fine.
I had the same problem today with primefaces 5.2.
I solved by adding a form and config modal="true" and appendTo="#(body)"
in the second dialog.
Follows example:
main.xhtml
<h:body>
<h:form id="frmMain">
<p:commandButton value="Open"
process="#this" update="frmMain:dialog1"
oncomplete="PF('wdgDialog1').show()">
</p:commandButton>
<p:dialog id="dialog1" header="Dialog 1"
dynamic="true" modal="true"
widgetVar="wdgDialog1" >
<ui:include src="/dialog/dialog2.xhtml" />
</p:dialog>
</h:form>
</h:body>
dialog2.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<p:dialog id="dialog2" header="Dialog 2"
modal="true" appendTo="#(body)"
widgetVar="wdgDialog" >
<h:form id="frmDialog">
<p:panel>
<p:commandButton value="Test"/>
</p:panel>
</h:form>
</p:dialog>
</ui:composition>
The short version of my problem is that the inputtext will not change the value in bean after I modified the value from the bean.
The longer version:
There is a form in which is a dataTable with user information; some inputTexts, and two buttons. If you fill the inputTexts, a new user will be created with the given data, and appears in dataTable - this works fine, I can create as many users as I can.
The tricky part is if you select a row from the dataGrid, the user information has to appear in the inputText fields - this works fine - so the admin can modify them. But after changing the inputText values in the bean, if the admin changes someting in the inputText, the value "will not follow" tha changes, the value remains the same. What could I do wrong?
The JSF page looks like this:
<html>
<h:body>
<h:form style="font-size:14px;" id="setupform">
...
<p:panel header="Edit users" id="userAddingPanel" rendered="#{settingsbean.validLogin}">
<p:panelGrid columns="2" id="userAddingGrid">
<p:outputLabel value="User Name: " />
<p:inputText id="userName" value="#{settingsbean.userName}" />
<p:outputLabel value="User Password: " />
<p:password id="userPass" value="#{settingsbean.userPassword}" />
<p:outputLabel value="E-mail address: " />
<p:inputText id="userMailAddress" value="#{settingsbean.mailAddress}" />
<p:outputLabel id="userDelete" value="Inactivate User: " />
<p:selectBooleanCheckbox id="isUserDeleted" value="#{settingsbean.deletedUser}" />
<p:commandButton id="addUser" value="Create User" update="userAddingGrid" icon="ui-icon-disk" action="#{settingsbean.addNewUser}" />
<p:commandButton id="modifyUser" value="Modify User" icon="ui-icon-wrench" update="userAddingGrid" action="#{settingsbean.updateUser}" process="setupform"/>
</p:panelGrid>
<br/>
<p:dataTable id="usersTable" var="users" value="#{settingsbean.userList}" tableStyle="overflow: auto;" stickyHeader="true" selectionMode="single" rowKey="#{users.id}" selection="#{settingsbean.selectedUser}">
<p:ajax event="rowSelect" update=":setupform:userName, :setupform:userName,
:setupform:userPass, :setupform:userMailAddress, :setupform:isUserDeleted" />
<p:column headerText="#ID">
<h:outputText value="#{users.id}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{users.loginName}" />
</p:column>
...
</p:dataTable>
</p:panel>
</h:form>
</h:body>
</html>
And my bean looks like this:
#ManagedBean(name ="settingsbean")
#ViewScoped
public class SettingsBean {
private String userName;
private String userPassword;
private boolean deletedUser;
private List<UserDTO> userList;
private UserDTO selectedUser;
/*with getters and setters, what is uncenventional is this setter*/
public void setSelectedUser(UserDTO selectedUser) {
/*if admin selects/unselects a user from dataTable*/
this.selectedUser = selectedUser;
/*if unselect user*/
if(selectedUser == null){
userName = "";
mailAddress = "";
deletedUser = false;
/*if selects user*/
}else {
userName = selectedUser.getLoginName();
mailAddress = selectedUser.getMailAddress();
deletedUser = selectedUser.getDeleted();
}
}
...
public void addNewUser(){
//creates a new user in DB
}
public void updateUser(){
//will update user in DB
}
}
You have to process the components that you want to be updated
<p:commandButton id="modifyUser" value="Modify User" icon="ui-icon-wrench" update="userAddingGrid" action="#{settingsbean.updateUser}" process="userAddingGrid"/>
I have a page to search for authors. It should show the information about the found author or show a message when the author is not found.
I'm trying to use <rich:notifyMessage>, but the problem is that when I use it, the results from the found authors don't appear and, also, the message appear on the right up corner of the page and I'd like it to appear bellow the panel, where the search results would appear.
Look at how I'm doing that, is there a better way to do it?
xhtml
<h:form>
<br />
<br />
Insert Author
<br />
<br />
<br />
<rich:panel id="panel" style="width:310px">
<f:facet name="header">Search for the author you want to insert</f:facet>
<h:panelGrid columns="3">
Name: <h:inputText value="#{insertAuthorController.nameToSearch}" />
<a4j:commandButton value="Search" action="#{insertAuthorController.searchAuthor()}">
</a4j:commandButton>
</h:panelGrid>
</rich:panel>
<br />
<rich:notifyMessage/>
<rich:dataTable value="#{insertAuthorController.authorListOfMap}" var="result">
<c:forEach items="#{insertAuthorController.variableNames}" var="vname">
<rich:column>
<f:facet name="header">#{vname}</f:facet>
#{result[vname]}
</rich:column>
</c:forEach>
</rich:dataTable>
<br />
<h:commandButton value="Go to insert page" action="#{insertAuthorController.searchAuthor()}" />
</h:form>
Bean
public void searchAuthor() {
this.variableNames.clear();
List<String> uris = new ArrayList<String>();
uris = this.authMapper.searchAuthorUriByName(this.nameToSearch);
if( (uris != null) && (!uris.isEmpty()) ) {
for( String uri : uris ) {
Map<String, String> map = new HashMap<String, String>();
String name = this.authMapper.searchNameByAuthorUri(uri);
String email = this.authMapper.searchEmailByAuthorUri(uri);
map.put("URI", uri);
map.put("Nome", name);
map.put("Email", email);
authorListOfMap.add(map);
}
this.addVariableNames();
} else {
FacesContext ctx = FacesContext.getCurrentInstance();
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,"Detail","Author not found!"); //FacesMessage has other info levels
ctx.addMessage(null,msg);
}
}
Thank you!
The notifyMessage is supposed to behave like that (i.e. pop up in the corner of the screen), if you want just a simple text message use <rich:message>.
Or in this simple case you can check if the result returned something:
<h:outputText value="No results"
rendered="#{fn:length(insertAuthorController.authorListOfMap) == 0}">
Your table doesn't show up because you need to rerender it if you want to see the changes:
<rich:dataTable id="authorsTable" …>
<a4j:commandButton … render="authorsTable" />
I am using Primefaces 3.5, Jsf 2 and I have a datatable, now I implemented a dialog like the primefaces showcase(singlerowselection), it works fine, but I want to edit the row IN the dialog. Furthermore I want that the inputtext is filled with the data from the cell of the datatable, so that you can easily edit it!(like the row editor does it, just in a dialog)
Not like this: http://i.stack.imgur.com/J55j0.jpg
Watermark works, but it is no option because the text disappears if you want to edit it.
It should be like that: http://i.stack.imgur.com/cAFLo.jpg
So, can someone tell me how the cell data can be displayed and edited?
Here is the xhtml (dialog is not in the datatable):
<p:dialog id="dialog" header="Server Detail" widgetVar="serDialog"
resizable="false" showEffect="clip" hideEffect="fold" dynamic="true">
<h:panelGrid id="display" columns="3" cellpadding="4">
<h:outputText value="Data Center Location " />
<p:inputText id="datacenter" value="#{server.dataCenterLocation}"></p:inputText>
<h:outputText value="Identification " />
<h:inputText id="identification" value="#{server.identification}"></h:inputText>
<p:watermark for="identification"
value="#{serverBean.selectedServer.identification}"></p:watermark>
</h:panelGrid>
<p:growl id="growl" showDetail="true" sticky="false" />
<p:commandButton value="Edit Server" action="#{server.onEdit}" update="#form, growl" />
</p:dialog>
the method in the bean(name= server)
(without the selectedServer(name =serverBean) with the getter and setter):
public void onEdit() throws Exception {
PreparedStatement ps = null;
Connection con = null;
int i = 0;
try {
Server ser = new Server();
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver")
.newInstance();
con = DriverManager
.getConnection("jdbc:sqlserver://...");
String sql = "UPDATE VAI_Serverlist SET [Data Center Location]= ?,... WHERE Identification='"
+ ser.identification + "'";
ps = con.prepareStatement(sql);
ps.setString(1, ser.dataCenterLocation);
...
i = ps.executeUpdate();
} catch (SQLException e) {
System.out.println(i);
e.printStackTrace();
} finally {
try {
con.close();
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Thanks in advance!
<h:form id="form">
<p:dataTable id="table" var="item" value="#{ManagedBean.list()}"
<f:facet name="footer">
<p:commandButton id="showUpdateButton" value="#{msgForms['actions.Edit']}"
update=":update_form"
icon="ui-icon-pencil"
style="margin: 0%"
ajax="true"
immediate="true"
oncomplete="PF('DialogUpdate').show()"
/>
</f:facet>
</p:dataTable>
<h:form id="form">
<p:dialog id="dialog_update"
modal="true"
header="${msgForms['titles.update']}"
widgetVar="DialogUpdate" resizable="false"
showEffect="clip" hideEffect="fold"
>
<h:form id="update_form">
<h:panelGrid columns="3" id="panel">
<!--FIELDS-->
<h:outputLabel for="nombre" value="#{msgForms['fields.nombre']}:" />
<p:inputText id="nombre"
value="#{ManagedBean.selectedItem.nombre}"
required="true"
requiredMessage="#{msgForms['field.required']}"
>
<p:ajax event="keyup" update="nombreMsg" global="false"/>
</p:inputText>
</h:panelGrid>
<!--/FIELDS-->
<!-- BUTTONS ACTIONS-->
<p:commandButton id="updateButtonDg"
value="#{msgForms['actions.update']}"
icon="ui-icon-pencil"
actionListener="#{ManagedBean.update()}"
update=":form:"
style="margin: 0%"
ajax="true"
onclick="DialogUpdate.hide();"
>
</p:commandButton>
<!-- /BUTTONS ACTIONS-->
</h:form>
</p:dialog>
the MANAGED BEAN..
#Named("ManagedBean")
#RequestScoped
public class ManagedBean {
//Spring Item Service is injected...
#Inject
IItemService itemService; //if not required because if you use dependencies injection to connect with de database
private List<Item> filteredItems; //only if you use the attribute: filteredValue="#{ManagedBean.filteredItems}" in the dataTable
private List<Item> items;
public void update() {
//here you save the changes in the data base
this.itemService().updateItem(this.selectedItem);
}
this is more or less what I use, I can not put the literal code, but I think I have not left anything important, so i hope it could to help you.
I recommend that you take a look at the tutorial
http://www.javacodegeeks.com/2012/04/jsf-2-primefaces-3-spring-3-hibernate-4.html
it shows how to integrate jsf2 Spring3 hibernate in your project and also how to inject dependencies using annotations, i recomend you the use of hibernate framework to interact with your database
I am trying to make a form with options to add rows. However, after I type in some input and click the add button again, the input I enter disappears. I'm not sure what is wrong with my code. In addition, when I click the add button, the page refreshes. Is there way to stop this page refresh?
Person.java
public class Person{
private List<String> guys = new ArrayList<String>();
public List<String> getGuys() {
return guys;
}
public void setGuys(List<String> guys) {
this.guys = guys;
public void addNewItem(){
guys.add("");
}
}
form.xhtml
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Guys: " />
<h:dataTable value="#{person.guys}" var="men">
<h:column>
<p:inputText value="#{men}" />
</h:column>
</h:dataTable>
<h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
</h:panelGrid>
<br />
<h:commandButton name="submit" type="submit" value="Submit"></h:commandButton>
</h:form>
Provided that the bean is placed in the right scope for the functional requirement, the view scope, the only major mistake left is that you're expecting that the String class has some magic setter method.
It hasn't. The String class is immutable. The following will never work on a String:
<p:inputText value="#{men}" />
You have 2 options:
Create a real model class. You can find complete examples in the following answers:
How to dynamically add JSF components
Recommended JSF 2.0 CRUD frameworks
Set the value by row index instead:
<h:dataTable binding="#{table}" value="#{person.guys}">
<h:column>
<p:inputText value="#{person.guys[table.rowIndex]}" />
</h:column>
</h:dataTable>
(note: no additional bean property necessary for the table! the code is as-is)
This does basically a person.getGuys().add(table.getRowIndex(), submittedValue). I.e. the setter is invoked on the List itself, which works perfectly fine. See also the following related answers concerning ui:repeat:
Using <ui:repeat><h:inputText> on a List<String> doesn't update model values
How map multiple inputText to an array property?
You never update your list, you are just adding empty items. You should do something like this:
Person.java (viewscoped)
public class Person implements Serializable {
private List<String> guys = new ArrayList<String>();
private HtmlDataTable dtGuys;
public void addNewItem() {
guys.add("");
}
public void addToList(ValueChangeEvent e) {
guys.set(dtGuys.getRowIndex(), e.getNewValue().toString());
}
public String save() {
System.out.println("saving...");
for (String item : guys) {
System.out.println("item= " + item);
}
return null;
}
//gettes and setters
}
form.xhtml
<h:form id="frmPrincipal">
<h:panelGrid columns="2">
<h:outputText value="Guys: " />
<h:dataTable value="#{person.guys}" var="men" binding="#{person.dtGuys}" >
<h:column>
<p:inputText value="#{men}" valueChangeListener="#{person.addToList}" />
</h:column>
</h:dataTable>
<h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
</h:panelGrid>
<br />
<h:commandButton id="submit" name="submit" value="Submit" action="#{person.save}"/>
</h:form>
Using jsf 2.0.10 and primefaces 3.5
Its because you don't have an scope for that bean, so its request scoped, so when you call the action the bean is created again, you can fix this using a sessionScope or conversationScope