Uploaded image for project: 'Tapestry 5'
  1. Tapestry 5
  2. TAP5-1746

Zone-Update inside a form inside a block (with generated ids) not working

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Critical
    • Resolution: Not A Problem
    • 5.3
    • None
    • tapestry-core
    • None

    Description

      Zone-Updates are not working under certain conditions when being rendered inside a block.

      If an outer zone receives a zone-update the components inside the content of the delegated block will have generated ids:

      <t:zone t:id="outerZone">
      <t:delegate t:to="block" />
      </t:zone>

      --> after a zone-update the "block" property resolves to the following block:

      <t:block t:id="editBlock">
      <t:form t:id="editForm">

      <t:select t:id="updateSelectBox" t:model="values" t:value="selected" t:zone="updateZone" />

      <t:zone t:id="updateZone">
      <t:select t:id="theOtherValue" t:model="otherValues" t:value="other" blankOption="never" />
      </t:zone>

      </t:form>
      </t:block>

      The select component "updateSelectBox" won't find the zone "updateZone" since the real clientId has a randomly generated number appended.
      To circumvent this feature one can write a getter to obtain the generated id each time the block renders:

      <t:select t:id="updateSelectBox" t:model="values" t:value="selected" t:zone="prop:updateZoneId" />

      public String getUpdateZoneId()

      { return updateZone.getClientId(); }

      However, this won't work as expected, either.
      Firstly because the clientId is always null at that point. It's being called before the zone's beginRender method is invoked.
      Secondly because you need this client id in the event handler as well. Even if you'd be able to get the id at this point, the execution of the processReply method in tapestry.js will fail because it can't find the zone. The id has been generated once more and is not yet known to the client:

      @OnEvent(component = "updateSelectBox", value = EventConstants.VALUE_CHANGED)
      void onValueSelected()

      { // this will also fail on the client side ajaxResponseRenderer.addRender(getUpdateZoneId(), updateZone); }

      Now what I found being the only workaround is to store the client id once it's generated, i.e. when the block renders the first time.
      But as I stated earlier the id is null before beginRender is called. So another workaround must be applied:

      Switch the order of the components:

      <t:block t:id="editBlock">
      <t:form t:id="editForm">

      <t:zone t:id="updateZone">
      <t:select t:id="theOtherValue" t:model="otherValues" t:value="other" blankOption="never" />
      </t:zone>

      <t:select t:id="updateSelectBox" t:model="values" t:value="selected" t:zone="prop:updateZoneId" />

      </t:form>
      </t:block>

      Now that the "updateZone" renders before the "updateSelectBox", "prop:updateZoneId" is able to return the correct id.

      Please make the first example work! It should not be necessary to deal with the generated ids. Tapestry.js should implement some magic-code to find out the correct zone if "updateZone" is referenced in the template. Since all components within the same block have the same generated value appended it might actually be possible to find the correct zone.

      Attachments

        Activity

          People

            Unassigned Unassigned
            criedel Christian Riedel
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: