JSF SelectOneMenu not working without converter? - jsf

So I have the following xhtml code:
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{interview.interviewer.name}" />
</f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{interview.interviewer}" style="width:100%" converter="interviewerConverter">
<f:selectItems value="#{interviewerController.allInterviewers}" var="s" itemLabel="#{s.name}" itemValue="#{s}" />
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
When I try to edit the data in the cell, I get the following error:
Conversion Error setting value 'com.jpa.entities.Interviewer#288002c2' for 'null Converter'.
I took a look at the similar posts but did not find out what is wrong here.
Also I have created the following converter, with this I do not get a converter error:
#FacesConverter("interviewerConverter")
public class InterviewerConverter implements Converter {
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if(value != null && value.trim().length() > 0) {
try {
InterviewerController service = (InterviewerController) fc.getExternalContext().getApplicationMap().get("interviewerController");
return service.getallInterviewers().get(Integer.parseInt(value));
} catch(NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid"));
}
}
else {
return null;
}
}
public String getAsString(FacesContext fc, UIComponent uic, Object object) {
if(object != null) {
return String.valueOf(((Interviewer) object).getId());
}
else {
return null;
}
}
}
After implementing the converter, I get a NullPointerException on the following list: (service.getallInterviewers())
return service.getallInterviewers().get(Integer.parseInt(value));
but in the controller, the list is initialized like this:
#PostConstruct
public void init(){
initAllInterviewers();
}
What can be wrong here?

Related

Why do I can alway get label in getAsObject() in Primefaces?

I do not why although I verify everything which is right. Anyone know?
I tried to debug:
- getAsString() return ID (that's right)
- when I submitted - getAsObject() always throw exception because the label values was always passed instead of ID values.
My code as below:
my xhtml file:
<div class="ui-grid-row" style="margin-top: 5px; margin-bottom: 5px;">
<div class="ui-grid-col-2 pdt4">
<p:outputLabel for="txtApprovalScheduler"
value="#{lang['workforce.category.parttimeManagement.approved.scheduler']}"/>
</div>
<div class="ui-grid-col-2">
<p:selectOneMenu value="#{parttimeController.selectedAgentDTO}"
id="txtApprovalScheduler"
filterMatchMode="contains" editable="true"
style="width: 86%;"
required="true"
requiredMessage="#{lang['workforce.category.parttimeManagement.approved.scheduler.missing']}">
<f:converter converterId="agentConverter"/>
<f:selectItem itemValue="" itemLabel="#{lang['wf.common.choose']}"/>
<f:selectItems value="#{parttimeController.agentDTOs}" var="agentItem1"
itemLabel="#{agentItem1.userName}"
itemValue="#{agentItem1}"/>
</p:selectOneMenu>
</div>
<div class="ui-grid-col-2 pdt4">
<p:outputLabel for="txtApprovalRegister"
value="#{lang['workforce.category.parttimeManagement.approved.register']}"/>
</div>
<div class="ui-grid-col-2">
<p:selectOneMenu value="#{parttimeController.selectedAgentDTOForRegister}"
id="txtApprovalRegister" editable="true"
filterMatchMode="contains" style="width: 86%; font-size: 12px !important;"
required="true"
requiredMessage="#{lang['workforce.category.parttimeManagement.approved.register.missing']}">
<f:converter converterId="agentConverter"/>
<f:selectItem itemValue="" itemLabel="#{lang['wf.common.choose']}"/>
<f:selectItems value="#{parttimeController.agentDTOs}" var="item1"
itemLabel="#{item1.userName}"
itemValue="#{item1}"/>
</p:selectOneMenu>
</div>
</div>
My Converter:
#FacesConverter(forClass = AgentDTO.class,value = "agentConverter")
public class AgentConverter implements Converter {
public static List<AgentDTO> listAgentDTOs;
#Override
public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String agentId) {
if (agentId.trim().equals("")) {
return null;
} else {
try {
Long number = Long.parseLong(agentId);
for (AgentDTO a : listAgentDTOs) {
if (a.getAgentId() == number) {
return a;
}
}
} catch (NumberFormatException exception) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid data"));
}
}
return null;
}
#Override
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) {
if (value == null || value.equals("") || "-1".equals(value)) {
return "";
} else {
String result = String.valueOf(((AgentDTO) value).getAgentId());
return result;
}
}
}
My bean:
#Component
#Scope("view")
#ManagedBean(name = "parttimeController")
public class ParttimeController extends BaseController implements Serializable {
private AgentDTO selectedAgentDTO;
private AgentDTO selectedAgentDTOForRegister;
private List<AgentDTO> agentDTOs;
.... getter/setter and initiallize AgentCenvert.listAgentDTOs
My class:
public class AgentDTO{
private Long agentId;
private String userName;
....getter/setter
}
I found out the reason - I only remove editable attribute in selectOneMenu. So getAsObject() will pass a value instead of a label

Listener is not called by selectOneMenu

I have a p:selectOneMenu that changing value should run a listener to update the value of another p:selectOneMenu (Type: state -> city). In addition to the items have the item "All" in the first p:selectOneMenu. When you select any item other than the "All" the listener is not called, but when I select the "All" option.
I also realized that the model will not be updated. That is the value of the first p:selectOneMenu is not set in the entity attribute,
The following codes:
First
<p:selectOneMenu id="pesquisaCategoria" style="width:100%;"
value="#{inscricaoFaces.entity.categoriaSelecionada}"
styleClass="input-block-level" converter="#{categoriaConverter}">
<f:selectItem itemLabel="#{msgs['label.dropdown.todos']}"
noSelectionOption="true" itemValue="#{null}" />
<f:selectItems value="#{categoriaFaces.listarTodasCategorias()}"
var="categoria" itemValue="#{categoria}"
itemLabel="#{categoria.descricao}" />
<p:ajax update="pesquisaAreaAtuacao" event="change"
listener="#{inscricaoFaces.atualizarAreasAtuacao}" />
</p:selectOneMenu>
Second
<p:selectOneMenu id="pesquisaAreaAtuacao" style="width:100%;"
value="#{inscricaoFaces.entity.areaAtuacao}"
styleClass="input-block-level" converter="#{areaAtuacaoConverter}">
<f:selectItem itemLabel="#{msgs['label.dropdown.todos']}"
noSelectionOption="true" itemValue="#{null}" />
<f:selectItems value="#{inscricaoFaces.areasAtuacao}" var="area"
itemValue="#{area}" itemLabel="#{area.descricao}" />
</p:selectOneMenu>
Convert
#ManagedBean
#RequestScoped
public class CategoriaConverter implements Converter, Serializable {
/**
*
*/
private static final long serialVersionUID = -1073909086688882110L;
#EJB
private CategoriaService categoriaService;
#Override
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if (value != null && value.trim().length() > 0 && !"Todos".equals(value)) {
return categoriaService.consultarPorId(new Categoria(Integer.valueOf(value)));
} else {
return null;
}
}
#Override
public String getAsString(FacesContext fc, UIComponent uic, Object value) {
if(value != null){
return value instanceof Categoria ? String.valueOf(((Categoria) value).getCodigo()) : null;
}else{
return null;
}
}
}

