selectCheckboxMenu primefaces return empty List - primefaces

I'm trying to get selected values from a selectCheckboxMenu using PrimeFaces 5.3 and JSF 2, but always the selection list is empty.
This is the HTML part:
<p:selectCheckboxMenu id="cours" value="#{etudiantController.checkedCours}"
converter="#{coursConverter}" label="Liste cours available" multiple="true"
panelStyle="width:250px">
<f:selectItems value="#{etudiantController.coursEtudiant}" var="coursEtd"
itemLabel="#{coursEtd.libelleCours}" itemValue="#{coursEtd.idCours}" />
</p:selectCheckboxMenu>
Bean part:
private List<Cours> checkedCours;
for(Cours coursToAdd : checkedCours){
System.out.println("enter ... !!!");
coursService.addCours(coursToAdd);
}
Converter :
public class CoursConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value != null && !value.isEmpty()) {
return component.getAttributes().get(value);
}
return null;
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) {
return "";
}
if (value instanceof Cours) {
Cours cours = (Cours) value;
String name = cours.getLibelleCours();
return name;
} else {
throw new ConverterException(new FacesMessage(value + " est un Cours non valide"));
}
} }
The problem here is that it never enter in the block.
Any help?
Thank you.

Try setting an Id to your converter and calling it using that id
#FacesConverter("coursConverter")
public class CoursConverter implements Converter {
...
}
--
<p:selectCheckboxMenu id="cours" value="#{etudiantController.checkedCours}"
converter="coursConverter" label="Liste cours available" multiple="true"
panelStyle="width:250px">
<f:selectItems value="#{etudiantController.coursEtudiant}" var="coursEtd"
itemLabel="#{coursEtd.libelleCours}" itemValue="#{coursEtd.idCours}" />

Related

PrimeFaces selectOneMenu displayed value not resetting

