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