2011-08-22 6 views
6

Piszę składnik niestandardowy autouzupełniania jako ćwiczenie do nauki z JSF 2.1.3. Pomysł (który jest prawdopodobnie dość znajomy) polega na wprowadzeniu tekstu do składnika i komponentu wejściowego oraz wyświetleniu listy z dopasowanymi wartościami. Pomysł polega na tym, aby mieć zdarzenie javascript na wejściu, które wywołuje jsf.ajax.request() , aby zaktualizować komponent. Do tej pory mam komponent, który mogę to jak to:Komponent niestandardowy JSF utrata koncentracji wejściowej na aktualizacji ajax

<mycc:autocomplete id="myauto" searchMethod="#{bean.doSearch}"/> 

Czyni html tak:

<span id="myauto"> 
    <input type="text" id="myauto_input" name="myauto_input" 
    onkeyup="com.myco.ajaxRequest(this, event)"/> 
    <select id="myauto_listbox" name="myauto_listbox"> 
    <option value="1st">First</option> 
    <option value="2nd">Second</option> 
    </select> 
</span> 

com.myco.ajaxRequest() funkcji javascript (keyup) robi to:

jsf.ajax.request(comp, null, { 
       execute: 'myauto', 
       render: 'myauto' 
       }); 

Tak, bo chcę się odbudować i rerender z listbox z sugestiami listy, jestem ponownego renderingu niestandardowy składnik „myauto”. Podając execute: 'myauto', wykonywana jest metoda decode() i mogę uzyskać wartość wejściową. Aby określało renderowanie: "myauto", metody encode ...() są wykonywane w celu odtworzenia html w postaci .

Wszystko jest w porządku, ale ponieważ renderuję element nadrzędny składnika myauto_input , tracę fokus za każdym razem, gdy uruchamiane jest zdarzenie keyup.

Gdybym określić coś jak render: „myauto_listbox” (i tylko naprawdę chcą rerender listbox po wszystkich) problemem jest to, że kodowanie ...() metody nie wykona, bo są za Niestandardowy komponent jako całość, a nie tylko listbox. I byłoby to w jednej z metod kodowania ...(), który przebuduję listbox zawierający sugestie.

Składnik rozciąga UIInput i generowania znaczników w oddzielnym renderujący (componentFamily = „javax.faces.Input”) w metodzie encodeEnd() (więc zawsze przebiega po każdej dołączonej przetwornicy - jeszcze realizowane). Przypuszczam, że , że wymuszenie skupienia z javascript jest okropnym hackerem i należy go unikać.

Nie jestem pewien, co z tym zrobić, ale podejrzewam, że to, co widzę wskazuje, że podchodzę do tego w niewłaściwy sposób. Jeśli ktokolwiek byłby na tyle dobry, aby wskazać mi właściwy kierunek, bardzo bym go docenił.

Odpowiedz

1

Spędziłem trochę czasu patrząc na to i ogólnej kwestii utraty ostrości po AJAX Update jest dość powszechne i jest opisany w Jim Driscolla blog (patrz „Utrzymywanie ostrości”).

W przypadku mojego komponentu niestandardowego I (myślę, że ...) trzeba zaktualizować komponent niestandardowy sam, który jest rodzicem danych wejściowych, więc stracę koncentrację w wyniku ajax aktualizuj i tak już jest. W związku z tym przyjrzałem się temu, co musi być zrobione, aby przywrócić fokus i wydaje mi się, że w moim kodowaniu renderera muszę po prostu wymusić przywrócenie fokusu na wejście, ale tylko wtedy, gdy odpowiadam na POST wysłany z zdarzenia onkeyup przez jsf.ajax.request. Używam jQuery i po prostu dzwonię.focus() nie jest wystarczający, ponieważ musisz również ustawić kursor na końcu każdego istniejącego wejścia . poniżej tego kodu wydaje się działać ok:

<script> 
    jQuery(function($){var cid='#myauto_input';$(cid).focus().focus().click();$(cid).val($(cid).val());}); 
</script> 

(uwaga:.. .focus() koncentrują() kliknij() wymagana dla IE8, tylko .focus() działa na chromie ...)

Wygląda na to, że ten straszny hack uratował dzień. Zastanawiam się, czy nie byłoby żadnej różnicy, jeśli użyłbym procedur ajax jQuery zamiast biblioteki jsf ajax, ale Nie sądzę, że to by miało jakąkolwiek różnicę.

Powiązane problemy