You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Tony Nelson <tn...@starpoint.com> on 2013/03/19 17:40:20 UTC

Component Problem

I built a page with some pieces that I want to extract to a component. The pieces are parts of a form.  I'm not sure I'm taking the proper approach. My current idea is to use delegates and blocks.  My component template is:

<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
             xmlns:p="tapestry:parameter">


    <t:block t:id="clientBlock">
        <t:hidden t:id="clientId" value="client" />
        <t:textfield t:id="clientName" value="clientName" />
        <t:checkbox type="checkbox" t:id="includeInactiveClients" value="includeInactiveClients" />
    </t:block>

    <t:block t:id="divisionBlock">
        <t:hidden t:id="divisionId" value="division" />
        <t:textfield t:id="divisionName" value="divisionName" />
        <t:checkbox type="checkbox" t:id="includeInactiveDivisions" value="includeInactiveDivisions" />
    </t:block>

</t:container>


Then in the actual page, I want to use it like this:

            <div class="control-group">
                <label class="control-label">
                    Client:
                </label>
                <div class="controls">
                    <t:delegate to="block:clientBlock" />
                </div>
            </div>


And a similar block to divisionBlock.

Right now I'm getting a null pointer exception from Hidden.java when I try to get it's client id.  Specifically:

    @Import(library = { "ClientDivisionAutoComplete.js" })
    public void afterRender() {

        JSONObject specs = new JSONObject(
                "clientId", "#" + clientIdField.getClientId(),
                "clientName", "#" + clientNameField.getClientId(),
                "includeInactiveClients", "#" + includeInactiveClientsField.getClientId(),
                "clientNameAutoCompleteUrl", componentResources.createEventLink("clientNameAutoComplete").toURI(),
                "divisionId", "#" + divisionId.getClientId(),
                "divisionName", "#" + divisionNameField.getClientId(),
                "includeInactiveDivisions", "#" + includeInactiveDivisionsField.getClientId(),
                "divisionNameAutoCompleteUrl", componentResources.createEventLink("divisionNameAutoComplete").toURI()
        );

        javaScriptSupport.addInitializerCall("clientDivisionAutoComplete", specs);
    }


The exception I'm getting is:

Caused by: java.lang.NullPointerException
        at org.apache.tapestry5.corelib.components.Hidden.getClientId(Hidden.java:152)
        at com.starpoint.instihire.web.components.ClientDivisionAutoComplete.advised$afterRender_12ecdf1ecc23b3d1(ClientDivisionAutoComplete.java:128)
        at com.starpoint.instihire.web.components.ClientDivisionAutoComplete$Invocation_afterRender_12ecdf1ecc23b3d0.proceedToAdvisedMethod(Unknown Source)


Is my approach wrong?  This all works when I put it together in a single page, but I'm not having much luck extracting it to a component.

Thanks for your help in advance
Tony Nelson
Starpoint Solutions




Since 1982, Starpoint Solutions has been a trusted source of human capital and solutions. We are committed to our clients, employees, environment, community and social concerns.  We foster an inclusive culture based on trust, respect, honesty and solid performance. Learn more about Starpoint and our social responsibility at http://www.starpoint.com/social_responsibility

This email message from Starpoint Solutions LLC is for the sole use of  the intended recipient(s) and may contain confidential and privileged  information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.  Opinions, conclusions and other information in this message that do not relate to the official business of Starpoint Solutions shall be understood as neither given nor endorsed by it.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


RE: Component Problem

Posted by Tony Nelson <tn...@starpoint.com>.
The real problem I'm having is an encapsulation problem.

My component needs to have several html elements that work together, but where they exist on the page is driven by the page template, not the component template.  So in my component template I define 2 blocks

<t:block t:id="blocka">...</t:block>
<t:block t:id="blockb">..</t:block>

Then in the page template I'm trying to:

<t:mycomponent />
<t:delegate to="block:blocka" />

If I try reversing the lines, putting the delegate before my component, I get "Template .. does not contain a block with identifier "blocka"" .

When I put my component first (as above), I *think* what's happening, is that afterRender() is trying to access the clientId of a hidden component before the block has actually been rendered.  It won't get rendered until the actual page is fully evaluated.  Does that make sense?

As a test I renamed afterRender() in the component so it would not execute.  The next error I get is

Template for component report/FullTimeHire does not contain a block with the identifier 'clientBlock'

I guess the simple question is, does it even make sense to define a block a in a component and reference in the page template?  Has anyone done that?  Has anyone seen an example of it?

Thanks
Tony

