当前位置: 首页 > 知识库问答 >
问题:

Primefaces自动完成具有不同值类型的组件,以获得建议和组件值

薄高懿
2023-03-14

我不确定这是否可能。。。但是我想使用autoComplete组件,其中value属性是String类型,completeMethod返回一些重对象的列表。

我还需要使用forceSelection=“false”

这是我认为应该起作用的(但没有):

        <p:autoComplete id="it_demandeur"
                        value="#{utilisateurDemandeurCtrl.critereRechercheDemandeur}"
                        var="demandeurItem"
                        itemLabel="#{demandeurItem ne null ? demandeurItem.numeroOW.toString().concat(' - ').concat(demandeurItem.nom) : ''}"
                        itemValue="#{demandeurItem.nom}"
                        completeMethod="#{utilisateurDemandeurCtrl.completeDemandeur}" 
                        minQueryLength="3"
                        cacheTimeout="10000">

           <p:column>
              #{demandeurItem.numeroOW} - #{demandeurItem.nom}

           </p:column>


        </p:autoComplete>

这是返回建议列表的方法:

@SuppressWarnings("unchecked")
   public List<Demandeur> completeDemandeur(String query) {

  StringBuilder jpql = new StringBuilder(128);

  jpql.append("SELECT d");
  jpql.append(" FROM Demandeur d");
  jpql.append(" WHERE UPPER(d.nom) LIKE :query");
  jpql.append(" OR d.numeroOW LIKE :query");

  Query demandeurQuery = em.createQuery(jpql.toString());

  demandeurQuery.setParameter("query", "%" + query.toUpperCase() + "%");

  return (List<Demandeur>) demandeurQuery.getResultList();
 }

如果用户选择一个建议,它会将itemValue设置为所选建议的名称,但会显示Demandeur对象中包含两个值的串联字符串。

建议确实会出现,我可以选择它们,但不幸的是,我在提交页面时出现了以下错误:

Exception message: /page/utilisateur.xhtml at line 27 and column 50 itemLabel="#{demandeurItem ne null ? demandeurItem.numeroOW.toString().concat(' - ').concat(demandeurItem.nom) : ''}": Property 'numeroOW' not found on type java.lang.String

我的理解是,自动完成组件的var属性是建议的迭代器,所以在我的例子中,类型Demandeur,而不是String。

任何帮助都将不胜感激!

谢谢

我使用的是primefaces 3.5.11,即WebSphere8.5.5.0上JSF的MyFaces实现

编辑:

这是我试过的转换器

@FacesConverter(value = "demandeurUIConverter")
public class DemandeurConverter implements Serializable, Converter {

   private static final long serialVersionUID = 1L;

   @Override
   public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) throws ConverterException {
      if (value == null || value.length() == 0) {
         return null;
      }
      ConverterCtrl cc = EJB.lookup(ConverterCtrl.class);
      Demandeur d = cc.getDemandeurFromCle(value);
      if (d == null) {
         d = new Demandeur();
         d.setNom(value);
         d.setNumeroOW(value);
      }
      return d;
   }

   @Override
   public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) throws ConverterException {
      if (value == null) {
         return "";
      }
      Demandeur demandeur = (Demandeur) value;
      return demandeur.getNom();
   }

}

共有3个答案

长孙鸿
2023-03-14

我也有同样的问题。

这给了我一个错误:itemLabel=“#{user.fullName}”:在java类型上找不到属性“fullName”。串

只有在提交后更新自动完成组件(以显示验证消息)时,才会出现此问题。如果从commandButton中删除“更新”属性,它就可以正常工作。

<p:panel id="resourceConfigNewFormPanel">
    <p:autoComplete id="newUsername" value="#{userResourceConfigurationListBean.resourceConfig.username}" completeMethod="#{userResourceConfigurationListBean.autocompleteUser}" var="user" itemLabel="#{user.fullName}" itemValue="#{user.userName}" forceSelection="true" required="true">
    </p:autoComplete>
    <p:commandButton value="..." action="..." update="resourceConfigNewForm" oncomplete="if (args &amp;&amp; !args.validationFailed) resourceConfigNewDlg.hide()" />

无论有无更新,这都适用:

<p:autoComplete id="newUsername" value="#{userResourceConfigurationListBean.resourceConfig.user}" completeMethod="#{userResourceConfigurationListBean.autocompleteUser}" var="user" itemLabel="#{user.fullName}" itemValue="#{user}" converter="#{userNameToUserConverter}" forceSelection="true" required="true">
</p:autoComplete>
苗阳文
2023-03-14

实际上,问题似乎就在这一部分

itemValue="#{demandeurItem.nom}"

如果itemValue是项目的名称,那么转换器将尝试从String转换,而不是从对象转换。因此,下面的转换器方法将收到"value"=string,而不是Demandeur。

public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) throws ConverterException

我试过下面的代码,我想这就是你需要的。我在tomee 1.6.0上使用primefaces 4.0。

转换器

import java.io.Serializable;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;

@ManagedBean
@RequestScoped
public class DemandeurConverter implements Converter, Serializable {

    private static final long   serialVersionUID    = 1L;

    @EJB
    Demandeurs                  ejb;

    @Override
    public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) throws ConverterException {
        if (value == null || value.length() == 0) {
            return null;
        } else {
            return ejb.getData().get(Long.parseLong(value));
        }
    }

    @Override
    public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) throws ConverterException {
        System.out.println(value.getClass());
        if (value == null) {
            return null;
        } else {
            return ((Demandeur) value).getId().toString();
        }
    }
}

