0

I have a table that looks like this:

+------------+---------+-----+
|System      |Title    |Genre|
+------------+---------+-----+
|PC          | A       | RPG |
|PC          | B       | FPS |
|Console     | C       | RPG |
|Console     | D       | RPG |
|Console     | E       | FPS |
+------------+---------+-----+

Each Title belongs to exactly one system, but each genre may belong to many titles.

My goal is to have three HTML select elements, with each populated with the distinct elements of the table above, but prepended with an ALL option. When an option is chosen from any select list, only those valid options in the other select elements should be visible.

For example, if System PC option is selected, only Title elements with values A and B should be visible. If Genre FPS is selected, all System options should be visible, but only Title options B and E should be visible. Hopefully the ALL option behaviour should be obvious.

My controller action looks like this:

def filter() {
  def attributes = Publication.createCriteria().list {
    projections {
      groupProperty 'system'
      groupProperty 'title'
      groupProperty 'genre'
    }
    cache(true)
  }

  [ attributes: attributes ]
}

And this is displayed in a view like this:

<div id="container">
    <form>
        <div>
            <label for="filterSystem">System</label>
            <select id="filterSystem">
                <option value="ALL">ALL</option>
                <g:each in="${attributes.collect { it[0] }.unique().sort()}">
                    <option value="${it}">${it}</option>
                </g:each>
            </select>
        </div>

        <div>
            <label for="filterTitle">Title</label>
            <select id="filterTitle">
                <option value="ALL">ALL</option>
                <g:each in="${attributes.collect { it[1] }.unique().sort()}">
                    <option value="${it}">${it}</option>
                </g:each>
            </select>
        </div>

        <div>
            <label for="filterGenre">Genre</label>
            <select id="filterGenre">
                <option value="ALL">ALL</option>
                <g:each in="${attributes.collect { it[2] }.unique().sort()}">
                    <option value="${it}">${it}</option>
                </g:each>
            </select>
        </div>
    </form>
</div>

I assume I'll need need to do some client-side scripting to dynamically update the option values, but I'm not sure how to bridge the gap between the Grails model and everything else.

A potential answer to my problem exists here, but the conditions are slightly different. There, all of the records are available in the table, while I have aggregated my results for distinct combinations. I think I can still use some of the basic ideas from that question, however. My first idea is to transform the Grails Domain object into a JSON object, either in the response or afterwards in a script. From there I might be able to filter down the option values depending on what was selected.

lealand
  • 367
  • 4
  • 13

0 Answers0