Email uniquness validate in jsf

Here is my JSF form email code section:
(Registration.xhtml)
<p:inputText id="email" required="true" label="Email" size="20" value="#{registrationBean.email}">
<f:validateRegex pattern="([^.#]+)(\.[^.#]+)*#([^.#]+\.)+([^.#]+)"/>
<f:validator id="uniqueEmailValidator"/>
</p:inputText>
<h:message for="email"/>
And this is my validator class:
#FacesValidator("uniqueEmailValidator")
public class UniqueEmailValidator implements Validator {
#Override
public void validate(FacesContext fc, UIComponent uic, Object value) throws ValidatorException {
if (value == null) {
return;
}
String email = (String) value;
CustomerService cService = new CustomerService();
if (!cService.exists(email)) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "mail is already in use.", "error"));
}
}
}
I got this error when to run the application:
/Registration.xhtml #49,73 <f:validator> A validator id was not specified. Typically the validator id is set in the constructor ValidateHandler(ValidatorConfig)
In your f:validator tag, change "id" to "validatorId"
<f:validator validatorId="uniqueEmailValidator"/>

primefaces `<p:selectOneMenu` [duplicate]

This question already has answers here:
Validation Error: Value is not valid
(3 answers)
Closed 8 years ago.
I keep getting this error addAddress:states: Validation Error: Value is not valid when using <p:selectOneMenu. I tried using the id and got rid of the converter, its doing the same. I tried debugging. Found that the converted is running twice and the last time it is checking blank value and returning null/false. What am I doing wrong? If need any more details let me know?
Code is as follows
Converter
#FacesConverter(value = "statemasterconverter", forClass = Statemaster.class)
public class StateConverter implements Converter {
public String getAsString(FacesContext context, UIComponent component,
Object value) {
return ConversionHelper.getAsString(value);
}
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
return ConversionHelper.getAsObject(Statemaster.class, value);
}
}
Conversion Helper
public final class ConversionHelper {
private ConversionHelper() {
}
#SuppressWarnings("unchecked")
public static <T> T getAsObject(Class<T> returnType, String value) {
BigDecimal id = BigDecimal.ZERO;
if (returnType == null) {
throw new NullPointerException(
"Trying to getAsObject with a null return type.");
}
if (value == null) {
throw new NullPointerException(
"Trying to getAsObject with a null value.");
}
try {
id = BigDecimal.valueOf(Long.parseLong(value));
} catch (NumberFormatException nfe) {
return null;
}
Session session = HibernateUtil.getSessionFactory().openSession();
try {
T r = (T) session.load(returnType, id);
if (r != null)
Hibernate.initialize(r);
return r;
} catch (HibernateException e) {
e.printStackTrace();
} finally {
session.close();
}
return null;
}
public static String getAsString(Object value) {
if (value instanceof Gendermaster) {
Gendermaster result = (Gendermaster) value;
return String.valueOf(result.getGenderid());
} else if (value instanceof Salutationmaster) {
Salutationmaster result = (Salutationmaster) value;
return String.valueOf(result.getSalutationid());
} else if (value instanceof Countrymaster) {
Countrymaster result = (Countrymaster) value;
return String.valueOf(result.getCountryid());
} else if (value instanceof Statemaster) {
Statemaster result = (Statemaster) value;
return String.valueOf(result.getStateid());
}
return null;
}
}
the xhtml code
<p:row>
<p:column>
Country
</p:column>
<p:column>
<p:selectOneMenu id="country"
value="#{customerBean.country.countryid}" required="true">
<f:selectItem itemLabel="Select Country" itemValue="" />
<f:selectItems value="#{customerBean.countrydropdown}"
var="countrymaster"
itemLabel="#{countrymaster.countryname} - #{countrymaster.countrycodeNn}"
itemValue="#{countrymaster.countryid}" />
<p:ajax update="states"
listener="#{customerBean.updateStates()}" />
</p:selectOneMenu>
</p:column>
</p:row>
<p:row>
<p:column>
State
</p:column>
<p:column>
<p:selectOneMenu id="states" required="true"
value="#{customerBean.state}" converter="statemasterconverter">
<f:selectItem itemValue="" itemLabel="Select State" />
<f:selectItems value="#{customerBean.statedropdown}"
var="statemaster"
itemLabel="#{statemaster.statename} - #{statemaster.statecode}"
itemValue="#{statemaster}" />
</p:selectOneMenu>
</p:column>
</p:row>
<p:commandButton id="saveBtn" value="Save Salutation"
update="msgs"
style="float: left;" icon="ui-icon-disk"
actionListener="#{customerBean.saveAddress()}" ajax="true" />
</p:column>
Use event="valueChange" in Ajax. and try to updated whole form by update="#form".
if above code is not work then try update=":id:id" update tag search id within the tag.
let consider this code.
<h:form id="myForm">
<h:sometag id="ineer1">
<p:ajax update="ineer3"/>// it is **not work**
<p:ajax update=":myForm:ineer2:ineer2"/>// it is **work**
</h:sometag>
<h:sometag id="ineer2">
<h:someoutfield id="ineer3"/>
</h:sometag>
<h:/form>
it is working at my end if not work then let me know.
Happy to help :)

