Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 4.1, 4.1.1
    • Fix Version/s: 4.1.1
    • Component/s: Framework, Web
    • Labels:
      None
    • Environment:
      Win XP, tomcat 5.5.17

      Description

      Got a problem with duplicate id's :

      <a jwcid="@DirectLink"
      listener="listener:setAvailable"
      id="ognl:currentHour.id"
      updateComponents="ognl:

      {'calendar'}

      "
      async="ognl:true"
      parameters="ognl:currentHour"
      class="setavailable">
      </a>

      When Tapestry render the HTML there are 2 id's in the code, and this gives the async update a javascript error.

      Want to make my own id because, the link will not be a link after the async update, and if I let Tapestry generate the id's, then the DirectLink id's will not be the same as before the update. And the AJAX/DOJO javascript is not updated, so the next time I click on a Link it will not be async.

        Activity

        Hide
        Jesse Kuhnert added a comment -

        I believe this was resolved recently, though I may still need to push a new snapshot out for people to see it.

        Show
        Jesse Kuhnert added a comment - I believe this was resolved recently, though I may still need to push a new snapshot out for people to see it.
        Hide
        Andy Yeung added a comment -

        I have tried the latest snapshot and found that the case is partly solved only.
        The dojo javascript is generated correctly. However for the directlink, the updateParts parameters is not generated correctly if I have 2 components with the same name. I have tried using

        {component.'name'.id}

        in the updateComponents but the output updateParts still be the name.

        Show
        Andy Yeung added a comment - I have tried the latest snapshot and found that the case is partly solved only. The dojo javascript is generated correctly. However for the directlink, the updateParts parameters is not generated correctly if I have 2 components with the same name. I have tried using {component.'name'.id} in the updateComponents but the output updateParts still be the name.
        Hide
        Andreas Andreou added a comment -

        how about using

        {component.'name'.clientId}

        ?

        Show
        Andreas Andreou added a comment - how about using {component.'name'.clientId} ?
        Hide
        Andy Yeung added a comment -

        Yes, I have tried that also. And I found out that the ajaxresponse started from 1 element nested within for the renamed component id.
        I have traced the problem until I reach the DojoAjaxReponseBuilder part, in the contains method, you check the renderStackIterator to found out whether there are component instance with the renamed ID in previous all parent rendered components. So the returned element will be 1 element nested within rather than the parent if the component is renamed. Also using this approach will cause the ajaxresponse to include more contents when updating the first component as the first checking condition use String id = getComponentId(target); where the clientId is the same as the id at that point.
        I am going to change that to use IRequestCycle.peekUniqueId(String baseId) to have a test.

        Show
        Andy Yeung added a comment - Yes, I have tried that also. And I found out that the ajaxresponse started from 1 element nested within for the renamed component id. I have traced the problem until I reach the DojoAjaxReponseBuilder part, in the contains method, you check the renderStackIterator to found out whether there are component instance with the renamed ID in previous all parent rendered components. So the returned element will be 1 element nested within rather than the parent if the component is renamed. Also using this approach will cause the ajaxresponse to include more contents when updating the first component as the first checking condition use String id = getComponentId(target); where the clientId is the same as the id at that point. I am going to change that to use IRequestCycle.peekUniqueId(String baseId) to have a test.
        Hide
        Andy Yeung added a comment -

        Tested and works. However I don't know whether this change will affect other use case.
        My use case is that I Use 2 RenderBlock to render the same Block. The Block contains a async DirectLink to update the message @Any +@ Insert within the block itself. (add @Any because @Insert wouldn't create Id in html and I think it is reasonable for not adding extra span tag in normal case just for the id)

        2 part of the code need to change in DojoAjaxResponseBuilder

        public IMarkupWriter getWriter(String id, String type)

        { .................. nestedWriter.attribute("id", _cycle.peekUniqueId(id)); .................. return nestedWriter; }

        public boolean contains(IComponent target)
        {
        if (target == null)
        return false;

        String id = getComponentId(target);
        String clientId = _cycle.peekUniqueId(id);

        if (_parts.contains(clientId))
        return true;

        // TO BE REMOVED
        // Iterator it = _cycle.renderStackIterator();
        // while (it.hasNext())

        { // // IComponent comp = (IComponent)it.next(); // String compId = getComponentId(comp); // // if (comp != target && _parts.contains(compId)) // return true; // }

        return false;
        }

        Show
        Andy Yeung added a comment - Tested and works. However I don't know whether this change will affect other use case. My use case is that I Use 2 RenderBlock to render the same Block. The Block contains a async DirectLink to update the message @Any +@ Insert within the block itself. (add @Any because @Insert wouldn't create Id in html and I think it is reasonable for not adding extra span tag in normal case just for the id) 2 part of the code need to change in DojoAjaxResponseBuilder public IMarkupWriter getWriter(String id, String type) { .................. nestedWriter.attribute("id", _cycle.peekUniqueId(id)); .................. return nestedWriter; } public boolean contains(IComponent target) { if (target == null) return false; String id = getComponentId(target); String clientId = _cycle.peekUniqueId(id); if (_parts.contains(clientId)) return true; // TO BE REMOVED // Iterator it = _cycle.renderStackIterator(); // while (it.hasNext()) { // // IComponent comp = (IComponent)it.next(); // String compId = getComponentId(comp); // // if (comp != target && _parts.contains(compId)) // return true; // } return false; }
        Hide
        Jesse Kuhnert added a comment -

        The For component and DojoAjaxResponseBuilder logic have been re-factored to properly handle these situations now. Please feel free to report back if the problem persists.

        Show
        Jesse Kuhnert added a comment - The For component and DojoAjaxResponseBuilder logic have been re-factored to properly handle these situations now. Please feel free to report back if the problem persists.
        Hide
        Andy Yeung added a comment -

        Tested and work. Thank you

        Show
        Andy Yeung added a comment - Tested and work. Thank you

          People

          • Assignee:
            Jesse Kuhnert
            Reporter:
            Frank Jørgensen
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development