You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Jim Menard <ji...@io.com> on 2004/02/20 01:55:35 UTC

Multiple copies of a component

I have an advanced search page. There are two different dates to search 
by, and for each one I want something like

	() on [date]
	() between [date] and [date]
	() [month] [year]

To me, this screams "build a component". I'm puzzled, though: how can I 
use the component twice on the same page and have each component set 
different properties in the page?

In other words, how do I get the first component to send its "date" 
value to the page's "uploadPhotoDate" value and get the second 
component to send its "date" value to the page's "originalPhotoDate" 
value?

Thank you for your help.

Jim
-- 
Jim Menard, jimm@io.com, http://www.io.com/~jimm/
"Congratulations are in order for Tom Reid. He says he just found out 
he is
the winner of the 2021 Psychic of the Year award." -- Seen on slashdot


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


Re: Multiple copies of a component

Posted by Jim Menard <ji...@io.com>.
On Feb 19, 2004, at 8:36 PM, Jonny Wray wrote:

> In your new component jwc file
>
> <parameter name="startDate" type="java.util.Date" required="yes" />
>
> <component id="startDate" type="DatePicker">
>     <inherited-binding name="value" parameter-name="startDate" />
> </component>
>
> etc.... for the rest (I'd put all 8 into one class and bind these
> classes rather than all the individual elements).
>
> Then in the page you can bind the actual page variables to the new
> component startDate etc.

I think I understand. So the .page would be

	<component id="uploadDateThing" type="MyDateComponent">
	  <binding name="startDate" value="uploadStartDate"/>
	  <binding name="endDate" value="uploadEndDate"/>
	</component>

	<component id="origDateThing" type="MyDateComponent">
	  <binding name="startDate" value="origStartDate"/>
	  <binding name="endDate" value="origEndDate"/>
	</component>

Right?

Thank you again for your help.

Jim
-- 
Jim Menard, jimm@io.com, http://www.io.com/~jimm/
"Good code in perl is fine, but there's something about bad code in perl
that's worse than bad code in other languages, something very HP-
Lovecraft-mad-servants-of-the-elder-gods-chattering-in-the-
extradimensional-insect-language kind of bad that makes my head hurt 
when I have to read it." -- Jish Karoshi in comp.lang.ruby


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


Re: Solved (Was Re: Multiple copies of a component (class for fields))

Posted by Jonny Wray <jo...@yahoo.com>.
Jim,

glad you figured it out. Sorry, I'd assumed you had your own page class
with the two instances of your bean, each bound to the different
instance of your component. One thing. In your page you can reduce java
code and have the framework deal with initialization details by
declaring the class abstract, providing two abstract methods (get and
set choices)  and declaring a property-specification eg

<property-specification name="choices"
type="com.preclick.photowiki.search.DateChoices" />

This is probably more important for persistant properties, but works
with non-peristant to reduce the LOC.

As for inherited-binding vs normal, now you have me having to go 
back to the docs and figure out the difference. Anyone else care to
explain the difference?

Jonny

--- Jim Menard <ji...@io.com> wrote:
> Solved! Thank you, Jonny.
> 
> I needed to make the component-specification a new class, not a  
> BaseComponent. The new class does nothing more than hold an instance
> of  
> the DateChoices object (the bean with the eight fields).
> 
> Then each component needed to use binding normally, not  
> inherited-binding, with expressions like "choices.year" and  
> "choices.startDate".
> 
> Here's the snippet from the page's .page:
> 
>    <component id="uploadDateChoices" type="SearchDate">
>      <binding name="choices" expression="uploadDateChoices"/>
>    </component>
> 
>    <component id="origDateChoices" type="SearchDate">
>      <binding name="choices" expression="origDateChoices"/>
>    </component>
> 
> Here's the part of the component's .jwc:
> 
> <component-specification
>          class="com.preclick.photowiki.tapestry.component.SearchDate"
>          allow-informal-parameters="no">
> 
>    <parameter name="choices" required="yes" direction="in"
>          java-type="com.preclick.photowiki.search.DateChoices"/>
> 
>    <component id="radioGroup" type="RadioGroup">
>      <binding name="selected" expression="choices.which"/>
>    </component>
> 
>    <!-- ... -->
> 
>    <component id="endDate" type="DatePicker">
>      <binding name="value" expression="choices.endDate"/>
>    </component>
> 
>    <component id="monthMenu" type="PropertySelection">
>      <binding name="value" expression="choices.monthEnum"/>
>      <binding name="model"
>           
>
expression="@com.preclick.photowiki.tapestry.page.AdvancedSearchPage@MON
> 
> TH_MENU_MODEL"/>
>    </component>
> 
>    <component id="year" type="TextField">
>      <binding name="value" expression="choices.year"/>
>    </component>
> 
> </component-specification>
> 
> Finally, here's the entire SearchDate.java file, sans comments:
> 
> 	package com.preclick.photowiki.tapestry.component;
> 	import com.preclick.photowiki.search.DateChoices;
> 	import org.apache.tapestry.BaseComponent;
> 
> 	public class SearchDate extends BaseComponent {
> 
> 	protected DateChoices choices;
> 
> 	public DateChoices getChoices() { return choices; }
> 	public void setChoices(DateChoices dc) { choices = dc; }
> 
> 	}
> 
> 
> Thank you, Jonny.
> 
> Jim
> -- 
> Jim Menard, jimm@io.com, http://www.io.com/~jimm/
> "COGITO, EGGO SUM." I think, therefore I am a waffle.
>     -- .sig of Mr. Ska on Slashdot.org
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail:
> tapestry-user-help@jakarta.apache.org
> 


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


