Problème: Parfois, vous souhaiterez accéder à un composant à partir de javascript avec getElementById
, mais les identifiants sont générés dynamiquement dans JSF, vous avez donc besoin d'un méthode d'obtention d'un identifiant d'objets. Je réponds ci-dessous sur la façon dont vous pouvez le faire.
Question d'origine: Je veux utiliser du code comme ci-dessous. Comment puis-je référencer le composant JSF inputText dans mon Javascript?
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://Java.Sun.com/jsf/html"
xmlns:f="http://Java.Sun.com/jsf/core">
<head>
<title>Input Name Page</title>
<script type="javascript" >
function myFunc() {
// how can I get the contents of the inputText component below
alert("Your email address is: " + document.getElementById("emailAddress").value);
}
</script>
</head>
<h:body>
<f:view>
<h:form>
Please enter your email address:<br/>
<h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
</h:form>
</f:view>
</h:body>
</html>
Mise à jour : ce post Identifiants clients dans JSF2. traite de l'utilisation d'une technique comme:
<script type="javascript" >
function myFunc() {
alert("Your email address is: " + document.getElementById("#{myInptTxtId.clientId}").value);
}
</script>
<h:inputText id="myInptTxtId" value="backingBean.emailAddress"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
Suggérant que l'attribut id
sur le composant inputText
crée un objet accessible avec EL à l'aide de #{myInptTxtId}
, Dans l'exemple ci-dessus. L'article poursuit en indiquant que JSF 2.0 ajoute la méthode getClientId()
à argument zéro à la classe UIComponent
. Autorisant ainsi la construction #{myInptTxtId.clientId}
Suggérée ci-dessus pour obtenir l'ID généré réel du composant.
Bien que dans mes tests, cela ne fonctionne pas. Quelqu'un d'autre peut-il confirmer/infirmer. Les réponses suggérées ci-dessous présentent l'inconvénient que la technique ci-dessus ne le fait pas. Il serait donc bon de savoir si la technique ci-dessus fonctionne réellement.
Réponse: C'est donc la technique qui me plaît le plus. Ne nécessite pas de faire aussi beaucoup de choses étranges pour comprendre l'id d'un composant. Rappelez-vous que le but de tout cela est que vous puissiez connaître le id
d'un composant de n'importe où sur votre page, pas seulement à partir du réel composant lui-même. C'est la clé. J'appuie sur un bouton, lance la fonction javascript et il devrait pouvoir accéder à tout autre composant, pas seulement celui qui l'a lancé.
Cette solution ne nécessite pas de "clic droit" et voit quel est l'identifiant. Ce type de solution est fragile, car l'ID est généré dynamiquement et si je change de page, je devrai passer par ce non-sens à chaque fois.
Liez le composant à un bean de sauvegarde.
Référencez le composant lié où vous le souhaitez.
Voici donc un exemple de la façon dont cela peut être fait.
Hypothèses: J'ai une page * .xhtml (pourrait être * .jsp) et j'ai défini un bean de sauvegarde. J'utilise également JSF 2.0.
* Page .xhtml
<script>
function myFunc() {
var inputText = document.getElementById("#{backBean.emailAddyInputText.clientId}")
alert("The email address is: " + inputText.value );
}
</script>
<h:inputText binding="#{backBean.emailAddyInputText}"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
BackBean.Java
UIInput emailAddyInputText;
Assurez-vous également de créer votre getter/setter pour cette propriété.
Vous devez utiliser exactement l'ID que JSF a attribué dans la sortie HTML générée. Faites un clic droit sur la page dans votre navigateur et choisissez Voir la source. C'est exactement le code HTML que JS voit (vous savez, JS s'exécute dans le navigateur Web et intercepte l'arborescence DOM HTML).
Donné un
<h:form>
<h:inputText id="emailAddresses" ... />
Cela ressemblera à ceci:
<form id="j_id0">
<input type="text" id="j_id0:emailAddress" ... />
Où j_id0
est l'ID généré du code HTML généré <form>
élément.
Vous préférez donner à tous les composants JSF NamingContainer
un id
fixe afin que JSF ne les génère pas automatiquement. Le <h:form>
est l'un d'eux.
<h:form id="formId">
<h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
De cette façon, le formulaire n'obtiendra pas un ID généré automatiquement comme j_id0
et le champ de saisie obtiendra un ID fixe de formId:emailAddress
. Vous pouvez ensuite simplement le référencer comme tel dans JS.
var input = document.getElementById('formId:emailAddress');
À partir de là, vous pouvez continuer à utiliser le code JS comme d'habitude. Par exemple. obtenir de la valeur via input.value
.
Mise à jour selon votre mise à jour: vous avez mal compris l'article de blog. Le spécial #{component}
référence fait référence au composant actuel dans lequel l'expression EL est évaluée et cela ne fonctionne qu'à l'intérieur des attributs du composant lui-même. Tout ce que vous voulez peut également être réalisé comme suit:
var input = document.getElementById('#{emailAddress.clientId}');
avec (notez le binding
à la vue, vous devez absolument pas le lier à un bean)
<h:inputText binding="#{emailAddress}" />
mais c'est tout simplement laid. Mieux utiliser l'approche suivante dans laquelle vous transmettez l'élément HTML DOM généré en tant que référence JavaScript this
à la fonction
<h:inputText onclick="show(this)" />
avec
function show(input) {
alert(input.value);
}
Si vous utilisez jQuery, vous pouvez même aller plus loin en les résumant en utilisant une classe de style comme interface de marqueur
<h:inputText styleClass="someMarkerClass" />
avec
$(document).on("click", ".someMarkerClass", function() {
var $input = $(this);
alert($input.val());
});
L'ID est généré dynamiquement, vous devez donc définir des noms pour tous les éléments parents pour éviter les id de type j_id123.
Notez que si vous utilisez jQuery pour sélectionner un élément, vous devez utiliser une double barre oblique avant les deux points:
jQuery("my-form-id\\:my-text-input-block\\:my-input-id")
au lieu de:
jQuery("my-form-id:my-text-input-block:my-input-id")
Dans le cas de Richfaces, vous pouvez utiliser el expression sur la page jsf:
#{rich:element('native-jsf-input-id')}
pour sélectionner l'élément javascript, par exemple:
#{rich:element('native-jsf-input-id')}.value = "Enter something here";
Vous pouvez afficher la source HTML lorsqu'elle est générée et voir à quoi l'ID est défini, vous pouvez donc l'utiliser dans votre JavaScript. Comme il est dans un formulaire, il y ajoute probablement l'ID du formulaire.
Je sais que ce n'est pas la manière JSF mais si vous voulez éviter la douleur d'ID, vous pouvez définir une classe CSS spéciale pour le sélecteur. Assurez-vous simplement d'utiliser un bon nom afin que lorsque quelqu'un lit le nom de la classe, il est clair qu'il a été utilisé à cette fin.
<h:inputText id="emailAddresses" class="emailAddressesForSelector"...
Dans votre JavaScript:
jQuery('.emailAddressesForSelector');
Bien sûr, vous devrez toujours gérer manuellement l'unicité des noms de classe. Je pense que cela est maintenable tant que vous ne l'utilisez pas dans des composants réutilisables. Dans ce cas, vous pouvez générer les noms de classe à l'aide d'une convention.