I have two combo boxes. The items of the second one are retrieved using the selected value of the first one. When the default empty value is selected in the first combo box, the second combo box is not rendered.
Everything works well except for one scenario :
select a value in the first combo box -> the second combo box appears
select a value in the second combo box
select the default empty value in the first combo box -> the second combo box disappears
select the same value that was selected at step 1 in the first combo box
The second combo box should appear with the empty default value selected, but instead displays the value that was selected at step 2.
If I select a different value at step 4, the second combo box is loaded correctly, with the default empty value selected.
The view :
<ui:composition template="/pages/include/templatePrincipal.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:d="http://iec.composants"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<ui:define name="pageActive">
<f:view>
<h:form>
<p:panel id="panelModifierUnParametreFonctionnel"
header="LISTE DES FE FILLES ORPHELINES">
<h:panelGrid columns="6">
<p:outputLabel
value="#{feFillesOrphelinesBean.labelComboRegion}" />
<p:selectOneMenu
value="#{feFillesOrphelinesBean.regionOption}"
valueChangeListener="#{feFillesOrphelinesBean.regionChanged}"
onchange="submit()">
<f:selectItems value="#{feFillesOrphelinesBean.listRegion}" />
</p:selectOneMenu>
<p:outputLabel
value="#{feFillesOrphelinesBean.labelComboCorps}"
rendered="#{feFillesOrphelinesBean.rendreComboCorps}" />
<p:selectOneMenu
value="#{feFillesOrphelinesBean.corpsOption}"
rendered="#{feFillesOrphelinesBean.rendreComboCorps}"
valueChangeListener="#{feFillesOrphelinesBean.corpsChanged}"
onchange="submit()">
<f:selectItems value="#{feFillesOrphelinesBean.listCorps}" />
</p:selectOneMenu>
</h:panelGrid>
</p:panel>
</h:form>
</f:view>
</ui:define>
</ui:composition>
The java bean :
public class FEFillesOrphelinesBean implements Serializable {
public final static String LABEL_COMBO_REGION = "ChaƮne fonctionnelle :";
public final static String LABEL_COMBO_CORPS = "Corps :";
private String labelComboRegion;
private String labelComboCorps;
private List<SelectItem> listRegion;
private Integer regionOption;
private List<SelectItem> listCorps;
private Integer corpsOption;
private Boolean rendreComboCorps;
public String init() {
this.chargerRegions();
this.chargerCorps();
this.setLabelComboRegion(LABEL_COMBO_REGION);
this.setLabelComboCorps(LABEL_COMBO_CORPS);
return "success";
}
public void chargerRegions() {
this.setListRegion(new ArrayList<>());
this.setRegionOption(new Integer(-1));
RegionAdmin[] tabRegions = ServiceFactory.getInstance().getGestionRegionSrv().findAll();
this.getListRegion().add(new SelectItem(new Integer(-1), " "));
for (RegionAdmin region : tabRegions) {
SelectItem regionItem = new SelectItem(region.getId(), region.getLib() + ": " + region.getLibelle());
this.getListRegion().add(regionItem);
}
}
public void chargerCorps() {
this.setListCorps(new ArrayList<>());
this.setCorpsOption(new Integer(-1));
if (this.getRegionOption().equals(new Integer(-1))) {
this.setRendreComboCorps(false);
} else {
Corps[] tabCorps = ServiceFactory.getInstance().getGestionCorpsSrv().findCorps(this.getRegionOption());
this.getListCorps().add(new SelectItem(new Integer(-1), " "));
for (Corps corps : tabCorps) {
SelectItem corpsItem = new SelectItem(corps.getId(), corps.getLib() + ": " + corps.getLibelle());
this.getListCorps().add(corpsItem);
}
this.setRendreComboCorps(true);
}
}
public void regionChanged(ValueChangeEvent event) {
Integer newRegionOption = (Integer) event.getNewValue();
this.setRegionOption(newRegionOption);
this.chargerCorps();
}
public void corpsChanged(ValueChangeEvent event) {
Integer newCorpsOption = (Integer) event.getNewValue();
this.setCorpsOption(newCorpsOption);
}
public String getLabelComboRegion() {
return labelComboRegion;
}
public void setLabelComboRegion(String labelComboRegion) {
this.labelComboRegion = labelComboRegion;
}
public String getLabelComboCorps() {
return labelComboCorps;
}
public void setLabelComboCorps(String labelComboCorps) {
this.labelComboCorps = labelComboCorps;
}
public List<SelectItem> getListRegion() {
return listRegion;
}
public void setListRegion(List<SelectItem> listRegion) {
this.listRegion = listRegion;
}
public Integer getRegionOption() {
return regionOption;
}
public void setRegionOption(Integer regionOption) {
this.regionOption = regionOption;
}
public List<SelectItem> getListCorps() {
return listCorps;
}
public void setListCorps(List<SelectItem> listCorps) {
this.listCorps = listCorps;
}
public Integer getCorpsOption() {
return corpsOption;
}
public void setCorpsOption(Integer corpsOption) {
this.corpsOption = corpsOption;
}
public Boolean getRendreComboCorps() {
return rendreComboCorps;
}
public void setRendreComboCorps(Boolean rendreComboCorps) {
this.rendreComboCorps = rendreComboCorps;
}
}
As you can see, the regionChanged method is called when the selected value of the first combo box changes, then it calls the chargerCorps method which set the corpsOption to the -1 default value. This means that in the scenario that I've described, the displayed selected value is not the same as the selected value in the bean, which can cause a lot of issues.

How to use LazyDataModel List in a selectOneMenu

I want to use a LazyDataModel List inside a SelectOneMenu, but the selectoneMenu doesn't show anything . this is my code
public void show() {
beneficiaries = new LazyDataModel<Fournisseur>() {
private static final long serialVersionUID = 1L;
private List<Fournisseur> list;
#Override
public List<Fournisseur> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters){
list = service.getAll((String)filters.get("benef.intitule"),first, pageSize);
this.setRowCount(service.count((String)filters.get("benef.intitule")));
return list;
}
#Override
public Object getRowKey(Fournisseur obj) {
return obj.getCpt();
}
#Override
public Fournisseur getRowData(String rowKey) {
Fournisseur o=null;
if(rowKey != null) {
for (Fournisseur obj : list) {
if(rowKey == obj.getCpt()) {
o = obj;
}
}
return o;
}else {
return null;
}
}
};
}
this is my html code
<p:selectOneMenu id="beneficiary" value="#
{documentController.doc.beneficiary}" converter="#
{beneficiaryConverter}" panelStyle="width:160px" required="true" >
<f:selectItem itemLabel="Selectionner" itemValue="" />
<f:selectItems value="#{beneficiaryController.beneficiaries}"
var="beneficiary" itemLabel="#{beneficiary.intitule}" itemValue="#
{beneficiary}" />
</p:selectOneMenu>
i've tested the list out side the selectOneMenu and it's work fine.
You are using PrimeFaces and want to allow the user to select one out of very many options. As Melloware mentioned, LazyDataModel is ment for use with DataTable or other components that support pagination this way ( e.g. DataGrid)
For your use case p:autoComplete seemes to be the best way to go.
dropdown="true" makes it look like a selectOneMenu, and you can limit the number of items show using maxResults="5".
<p:autoComplete dropdown="true" maxResults="5" value="#{autoCompleteView.txt6}"
completeMethod="#{autoCompleteView.completeText}" />
You'll need to write a custom autoComplete method that finds matches for given user search input:
public List<String> completeText(String query) {
List<String> results = new ArrayList<String>();
// fill the result matching the query from user input
return results;
}

