2013-09-10 76 views
2

我有這個編輯表單:彈簧形式:選擇多個選定的值?

enter image description here

我想的是,用戶的角色都被選擇。如果這是一對多的關係,我知道我可以這樣做:

 <form:label path="roles">Roles:</form:label> 
     <form:select multiple="true" path="roles"> 
      <c:forEach items="${roles}" var="rol"> 
       <c:choose> 
        <c:when 
         test="${usuarioEdit.rol.id ==rol.id}"> 
         <option value="${rol.id}" selected="selected">${rol.nombre}</option> 
        </c:when> 
        <c:otherwise> 
         <option value="${rol.id}">${rol.nombre}</option> 
        </c:otherwise> 
       </c:choose> 

      </c:forEach> 
     </form:select> 
     <form:errors cssStyle="color:red" path="roles"></form:errors> 

但是這是一個多對多的關係。如何在編輯表單中選擇選項?有一種簡單的形式嗎?

此代碼的工作,但我不知道春天提供任何設施:

<form:select multiple="true" path="roles"> 
      <c:forEach items="${roles}" var="rol"> 
       <c:set var="isSelected" value="false" /> 
       <c:forEach items="${rolesUsu}" var="rolUsu"> 
        <c:if test="${rolUsu.getRol().getId()==rol.id}"> 
         <c:set var="isSelected" value="true" /> 
        </c:if> 
       </c:forEach> 
       <c:choose> 
        <c:when test="${isSelected}"> 
         <option value="${rol.id}" selected="selected">${rol.nombre}</option> 
        </c:when> 
        <c:otherwise> 
         <option value="${rol.id}">${rol.nombre}</option> 
        </c:otherwise> 
       </c:choose> 
      </c:forEach> 
     </form:select> 

編輯:

在我的控制,我有:

@InitBinder 
    public void initBinder(WebDataBinder binder) { 

     binder.registerCustomEditor(Set.class, "roles", 
       new RolCollectionEditor(Set.class, rolDao)); 

    } 

RolCollectionEditor:

public class RolCollectionEditor extends CustomCollectionEditor { 

    private final RolDAO rolDao; 


    public RolCollectionEditor(Class<?> collectionType, RolDAO rolDao) { 

     super(collectionType); 
     this.rolDao = rolDao; 

    } 

    @Override 
    protected Object convertElement(Object element) { 
     String rolId = (String) element; 

     Rol rol = rolDao.findById(rolId); 
     Usuario_Rol usuRol = new Usuario_Rol(); 

     //Agregamos un usuario vacio temporal 
     //y lo sobreescribimos en el controlador 
     Usuario usuario = new Usuario(); 

     usuRol.setUsuario(usuario); 
     usuRol.setRol(rol); 
     usuRol.setFechaCreacion(new Date()); 
     usuRol.setFechaModificacion(new Date()); 
     usuRol.setStatus("activo"); 

     return usuRol; 
    } 

} 

這裏Usuario_Rol是多對多關係的中間表,除了userId和rolId之外,還有其他屬性。

EDIT2:

ROL類:

@Entity 
@Table(name = "rol", uniqueConstraints = { @UniqueConstraint(columnNames = "nombre") }) 
public class Rol implements Serializable{ 

    @Id 
    @Column(name = "_id") 
    private String id; 

    @Column(name = "nombre") 
    @NotNull 
    private String nombre; 

    @Column(name = "descripcion") 
    private String descripcion; 

    @Column(name = "status") 
    private String status; 

    @Column(name = "fechaCreacion") 
    private Date fechaCreacion; 

    @Column(name = "fechaModificacion") 
    private Date fechaModificacion; 

    @Column(name = "fechaSincronizacion") 
    private Date fechaSincronizacion; 

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "usuarioRol_pk.rol", orphanRemoval = true, cascade=CascadeType.ALL) 
    private Set<Usuario_Rol> usuarios = new HashSet<Usuario_Rol>(0); 


    //getters and setters 

    @Override 
    final public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((nombre == null) ? 0 : nombre.hashCode()); 
     return result; 
    } 

    @Override 
    final public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (!(obj instanceof Rol)) 
      return false; 
     Rol other = (Rol) obj; 
     if (nombre == null) { 
      if (other.nombre != null) 
       return false; 
     } else if (!nombre.equals(other.nombre)) 
      return false; 
     return true; 
    } 