Primefaces remotecommand action called only once

I have
<p:remoteCommand name="updateSelectedTarget" update="partToUpdate" actionListener="#{bean.onSelectedTarget}"/>
bean.java
public void onSelectedTarget() {
System.out.println("here");
}
With this configuration, the action is only fired once. Do I need to use actionListener or action? And is there something to do with the process parameter of remoteCommand?
I just want to add that it was working before. I just changed the updated part below
<h:panelGroup id="partToUpdate" layout="block">
<p:panelGrid rendered="#{bean.selectedTarget == null ? false : true}">
...
<h:selectOneMenu value="#{bean.stuffID}">
...
</h:selectOneMenu>
...
</p:panelGrid>
</h:panelGroup>
Before there was just an ID one the selectOneMenu
<h:selectOneMenu value="#{bean.stuffID}">
and now I have the object
<h:selectOneMenu value="#{bean.stuff}">
the java.lang.ClassCastException comes from the line
<f:selectItem itemLabel="None" itemValue="null" />
Could you verify this
#FacesConverter("user")
public class UserConverter implements Converter{
private List<User> users;
public UserConverter(){
this.users = myController.getAllUsers();
}
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return this.getUser(value);
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
return String.valueOf(((User) value).getId()).toString();
}
public User getUser(String id) {
Iterator<User> iterator = this.users.iterator();
while(iterator.hasNext()) {
User user = iterator.next();
if(user.getId() == Integer.valueOf(id)) {
return user;
}
}
return null;
}
}
I think my converter is good because I use it somewhere else.
Maybe the mistake is how to use it with the h:selectOneMenu
I have this
<h:selectOneMenu value="#{bean.selectedUser}">
<f:selectItem itemLabel="None" itemValue="null" />
<f:selectItems value="#{bean.allusers}" var="user" itemValue="#{user.id}" itemLabel="#{user.name}"/>
<f:converter converterId="user"/>
</h:selectOneMenu>
So to conclude I changed my selectOneMenu to
<h:selectOneMenu value="#{bean.selectedUser}">
<f:selectItem itemLabel="None" itemValue="#{null}" />
<f:selectItems value="#{bean.allusers}" var="user" itemValue="#{user}" itemLabel="#{user.name}"/>
<f:converter converterId="user"/>
</h:selectOneMenu>
And in my converter
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(!StringUtils.isInteger(value)) {
return null;
}
return this.getUser(value);
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value == null) {
return null;
}
return String.valueOf(((User) value).getId()).toString();
}
With the method below because I am looking for id and getAsObject value returned the label "None"
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
}
return true;
}
And problem solved.
Thnks
EDIT
Don't forget to add the equals override method to the User class.
it happens to me many times like this and I find that the problem comes from previous page that call the current one

Resources