Grails
  1. Grails
  2. GRAILS-1244

Incomplete INPUT Id and Name Support on GSP Form and Remote Tags

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 0.5
    • Fix Version/s: 1.0-RC1
    • Component/s: TagLib
    • Labels:
      None
    • Environment:
      Any
    • Patch Submitted:
      Yes

      Description

      All g:form tag elements, including remote tags (like remoteField) that support a NAME parameter should also support or imply the ID parameter. Some of the g:form tags do support or imply the ID parameter with a pattern similar to:

      attrs.id = attrs.id ? attrs.id : attrs.name

      That is, if the id is set, use the parameter, else set the id parameter to the name parameter.

      This really came back to bite me trying to use AJAX and the remoteField. I had to add the following fix to g:remoteField:

      def remoteField = { attrs, body ->
      def paramName = attrs.paramName ? attrs.remove('paramName') : 'value'
      def value = attrs.remove('value')
      if(!value) value = ''

      // FIX ON NEXT TWO LINES
      attrs.id = attrs.id ? attrs.id : attrs.name
      out << "<input type=\"text\" id=\"$

      {attrs.remove('id')}

      \" name=\"$

      {attrs.remove('name')}

      \" value=\"$

      {value}

      \" onkeyup=\""

      ...

      A few other tags in the library(-ies), like g:checkbox, also are missing proper name/id support.

        Activity

        Hide
        Clay Luther added a comment -

        The fix presented above isn't the best for remote tags. I noticed that the "real" problem is that Grails makes an assumption about what the "id" is, namely it's part of the controller-action-id trio. Thus, the remote tags expect and use id current to build the URI for the remote call. If the programmer wants to assign the actual DOM id of the resultant tag in the HTML view, he cannot. The fix above grants the second ability, but removes the current ability to specify controller-action-id.

        A more proper fix would be to make the remote* tags accept another ID, perhaps MYID, which is output as the ID of the tag:

        attrs.myid = attrs.myid ? attrs.myid : attrs.name
        out << "<input type=\"text\" id=\"$

        {attrs.remove('myid')}

        \" name=\"$

        {attrs.remove('name')}

        \" value=\"$

        {value}

        \" onkeyup=\"

        Show
        Clay Luther added a comment - The fix presented above isn't the best for remote tags. I noticed that the "real" problem is that Grails makes an assumption about what the "id" is, namely it's part of the controller-action-id trio. Thus, the remote tags expect and use id current to build the URI for the remote call. If the programmer wants to assign the actual DOM id of the resultant tag in the HTML view, he cannot. The fix above grants the second ability, but removes the current ability to specify controller-action-id. A more proper fix would be to make the remote* tags accept another ID, perhaps MYID, which is output as the ID of the tag: attrs.myid = attrs.myid ? attrs.myid : attrs.name out << "<input type=\"text\" id=\"$ {attrs.remove('myid')} \" name=\"$ {attrs.remove('name')} \" value=\"$ {value} \" onkeyup=\"
        Hide
        Nicholas Vaidyanathan added a comment -

        ..or using the name as the HTML id in the output stream and the model object id (which sadly has the id attribute...I never realized how much trouble Grails can cause by overloading id with its own meaning) for the remote link call.

        Calling this "fixed" when no proper workaround has been provided is nasty. I just got bitten by this by trying to do a jQuery selector in my own client side code where I expected the id to be set equal to the name.

        I've looked at https://github.com/grails/grails-core/blob/master/grails-plugin-gsp/src/main/groovy/org/codehaus/groovy/grails/plugins/web/taglib/JavascriptTagLib.groovy and https://github.com/grails/grails-core/blob/master/grails-plugin-gsp/src/main/groovy/org/codehaus/groovy/grails/plugins/web/taglib/FormTagLib.groovy

        I still don't understand why a simple refactoring:
        JavascriptTagLib.groovy (294) : out << "<input type=\"text\" name=\"$

        {attrs.remove('name')}

        \" value=\"$

        {value}\" onkeyup=\""

        to

        def nameAndId = attrs.remove('name')
        out << "<input type=\"text\" name=\"${nameAndId}\" id=\"${nameAndId} value=\"${value}

        \" onkeyup=\""

        doesn't fix this problem. The writing out the id as the name in the rendered HTML tag here does nothing to id attribute that's being passed to the other closures (I assume being used in the Javascript provider's doRemote()).

        Also, some meta analysis: Can you say nested dependency hell? remoteField calling remoteFunction calling doRemoteFunction with a global attr array that's being trimmed and modified ad hoc and random nested outputs everywhere?

        It's like the brilliant developers who leveraged the Spring framework with its DI and OOP principles to make this amazing framework suddenly got to the GSP side and gave up on Object Oriented Programming. I mean, every tag in a global namespace ("namespaces are a great honking idea", as Python says. If we put everything in g:, we kind of defeat the point), as methods, with nested calls that rely on other methods? What is this, PHP?

        Show
        Nicholas Vaidyanathan added a comment - ..or using the name as the HTML id in the output stream and the model object id (which sadly has the id attribute...I never realized how much trouble Grails can cause by overloading id with its own meaning) for the remote link call. Calling this "fixed" when no proper workaround has been provided is nasty. I just got bitten by this by trying to do a jQuery selector in my own client side code where I expected the id to be set equal to the name. I've looked at https://github.com/grails/grails-core/blob/master/grails-plugin-gsp/src/main/groovy/org/codehaus/groovy/grails/plugins/web/taglib/JavascriptTagLib.groovy and https://github.com/grails/grails-core/blob/master/grails-plugin-gsp/src/main/groovy/org/codehaus/groovy/grails/plugins/web/taglib/FormTagLib.groovy I still don't understand why a simple refactoring: JavascriptTagLib.groovy (294) : out << "<input type=\"text\" name=\"$ {attrs.remove('name')} \" value=\"$ {value}\" onkeyup=\"" to def nameAndId = attrs.remove('name') out << "<input type=\"text\" name=\"${nameAndId}\" id=\"${nameAndId} value=\"${value} \" onkeyup=\"" doesn't fix this problem. The writing out the id as the name in the rendered HTML tag here does nothing to id attribute that's being passed to the other closures (I assume being used in the Javascript provider's doRemote()). Also, some meta analysis: Can you say nested dependency hell? remoteField calling remoteFunction calling doRemoteFunction with a global attr array that's being trimmed and modified ad hoc and random nested outputs everywhere? It's like the brilliant developers who leveraged the Spring framework with its DI and OOP principles to make this amazing framework suddenly got to the GSP side and gave up on Object Oriented Programming. I mean, every tag in a global namespace ("namespaces are a great honking idea", as Python says. If we put everything in g:, we kind of defeat the point), as methods, with nested calls that rely on other methods? What is this, PHP?

          People

          • Assignee:
            Graeme Rocher
            Reporter:
            Clay Luther
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development