Solved (Was Re: Multiple copies of a component (class for fields))

Posted by Jim Menard <ji...@io.com>.
Solved! Thank you, Jonny.

I needed to make the component-specification a new class, not a  
BaseComponent. The new class does nothing more than hold an instance of  
the DateChoices object (the bean with the eight fields).

Then each component needed to use binding normally, not  
inherited-binding, with expressions like "choices.year" and  
"choices.startDate".

Here's the snippet from the page's .page:

   <component id="uploadDateChoices" type="SearchDate">
     <binding name="choices" expression="uploadDateChoices"/>
   </component>

   <component id="origDateChoices" type="SearchDate">
     <binding name="choices" expression="origDateChoices"/>
   </component>

Here's the part of the component's .jwc:

<component-specification
         class="com.preclick.photowiki.tapestry.component.SearchDate"
         allow-informal-parameters="no">

   <parameter name="choices" required="yes" direction="in"
         java-type="com.preclick.photowiki.search.DateChoices"/>

   <component id="radioGroup" type="RadioGroup">
     <binding name="selected" expression="choices.which"/>
   </component>

   <!-- ... -->

   <component id="endDate" type="DatePicker">
     <binding name="value" expression="choices.endDate"/>
   </component>

   <component id="monthMenu" type="PropertySelection">
     <binding name="value" expression="choices.monthEnum"/>
     <binding name="model"
          
expression="@com.preclick.photowiki.tapestry.page.AdvancedSearchPage@MON 
TH_MENU_MODEL"/>
   </component>

   <component id="year" type="TextField">
     <binding name="value" expression="choices.year"/>
   </component>

</component-specification>

Finally, here's the entire SearchDate.java file, sans comments:

	package com.preclick.photowiki.tapestry.component;
	import com.preclick.photowiki.search.DateChoices;
	import org.apache.tapestry.BaseComponent;

	public class SearchDate extends BaseComponent {

	protected DateChoices choices;

	public DateChoices getChoices() { return choices; }
	public void setChoices(DateChoices dc) { choices = dc; }

	}


Thank you, Jonny.

Jim
-- 
Jim Menard, jimm@io.com, http://www.io.com/~jimm/
"COGITO, EGGO SUM." I think, therefore I am a waffle.
    -- .sig of Mr. Ska on Slashdot.org


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


Re: Multiple copies of a component (class for fields)

Posted by Jim Menard <ji...@io.com>.
I'm really close to getting this to work. I'm stuck by this error  
message:

Required parameter value of component  
AdvancedSearch/origDateChoices.monthMenu is not bound.

Here's the search page .page snippet:

   <component id="uploadDateChoices" type="SearchDate">
     <binding name="choices" expression="uploadDateChoices"/>
   </component>

   <component id="origDateChoices" type="SearchDate">
     <binding name="choices" expression="origDateChoices"/>
   </component>

Here's the component .jwc file, minus the XML and DOCTYPE. Sorry for  
posting so much, but I can't see the difference between the monthMenu  
component and all the rest of the components.

