18

How do I refer to JSF components in jquery, as I dont know the id(s) prepended to the id of component I want to refer ?

Rajat Gupta
  • 25,853
  • 63
  • 179
  • 294

5 Answers5

33

You can give all NamingContainer components in the view such as <h:form>, <h:dataTable>, <ui:repeat>, <my:composite> a fixed ID so that the HTML-generated client ID is safely predictable. If you're uncertain, just open the page in webbrowser, rightclick and do View Source. If you see an autogenerated ID like j_id123 in the client ID chain, then you need to give exactly that component a fixed ID.

Alternatively, you can use #{component.clientId} to let EL print the component's client ID to the generated HTML output. You can use component's binding attribute to bind the component to the view. Something like this:

<h:inputText binding="#{foo}" />
<script>
    var $foo = $("[id='#{foo.clientId}']"); // jQuery will then escape ":".
    // ...
</script>

This only requires that the script is part of the view file.

As another alternative, you could give the element in question a classname:

<h:inputText styleClass="foo" />
<script>
    var $foo = $(".foo");
    // ...
</script>

As again another alternative, you could just pass the HTML DOM element itself into the function:

<h:inputText onclick="foo(this)" />
<script>
    function foo(element) {
        var $element = $(element);
        // ...
    }
</script>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Sorry about this..Actually I'm so disheartened that JSF doesnt offer a right way to do this.. using generated ids in code after looking from the generated HTML proved not a very good way to me.. it breaks when you make some changes to code & using the class names worked easy but I didnt liked creating large no of classes just for that. Another way by providing ids to all components up the DOM structure, is also just too hectic (forced to write all the ids :( ) I didn't found a better way but these solutions didn't really worked fine for me & was thus looking for some more responses. – Rajat Gupta Dec 07 '11 at 19:19
  • but as of now since there are no better ways, & you listed all the practically possible ways to do that, I think I should accept the solutions proposed by you until I find some better ways to do this.. – Rajat Gupta Dec 07 '11 at 19:25
  • Well, that's what you get in standard JSF. Component libraries like RichFaces and PrimeFaces offers ways to more easily refer JSF components by IDs. RichFaces for example has a `#{rich:component('foo')}` which generates a jQuery call to the DOM element with the right client ID. PrimeFaces for example has on several components a `widgetVar` attribute which puts a jQuery reference to the DOM element straight in the global JS scope. But anyway, if you want more fine grained control over view than what JSF allows, perhaps JSF isn't what you need. See also http://stackoverflow.com/q/4421839/157882. – BalusC Dec 07 '11 at 19:27
4

Check out the Attribute Contains Selector if you're keen on using the ID as the selector. Then you can do something like:

$('input[id*="mycomponentid"]').fadeIn();

Another option is to assign distinct CSS classes to the components you need to interact with in jQuery. I.e.

$('.jsf-username-field').fadeIn();

If you use the later approach, you can allow the framework to generate IDs and you don't even need to bother with them most of the time, especially if you're using a nice AJAX-JSF framework. I favor this approach because it doesn't mingle HTML / JavaScript with JSF.

jonathan.cone
  • 6,592
  • 2
  • 30
  • 30
1

The id of the object is composed of its parents' ids. for example form1:button1. You can check how they are generated, and I think it is guaranteed not to change (but you'd better to specify explicit ids for all parents)

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 1
    `Id` changes even if you make a minor change to the xhtml & supplying the ids up the DOM structure to all the components really sucks.. There should have been a better way perhaps.. – Rajat Gupta Dec 05 '11 at 11:55
1

Use UIComponent.getClientId to get the actual Id of the component you're interested in.

Render this ID on your page inside a javascript fragment (js function call, variable, whatever) so you can pick it up with jQuery.

There are various ways to use EL on a Facelet to achieve this effect, but it largely depends on what you want: eg a single component's onclick handler, or a random component's Id in a script that executes at the bottom of the page...

Mike Braun
  • 3,729
  • 17
  • 15
-1

It is possible for JQuery to use id set by JSF variables directly.

For example, in JSF you have:

  <c:set var="radioId" value="#{groupId}_#{Id}_radio"/>

Later you use this ID for the radio button

And for the script you use:

            <script type="text/javascript">
                $( "##{radioId}" ).change(function() {
                    alert( "radio changed" );
                });
            </script>

It works!

Gangnus
  • 24,044
  • 16
  • 90
  • 149
  • That's already answered. You have a major fundamental misunderstanding of server side web development. To start, open JSF page in webbrowser, rightclick and choose *View Page Source*. Stare at it around the places of and #{radioId} as long as until you get a moment of enlightement. Your approach is just slightly different because you have changed the default naming container separator character. Here's then food for read: http://stackoverflow.com/q/10726653 – BalusC Jan 14 '16 at 11:19
  • @BalusC I know that I can use hard set IDs. But I don't need them. And the author of the question, too. As for your reference, it is interesting, thank you, and it is about the theme, but does not contain an answer to the question... As for misunderstandings, yes, and I am not afraid to recognize littlo knowledge on some theme. And you? BTW, my solution works. – Gangnus Jan 14 '16 at 12:10
  • @BalusC Now I have understood your answer. It is correct, sorry. (but I never downvoted it) – Gangnus Jan 15 '16 at 11:44