Why is this <p:selectManyMenu> not working? (getAllDatasourceGroups() is not even called once)

My problem is about this primefaces tag:
<p:selectManyCheckbox id="datasourceGroup" value="#{sessionBean.datasourceGroups}" converter="datasourceGroupConverter">
<f:selectItems value="#{sesionBean.getAllDatasourceGroups()}" var="group" itemLabel="#{group.toString()}" itemValue="#{group}" />
</p:selectManyCheckbox>
It does not render any visible output (checkboxes) at all. From logging output i know that the 'sessionBean.getAllDatasourceGroups()' method is not even called once during page refresh. only the 'sessionBean.getDatasourcegroups()' getter for the 'datasourceGroups' property is called once.
And i can't figure out what the problem is. I have very similar usecases of <p:selectManyMenu> and <p:selectOneMenu> on the same page and they work fine. So i have a basic understanding of how this works...or so i thought :-)
here are the other relevant parts of the code for reference:
SessionBean:
#ManagedBean
#SessionScoped
public class SessionBean implements Serializable {
private List<DatasourceGroup> datasourceGroups = new ArrayList<>();
public List<DatasourceGroup> getDatasourceGroups() {
return datasourceGroups;
}
public void setDatasourceGroups(List<DatasourceGroup> datasourceGroups) {
this.datasourceGroups = datasourceGroups;
}
public List<DatasourceGroup> getAllDatasourceGroups() {
List<DatasourceGroup> list = Arrays.asList(DatasourceGroup.values());
return list;
}
}
DatasourceGroup Enum:
public enum DatasourceGroup {
KUNDEN (Permission.ZugriffKunden),
INKASSO (Permission.ZugriffInkasso),
INTERESSENTEN (Permission.ZugriffInteressenten),
WARN (Permission.ZugriffWarnadressen);
private Permission permissionNeeded;
DatasourceGroup(Permission permission) {
this.permissionNeeded=permission;
}
public Permission getPermissionNeeded() {
return permissionNeeded;
}
}
And the DatasourceGroupConverter:
#FacesConverter("datasourceGroupConverter")
public class DatasourceGroupConverter implements Converter {
#Override
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if (Toolbox.isNullOrEmpty(value))
return null;
try {
return DatasourceGroup.valueOf(value);
} catch (IllegalArgumentException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error:",
"'" + value + "' is not a valid datasource group name"));
}
}
#Override
public String getAsString(FacesContext fc, UIComponent uic, Object object) {
if(object != null && object instanceof DatasourceGroup) {
return ((DatasourceGroup)object).toString();
}
return null;
}
}
I'm using primefaces 6.0 by the way.

How to write a function that can be available in all Razor views?