<component-specification
         class="org.apache.tapestry.BaseComponent"
         allow-informal-parameters="no">

   <parameter name="choices"
         java-type="com.preclick.photowiki.search.DateChoices"
         required="yes"/>
   <!-- the DateChoices class is a simple bean-type Java class -->

   <component id="radioGroup" type="RadioGroup">
     <inherited-binding name="selected" parameter-name="choices.which"/>
   </component>

   <component id="radioNoDate" type="Radio">
     <binding name="value" expression="0"/>
   </component>

   <component id="radioOnDate" type="Radio">
     <binding name="value" expression="1"/>
   </component>

   <component id="radioBetweenDates" type="Radio">
     <binding name="value" expression="2"/>
   </component>

   <component id="radioInMonth" type="Radio">
     <binding name="value" expression="3"/>
   </component>

   <component id="date" type="DatePicker">
     <inherited-binding name="value" parameter-name="choices.date"/>
   </component>

   <component id="startDate" type="DatePicker">
     <inherited-binding name="value" parameter-name="choices.startDate"/>
   </component>

   <component id="endDate" type="DatePicker">
     <inherited-binding name="value" parameter-name="choices.endDate"/>
   </component>

   <component id="monthMenu" type="PropertySelection">
     <inherited-binding name="value" parameter-name="choices.month"/>
     <binding name="model"
          
expression="@com.preclick.photowiki.tapestry.page.AdvancedSearchPage@MON 
TH_MENU_MODEL"/>
   </component>

   <component id="year" type="TextField">
     <inherited-binding name="value" parameter-name="choices.year"/>
   </component>

</component-specification>

Thanks for any suggestions you have.

Jim
-- 
Jim Menard, jimm@io.com, http://www.io.com/~jimm/
DataVision, the Open Source report designer.
http://datavision.sourceforge.net


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


Re: Multiple copies of a component (class for fields)

Posted by Jim Menard <ji...@io.com>.
On Feb 19, 2004, at 9:30 PM, Jonny Wray wrote:

> I think you got what I meant. Just to be sure:
>
> I'd create a java bean (say SearchParameters) with all the 8 required 
> search
> parameters. Then, on the page:
>
> <span jwcid="@YourSearchComponent" 
> expression="ognl:searchParametersOne" />
> <span jwcid="@YourSearchComponent" 
> expression="ognl:searchParametersTwo" />
>
> Then in the jwc for YourSearchComponent:
>
> <parameter name="parameters type="yourpackage.SearchParameters"
> required="yes" />
>
> <component id="startDate" type="DatePicker"
>     <inherited-binding name="value" 
> parameter-name="parameters.startDate" />
> </component>

Hmm. I don't understand the need for the parameter or how it's being 
used. I have to study the Tapestry docs some more.

Again, thank you for all of your time and help. I'm going to bed.

Jim
-- 
Jim Menard, jimm@io.com, http://www.io.com/~jimm/
"I've memorized all the digits of pi. Just not the order they go in."
     -- Charles A. Lieberman, in rec.humor.oracle.d


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


Re: Multiple copies of a component (class for fields)

Posted by Jonny Wray <jo...@yahoo.com>.
I think you got what I meant. Just to be sure:

I'd create a java bean (say SearchParameters) with all the 8 required search
parameters. Then, on the page:

<span jwcid="@YourSearchComponent" expression="ognl:searchParametersOne" />
<span jwcid="@YourSearchComponent" expression="ognl:searchParametersTwo" />

Then in the jwc for YourSearchComponent:

<parameter name="parameters type="yourpackage.SearchParameters"
required="yes" />

<component id="startDate" type="DatePicker"
    <inherited-binding name="value" parameter-name="parameters.startDate" />
</component>

Etc. for the other elements of YourSearchComponent

On 2/19/04 6:16 PM, "Jim Menard" <ji...@io.com> wrote:

