How to insert PrimeFaces p:selectManycheckbox value to database - jsf

I am new to primefaces and i have a problem to save my primefaces SelectManyCheckbox value to database. I am using hibernate and mysql. The sample code are give as below
My xhtml pages code is:
<h:outputText value="#{msg['elicense.examinationform.personal.classofcertificates']}"/>
<p:selectManyCheckbox id="grid" value="#{examinationFormBean.selectedClass}" layout="grid" columns="1">
<f:selectItems value="#{examinationFormBean.examinationPart}"var="className" itemLabel="#{className.name}" itemValue="#{className}" />
</p:selectManyCheckbox>
My bean is:
private String[] selectedClass;
private List<CertificateClass> examinationPart=new ArrayList<CertificateClass>();
getter()
setter()
The method where I want to save my checkbox is:
private void saveExaminationDetails()
{
examDetails.setElementaryPrinciples(); //bolean field
examDetails.setLightinig()
//no of setter
}
I am not able to find out how I will set the selected and not selected checkbox value on the method

Look at primefaces showcases: http://primefaces-rocks.appspot.com/ui/selectManyCheckbox.jsf
Selected values from examinationFormBean.examinationPart should setting in p:selectManyCheckbox attribute value and then you can used this selected list in bean method.
For your example should be something:
<p:selectManyCheckbox id="grid" value="#{examinationFormBean.selectedExaminationParts}" layout="grid" columns="1">
<f:selectItems value="#{examinationFormBean.examinationParts}" var="className" itemLabel="#{className.name}" itemValue="#{className}" />
</p:selectManyCheckbox>
And then you can use selectedExaminationParts in your saveExaminationDetails()