I'm trying to write a function that can bring a language resource from database in MVC 5 and Razor,
I want it to be very simple to use, for example, the following function should just get some text:
#T("ResourceType", "ResourceName")
I don't want to use #this. - just the the function name...
I saw some posts about it mentioning the line below, but still trying to understand how to do it
public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>
Any help will be greatly appreciated.
Thanks in advance.
I finally found a way to do it, inspired by the NopCommerce project, see the code below.
The code can be used in any Razor (cshtml) view like this:
<h1>#T("StringNameToGet")</h1>
Also, note that pageBaseType needs to be updated with the correct new namespace,
this is the web.config in the Views folder - not the main one, should look like this:
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="MyNameSpace.Web.Extensions.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization"/>
<add namespace="System.Web.Routing" />
<add namespace="APE.Web" />
</namespaces>
</pages>
The code:
namespace MyNameSpace.Web.Extensions
{
public delegate LocalizedString Localizer(string text, params object[] args);
public abstract class WebViewPage : WebViewPage<dynamic>
{
}
/// <summary>
/// Update the pages element /views/web.config to reflect the
/// pageBaseType="MyNameSpace.Web.Extensions.WebViewPage"
/// </summary>
/// <typeparam name="TModel"></typeparam>
public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>
{
private Localizer _localizer;
/// <summary>
/// Get a localized resources
/// </summary>
public Localizer T
{
get
{
if (_localizer == null)
{
//null localizer
//_localizer = (format, args) => new LocalizedString((args == null || args.Length == 0) ? format : string.Format(format, args));
//default localizer
_localizer = (format, args) =>
{
var resFormat = SampleGetResource(format);
if (string.IsNullOrEmpty(resFormat))
{
return new LocalizedString(format);
}
return
new LocalizedString((args == null || args.Length == 0)
? resFormat
: string.Format(resFormat, args));
};
}
return _localizer;
}
}
public string SampleGetResource(string resourceKey)
{
const string resourceValue = "Get resource value based on resourceKey";
return resourceValue;
}
}
public class LocalizedString : System.MarshalByRefObject, System.Web.IHtmlString
{
private readonly string _localized;
private readonly string _scope;
private readonly string _textHint;
private readonly object[] _args;
public LocalizedString(string localized)
{
_localized = localized;
}
public LocalizedString(string localized, string scope, string textHint, object[] args)
{
_localized = localized;
_scope = scope;
_textHint = textHint;
_args = args;
}
public static LocalizedString TextOrDefault(string text, LocalizedString defaultValue)
{
if (string.IsNullOrEmpty(text))
return defaultValue;
return new LocalizedString(text);
}
public string Scope
{
get { return _scope; }
}
public string TextHint
{
get { return _textHint; }
}
public object[] Args
{
get { return _args; }
}
public string Text
{
get { return _localized; }
}
public override string ToString()
{
return _localized;
}
public string ToHtmlString()
{
return _localized;
}
public override int GetHashCode()
{
var hashCode = 0;
if (_localized != null)
hashCode ^= _localized.GetHashCode();
return hashCode;
}
public override bool Equals(object obj)
{
if (obj == null || obj.GetType() != GetType())
return false;
var that = (LocalizedString)obj;
return string.Equals(_localized, that._localized);
}
}
}

Validation error value is not valid: primefaces [duplicate]

This question already has answers here:
Validation Error: Value is not valid
(3 answers)
Closed 6 years ago.
Please help me to find the solution.
this is the xhtml code:
<p:selectOneMenu value="#{activteBean.act.activiteFamille}"
converter="familleAct"
var="f" required="Une famille est obligatoire" >
<f:selectItems value="#{activteBean.actFamList}" var="famille" itemLabel="# {famille.dsgFam}" itemValue="#{famille}"/>
<p:column>#{f.refFam}</p:column>
<p:column>#{f.dsgFam}</p:column>
</p:selectOneMenu>
here is my converter:
#FacesConverter(forClass=ActiviteFamille.class,value="familleAct" )
public class ActiviteFamilleConverter implements Converter {
#Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String code) {
if (code.trim().equals("")) {
return null;
} else {
ActiviteFamilleDao actFamDao = new ActiviteFamilleDao();
List<ActiviteFamille> actFamList = actFamDao.findAll();
for (ActiviteFamille af : actFamList) {
if (af.getRefFam().equals(code)) {
return af;
}
}
}
return null;
}
#Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object value) {
if (value == null || value.equals("")) {
return "";
} else {
return String.valueOf(((ActiviteFamille) value).getRefFam());
}
}
}
The managed bean:
#ManagedBean(name = "activteBean")
#ViewScoped
public class ActivteBean implements Serializable {
private Activite act = new Activite();
private ActiviteDao actDao = new ActiviteDao();
private List<Activite> actList;
private boolean init;
private ActiviteFamilleDao actFamDao = new ActiviteFamilleDao();
private List<ActiviteFamille> actFamList;
public boolean isInit() {
act = new Activite();
actList = actDao.findAll();
actFamList=actFamDao.findAll();
return init;
}
....
}
and thank you for your help.
This can happen if the equals() method for ActiveFamille is not implemented properly.
The error message indicates that the selected (and converted) value does not match any of the elements in your list activteBean.actFamList.
Try to debug and set a break point into the equals() method of ActiveFamille and try to find out why it does not match.