dev@jsftemplating.java.net

Re: JSFTemplating: Dynamic table question

From: Ken Paulsen <Ken.Paulsen_at_Sun.COM>
Date: Sun, 16 Mar 2008 14:21:10 -0700

Yes.

And if you do need to pass data out of the handler, you can do that just
like any other handler. But the framework itself doesn't need any value
that returned.

Ken

Karam Singh Badesha wrote:
> Ken,
>
> > Do you mean update to make the table data change when you click a
> button/link? If so, you'll need to either navigate back to the same
> page with different data to the page, or you'll need to write a
> handler to get the DataProvider associated with each tableRowGroup and
> make changes to the data which the table is based on manually.
>
> createTRGs function doesn't have a return type. So I was wondering
> what part of the code in that function is actually creating the table
> row groups. Is it the following:
> UIComponent rowGroup =
> ComponentUtil.createChildComponent(facesContext, desc, table);
>
> -Karam
>
> Ken Paulsen wrote:
>>
>> Hi Karam,
>>
>> Good questions, see responses below.
>>
>> Karam Singh wrote:
>>>
>>> Some minor questions:
>>> - how would I add the data property using the desc.addOption(key,
>>> value)? The reason I am asking is because on the jsf page there is
>>> "{}" outside of quotes. For others I am assuming I will just do
>>> desc.addOption("sourceVar", "tRow")
>> {"a", "b", "c"} becomes a List<String>, in Java code, you'll need to
>> pass in the List<String>, not the {} syntax.
>>
>>> - what part of handler code will update the table data? Is there a
>>> method that I need to call to make that happen or it automatic.
>>
>> Do you mean update to make the table data change when you click a
>> button/link? If so, you'll need to either navigate back to the same
>> page with different data to the page, or you'll need to write a
>> handler to get the DataProvider associated with each tableRowGroup
>> and make changes to the data which the table is based on manually.
>> Thanks!
>>
>> Ken
>>>
>>>
>>>
>>>
>>> Ken,
>>> Let me recap:
>>>
>>> On the jsf page I would have:
>>>
>>> <sun:table id="table1" title="#">
>>> <!afterCreate
>>> createChildDynamicColumnRowGroups(table="$this{component}");
>>> />
>>> </sun:table>
>>>
>>> and the handler would have:
>>>
>>> public static void createTRGs(HandlerContext context) {
>>> LayoutElement parentLE = context.getLayoutElement();
>>> UIComponent parent = (UIComponent)
>>> context.getInputValue("table");
>>> // Create the dynamicColumnRowGroup(s)
>>> ComponentType type =
>>> LayoutDefinitionManager.getGlobalComponentType("sun:dynamicColumnRowGroup");
>>>
>>> for (Object yourData : listOfYourData) {
>>> LayoutComponent desc = new LayoutComponent(parentLE,
>>> yourData.getId(), type);
>>> for (.... : listOfProperties) {
>>> // Add each property that would normally appear in the .jsf
>>> file, i.e:
>>> // <sun:dynamicColumnRowGroup ... property1="value1"
>>> property2="value2"...
>>> desc.addOption(key, value);
>>> }
>>>
>>> // Create and add child component (dynamicColumnRowGroup)
>>> UIComponent rowGroup = ComponentUtil.createChildComponent(
>>> facesContext, desc, table);
>>> }
>>> ...
>>> }
>>>
>>> Some minor questions:
>>> - how would I add the data property using the desc.addOption(key,
>>> value)? The reason I am asking is because on the jsf page there is
>>> "{}" outside of quotes. For others I am assuming I will just do
>>> desc.addOption("sourceVar", "tRow")
>>>
>>> - what part of handler code will update the table data? Is there a
>>> method that I need to call to make that happen or it automatic.
>>>
>>> thanks
>>> Karam
>>>
>>>
>>> Ken Paulsen wrote:
>>>>
>>>> Hi Karam,
>>>>
>>>> #3 (handler approach) would be something like:
>>>>
>>>> <sun:table id="..." ....>
>>>> <!afterCreate
>>>> createChildDynamicColumnRowGroups(yourData="...",
>>>> moreData="...");
>>>> />
>>>> </sun:table>
>>>>
>>>> You could pass in any data you want to help you know how many table
>>>> row groups to create, or the data needed to pass to the individual
>>>> table row groups. You could also pass in the table itself
>>>> (table="$this{component}") if you want. In the Handler Java code,
>>>> you can get those parameter values by doing:
>>>>
>>>> public static void createTRGs(HandlerContext context) {
>>>> LayoutElement parentLE = context.getLayoutElement();
>>>> UIComponent parent = (UIComponent)
>>>> context.getEventObject().getSource();
>>>> // OR if you passed in the table via "table":
>>>> UIComponent parent = (UIComponent)
>>>> context.getInputValue("table");
>>>> Object yourData = context.getInputValue("yourData");
>>>> Object moreData = context.getInputValue("moreData");
>>>> ...
>>>> }
>>>>
>>>> You can use the data you pass in (yourData, moreData, etc.) to do
>>>> what you need to do. The "parentLE" is what should be passed in
>>>> instead of (null) to the LayoutComponent(...) constructor in the
>>>> previous email code. The rest is the same as the code I previously
>>>> emailed.
>>>>
>>>> Ken
>>>>
>>>> Karam Singh wrote:
>>>>> Ken,
>>>>> I would like to go with option # 3 :)
>>>>> Can you explain it a little (mostly inputs & outputs) ?
>>>>>
>>>>> thanks
>>>>> Karam
>>>>>
>>>>> Ken Paulsen wrote:
>>>>>>
>>>>>> In a JSFTemplating page:
>>>>>>
>>>>>> <sun:table ... binding="bean.table" />
>>>>>>
>>>>>> In your Bean.getTable() method:
>>>>>>
>>>>>> public Table getTable() {
>>>>>> Table table = ...;
>>>>>> ...
>>>>>> // Create the DynamicColumnRowGroup(s)
>>>>>> ComponentType type =
>>>>>> LayoutDefinitionManager.getGlobalComponentType("sun:dynamicColumnRowGroup");
>>>>>>
>>>>>> for (Object yourData : listOfYourData) {
>>>>>> LayoutComponent desc = new LayoutComponent(null,
>>>>>> yourData.getId(), type);
>>>>>> for (.... : listOfProperties) {
>>>>>> // Add each property that would normally appear in the
>>>>>> .jsf file, i.e:
>>>>>> // <sun:dynamicColumnRowGroup ... property1="value1"
>>>>>> property2="value2"...
>>>>>> desc.addOption(key, value);
>>>>>> }
>>>>>>
>>>>>> // Create and add child component (dynamicColumnRowGroup)
>>>>>> UIComponent rowGroup = ComponentUtil.createChildComponent(
>>>>>> facesContext, desc, table);
>>>>>> }
>>>>>>
>>>>>> // Return the populated table
>>>>>> return table;
>>>>>> }
>>>>>>
>>>>>> However, now that I went through the motions of giving you the
>>>>>> above pseudo-code, I realize why I don't like "binding". :) The
>>>>>> above will work, however, you can't parameterize a binding. If
>>>>>> you want to pass in a reference to "yourData" it's not possible.
>>>>>> So instead, if you want, you can create a custom JSFT Factory
>>>>>> (just like DynamicColumnTableRowGroupFactory). This could do
>>>>>> essentially the exact same code, you can just take advantage of
>>>>>> the properties passed in, and also context.getLayoutElement()
>>>>>> which is what should have been passed into the "null" argument in
>>>>>> new LayoutComponent() (but it's not available via a binding...
>>>>>> not very important, though).
>>>>>>
>>>>>> A 3rd option, would be to write this code in a handler and invoke
>>>>>> it on the afterCreate event.
>>>>>>
>>>>>> So many choices. :) I hope this helps!
>>>>>>
>>>>>> Ken
>>>>>>
>>>>>>
>>>>>> Karam Singh wrote:
>>>>>>> Any pointer to some example code? Are you suggesting that I use
>>>>>>> it in a jsp page using beans (like shown in woodstock preview
>>>>>>> examples)?
>>>>>>>
>>>>>>> -Karam
>>>>>>>
>>>>>>> Ken Paulsen wrote:
>>>>>>>>
>>>>>>>> Hi Karam,
>>>>>>>>
>>>>>>>> You can do:
>>>>>>>>
>>>>>>>> <sun:table binding="#{some.method}" />
>>>>>>>>
>>>>>>>> Then you could create create the components you need via java
>>>>>>>> code. However, you'd have have to create a LayoutComponent
>>>>>>>> object to pass to the factory that contained all the data that
>>>>>>>> is normally found in the .jsf file.
>>>>>>>>
>>>>>>>> That's probably the simplest solution.
>>>>>>>>
>>>>>>>> Ken
>>>>>>>>
>>>>>>>> Karam Singh wrote:
>>>>>>>>> Hi Ken,
>>>>>>>>> Remember that dynamic table code that we have in
>>>>>>>>> jsftemplating, how will it work if I have multiple
>>>>>>>>> tableRowGroup entries? Currently (what I have been using so
>>>>>>>>> far) I have to define dynamicRowGroup in the jsf page itself.
>>>>>>>>> Using this approach, I would have to define several
>>>>>>>>> dynamicRowGroup on the jsf page. But I don't know how many I
>>>>>>>>> need before hand. So how would I take care of that scenario?
>>>>>>>>> Please let me know.
>>>>>>>>>
>>>>>>>>> thanks
>>>>>>>>> Karam
>