The p:selectManyCheckbox select values are biding a String Collection(List, ArrayList... etc) on managed bean. You just need to save each String existent on the Collection.
I will give you an example showing how you can do that:
Example:
...
#Named(value = "myBean")
#SessionScoped
public class InscricaoBean implements Serializable {
...
private List<String> selectedElemnts = new ArrayList();
//selectedElements get and set
...
On JSF you have something like:
...
<h:outputText value="#{msg['elicense.examinationform.personal.classofcertificates']}"/>
<p:selectManyCheckbox id="grid" value="#{examinationFormBean.selectedElemnts}"...>
<f:selectItems value="#{examinationFormBean.examinationPart}"var="className"
itemLabel="#{className.name}" itemValue="#{className}" />
</p:selectManyCheckbox>
...
On save method:
...
private void saveExaminationDetails()
{
for (String nameAux: selectedElemnts )
{
//you save the data here
}
}
...

Related

How to pass the selected values from selectcheckBoxMenu to my bean?

I'm using JSF 2.2.8 and primefaces 6.0, and i have a selectCheckBoxMenu i want to retrieve the selected values in my bean.
The selectCheckboxMenu is filled from the database but when i select the attributes and I save nothing happens it does not call the save function
Here is my selectCheckBoxMenu
<p:outputLabel for="ressource" value="Ressource"/>
<h:panelGroup >
<p:selectCheckboxMenu id="ressource" label="Ressource" value="#{affectationBean.selectedRessource}" multiple="true">
<f:selectItems value="#{affectationBean.ressources}" var="r" itemLabel="#{r.nom}" itemValue="r.idt_ressource" />
</p:selectCheckboxMenu>
</h:panelGroup>
<p:commandButton icon="ui-icon-save" actionListener="#{affectationBean.save}" value="Save" update="#affectation" ajax="false" style="display:inline-block;margin-top:5px"/>
Here is the the declaration of the selectedRessource and the actionListener save
private Long [] selectedRessource;
// Getters setters and Construct
public void save(){
for(int i=0 ;i<selectedRessource.length;i++){
system.out.println("id ===> " + selectedRessource[i]);
}
My suggestion would be:
First make sure everything is inside the h:form tag.
don't need to multiple = true as this tag does not take this attribute
i tested with below modification and got the selected multiple value in my bean. The only difference is i am using same value for itemLabel and itemValue but in your case it is object. i am using primefaces 6 also and dont even need to change actionListner to action. It is working as it is.sample xhtml
sample ResourceBean.java
<p:outputLabel for="ressource" value="Ressource"/>
<h:panelGroup >
<p:selectCheckboxMenu id="ressource" label="Ressource" value="#{resourceBean.selectedRessource}">
<f:selectItems value="#{resourceBean.ressources}" var="r" itemLabel="#{r}" itemValue="#{r}" />
</p:selectCheckboxMenu>
</h:panelGroup>
<p:commandButton icon="ui-icon-save" actionListener="#{resourceBean.save}" value="Save" ajax="false" style="display:inline-block;margin-top:5px"/>
The problem is in your p:commandButton, you have 3 options
change your method:
public void save(ActionEvent actionEvent){...}
change your action listener value:
actionListener="#{affectationBean.save()}"
or change your button to use action
action="#{affectationBean.save}"
DISCLAIMER: This is a workaround. It is not intended to be a permanent solution but will allow you to use selectCheckboxMenu and keep working.
There is an issue with this component that prevents it from passing values to the backing bean upon submit.
For some reason the array that should contain the selected values gets cleared out upon submit. Therefore I made an extra array that I did not declare in the tag, and updated in on every change event. Then on submit the values were still there. See below:
BackingBean.java
private String[] sCodes;
private String[] sCodes2; //extra array, not in form.xhtml
public void updateCodes()
{
sCodes2 = sCodes; //keeps the values in the other array
}
public void doSend() throws IOException
{
log.trace("selected codes: {} selected codes2 length: {}", sCodes.length, sCodes2.length);
}
form.xhtml
<p:selectCheckboxMenu id="codeCtl" value="#{bean.SCodes}" label="Codes" filter="true" filterMatchMode="startsWith" panelStyle="width:250px">
<f:selectItems value="#{bean.menuCodes}" />
<p:ajax event="change" listener="#{bean.updateCodes()}" />
</p:selectCheckboxMenu>
<p:commandButton value="submit" actionListener="#{bean.doSend}" id="ctlSubmit" update="appform"/>

Submitting ID of object-populated h:selectOneMenu still causes conversion error

I populated my selectOneMenu with objects and trying to send the id (in itemValue) back to my bean from the selected item, I tried it using the below functionality but I keep getting error about a null converter (Which I'm trying to avoid by sending the id to my bean).
xhtml:
<h:form>
<h:selectOneMenu value="#{bean.id}">
<f:selectItems value="#{bean.objectList}" var="f" itemValue="#{f.id}" itemLabel="#{f.name}" />
</h:selectOneMenu>
<h:commandButton action="#{bean.function}" value="OK"/>
</h:form>
bean:
private Collection<Object> objectList; //Object is an example, It is not the real class that is used
private int id;
public void function() {
// place where id is needed.
}
// id getters & setters
The collection you are using:
private Collection<Object> objectList;
Has a plain object as the class type for its elements.
You need to change it to:
private Collection<MyCustomClassElement> objectList;
Where MyCustomClassElement is the class for your collection elements used in the select.
I think the value is not updated, use ajax to update the value once you select it...
<h:form id="forms">
<h:selectOneMenu id="beanid" value="#{bean.id}">
<f:selectItems value="#{bean.objectList}" var="f" itemValue="#{f.id}" itemLabel="#{f.name}" />
<f:ajax event="change" render="forms" />
</h:selectOneMenu>
<h:commandButton action="#{bean.function}" value="OK"/>
</h:form>

<p:inputText> value not updated in model on change

I have a form that lets me edit a list of beans (one at a time), using buttons I can switch between the beans.
Keeping it simple :
public class MyBean {
private String text;
}
public class MyController {
private List<MyBean> availableBeans = new ArrayList<MyBean>(); // has five MyBeans with random text
private MyBean selectedBean; // initialized with first element of list
private int index = 0;
public void nextBean() { index++; }
public void previousBean() { index--; }
private void refreshBean() { selectedBean = availableBeans.get(index); }
}
For the html part I have something like
<h:form id="someForm">
<!-- stuff -->
<p:inputText value="#{myController.selectedBean.text}" />
<p:inplace editor="true" label="#{myController.selectedBean.text}" >
<p:inputText value="#{myController.selectedBean.text}" />
</p:inplace>
<!-- more stuff-->
</h:form>
If I change the text inside the inplace tag, the variable in myBean will be updated just fine, but If I only use inputText the bean will still have the old value, even if I change it on the webpage. Why is that?
Its because the p:inplace editor="true" implicitly submits the value to the server while <p:inputText does not do it implicitly,
You can solve it in several ways
1) add submit button like <p:commandButton to submit the value from p:inputText
2) use p:ajax event="keyup" or event="change",inside p:inputText
also take a look at the showcase p:ajax enables ajax features on supported components.
p.s , remove the value attribute from the p:inplace (there is no such attribute in p:inplace)
Lets give your components ids:
<h:form id="someForm">
<p:inputText id="first" value="#{myController.selectedBean.text}" />
<p:inplace id="second" editor="true" value="#{myController.selectedBean.text}">
<p:inputText id="third" value="#{myController.selectedBean.text}" />
</p:inplace>
</h:form>
According to the Primefaces Documentation 3.5 the component p:inplace has no attribute called value.
Do you submit the form someForm when changing the value of first? Otherwise the updated values from first won't be passed to MyController and MyBean. p:inplace submits the values automatically whereby you have to do it yourself it you use the standard p:inputText.

JSF h:selectOneMenu is never set even when using f:ajax

I want to implement a filtering facility in a JSF web application as follows: The users can add as many filters as they want. They can also delete them. So I am having a dataTable of filters. Each row consists of one h:selectOneMenu which has an ajax “change” event in order to make a second h:selectOneMenu visible in the same row. The options of the second h:selectOneMenu are calculated dynamically according to the selected option of the first.
The problem is that the value of second h:selectOneMenu is never set to the back-end object even if I added an ajax event. However the value of the first h:selectOneMenu is set.
I have the following fragment of code in an .xhtml page:
<h:form id="filterForm">
<h:dataTable id="filterTable" value="#{filterManager.filters}" var="filter">
<h:column>
<h:outputLabel value="#{msgs.filterBy}:" for="availableFilters" />
<h:selectOneMenu id="availableFilters" value="#{filter.filter}">
<f:selectItems value="#{filterManager.getProperties(typeSelector.typeSelected)}" />
<f:ajax event="change" render=":filterForm" />
</h:selectOneMenu>
</h:column>
<h:column>
<h:panelGroup id="filterValuesPanel" >
<h:outputLabel value="#{msgs.value}:" for="filterValues" rendered="#{!filter.filterEmpty}" />
<h:selectOneMenu value="#{filter.value}" id="filterValues" rendered="#{!filter.filterEmpty}" >
<f:selectItems value="#{filterManager.getPossibleAnswers(filter)}" />
<f:ajax event="change" render=":filterForm" />
</h:selectOneMenu>
</h:panelGroup>
</h:column>
<h:column>
<h:commandButton value="#{msgs.delete}" title="#{msgs.deleteFilter}">
<f:ajax event="click" listener="#{filterManager.removeFilter(filter)}" render=":filterForm" />
</h:commandButton>
</h:column>
</h:dataTable>
<h:commandButton value="#{msgs.addNewFilter}">
<f:ajax event="click" listener="#{filterManager.addNewFilter}" render=":filterForm" />
</h:commandButton>
</h:form>
I have a bean called “FilterManager” which has a ViewScoped. Important parts are shown below:
#ManagedBean
#ViewScoped
public class FilterManager implements Serializable {
private List<Filter> filters; // it has a getter
private int currentFilterId;
public void addNewFilter(AjaxBehaviorEvent event) {
this.currentFilterId++;
this.filters.add(Filter.getEmptyFilter(this.currentFilterId));
}
public void removeFilter(Filter filter) {
this.filters.remove(filter);
}
...
}
The Filter class is a normal class (not a bean) and is shown below:
public class Filter implements Serializable {
private int id;
private String filter;
private String value;
public String getFilter() {
return filter;
}
public void setFilter(String theFilter) {
if (theFilter != null && !theFilter.isEmpty())
this.filter = theFilter;
}
public String getValue() {
return value;
}
public void setValue(String theValue) {
this.value = theValue;
}
public boolean isFilterEmpty() {
return this.filter == null || this.filter.isEmpty();
}
...
}
Notice that TypeSelector is a SessionScoped bean which has a typeSelected property along with getter and setter.
The problem is: filter.filter is set correctly whereas filter.value is never set. I can't find the problem so I need your help please. Apologies for all this code but I needed to provide you with all the necessary details.
Thanks in advance!
Okay guys that was my fault. I had a bug in FilterManager.getPossibleAnswers(Filter filter) method. Basically, at the end of the method, I was setting filter.value to the first element of List unconditionally. Eg instead of writing
if (filter.getValue() == null || filter.getValue().isEmpty()) {
SelectItem first = answers.get(0);
filter.setValue((String) first.getValue());
}
I just wrote:
SelectItem first = answers.get(0);
filter.setValue((String) first.getValue());
Although filter.value was updating as normal, the value was changing back to default (first element in list) during re-rendering of dataTable component.

Editable Datatable using a Dialog in JSF 2.0

I am currently running my web application in JSF 2.0, It also is using Primefaces 2.2RC2.
I know that primefaces gives you the ability to have editable rows, but for my project I would prefer if a user clicks on a commandButton within the table that a dialog is displayed prepopulated with that particular rows values and the user can edit the row that way.
The only way I have gotten this to work is to in the column that contains the commandButton, pass that rows contents as params like the example below:
<p:dataTable var="car" value="#{myBean.cars}" id="carList">
<h:column>
<h:inputText value="#{car.id}" style="width:100%"/>
</h:column>
<h:column>
<h:inputText value="#{car.name}" style="width:100%"/>
</h:column>
<h:column>
<h:commandButton actionListener=#{myBean.updateRow} onsuccess="editCardDialog.show()" >
<f:param name="carId" value=#{car.id} />
<f:param name="carName" value=#{car.name} />
</h:commandButton>
</h:column>
...
</p:dataTable>
So my Question is this, currently the only way I have gotten this to work is to in my backing bean create dummy temp global variables to set the params to so when my dialog opens it can reference the values like this
//myBean.java
private String tempCarId;
private String tempCarName;
public void setTempCarId(String tempCarId) {
this.tempCarId = carId;
}
public String getTempCarId() {
return tempCarId;
}
public void setTempCarName(String tempCarName) {
this.tempCarName = carName;
}
public String getTempCarName() {
return tempCarName;
}
public void updateRow(ActionEvent event) {
String carId = FaceContext...getParameterMap("carId");
String carName = FacesContext...getParameterMap("carName");
setTempCarId(carId);
setTempCarName(carName);
}
Then in the dialog I will just reference those temp variables
<p:dialog>
<h:inputText value=#{myBean.tempCarId} />
<h:inputText value=#{myBean.tempCarName} />
</p:dialog>
I am not sure if this is the correct way of doing it. My gut is telling me its not because it seems extremely redundant to have to create temp variables in my Bean just so I can pass them to the dialog. Does anyone know of a better more concise way of doing this so I dont have to create a million temporary variables in my backing bean?
Just replace the outputTexts in dialog below with inputTexts;
http://www.primefaces.org/showcase/ui/datatableRowSelectionByColumn.jsf
or
http://www.primefaces.org/showcase/ui/datatableRowSelectionInstant.jsf

Resources