9 Stimmen

eine Liste von Kontrollkästchen

Ich habe zwei Domänenklassen

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

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

Ich möchte alle in meinem gsp verfügbaren Erklärungen mit einem Kontrollkästchen neben jeder Erklärung anzeigen, so dass der Benutzer auswählen kann, welche Erklärungen auf den Vertrag anwendbar sind. Also so etwas wie:

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

Ich habe damit angefangen:

<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>

Aber ich kann einfach nicht eine Liste der geprüften Anweisungen an den Controller zu bekommen (es gibt null Elemente in der Liste, gibt es wiederholte Anweisungen...).

Haben Sie eine Idee, wie man das erreichen kann?

6voto

Peter Ledbrook Punkte 4172

Das ist möglich, erfordert aber einen kleinen Hack. Zunächst einmal muss jedes Kontrollkästchen denselben Namen haben: "statements":

<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>

Zweitens müssen Sie im Controller die Eigenschaft "_statements" vor dem Binden entfernen:

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

Die Unterstützung von Kontrollkästchen ist für diesen Anwendungsfall nicht vorgesehen, daher ist ein Hack erforderlich. In der Regel wird für diese Art von Szenario das Listenfeld mit mehreren Auswahlmöglichkeiten verwendet.

2voto

Wytze Punkte 1402

Ich persönlich ziehe es in diesem Fall vor, die Liste der Id's zu erhalten.

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

Befehlsobjekt:

class BookCommand {
    List<Serializable> bookIds
}

In der Controller-Aktion:

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

1voto

sikrip Punkte 661

Ändern Sie das Kontrollkästchen in etwa so.

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

und dann im Controller, in params.statements erhalten Sie eine Liste mit den IDs der geprüften Aussagen.

Beachten Sie auch die ?:'' in die Eigenschaft "checked" einzufügen, ist eine gute Idee, da jeder Wert (auch "false") in der Eigenschaft "checked" als "checked" interpretiert wird.

0voto

Igor Artamonov Punkte 34640

Sie leiten die Anfrage direkt an Contract ? Es ist viel sicherer, eine eingehende Anfrage in eine Command object .

Was die Zuordnung einer Liste betrifft, so werden die Werte nur den vorhandenen Elementen zugeordnet. Das heißt, es können keine neuen Listenelemente erstellt werden. Sie müssen sie vor dem Mapping vorbereiten. Wenn Sie wissen, dass es immer 3 Elemente gibt, können Sie sie erstellen:

class ContractCommand {

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

und die Anfrage auf dieses Objekt abbilden

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X