>> In your new component jwc file
>> 
>> <parameter name="startDate" type="java.util.Date" required="yes" />
>> 
>> <component id="startDate" type="DatePicker">
>>     <inherited-binding name="value" parameter-name="startDate" />
>> </component>
>> 
>> etc.... for the rest (I'd put all 8 into one class and bind these
>> classes rather than all the individual elements).
> 
> I'm not exactly sure what you mean by this. I already created a class
> to hold all eight elements. How would I bind the component with eight
> widgets to the class with eight fields (I know how to do that), yet
> still have each instance of the class appear separately to the page?
> 
> I have DateChoices.java, the container:
> 
> protected Date startDate;
> protected Date endDate;
> protected int month;
> protected int year;
> // ... more ...
> 
> // ... accessor methods
> 
> I can create DateChoiceWidget.java, the component:
> 
> protected DateChoice choice;
> // example methods:
> public Date getStartDate() { return choice.getStartDate(); }
> public int getMonth() { return choice.getMonth(); }
> 
> This goes back to my original question, though: how can I use the
> component twice on the same page and have each component set different
> properties in the page?
> 
> Wait a minute! Can I make my page have methods like
> 
> DateChoiceWidget uploadWidget;
> DateChoiceWidget origWidget;
> 
> public DateChoices getUploadDateChoicesWidget() {
> return uploadWidget;
> }
> public void setUploadDateChoices(DateChoices dc) {
> uploadWidget = dc;
> }
> 
> and have the .page file do
> 
> <component id="uploadDateChoice" type="MyDateChoicesWidget">
>  <binding name="value" expression="uploadDateChoicesWidget"/>
> </component>
> 
> Does that make sense? Well, I'm gonna go try it.
> 
> Thanks again.
> 
> Jim


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


Re: Multiple copies of a component (class for fields)

Posted by Jim Menard <ji...@io.com>.
> In your new component jwc file
>
> <parameter name="startDate" type="java.util.Date" required="yes" />
>
> <component id="startDate" type="DatePicker">
>     <inherited-binding name="value" parameter-name="startDate" />
> </component>
>
> etc.... for the rest (I'd put all 8 into one class and bind these
> classes rather than all the individual elements).

I'm not exactly sure what you mean by this. I already created a class 
to hold all eight elements. How would I bind the component with eight 
widgets to the class with eight fields (I know how to do that), yet 
still have each instance of the class appear separately to the page?

I have DateChoices.java, the container:

	protected Date startDate;
	protected Date endDate;
	protected int month;
	protected int year;
	// ... more ...

	// ... accessor methods

I can create DateChoiceWidget.java, the component:

	protected DateChoice choice;
	// example methods:
	public Date getStartDate() { return choice.getStartDate(); }
	public int getMonth() { return choice.getMonth(); }

This goes back to my original question, though: how can I use the 
component twice on the same page and have each component set different 
properties in the page?

Wait a minute! Can I make my page have methods like

	DateChoiceWidget uploadWidget;
	DateChoiceWidget origWidget;

	public DateChoices getUploadDateChoicesWidget() {
		return uploadWidget;
	}
	public void setUploadDateChoices(DateChoices dc) {
		uploadWidget = dc;
	}

and have the .page file do

	<component id="uploadDateChoice" type="MyDateChoicesWidget">
	  <binding name="value" expression="uploadDateChoicesWidget"/>
	</component>

Does that make sense? Well, I'm gonna go try it.

Thanks again.

Jim
-- 
Jim Menard, jimm@io.com, http://www.io.com/~jimm/
As a math major, I don't have to be able to add -- I just have to be 
able
to PROVE that I can add.


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


Re: Multiple copies of a component

Posted by Jonny Wray <jo...@yahoo.com>.
Ah, thought that was too simple an answer.

As for your real question. 

In your new component jwc file

<parameter name="startDate" type="java.util.Date" required="yes" />

<component id="startDate" type="DatePicker">
    <inherited-binding name="value" parameter-name="startDate" />
</component>

etc.... for the rest (I'd put all 8 into one class and bind these
classes rather than all the individual elements).

Then in the page you can bind the actual page variables to the new
component startDate etc.

