Set only entity ID instead of whole entity in p:selectOneMenu - jsf

I'm using JSF 2.1 and Tomcat 7. I have the following PrimeFaces select one menu:
<p:selectOneMenu id="idMarcaEdit"
value="#{cfgCentraleController.selMarcaEdit}"
var="p"
height="250"
effect="fade"
converter="marcaConverter"
>
<f:selectItems value="#{cfgCentraleController.marche}" var="c" itemLabel="#{c.marca}-#{c.modello}-#{c.versione}" itemValue="#{c}"/>
<p:column>
<h:outputText value="#{p.marca}" />
</p:column>
<p:column>
<h:outputText value="#{p.modello}" />
</p:column>
<p:column>
<h:outputText value="#{p.versione}" />
</p:column>
<p:column>
<h:outputText value="#{p.provisioning}" />
</p:column>
</p:selectOneMenu>
I have this in #{cfgCentraleController}
private List<Marca> marche;
private Marca selMarcaEdit;
public Marca getSelMarcaEdit() {
return selMarcaEdit;
}
public void setSelMarcaEdit( Marca selMarcaEdit ) {
this.selMarcaEdit = selMarcaEdit;
this.selectedCentrale.setIdRete( this.selMarcaEdit.getIdMarca());
}
public List<Marca> getMarche() {
return marche;
}
It works fine, but I don't realy need the whole entity to be submitted. I just need its ID.
I'm using OmniFaces for the converter:
import org.omnifaces.converter.SelectItemsConverter;
#Override
public String getAsString( FacesContext context, UIComponent component, Object value ) {
Integer id = (value instanceof Marca) ? ((Marca) value).getIdMarca() : null;
return (id != null) ? String.valueOf( id ) : null;
}
How do I obtain only the ID of the entity in the model?

If you need only the ID, then just set only the ID as select item value.
Change
<f:selectItems ... itemValue="#{c}" />
to
<f:selectItems ... itemValue="#{c.idMarca}" />
and change
private Marca selMarcaEdit;
to
private Integer selMarcaEdit;
then you can remove the converter from <p:selectOneMenu>.
See also:
Our selectOneMenu wiki page
Update: this is not possible in this construct with menu with "custom layout". After all, it turns out that the <p:selectOneMenu var> is getting its value from <f:selectItems itemValue> instead of <f:selectItems var>. Sorry, I totally didn't expect that. Given this, you cannot change the model and get rid of the converter. You should keep the code as is. Your best bet is to post an enhancement request to PF guys to improve this situation.

Related

jsf inputText only displayed value when is readonly true or outputText

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?

p:selectOneMenu value not set in bean

In p:selectOneMenu loginbranchName value is not set in bean.In selectItems having list of branchName.I'm using listener to select value from list but value not set in getLoginBranchId method....
<h:outputLabel value="Branch Name:*" style="text-align: left;display: block;" rendered="#{loginBean.userLoggedIn}"/>
<p:selectOneMenu value="#{loginBean.loginbranchName}"
rendered="#{loginBean.userLoggedIn}"
style="width:175px;">
<f:selectItem itemLabel="Select" itemValue="0" />
<f:selectItems value="#{loginBean.branchName}" />
<p:ajax event="change" listener="#{loginBean.getLoginBranchId}"/>
</p:selectOneMenu>
login.java
public String getLoginbranchName() {
return loginbranchName;
}
public void setLoginbranchName(String loginbranchName) {
System.out.println("loginbranchName"+loginbranchName);
this.loginbranchName = loginbranchName;
}
public void getLoginBranchId()
{
System.out.println("enter into getloginbranchid");
System.out.println("loginbranchName"+loginbranchName);
int unitId=loginDAO.getLoginBranchId(loginbranchName);
System.out.println("unitId"+unitId);
}
#BalusC was correct regarding the above discussion where, JSF2 can work with List and SelectItem https://stackoverflow.com/tags/selectonemenu/info I think you might be missing
<h:form>
</h:form>
tag.

