BTW: if i remember correct the generated row index is changed to ':0' in
svn.
Volker Weber wrote:
> Hi Enrique,
>
> the '_0' is added by the datatable while rendering row 1 (index 0).
> This is needed to generate uniqe ids over multiple rows.
>
> Looks like you have nested datatables?
>
> To get the '_0' you can call setRowIndex(0) on the datatable component,
> but if your table contains more rows the ids are incrementing each row
> and you can't, at component creation time, not set different onclick
> values for the rows.
>
> if your data has only one row you can use setRowIndex() (but datatable
> with one row ?),
> otherwise you can try to get the correct index in your javascript code,
> by parsing 'this.id' (you need of cause the this refferece in your
> function call) and inserting the extracted id(s) at the corresponding
> position(s) in the id of the needed element.
>
> Regards,
> Volker
>
> Enrique Medina wrote:
>
>>I have been implementing the dynamic creation of my tree component as
>>you mentioned, i.e. adding all the components to their parents before
>>calling getClientId().
>>
>>But it seems that there is something more to do, looking at the
>>generated code:
>>
>><input id="tablaEdicionPuntuaciones0_0:_id30_0:_input"
>>
>>name="tablaEdicionPuntuaciones0_0:_id30_0:_input"
>>type="text"
>>value="x+2" class="txt" />
>>&
>>nbsp;
>><a href='#'>
>><img src=
>>"/DeltaR/images/check.gif" alt="Validar"
>>height=
>>"11" width="12"
>>onclick="PuntuacionesAjax.validarFormula
>>(respuestaValidacion,
>>getElmById('tablaEdicionPuntuaciones0:_id30:_input').value); return true" />
>>
>>
>>Can you see that the input ID is
>>
>>tablaEdicionPuntuaciones0_0:_id30_0:_input
>>
>>, but the ID obtained from getClientId in the onclick method is
>>
>>tablaEdicionPuntuaciones0:_id30:_input
>>
>>, where there is a _0 missing? Any ideas?
>>
>>I assert that the call to getClientId within my code is the last call,
>>but as I use an HtmlDataTable, maybe there is another part of the ID I'm
>>missing...
>>
>>2006/1/19, Simon Kitching <[EMAIL PROTECTED]
>><mailto:[EMAIL PROTECTED]>>:
>>
>> I believe Volker's answer is exactly what you're looking for. Unless
>> I've misunderstood your question, method getClientId is what you want;
>> you just need to make sure the component is attached to the view tree
>> before calling that method.
>>
>> ie:
>>
>> UIOutput texto4 = createComponent(..);
>> texto4.setId("texto4");
>>
>> // parent is expected to already be attached to the view tree.
>> parent.getChildren().add(texto4);
>>
>> // do this only after adding to view tree. You'll then get the
>> // full final id of the component, eg "form1:subview1:table3:texto4"
>> String texto4ClientId = texto4.getClientId(facesContext);
>>
>> // use texto4ClientId in javascript emitted for some other component
>>
>> If you need to "find" the texto4 client from some other renderer, you
>> can search for it:
>> ....
>> UIOutput text05 = createComponent(..);
>>
>> // find a component with the specified name within the same
>> // naming container as the component the find is invoked on
>> UIOutput targetComponent = parent.findComponent("texto4");
>>
>> String targetClientId = targetComponent.getClientId();
>> // use targetClientId in javascript emitted for texto5 component
>>
>>
>> Note also that component ids starting with underscores are reserved for
>> the use of the JSF framework; any id you assign explicitly should *not*
>> start with an underscore.
>>
>> Regards,
>>
>> Simon
>>
>> On Thu, 2006-01-19 at 16:49 +0100, Enrique Medina wrote:
>> > See what is generated at runtime:
>> >
>> > <input
>> id="bodySubview:_id23:tablaEdicionPuntuaciones0_1:_id24_4_0:_input"
>> >
>> name="bodySubview:_id23:tablaEdicionPuntuaciones0_1:_id24_4_0:_input"
>> type=
>> > "text" value="12" onclick="myAlert(_input.value)"
>> > class="txt" />
>> >
>> > And obviously, a component with "_input" ID does not exist,
>> because as
>> > being contained, the ID generated for the input component is
>> > different...
>> >
>> > 2006/1/19, Volker Weber <[EMAIL PROTECTED]
>> <mailto:[EMAIL PROTECTED]> >:
>> > Hi,
>> >
>> > you can get the rendered 'htmlId' of a component by
>> > component.getCientId(facesContext);
>> >
>> > so you can do :
>> >
>> > UIOutput texto5 = (HtmlOutputText)
>> > FacesUtils.getApplication()
>> > .createComponent( HtmlOutputText.COMPONENT_TYPE);
>> >
>> > texto5.getAttributes().put("onclick",
>> > "validate('" + texto4.getClientId(facesContext) + "')");
>> >
>> > Regards,
>> > Volker
>> >
>> > Enrique Medina wrote:
>> > > Also I forgot to say, that if I wanted to use the onclick
>> > method on the
>> > > same UIInput component, I could define it easily by:
>> > >
>> > > texto4.getAttributes().put("onclick",
>> > "validate( this.value)");
>> > >
>> > > As you can see, I know that 'this' refers to my component.
>> > But what
>> > > happens if I need to refer to "texto4" component value from
>> > another
>> > > component. Imagine:
>> > >
>> > > UIOutput texto5 = (HtmlOutputText)
>> > FacesUtils.getApplication()
>> > > .createComponent(
>> HtmlOutputText.COMPONENT_TYPE);
>> > >
>> > > texto5.getAttributes().put("onclick",
>> > validate(XXXXXX));
>> > >
>> > > where XXXXXX is a Javascript reference to the value of
>> > "texto4".
>> > >
>> > >
>> > > 2006/1/19, Enrique Medina <[EMAIL PROTECTED]
>> <mailto:[EMAIL PROTECTED]>
>> > > <mailto: [EMAIL PROTECTED]
>> <mailto:[EMAIL PROTECTED]>>>:
>> > >
>> > > Let me give a more detailed explanation of what I am
>> > trying to achieve..
>> > >
>> > > In my application I need to work with data in a
>> > spreadsheet form, so
>> > > I decided to use a PanelTabbed component, where each tab
>> > would
>> > > contain a HtmlDataTable. All these would simulate an
>> > Excel page,
>> > > where I can change the actual tab, make some
>> > modifications to the
>> > > elements in the table, go to another tab, modify, etc,
>> > so at the end
>> > > I would press the save button, and all the changes would
>> > be
>> > > persisted to the DB.
>> > >
>> > > The big problem I had with defining this page was the
>> > fact that all
>> > > the data that was used to populate the tables in each
>> > tab was not
>> > > known at compile time, as it depended on the values
>> > entered by the
>> > > user during the normal use of the application.
>> > >
>> > > So I had to create all the components dynamically
>> > through Java code.
>> > > To accomplish this objective, I created a JSP file with
>> > simply a
>> > > PanelTabbed tag that I binded to a property in my
>> > backing bean, so
>> > > whenever JSF called my setBindedTabbedPane method, I
>> > could create
>> > > all the tabs, tables, labels, inputs, etc, in code.
>> > >
>> > > Once done, everything was perfect, in the sense that my
>> > application
>> > > was implemented to dynamically create all the
>> components
>> > needed to
>> > > simulate an Excel worksheet; i.e. dynamic number of
>> > columns and
>> > > rows, dynamic number of tabs, etc.
>> > >
>> > > On the other hand, I have also added DWR to my
>> > application in order
>> > > to use Ajax for particular purposes, like showing child
>> > data in a
>> > > datatable, or simply validate some specific fields
>> > without having to
>> > > make a JSF request. So I decided to add a DWR Ajax
>> > validate process
>> > > to my recently created Excel worksheet.
>> > >
>> > > But the problem comes because when using DWR Ajax, I
>> > need to define
>> > > a callback function in Javascript where I have to pass
>> > as a
>> > > parameter the value that I want to be validated. As you
>> > already
>> > > know, I am generating all the components dynamically in
>> > code, within
>> > > a loop that reuses temporal variable names for the sake
>> > of
>> > > performance and clearness. This means that I use the
>> > > FacesContext.getApplication().createComponent() to
>> > create every
>> > > component, but reusing the same variable in the
>> loop, as
>> > I don't
>> > > know how many components will I have to create (i.e. how
>> > many inputs
>> > > or datatables or tabs).
>> > >
>> > > To better clarify, imagine that I want to add a
>> > Javascript call in
>> > > the onclick method of an input text box. When creating
>> > the component
>> > > dynamically, I could do:
>> > >
>> > > UIInput texto4 = (HtmlInputText)
>> > FacesUtils.getApplication()
>> > >
>> .createComponent(HtmlInputText.COMPONENT_TYPE);
>> > >
>> > > texto4.getAttributes ().put("styleClass",
>> > "txt");
>> > > texto4
>> > > .setValueBinding(
>> > > "rendered",
>> > > FacesUtils
>> > >
>> > >
>> .getValueBinding("#{puntuacionesBean.mapaScoreboardPuntuaciones['"
>> > > +
>> > codigoGrupo
>> > > +
>> > "'].puntuacionColumna
>> > > != null}"));
>> > > texto4
>> > > .setValueBinding(
>> > > "value",
>> > > FacesUtils
>> > >
>> > >
>> .getValueBinding("#{puntuacionesBean.mapaScoreboardPuntuaciones ['"
>> > > +
>> > codigoGrupo
>> > > +
>> > > "'].puntuacionColumna}"));
>> > >
>> > > Please notice that this piece of code will be executed
>> > for each
>> > > input text box that is needed. If I set the Id with:
>> > >
>> > > texto4.setId("_input");
>> > >
>> > > Then this ID will be used as the last part of the HTML
>> > generated ID
>> > > when rendering the page, so there is no way to know it
>> > when writing
>> > > this code in the backing bean.
>> > >
>> > > So in the end, my question was about how could I know
>> > that ID at
>> > > runtime. I mean, I can use EL to bind values with my
>> > objects'
>> > > properties, but could I also do something similar with
>> > component
>> > > attributes?
>> > >
>> > > 2006/1/19, Volker Weber
>> > <[EMAIL PROTECTED]
>> <mailto:[EMAIL PROTECTED]>
>> > > <mailto:[EMAIL PROTECTED]
>> <mailto:[EMAIL PROTECTED]>>>:
>> > >
>> > > Hi,
>> > >
>> > > Enrique Medina wrote:
>> > >> But I don't want to inject another bean. When I talk about
>> > > components I
>> > >> mean view components in the model component; e.g. refer to
>> > an
>> > >> HtmlInputText from another HtmlOutputText.
>> > >>
>> > >> The problem I have is that I need to refer to the value of
>> > one
>> > > component
>> > >> from another one in code, and both of them are dynamically
>> > > created in
>> > >> the same backing bean.
>> > >>
>> > >
>> > > If you create the components you can store
>> > references to them in
>> > > your bean.
>> > >
>> > > Ohterwise you need to walk through the component
>> > tree, or try to
>> > > fetch
>> > > them via findComponent(id) method.
>> > >
>> > > Regards,
>> > > Volker
>> > >
>> > > --
>> > > Don't answer to From: address!
>> > > Mail to this account are droped if not recieved via
>> > mailinglist.
>> > > To contact me direct create the mail address by
>> > > concatenating my forename to my senders domain.
>> > >
>> > >
>> > >
>> >
>> > --
>> > Don't answer to From: address!
>> > Mail to this account are droped if not recieved via
>> > mailinglist.
>> > To contact me direct create the mail address by
>> > concatenating my forename to my senders domain.
>> >
>>
>>
>
--
Don't answer to From: address!
Mail to this account are droped if not recieved via mailinglist.
To contact me direct create the mail address by
concatenating my forename to my senders domain.