> -----Original Message-----
> From: Howard Lewis Ship [mailto:hlship@gmail.com]
> Sent: Tuesday, March 19, 2013 4:48 PM
> To: Tapestry users
> Subject: Re: Component Problem
>
> Taking a peek:
>
>     public String getClientId()
>     {
>         if (clientId == null)
>         {
>             clientId = jsSupport.allocateClientId(resources);
>             hiddenInputElement.forceAttributes("id", clientId);  // Hidden.java,
> line 152
>         }
>
>         return clientId;
>     }
>
> An NPE there makes it look like the Hidden element has not yet rendered.
>
> It would be interesting to capture the MarkupWriter and see what markup
> has been written at the point your afterRender() method is invoked.
> Possibly, you are returned the wrong Block from clientBlock, so the Hidden
> component is never rendered.
>
>
> On Tue, Mar 19, 2013 at 9:40 AM, Tony Nelson <tn...@starpoint.com>
> wrote:
>
> > I built a page with some pieces that I want to extract to a component.
> > The pieces are parts of a form.  I'm not sure I'm taking the proper approach.
> > My current idea is to use delegates and blocks.  My component template is:
> >
> > <t:container
> xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
> >              xmlns:p="tapestry:parameter">
> >
> >
> >     <t:block t:id="clientBlock">
> >         <t:hidden t:id="clientId" value="client" />
> >         <t:textfield t:id="clientName" value="clientName" />
> >         <t:checkbox type="checkbox" t:id="includeInactiveClients"
> > value="includeInactiveClients" />
> >     </t:block>
> >
> >     <t:block t:id="divisionBlock">
> >         <t:hidden t:id="divisionId" value="division" />
> >         <t:textfield t:id="divisionName" value="divisionName" />
> >         <t:checkbox type="checkbox" t:id="includeInactiveDivisions"
> > value="includeInactiveDivisions" />
> >     </t:block>
> >
> > </t:container>
> >
> >
> > Then in the actual page, I want to use it like this:
> >
> >             <div class="control-group">
> >                 <label class="control-label">
> >                     Client:
> >                 </label>
> >                 <div class="controls">
> >                     <t:delegate to="block:clientBlock" />
> >                 </div>
> >             </div>
> >
> >
> > And a similar block to divisionBlock.
> >
> > Right now I'm getting a null pointer exception from Hidden.java when I
> > try to get it's client id.  Specifically:
> >
> >     @Import(library = { "ClientDivisionAutoComplete.js" })
> >     public void afterRender() {
> >
> >         JSONObject specs = new JSONObject(
> >                 "clientId", "#" + clientIdField.getClientId(),
> >                 "clientName", "#" + clientNameField.getClientId(),
> >                 "includeInactiveClients", "#" +
> > includeInactiveClientsField.getClientId(),
> >                 "clientNameAutoCompleteUrl",
> >
> componentResources.createEventLink("clientNameAutoComplete").toURI()
> ,
> >                 "divisionId", "#" + divisionId.getClientId(),
> >                 "divisionName", "#" + divisionNameField.getClientId(),
> >                 "includeInactiveDivisions", "#" +
> > includeInactiveDivisionsField.getClientId(),
> >                 "divisionNameAutoCompleteUrl",
> >
> componentResources.createEventLink("divisionNameAutoComplete").toURI
> ()
> >         );
> >
> >
> > javaScriptSupport.addInitializerCall("clientDivisionAutoComplete",
> > specs);
> >     }
> >
> >
> > The exception I'm getting is:
> >
> > Caused by: java.lang.NullPointerException
> >         at
> >
> org.apache.tapestry5.corelib.components.Hidden.getClientId(Hidden.java:1
> 52)
> >         at
> >
> com.starpoint.instihire.web.components.ClientDivisionAutoComplete.advise
> d$afterRender_12ecdf1ecc23b3d1(ClientDivisionAutoComplete.java:128)
> >         at
> >
> com.starpoint.instihire.web.components.ClientDivisionAutoComplete$Invo
> >
> cation_afterRender_12ecdf1ecc23b3d0.proceedToAdvisedMethod(Unknow
> n
> > Source)
> >
> >
> > Is my approach wrong?  This all works when I put it together in a
> > single page, but I'm not having much luck extracting it to a component.
> >
> > Thanks for your help in advance
> > Tony Nelson
> > Starpoint Solutions
> >
> >
> >
> >
> > Since 1982, Starpoint Solutions has been a trusted source of human
> > capital and solutions. We are committed to our clients, employees,
> > environment, community and social concerns.  We foster an inclusive
> > culture based on trust, respect, honesty and solid performance. Learn
> > more about Starpoint and our social responsibility at
> > http://www.starpoint.com/social_responsibility
> >
> > This email message from Starpoint Solutions LLC is for the sole use of
> > the intended recipient(s) and may contain confidential and privileged
> > information.  Any unauthorized review, use, disclosure or distribution
> > is prohibited.  If you are not the intended recipient, please contact
> > the sender by reply email and destroy all copies of the original message.
> >  Opinions, conclusions and other information in this message that do
> > not relate to the official business of Starpoint Solutions shall be
> > understood as neither given nor endorsed by it.
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>
>
> --
> Howard M. Lewis Ship
>
> Creator of Apache Tapestry
>
> The source for Tapestry training, mentoring and support. Contact me to learn
> how I can get you up and productive in Tapestry fast!
>
> (971) 678-5210
> http://howardlewisship.com