How do I save an Object from selectOneMenu using Omnifaces Converter into a database?

I have a problem using a OmniFaces converter with primefaces selectOneMenu. I am displaying a list of Departments in a primefaces datatable with in-cell editing function, one column displays department name while the other displays faculty name.
When editing, the selectOneMenu shows correctly with a list of faculties to select from but won't get saved on submitting, when i remove the faculty column in datatable, the department name get saved without a problem, someone help me find out why i cant save faculty name.
Here are is my datatable code
<p:dataTable id="deptTable" var="department"
value="#{departmentMB.departmentList}" editable="true"
rowIndexVar="rowIndex">
<p:ajax event="rowEdit" listener="#{departmentView.onEdit}"
update=":deptForm:messages" />
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{department.departmentName}" />
</f:facet>
<f:facet name="input">
<h:inputText value="#{department.departmentName}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Faculty">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{department.faculty.facultyName}" />
</f:facet>
<f:facet name="input">
<p:selectOneMenu id="iterator"
value="#{departmentMB.selectedFaculty}"
converter="facultyConverter" label="Faculty">
<f:selectItem itemLabel="Select one" noSelectionOption="true" />
<f:selectItems value="#{facultyMB.facultyList}" var="faculty"
itemLabel="#{faculty.facultyName}" itemValue="#{faculty}" />
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column>
<p:rowEditor />
</p:column>
</p:dataTable>
here is department controller
#ManagedBean(name = "departmentMB")
#RequestScoped
public class DepartmentController implements Serializable {
#ManagedProperty(value = "#{DepartmentService}")
IDepartmentService departmentService;
private static final long serialVersionUID = 1L;
private int department_id;
private String departmentName;
private Faculty selectedFaculty;
.
.
.//getters and setters
Here is onEdit method
public void onEdit(RowEditEvent event) {
try {
Department department = (Department) event.getObject();
DepartmentController departmentController = (DepartmentController) FacesContext
.getCurrentInstance().getExternalContext().getRequestMap()
.get("departmentMB");
departmentController.updateDepartment(department);
} catch (Exception e) {
e.printStackTrace();
}
}
Here is the update method - uses hibernate save() method
public void updateDepartment(Department department) {
try {
getDepartmentService().updateDepartment(department);
} catch (DataAccessException e) {
e.printStackTrace();
}
}
And finally my OmniFaces Converter
#FacesConverter("facultyConverter")
public class FacultyConverter extends SelectItemsConverter {
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
Integer id = (value instanceof Faculty) ? ((Faculty) value).getFacultyId() : null;
return (id != null) ? String.valueOf(id) : null;
}
}
In the <p:selectOneMenu>, you need to set the selected faculty on the currently iterated row, not on the parent backing bean.
In other words, replace
<p:dataTable ... value="#{departmentMB.departmentList}" var="department">
...
<p:selectOneMenu ... value="#{departmentMB.selectedFaculty}">
by
<p:dataTable ... value="#{departmentMB.departmentList}" var="department">
...
<p:selectOneMenu ... value="#{department.faculty}">
This concrete problem is further unrelated to the converter. It is doing its job just fine.
Wrong question. JSF is a presentation framework, it does not handle storage/bussiness logic.
In your backing bean, the appropiate method should take care of storage, but it will ignore from where your bean comes. You can do manually (JDBC) or with an ORM framework (Hibernate, JPA)
And BTW, if your question is "Why the selected object is not stored in departmentMB.selectedFaculty?", your converter is not implementing getAsObject()

Using <h:selectBooleanCheckbox> with Map in a paginated <p:dataTable> throws NullPointerException

