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]>:
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" >> 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] >:
>         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]>>:
>         >
>         >     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] >>:
>         >
>         >         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.
>




Reply via email to