Dynamiczne ID w komponentach JSF
Twórcy specyfikacji JSF nie przewidzieli (chyba), że zdarzają się aplikacje webowe w których należy wykorzystać formularze dynamiczne, czyli takie w których liczba pól zmienia się w zależności od wcześniejszych poczynań użytkownika. W formularzach takich od czasu do czasu ktoś będzie chciał wykorzystać JavaScript. Znacznik html:inputText w swoim atrybucie id przyjmuje tylko i wyłącznie statyczne stringi.. a więc możemy napisać coś takiego: html:inputText id=”bleble” ale nie możemy już użyć takiej: html:inputText id=”#{bleble}” lub takiej: html:inputText id=”${bleble}” formy zapisu. Jak w takim razie z poziomu funkcji JS dostać się do wartości takiego pola ???
Po kilku ładnych godzinach poszukiwań natrafiłem na projekt javascript4jsf… i problem został rozwiązany :)
- Ściągamy bibliotekę i umieszczamy w odpowiednim folderze w naszej aplikacji (lib)
- Do pliku faces-config.xml dodajemy:
<component> <component-type>org.j4j.idProxy</component-type> <component-class>org.j4j.components.UIIDProxy</component-class> </component>
- Do strony JSP w której chcemy użyć dodajemy definicje taglib:
<%@ taglib uri="http://javascript4jsf.dev.java.net/" prefix="j4j" %>
- Następnie do ciała znacznika wstawiamy nasz znacznik proxy
<h:inputText id="firstName" value="#{GetNameBean.firstName}"> <j4j:idProxy id="firstName_" /> </h:inputText> - Z poziomu JavaScript odwołujemy się do interesującego nas pola w nastepujący sposób (tutaj przykład uaktywnienia pola)
<script language="javascript"> var iid=document.getElementById("firstName_").title; document.getElementById(iid).focus(); </script>
Jak to działa ? Biblioteka J4J wstawia znacznik span, który posiada odpowiednie ID, przed komponent JSF. Wspomnę jeszcze tylko na koniec, że atrybut ID znacznika przyjmuje dynamiczne wartości !








October 15th, 2007 at 16:26
Z tego co widzę to jest ten sam problem co ze strutsem i zabawami z html:multibox czy też bardziej złożonymi strukturami.
Drobna uwaga – w przykładowym kodzie, który jest na stronie j4j komponent nie jest zamknięty w wygenerowanym span-ie a poprzedzony nim.
Co do samego JavaScriptu myślę, że z powodzeniem można by użyć np funkcji:
* getElementsBySelector (podanie ścieżki do elementu, niekoniecznie pełnej nazwy z jakiegoś atrybutu)
* getElementsByClassName (powiedzmy generowanie dynamicznej nazwy klasy i posługiwanie się nią)
* getElementsByName (tutaj brana jest pod uwagę wartość atrybutu name)
* getElementsByAttribute (tutaj wystarczy podać nazwę, wartość atrybutu plus nazwę znacznika – np wstawianie do atrybutu rel, który jest w specyfikacji w3c własnych wartości).
Nieco szerszy opis w/w funkcji można znaleźć na http://getelementsby.com/.
Myślę, że przy odrobinie wysiłku udało by się stworzyć kod wolny od dodatkowych elementów (taglibów) ze zminimalizowanym kodem JS.
October 15th, 2007 at 18:21
Masz racje jeśli chodzi o obejście problemu za pomocą wysiłku i JS :) Jednak z wykorzystaniem j4j możemy wyeliminować wysiłek i nie zastanawiać się zbyt długo nad JS, którego wiele osób (w tym ja) nie zna zbyt dobrze. Chciałem Ci jednak raz jeszcze przyznać racje i potwierdzić, że problem można obejść bez dodatkowych taglibów. Poprawiam także od razu info o poprzedzającym spanie ! Dzięki za komentarz.
November 24th, 2009 at 23:23
Tak standardowo w JS można się odwołać do pola, można użyć też ajax, i dynamicznie zmieniać sobie formularz tak jak tylko się chce, poprzez modyfikację JSFa z kodu Javy.