Как узнать идентификатор компонента JSF, чтобы я мог использовать его в Javascript

Проблема: Иногда вам нужно получить доступ к компоненту из javascript с помощью getElementById, но id генерируются динамически в JSF, поэтому вы нужен метод получения идентификатора объектов. Ниже я расскажу о том, как вы можете это сделать.


Оригинальный вопрос: Я хочу использовать некоторый код, как показано ниже. Как я могу ссылаться на компонент inputText JSF в своем 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>

Обновить: этот пост Идентификаторы клиента в JSF2.0 обсуждается с использованием такой техники, как:

<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"/>

Предполагая, что атрибут id в компоненте inputText создает объект, к которому можно получить доступ с помощью EL, используя #{myInptTxtId}, в приведенном выше примере. В статье далее говорится, что JSF 2.0 добавляет метод zero-argument getClientId() для класса UIComponent. Таким образом, предлагаемая конструкция #{myInptTxtId.clientId} выше, чтобы получить фактический сгенерированный идентификатор компонента.

Хотя в моих тестах это не работает. Может ли кто-нибудь подтвердить/опровергнуть. Нижеприведенные ответы имеют недостаток, техника не делает. Поэтому было бы хорошо знать, была ли упомянутая выше техника фактически работает.

Ответ 1

Ответ: Итак, это техника, с которой мне очень нравится. Не нужно делать слишком много странных вещей, чтобы выяснить идентификатор компонента. Помните, что все это означает, что вы можете узнать id компонента из любой точки вашей страницы, а не только от самого фактического компонента. Это ключ. Я нажимаю кнопку, запускаю функцию javascript и должен иметь доступ к любому другому компоненту, а не только к запущенному ему.

Это решение не требует "щелчка правой кнопкой мыши" и показывает, что такое идентификатор. Этот тип решения является хрупким, поскольку идентификатор динамически генерируется, и если я изменю страницу, мне придется каждый раз проходить через эту ерунду.

  • Привяжите компонент к поддержке bean.

  • Ссылка на связанный компонент везде, где вы хотите.

Итак, вот пример того, как это можно сделать.

Предположения: У меня есть *.xhtml-страница (может быть *.jsp), и я определил поддержку bean. Я также использую JSF 2.0.

*. xhtml page

<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;

Обязательно создайте свой getter/setter для этого свойства.

Ответ 2

Вам нужно использовать именно тот идентификатор, который JSF назначил в сгенерированном выводе HTML. Щелкните правой кнопкой мыши страницу в веб-браузере и выберите "Просмотр источника". Это именно тот HTML-код, который видит JS (вы знаете, JS запускается в веб-браузере и перехватывает дерево HTML DOM).

Учитывая

<h:form>
    <h:inputText id="emailAddresses" ... />

Это будет выглядеть примерно так:

<form id="j_id0">
    <input type="text" id="j_id0:emailAddress" ... />

Где j_id0 - сгенерированный идентификатор сгенерированного HTML-элемента <form>.

Вы бы предпочли дать всем компонентам JSF NamingContainer фиксированный id чтобы JSF не NamingContainer. <h:form> является одним из них.

<h:form id="formId">
    <h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>

Таким образом, форма не получит j_id0 идентификатор, такой как j_id0 а поле ввода получит фиксированный идентификатор formId:emailAddress. Затем вы можете просто сослаться на это в JS.

var input = document.getElementById('formId:emailAddress');

С этого момента вы можете продолжать использовать код JS как обычно. Например, получение значения через input.value.

Смотрите также:


Обновление согласно вашему обновлению: вы неправильно поняли статью блога. Специальная ссылка #{component} относится к текущему компоненту, где выражение EL было оценено, и это работает только внутри любого из атрибутов самого компонента. Все, что вы хотите, также может быть достигнуто следующим образом:

var input = document.getElementById('#{emailAddress.clientId}');

с (обратите внимание на binding к представлению, вы абсолютно не должны привязывать его к бобу)

<h:inputText binding="#{emailAddress}" />

но это безобразно Лучше использовать следующий подход, в котором вы передаете сгенерированный HTML-элемент DOM как JavaScript, this ссылка на функцию

<h:inputText onclick="show(this)" />

с

function show(input) {
    alert(input.value);
}

Если вы используете jQuery, вы можете даже пойти на шаг дальше, абстрагировав их, используя класс стиля в качестве интерфейса маркера

<h:inputText styleClass="someMarkerClass" />

с

$(document).on("click", ".someMarkerClass", function() {
    var $input = $(this);
    alert($input.val());
});

Ответ 3

Идентификатор динамически генерируется, поэтому вы должны определять имена всех родительских элементов, чтобы избежать идентификаторов j_id123.

Обратите внимание, что если вы используете jQuery для выбора элемента - вам следует использовать двойную косую черту перед двоеточием:

    jQuery("my-form-id\\:my-text-input-block\\:my-input-id")

вместо:

    jQuery("my-form-id:my-text-input-block:my-input-id")

В случае Richfaces вы можете использовать выражение el на странице jsf:

    #{rich:element('native-jsf-input-id')} 

чтобы выбрать элемент javascript, например:

    #{rich:element('native-jsf-input-id')}.value = "Enter something here";

Ответ 4

Я знаю, что это не способ JSF, но если вы хотите избежать боли в ID, вы можете установить специальный класс CSS для селектора. Просто убедитесь, что вы используете хорошее имя, чтобы, когда кто-то читает имя класса, ясно, что он использовался для этой цели.

<h:inputText id="emailAddresses" class="emailAddressesForSelector"...

В вашем JavaScript:

jQuery('.emailAddressesForSelector');

Конечно, вам все равно придется вручную управлять уникальностью имени класса. Я считаю, что это поддерживается, если вы не используете это в компонентах многократного использования. В этом случае вы можете сгенерировать имена классов с помощью соглашения.

Ответ 5

Вы можете просмотреть исходный код HTML при его создании и посмотреть, для чего установлен идентификатор, поэтому вы можете использовать его в своем JavaScript. Поскольку он в форме, вероятно, добавляет ему идентификатор формы.

Ответ 6

<h:form  id="myform">
 <h:inputText  id="name" value="#{beanClass.name}" 
                a:placeholder="Enter Client Title"> </h:inputText>
</h:form>

Это небольшой пример JSF. Теперь я напишу код JavaScript, чтобы получить значение вышеуказанного компонента jsf:

    var x = document.getElementById('myform:name').value; //here x will be of string type

   var y= parseInt(x,10); //here we converted x into Integer type and can do the 
                           //arithmetic operations as well