--- Jim Menard <ji...@io.com> wrote:
> On Feb 19, 2004, at 8:08 PM, Jonny Wray wrote:
> 
> >
> > Unless I'm missing what you mean, this should work:
> >
> > <span jwcid="@DatePicker" value="ognl:uploadPhotoDate"/>
> > <span jwcid="@DatePicker" value="ognl:originalPhotoDate"/>
> 
> Thanks, but I want to create a new component that contains the three 
> choices (a total of 8 input fields). Then I want to use that new 
> component two times, one for each of the two different date searches
> in 
> my advanced search page.
> 
> I want the new component to be something like
> 
> <span jwcid="radioGroup">
> 
>    <span jwcid="radioNoDate"/> 
>    <span key="none"/><br>
> 
>    <span jwcid="radioOnDate"/> 
>    <span key="on"/> <input jwcid="date"/><br>
> 
>    <span jwcid="radioBetweenDates"/> 
>    <span key="between"/>  
>    <input jwcid="startDate"/>   <span key="and"/>
>    <input jwciid="endDate"/><br>
> 
>    <span jwcid="radioInMonth"/> 
>    <span key="monthMenu"/> <input jwcid="year"/>
> 
> </span>
> 
> and then the advanced search page could have
> 
> <span jwcid="uploadPhotoDateChoices"/>
> <span jwcid="originalPhotoDateChoices"/>
> 
> with the advanced search .page file containing
> 
> <component id="uploadPhotoDateChoices" type="MyNewDateComponent">
>    <binding ?????? />
> </component>
> 
> <component id="uploadPhotoDateChoices" type="MyNewDateComponent">
>    <binding ?????? />
> </component>
> 
> 
> 
> Jim
> -- 
> Jim Menard, jimm@io.com, http://www.io.com/~jimm/
> Dash dash space newline
> Four-line witty quotation
> Perfect message end
> -- Donald Welsh in rec.humor.oracle.d
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail:
> tapestry-user-help@jakarta.apache.org
> 


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


Re: Multiple copies of a component

Posted by Jim Menard <ji...@io.com>.
On Feb 19, 2004, at 8:08 PM, Jonny Wray wrote:

>
> Unless I'm missing what you mean, this should work:
>
> <span jwcid="@DatePicker" value="ognl:uploadPhotoDate"/>
> <span jwcid="@DatePicker" value="ognl:originalPhotoDate"/>

Thanks, but I want to create a new component that contains the three 
choices (a total of 8 input fields). Then I want to use that new 
component two times, one for each of the two different date searches in 
my advanced search page.

I want the new component to be something like

<span jwcid="radioGroup">

   <span jwcid="radioNoDate"/>&#32;
   <span key="none"/><br>

   <span jwcid="radioOnDate"/>&#32;
   <span key="on"/>&#32;<input jwcid="date"/><br>

   <span jwcid="radioBetweenDates"/>&#32;
   <span key="between"/> &#32;
   <input jwcid="startDate"/> &#32; <span key="and"/>
   <input jwciid="endDate"/><br>

   <span jwcid="radioInMonth"/>&#32;
   <span key="monthMenu"/> <input jwcid="year"/>

</span>

and then the advanced search page could have

<span jwcid="uploadPhotoDateChoices"/>
<span jwcid="originalPhotoDateChoices"/>

with the advanced search .page file containing

<component id="uploadPhotoDateChoices" type="MyNewDateComponent">
   <binding ?????? />
</component>

<component id="uploadPhotoDateChoices" type="MyNewDateComponent">
   <binding ?????? />
</component>



Jim
-- 
Jim Menard, jimm@io.com, http://www.io.com/~jimm/
Dash dash space newline
Four-line witty quotation
Perfect message end
-- Donald Welsh in rec.humor.oracle.d


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


Re: Multiple copies of a component

Posted by Jonny Wray <jo...@yahoo.com>.
Unless I'm missing what you mean, this should work:

<span jwcid="@DatePicker" value="ognl:uploadPhotoDate"/>
<span jwcid="@DatePicker" value="ognl:originalPhotoDate"/>

--- Jim Menard <ji...@io.com> wrote:
> I have an advanced search page. There are two different dates to
> search 
> by, and for each one I want something like
> 
> 	() on [date]
> 	() between [date] and [date]
> 	() [month] [year]
> 
> To me, this screams "build a component". I'm puzzled, though: how can
> I 
> use the component twice on the same page and have each component set 
> different properties in the page?
> 
> In other words, how do I get the first component to send its "date" 
> value to the page's "uploadPhotoDate" value and get the second 
> component to send its "date" value to the page's "originalPhotoDate" 
> value?
> 
> Thank you for your help.
> 
> Jim
> -- 
> Jim Menard, jimm@io.com, http://www.io.com/~jimm/
> "Congratulations are in order for Tom Reid. He says he just found out
> 
> he is
> the winner of the 2021 Psychic of the Year award." -- Seen on
> slashdot
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail:
> tapestry-user-help@jakarta.apache.org
> 


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