[ 
https://issues.apache.org/jira/browse/TAP5-1746?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Christian Riedel updated TAP5-1746:
-----------------------------------

    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:

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

--> 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.

  was:
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.

    
> Zone-Update inside a form inside a block (with generated ids) not working
> -------------------------------------------------------------------------
>
>                 Key: TAP5-1746
>                 URL: https://issues.apache.org/jira/browse/TAP5-1746
>             Project: Tapestry 5
>          Issue Type: Bug
>          Components: tapestry-core
>    Affects Versions: 5.3
>            Reporter: Christian Riedel
>            Priority: Critical
>
> 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:
> {noformat}
>     <t:zone t:id="outerZone">
>         <t:delegate t:to="block" />
>     </t:zone>
> {noformat}
> --> 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.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to