复选框列表

时间:2012-01-05 04:41:36

标签: grails

我有两个域类

class Contract {
    String number
    static hasMany = [statements:Statement]
}

class Statement {
    String code
    static hasMany = [contracts:Contract]
}

我想在我的gsp中显示所有可用的语句,每个语句旁边都有一个复选框,允许用户选择适用于合同的语句。如下所示:

[ ] Statement Code 1
[ ] Statement Code 2
[ ] Statement Code 3

我从这开始:

<g:each in="${Statement.list()}" var="statement" status="i">
    <g:checkBox name="statements[${i}].id" value="${statement.id}" checked="${contractInstance.statements.contains(statement.id)}" />
    <label for="statements[${i}]">${statement.code}</label>
</g:each>

但是我无法获得一个已检查语句的列表给控制器(列表中有null个元素,有重复的语句......)。

知道如何实现这个目标吗?

4 个答案:

答案 0 :(得分:6)

这是可能的,但它确实需要一点点黑客攻击。首先,每个复选框必须具有相同的名称,“语句”:

<g:each in="${org.example.Statement.list(sort: 'id', order: 'asc')}" var="statement" status="i">
    <g:checkBox name="statements" value="${statement.id}" checked="${contract.statements.contains(statement)}" />
    <label for="statements">${statement.content}</label>
</g:each>

其次,在控制器中,您必须在绑定之前删除“_statements”属性:

def contract = Contract.get(params.id)
params.remove "_statements"
bindData contract, params
contract.save(failOnError: true)

复选框支持尚未针对此用例设计,因此需要进行黑客攻击。多选列表框是通常用于此类场景的列表。

答案 1 :(得分:2)

我个人更喜欢在这种情况下获取Id列表。

<g:each var="book" in="${books}">
    <g:checkBox name="bookIds" value="${book.id}" ...
</g:each>

命令对象:

class BookCommand {
    List<Serializable> bookIds
}

在控制器操作中:

BookCommand bc ->
    author.books = Book.getAll(bc.bookIds)

答案 2 :(得分:1)

将复选框更改为此类似的内容。

<g:checkBox name="statements.${statement.id}" value="true" checked="${contractInstance.statements.contains(statement)?:''}" />

然后在控制器中,在params.statements中,您将获得一个包含已检查语句ID的列表。

另外注意checked属性中的?:'',最好添加它,因为checked属性中的任何值(甚至是'false')都被解释为已检查。

答案 3 :(得分:0)

您是否将请求直接映射到Contract?将传入的请求映射到Command object

会更安全

关于映射列表 - 值仅映射到现有元素。我的意思是它无法创建新的列表元素。您需要在映射之前准备它。如果你知道总有3个元素,你可以:

class ContractCommand {

   List statements = [
       new Statement(),
       new Statement(),
       new Statement(),
   ]
}

并将请求映射到此对象