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

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


Оригинальный вопрос: я хочу использовать некоторый код, как показано ниже. Как я могу сослаться на JSF-компонент inputText в моем 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 добавляет нулевой аргумент getClientId() метод к UIComponent учебный класс. Тем самым позволяя #{myInptTxtId.clientId} предложенная выше конструкция, чтобы получить фактический сгенерированный идентификатор компонента.

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

5 ответов

Решение

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

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

  1. Свяжите компонент с компонентом поддержки.

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

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

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

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

Убедитесь, что вы также создали свой метод получения / установки для этого свойства.

Вам нужно использовать именно тот идентификатор, который 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 не генерировал их автоматически. <h:form> это один из них.

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

Таким образом, форма не получит автоматически сгенерированный идентификатор, например 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());
});

Id генерируется динамически, поэтому вы должны определить имена для всех родительских элементов, чтобы избежать 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";

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

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

В вашем JavaScript:

jQuery('.emailAddressesForSelector');

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

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

<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
Другие вопросы по тегам