Grails
  1. Grails
  2. GRAILS-1197

Allow multiple selected values in a <g:select multiple="multiple" /> tag

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 0.5
    • Fix Version/s: 1.0
    • Component/s: TagLib
    • Labels:
      None
    • Patch attached:
      Yes

      Description

      When using a <g:select /> with multiple selection enabled, there is no way at the moment to tell grails to "pre-select" multiple values. Changing the following (line 513 in 5.0):

      if(keyValue==value) {
      out << 'select="selected" '
      }

      to:

      if(attrs.multiple) {
      if((value instanceof ArrayList && value.contains(keyValue)) || (!(value instanceof ArrayList) && keyValue == value))

      { out << 'selected="selected" ' }

      }
      else {
      if(keyValue==value)

      { out << 'select="selected" ' }

      }

      allows doing something like this:
      <g:select from="[1, 2, 3, 4]" value="[2, 4]" />

      (I guess there might be a cleaner way to do that, though)

        Activity

        Hide
        Michael Kimsal added a comment -

        Thanks Peter. I saw the 1250 issue and still didn't quite understand, given the fix that's in there. Yes, it might not work for all types. Having a toString() will probably fix the issue in almost all cases, however, and give people a defined way to deal with the issue for other types in a list.

        I wasn't suggesting that you didn't want the functionality, but perhaps text only doesn't always get across the whole tone of a post.

        Thanks for the attention on this one!

        Show
        Michael Kimsal added a comment - Thanks Peter. I saw the 1250 issue and still didn't quite understand, given the fix that's in there. Yes, it might not work for all types. Having a toString() will probably fix the issue in almost all cases, however, and give people a defined way to deal with the issue for other types in a list. I wasn't suggesting that you didn't want the functionality, but perhaps text only doesn't always get across the whole tone of a post. Thanks for the attention on this one!
        Hide
        Graeme Rocher added a comment -

        The fix for GRAILS-1250 was incorrect and hacky and needs to be reverted so this can be applied an another solution found for it. It may be just a matter of throwing a better error message

        Show
        Graeme Rocher added a comment - The fix for GRAILS-1250 was incorrect and hacky and needs to be reverted so this can be applied an another solution found for it. It may be just a matter of throwing a better error message
        Hide
        Graeme Rocher added a comment -

        Note, Alain's solution is actually better as the attached patch seems to just call contains on the value. If its meant to use String.contains that is a JDK 1.5 method

        Show
        Graeme Rocher added a comment - Note, Alain's solution is actually better as the attached patch seems to just call contains on the value. If its meant to use String.contains that is a JDK 1.5 method
        Hide
        Graeme Rocher added a comment -

        Ok so this is the tests I have passing now for this:

            void testSimpleSelect() {
                def template = '<g:select name="foo" from="[1,2,3]" value="1" />'
        
        assertOutputEquals('''<select name="foo" id="foo" >
        <option value="1" selected="selected" >1</option>
        <option value="2" >2</option>
        <option value="3" >3</option>
        </select>''', template)
        
            }
        
        
            void testMultiSelect() {
                def template = '<g:select name="foo" from="[1,2,3]" value="[2,3]" />'
        
        assertOutputEquals('''<select name="foo" id="foo" multiple="true" >
        <option value="1" >1</option>
        <option value="2" selected="selected" >2</option>
        <option value="3" selected="selected" >3</option>
        </select>''', template)
        
            }
        

        Note you dont have to set multiple=true it just assumes that the case if the value is a collection (i don't see what else it could be other than a multi select in this case)

        Show
        Graeme Rocher added a comment - Ok so this is the tests I have passing now for this: void testSimpleSelect() { def template = '<g:select name= "foo" from= "[1,2,3]" value= "1" />' assertOutputEquals('''<select name= "foo" id= "foo" > <option value= "1" selected= "selected" >1</option> <option value= "2" >2</option> <option value= "3" >3</option> </select>''', template) } void testMultiSelect() { def template = '<g:select name= "foo" from= "[1,2,3]" value= "[2,3]" />' assertOutputEquals('''<select name= "foo" id= "foo" multiple= " true " > <option value= "1" >1</option> <option value= "2" selected= "selected" >2</option> <option value= "3" selected= "selected" >3</option> </select>''', template) } Note you dont have to set multiple=true it just assumes that the case if the value is a collection (i don't see what else it could be other than a multi select in this case)
        Hide
        Alexandre Masselot added a comment -

        a short low invasive fix:
        my g:select name is remoteService, and I want to have default selecteion to 'neXtProt','IntAct':

        <jq:jquery>
        var sel = $('#remoteServices');
        <g:each in ="$

        {(params.remoteServices in String)?[params.remoteServices]:params.remoteServices?.toList()?:['neXtProt', 'IntAct'] }

        " var="s">
        sel.find('option[value="$

        {s }

        "]').attr('selected', 'selected');
        </g:each>
        </jq:jquery>

        Show
        Alexandre Masselot added a comment - a short low invasive fix: my g:select name is remoteService, and I want to have default selecteion to 'neXtProt','IntAct': <jq:jquery> var sel = $('#remoteServices'); <g:each in ="$ {(params.remoteServices in String)?[params.remoteServices]:params.remoteServices?.toList()?:['neXtProt', 'IntAct'] } " var="s"> sel.find('option[value="$ {s } "]').attr('selected', 'selected'); </g:each> </jq:jquery>

          People

          • Assignee:
            Graeme Rocher
            Reporter:
            Alain Perry
          • Votes:
            4 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development