I am using PrimeFaces <p:dataTable> with pagination. I use <h:selectBooleancheckbox> with a Map property for corresponding row selection. The problem which I am facing is when I select and submit the values, there is a NullPointerException. The values are checked for particular rows only. I am using JSF 2.0 and PrimeFaces 3.0.
My page is:
<p:dataTable id="ngoPhotoTab" paginator="true" rows="10" value="# {photoApprovelBean.lstNgoPhotos}" var="ngoPhoto">
<p:column headerText="NgoName">
#{ngoPhoto.ngoName}
</p:column>
<p:column headerText="Select">
<h:selectBooleanCheckbox id="ngoSelect" layout="pageDirection" value="#{photoApprovelBean.checked[ngoPhoto.photo_id]}" />
</p:column>
<f:facet name="footer">
<p:commandButton onclick="deletePhoto();" value="Delete" />
</f:facet>
</p:dataTable>
Backing bean logic:
public class PhotoApprovelBean {
public String deleteActPhoto() {
List checkedItems = new ArrayList();
try {
for (Iterator<PhotoApprovelBean> itr = disAppPhotoList.iterator(); itr.hasNext();) {
PhotoApprovelBean item = (PhotoApprovelBean) itr.next();
if (checked.get(item.getPhotoId())) {
checkedItems.add(item.getPhotoId());
}
}
toDeletePhoto(checkedItems);
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
public Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
public Map<Long, Boolean> getChecked() {
return checked;
}
}
The NullPointerException is caused in the line if (checked.get(item.getPhotoId())). The The Map is filled with values of first page only. How is this caused and how can I solve it?
You got a NullPointerException, because the if statement expects a boolean, but the Map contains Boolean values only which can possibly be null. They will be null for other pages. The Boolean value of null can't be autoboxed to a boolean. You'd need to add a nullcheck.
Boolean itemChecked = checked.get(item.getPhotoId());
if (itemChecked != null && itemChecked) {
// ...
}
Better, however, is to use PrimeFaces own <p:column selectionMode="multiple"> instead. It will remember the selection on other pages. The Map approach is only suitable if you don't use pagination. See also the showcase example. Here's how it can look like for you:
<p:dataTable id="ngoPhotoTab" paginator="true" rows="10"
value="#{photoApprovelBean.lstNgoPhotos}" var="ngoPhoto"
selection="#{photoApprovelBean.selectedNgoPhotos}" rowKey="#{ngoPhoto.photoId}"
>
<p:column headerText="NgoName">
#{ngoPhoto.ngoName}
</p:column>
<p:column headerText="Select" selectionMode="multiple" />
<f:facet name="footer">
<p:commandButton onclick="deletePhoto();" value="Delete" />
</f:facet>
</p:dataTable>
with
private PhotoApprovelBean[] selectedNgoPhotos;

JSF commandbutton id inside datatable

How can I add in commandbutton inside datatable?
<hx:dataTableEx value="#{searchData.searchFriends}" var="s">
<hx:columnEx>
<f:facet name="header">
<h:outputText value="First Name" />
</f:facet>
<hx:requestLink action="#{pc_Search.doAddFriendAction}">
<h:outputText value="Add as Friend" />
<f:param name="friendId" value="#{s.memberId}" />
</hx:requestLink>
</hx:columnEx>
</hx:dataTableEx>
To get the data at backend
String friendId = (String)getRequestParam().get("friendId");
But once I change the requestlink to command button the friedId = null? any idea how can i pass value using command button
Wrap the datatable value in a DataModel. Then you can obtain the selected row by DataModel#getRowData().
public class Bean {
private List<Friend> friends;
private DataModel friendsModel;
public Bean () {
friends = getItSomehow();
friendsModel = new ListDataModel(friends);
}
public void addAsFriend() {
Friend selectedFriend = (Friend) friendsModel.getRowData();
// ...
}
}
with
<h:dataTable value="#{bean.friendsModel}" var="friend">
<h:column>
<h:commandButton value="Add as friend" action="#{bean.addAsFriend}" />
</h:column>
</h:dataTable>
Should work as good with IBM Faces Client Framework (those hx: components).

Resources