類Usuario:

@Entity @Table(名稱= 「usuario」,uniqueConstraints = { @UniqueConstraint(COLUMNNAMES = 「login」), @UniqueConstraint(columnNames =「correo」)}) public class Usuario implements Serializable {

@Id 
@Column(name = "_id") 
private String id; 

@Column(name = "nombre") 
@NotEmpty 
private String nombre; 

@Column(name = "apellido") 
@NotEmpty 
private String apellido; 

@Column(name = "login") 
@Size(min = 4) 
@NotEmpty 
private String login; 

@Column(name = "password") 
@NotEmpty 
@Size(min = 4) 
private String password; 

@Column(name = "salt") 
private String salt; 

@Column(name = "correo") 
@NotEmpty 
@Email 
private String correo; 

@Column(name = "token") 
private String token; 

@Column(name = "status") 
private String status; 

@Column(name = "fechaUltimoLogin") 
private Date fechaUltimoLogin; 

@Column(name = "fechaCreacion") 
private Date fechaCreacion; 

@Column(name = "fechaModificacion") 
private Date fechaModificacion; 

@Column(name = "fechaSincronizacion") 
private Date fechaSincronizacion; 

@NotEmpty 
@OneToMany(fetch = FetchType.EAGER, mappedBy = "usuarioRol_pk.usuario", orphanRemoval = true, cascade = CascadeType.ALL) 
private Set<Usuario_Rol> roles = new HashSet<Usuario_Rol>(0); 


//constructor, getters and setters. 

@Override 
final public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + ((login == null) ? 0 : login.hashCode()); 
    return result; 
} 

@Override 
final public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (!(obj instanceof Usuario)) 
     return false; 
    Usuario other = (Usuario) obj; 
    if (login == null) { 
     if (other.login != null) 
      return false; 
    } else if (!login.equals(other.login)) 
     return false; 
    return true; 
} 

中級班:

@Entity 
@Table(name = "usuario_rol") 
@AssociationOverrides({ 
    @AssociationOverride(name = "usuarioRol_pk.usuario", joinColumns = @JoinColumn(name = "idUsuario")), 
    @AssociationOverride(name = "usuarioRol_pk.rol", joinColumns = @JoinColumn(name = "idRol")) 
}) 
public class Usuario_Rol implements Serializable{ 

    @EmbeddedId 
    private Usuario_RolId usuarioRol_pk = new Usuario_RolId(); 

    @Temporal(TemporalType.DATE) 
    @Column(name = "fechaCreacion") 
    private Date fechaCreacion; 

    @Temporal(TemporalType.DATE) 
    @Column(name = "fechaModificacion") 
    private Date fechaModificacion; 

    @Temporal(TemporalType.DATE) 
    @Column(name = "fechaSincronizacion") 
    private Date fechaSincronizacion; 

    @Column(name = "status") 
    private String status; 

    //gettters, setters 

    @Override 
    final public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((usuarioRol_pk == null) ? 0 : usuarioRol_pk.hashCode()); 
     return result; 
    } 


    @Override 
    final public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (!(obj instanceof Usuario_Rol)) 
      return false; 
     Usuario_Rol other = (Usuario_Rol) obj; 
     if (usuarioRol_pk == null) { 
      if (other.usuarioRol_pk != null) 
       return false; 
     } else if (!usuarioRol_pk.equals(other.usuarioRol_pk)) 
      return false; 
     return true; 
    } 

Usuario_RolId:

@Embeddable 
public class Usuario_RolId implements Serializable{ 

    @ManyToOne 
    private Usuario usuario; 

    @ManyToOne 
    private Rol rol; 