管理豆

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class UtilisateurDemandeurCtrl implements Serializable {

    private static final long   serialVersionUID    = -3027573774106311465L;

    @EJB 
    private Demandeurs                  ejb;

    private Demandeur critereRechercheDemandeur;

    public List<Demandeur> completeDemandeur(String query) {
        List<Demandeur> l = new ArrayList<Demandeur>();

        for(Entry<Long, Demandeur> entryset:ejb.getData().entrySet()){
            if (entryset.getValue().getNom().contains(query)){
                l.add(entryset.getValue());
            }
        }

        return l;
    }

    public Demandeur getCritereRechercheDemandeur() {
        return critereRechercheDemandeur;
    }

    public void setCritereRechercheDemandeur(Demandeur critereRechercheDemandeur) {
        this.critereRechercheDemandeur = critereRechercheDemandeur;
    }
}

EJB

import java.util.HashMap;
import java.util.Map;

import javax.ejb.Singleton;


@Singleton
public class Demandeurs {

    private static final Map<Long,Demandeur> data = new HashMap<Long,Demandeur>(){
        private static final long   serialVersionUID    = -4394378761837292672L;

        {
             put(1L,new Demandeur(1L,"ooooooooooone",111));
             put(2L,new Demandeur(2L,"ttttttttttttwo",222));
        }
    };

    public static Map<Long, Demandeur> getData() {
        return data;
    }


}

实体bean

import java.io.Serializable;


public class Demandeur implements Serializable{

    private static final long   serialVersionUID    = 4023658749746098762L;
    private Long id;
    private String nom;
    private Integer numeroOW;
    public Demandeur() {}

    public Demandeur(Long id, String nom, Integer numeroOW) {
        super();
        this.id = id;
        this.nom = nom;
        this.numeroOW = numeroOW;
    }

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getNom() {
        return nom;
    }
    public void setNom(String nom) {
        this.nom = nom;
    }
    public Integer getNumeroOW() {
        return numeroOW;
    }
    public void setNumeroOW(Integer numeroOW) {
        this.numeroOW = numeroOW;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((nom == null) ? 0 : nom.hashCode());
        result = prime * result + ((numeroOW == null) ? 0 : numeroOW.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Demandeur other = (Demandeur) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (nom == null) {
            if (other.nom != null)
                return false;
        } else if (!nom.equals(other.nom))
            return false;
        if (numeroOW == null) {
            if (other.numeroOW != null)
                return false;
        } else if (!numeroOW.equals(other.numeroOW))
            return false;
        return true;
    }

}

还有xhtml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
<h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Test</title>
    <h:outputScript library="js" name="common.js" />
</h:head>
<h:body>

    <h:form id="somePrefix">

        <p:autoComplete 
            id="it_demandeur"
            value="#{utilisateurDemandeurCtrl.critereRechercheDemandeur}"
            var="demandeurItem"
            converter="#{demandeurConverter}"
            itemLabel="#{demandeurItem ne null ? demandeurItem.numeroOW.toString().concat(' - ').concat(demandeurItem.nom) : ''}"
            itemValue="#{demandeurItem}"
            forceSelection="true"
            completeMethod="#{utilisateurDemandeurCtrl.completeDemandeur}">

            <p:column>
              #{demandeurItem.numeroOW} - #{demandeurItem.nom}
            </p:column>
        </p:autoComplete>

    </h:form>
</h:body>
</html>
沃博裕
2023-03-14

如果为Demandeur制作一个转换器,这将起作用。

 类似资料:
  • 动态实例化PF 3.4.2自动完成组件时,我遇到了一个问题。组件最初呈现ok,部分处理时刷新其值,但从不显示建议。 我通过以下方式实例化此控件: 然后使用将其添加到父控件 父组件是PF PanelGrid的派生。我使用这种方法成功地生成了各种版本面板,效果非常好。但我不明白为什么它没有自动完成。 父控件看起来像: 它只是将子对象添加到面板网格。 自定义组件声明的其他方面(在taglib等中)也可以

  • 我正在使用primefaces AutoMLETE强制选择按名称搜索帐户 JSF组件 Bean方法: 这工作正常,现在如果我想把搜索更改为在查询值中搜索账号。我使用了以下内容: 但是,过滤器只返回搜索号码,而忽略名称搜索。我怎样才能做到这一点?

  • 问题内容: 例如: 因为json数组被解码为go数组,并且go数组需要显式定义类型,所以我不知道如何处理它。 问题答案: 首先,json无效,对象必须具有键,因此它应该类似于或just 。 而当您处理多种随机类型时,只需使用即可。

  • 我试图创建自己的自定义angular material组件,该组件能够使用控件。 除此之外,我希望该控件使用指令。 我的目的只是创建一个更好看的组件,该组件包含一个集成的clear按钮和自定义css箭头,如下图所示。我使用标准组件成功地获得了它,并添加了我想要的内容,但现在我想将它导出到泛型组件中。 null 即使正确选择了值,我的窗体也无效。 选择某个选项后,占位符自身设置不正确。 自动完成筛选

  • 葡萄牙语:java.lang.IllegalArgumentException jsf composite componente composto jsf com dataTable do primefaces tabela-padrao.xhtml 使用组件/Usando o组件 我有一个例外/Ocorreu esta Exceção! 葡萄牙人:Oque estou fazendo de er

  • 我有以下组件,它主要依赖于react native的 我能够输入注释我自己的道具,但在上面的例子中抛出了一个错误 [flow]属性<代码>样式(在道具中找不到属性)常量样式:任意 我知道在typescript中,我可以将接口扩展到Image one,流程中是否有一些东西可以让我的道具以某种方式从继承所有类型?我如何从react native导入这些类型? 编辑我发现了一个叫做交叉点类型的概念,并尝