Since 1982, Starpoint Solutions has been a trusted source of human capital and solutions. We are committed to our clients, employees, environment, community and social concerns.  We foster an inclusive culture based on trust, respect, honesty and solid performance. Learn more about Starpoint and our social responsibility at http://www.starpoint.com/social_responsibility

This email message from Starpoint Solutions LLC is for the sole use of  the intended recipient(s) and may contain confidential and privileged  information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.  Opinions, conclusions and other information in this message that do not relate to the official business of Starpoint Solutions shall be understood as neither given nor endorsed by it.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Component Problem

Posted by Howard Lewis Ship <hl...@gmail.com>.
Taking a peek:

    public String getClientId()
    {
        if (clientId == null)
        {
            clientId = jsSupport.allocateClientId(resources);
            hiddenInputElement.forceAttributes("id", clientId);  //
Hidden.java, line 152
        }

        return clientId;
    }

An NPE there makes it look like the Hidden element has not yet rendered.

It would be interesting to capture the MarkupWriter and see what markup has
been written at the point your afterRender() method is invoked.  Possibly,
you are returned the wrong Block from clientBlock, so the Hidden component
is never rendered.


On Tue, Mar 19, 2013 at 9:40 AM, Tony Nelson <tn...@starpoint.com> wrote:

> I built a page with some pieces that I want to extract to a component. The
> pieces are parts of a form.  I'm not sure I'm taking the proper approach.
> My current idea is to use delegates and blocks.  My component template is:
>
> <t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
>              xmlns:p="tapestry:parameter">
>
>
>     <t:block t:id="clientBlock">
>         <t:hidden t:id="clientId" value="client" />
>         <t:textfield t:id="clientName" value="clientName" />
>         <t:checkbox type="checkbox" t:id="includeInactiveClients"
> value="includeInactiveClients" />
>     </t:block>
>
>     <t:block t:id="divisionBlock">
>         <t:hidden t:id="divisionId" value="division" />
>         <t:textfield t:id="divisionName" value="divisionName" />
>         <t:checkbox type="checkbox" t:id="includeInactiveDivisions"
> value="includeInactiveDivisions" />
>     </t:block>
>
> </t:container>
>
>
> Then in the actual page, I want to use it like this:
>
>             <div class="control-group">
>                 <label class="control-label">
>                     Client:
>                 </label>
>                 <div class="controls">
>                     <t:delegate to="block:clientBlock" />
>                 </div>
>             </div>
>
>
> And a similar block to divisionBlock.
>
> Right now I'm getting a null pointer exception from Hidden.java when I try
> to get it's client id.  Specifically:
>
>     @Import(library = { "ClientDivisionAutoComplete.js" })
>     public void afterRender() {
>
>         JSONObject specs = new JSONObject(
>                 "clientId", "#" + clientIdField.getClientId(),
>                 "clientName", "#" + clientNameField.getClientId(),
>                 "includeInactiveClients", "#" +
> includeInactiveClientsField.getClientId(),
>                 "clientNameAutoCompleteUrl",
> componentResources.createEventLink("clientNameAutoComplete").toURI(),
>                 "divisionId", "#" + divisionId.getClientId(),
>                 "divisionName", "#" + divisionNameField.getClientId(),
>                 "includeInactiveDivisions", "#" +
> includeInactiveDivisionsField.getClientId(),
>                 "divisionNameAutoCompleteUrl",
> componentResources.createEventLink("divisionNameAutoComplete").toURI()
>         );
>
>         javaScriptSupport.addInitializerCall("clientDivisionAutoComplete",
> specs);
>     }
>
>
> The exception I'm getting is:
>
> Caused by: java.lang.NullPointerException
>         at
> org.apache.tapestry5.corelib.components.Hidden.getClientId(Hidden.java:152)
>         at
> com.starpoint.instihire.web.components.ClientDivisionAutoComplete.advised$afterRender_12ecdf1ecc23b3d1(ClientDivisionAutoComplete.java:128)
>         at
> com.starpoint.instihire.web.components.ClientDivisionAutoComplete$Invocation_afterRender_12ecdf1ecc23b3d0.proceedToAdvisedMethod(Unknown
> Source)
>
>
> Is my approach wrong?  This all works when I put it together in a single
> page, but I'm not having much luck extracting it to a component.
>
> Thanks for your help in advance
> Tony Nelson
> Starpoint Solutions
>
>
>
>
> Since 1982, Starpoint Solutions has been a trusted source of human capital
> and solutions. We are committed to our clients, employees, environment,
> community and social concerns.  We foster an inclusive culture based on
> trust, respect, honesty and solid performance. Learn more about Starpoint
> and our social responsibility at
> http://www.starpoint.com/social_responsibility
>
> This email message from Starpoint Solutions LLC is for the sole use of
>  the intended recipient(s) and may contain confidential and privileged
>  information.  Any unauthorized review, use, disclosure or distribution is
> prohibited.  If you are not the intended recipient, please contact the
> sender by reply email and destroy all copies of the original message.
>  Opinions, conclusions and other information in this message that do not
> relate to the official business of Starpoint Solutions shall be understood
> as neither given nor endorsed by it.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>


-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com