    public Usuario getUsuario() { 
     return usuario; 
    } 
    public void setUsuario(Usuario usuario) { 
     this.usuario = usuario; 
    } 
    public Rol getRol() { 
     return rol; 
    } 
    public void setRol(Rol rol) { 
     this.rol = rol; 
    } 


    @Override 
    final public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((rol == null) ? 0 : rol.hashCode()); 
     result = prime * result + ((usuario == null) ? 0 : usuario.hashCode()); 
     return result; 
    } 

    @Override 
    final public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (!(obj instanceof Usuario_RolId)) 
      return false; 
     Usuario_RolId other = (Usuario_RolId) obj; 
     if (rol == null) { 
      if (other.rol != null) 
       return false; 
     } else if (!rol.equals(other.rol)) 
      return false; 
     if (usuario == null) { 
      if (other.usuario != null) 
       return false; 
     } else if (!usuario.equals(other.usuario)) 
      return false; 
     return true; 
    } 

這最後一堂課是用於模擬一個多對多關係的伎倆。我遵循本教程:http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/

+0

我不明白如何在選擇輸入中有多對多的關係...在時間t,選定的元素將始終屬於一個實體(用戶)。或者,也許我誤解你的問題 –

+0

是的,這是一個多對多的關係,但我只使用一個方向一個用戶 - >很多角色,但在我的數據庫中,我有一個idUser和idRol的表。我用一個解決方案編輯了這個問題,但仍然想知道春天是否提供了任何設施來實現我想要的。 – kiduxa

+0

好了,現在我明白了。我不認爲這個春天有特定的東西來實現這個......但是你應該在控制器端做這種行爲,然後返回屬於用戶列表的角色ID數組。然後使用該數組來檢查是否應該選擇選項。它使視圖更清晰,我通常嘗試避免許多嵌入式JSTL標籤,它很難理解 –

回答

4

你爲什麼寫自己的?春天應該能夠爲你做到這一點。而不是<c:forEach /><form options .. />標記替換整個塊。 Spring將能夠自己做出選擇(您可能需要ConverterPropertyEditor)。

<form:select multiple="true" path="roles" items="${roles}" itemLabel="nombre" itemValue="id" /> 

沿着這些線......

鏈接:

  1. 窗體選項documentation
  2. 形式選擇documentation
  3. Reference Guide
+0

我已經做了,但沒有工作,我沒有得到選擇的選項。我以一種新形式使用它,但是在我的編輯表單中不起作用。不知道爲什麼... – kiduxa

+0

如上所述,你可能需要一個自定義的轉換器(檢查我的答案中的鏈接)。另外角色路徑(我猜你的用戶對象的屬性)應該包含與列表中所有可用角色相同的類型,否則它將不起作用。 –

+0

好的,讓我更好地解釋一下。我有2種形式,一種新的形式和編輯形式。新表單只是一個空白表單,沒有任何信息。一旦您提交新表單,編輯表單就會充滿用戶信息。因此,如果我的用戶在新窗體中選擇了「管理員」(管理員用英語),當我編輯表單時,我需要選擇「管理員」。 。爲什麼我應該使用JavaScript? – kiduxa

2

如果使用這樣的:

<form:select multiple="true" path="roles" items="${roles}" itemLabel="nombre" itemValue="id" /> 

你需要以正確的方式覆蓋Usuario_Rol的toString()方法,以確保Spring爲您預先選擇初始值。

1

如果我理解正確的問題,你要的是你的Spring標籤生成HTML像這樣的:

<select id="roles" name="roles multiple="multiple"> 
     <option value="1">Administrador</option> 
     <option value="2">Usuario avanzado</option> 
     <option value="3" selected="selected">Usuario </option> 
     <option value="4" selected="selected">Invitado</option> 
    </select> 

正如你可以看到,兩個值選擇(「Usuario」和「Invitado」) 。

在您的Spring標記中,「path」引用的「roles」模型屬性是一個數組而不是單個值。這很簡單。請注意,我在我的控制器中手動設置陣列。我不熟悉代碼的ORM方面的含義。