grails3

How to change what grails puts into dropdown in f:all


I have a very simple project with users have accounts and accounts have transactions.

I generated the views, controllers and services using grails generate-all Transaction.

Transaction domain object looks like this:

class Transaction {
    Account account
    BigDecimal debit = 0
    BigDecimal credit = 0
    static constraints = {
    }
}

The controller only has this:

def create() {
    respond new Transaction(params)
}

I.e. only sends a new transaction (not a list of accounts).

However, the create UI has a dropdown of all accounts in the system (not just for this user):

enter image description here

The question is, is there a way to "fix" to only show the users accounts? If not, I can always manually write the create view with each field hard coded. Just wondered if there was a cool grails way to do it.

See https://github.com/nutmix/grails-dropdow-air


Solution

  • This is a tricky question, isn't it? After investigating the solution to this question for a while, I found we could accomplish the need by doing as described below.

    In create view of transaction, customise a bit of how to render data:

    <g:form resource="${this.transaction}" method="POST">
        <fieldset class="form">
             <f:field bean="transaction" property="account" wrapper="transaction/account"/>
             <f:all bean="transaction" except="account"/>
        </fieldset>
    ...
                </g:form>
    

    where wrapper is the directories (i.e. path) where we place _wrapper.gsp. Read more about Loading Templates Conventionally Example section to know how and where you define customised wrapper, template and widget. To solve your problem, _wrapper.gsp has the following codes:

    <%@ page import="dropdown.Account" %>
    <%
        def values = dropdown.Account.all.collect {it.currencyIso}.unique(true)
        //println values
    %>
    <div class="fieldcontain required">
        <label for="account">Account <span class="required-indicator">*</span></label>
        <g:select name="account" from="${values}"
                  value="${transaction?.account}"/>
    </div>
    

    The location of _wrapper.gsp is grails-app/views/_fields/transaction/account/_wrapper.gsp.

    The result looks like the following screenshot. enter image description here

    P/S: I got this idea when I came across the answer about f:table.