dev@jsftemplating.java.net

Re: JSFTemplating: Dynamic table question

From: Karam Singh Badesha <Karam.Badesha_at_Sun.COM>
Date: Sun, 16 Mar 2008 12:32:33 -0700

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