2011-08-22 28 views
6

Estoy escribiendo un componente personalizado de autocompletar como ejercicio de aprendizaje con JSF 2.1.3. La idea (que probablemente sea bastante familiar) es ingresar texto en y el componente de entrada, y presentar un cuadro de lista con valores coincidentes. La idea es para tener un evento keyup javascript en la entrada que llama a jsf.ajax.request() para actualizar el componente. Hasta ahora tengo un componente que puedo incluir como esto:Componente personalizado de JSF que pierde el foco de entrada en la actualización ajax

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

Esto representa HTML así:

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

El com.myco.ajaxRequest() de JavaScript (keyup) hace esto:

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

Así pues quiero reconstruir y regenere el cuadro de lista con las sugerencias lista, estoy re-haciendo que el componente personalizado 'myauto'. Al especificar ejecutar: 'myauto' se ejecuta el método decode() y puedo obtener el valor de entrada. Por especificando render: 'myauto' los métodos encode ...() se ejecutan para regenerar el html.

Esto está bien, pero debido a que estoy procesando el componente myauto_input , pierdo el foco de entrada cada vez que se activa el evento de la tecla.

Si yo indique algo así como render: 'myauto_listbox' (lo único que realmente quiero reRender el cuadro de lista, después de todo), el problema es que la codificación ...() métodos no ejecutar, porque son de el componente personalizado como un todo, no solo el listbox. Y sería en uno de los métodos de codificación ...() que reconstruyo el cuadro de lista que contiene las sugerencias.

El componente se extiende UIInput y generar el marcado en un procesador separado (componentFamily = "javax.faces.Input") en el método encodeEnd() (por lo que este siempre se ejecuta después de cualquier convertidor suministrado - todavía no implementado). Supongo que forzar el foco desde javascript es un truco horrible y que debe evitarse.

No estoy seguro de dónde ir con esto, pero sospecho que lo que estoy viendo indica que me estoy acercando a esto de la manera incorrecta de alguna manera. Si alguien fuera lo suficientemente bueno como para apuntarme en la dirección correcta, le agradecería enormemente .

Respuesta

1

He pasado algún tiempo buscando en esto y el tema general de la pérdida de enfoque después de una actualización Ajax es bastante común y se describe con Jim Driscoll blog (ver 'Mantener Focus').

En el caso de mi componente personalizado I (creo que ...) tiene que actualizar el componente personalizado en sí, que es el padre de la entrada, así que voy a perder el foco, como resultado de la ajax actualización, y así son las cosas. Como tal, he visto lo que necesita ser hecho para restaurar el foco, y parece que en mi procesador de codificación simplemente tengo que restaurar a la fuerza el foco en la entrada, pero solo cuando respondo a la POST enviada desde el evento onkeyup por jsf.ajax.request. Uso jQuery y solo llamo.focus() no es suficiente porque también tiene que colocar la posición del cursor al final de cualquier entrada existente. Este código de abajo parece funcionar bien:

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

(nota:.. .focus() enfocar() haga clic en() que se requieren para IE8, simplemente .focus() funciona en el cromo ...)

Entonces parece que el horrible hack ha salvado el día. Me pregunté si habría alguna diferencia si usaba las rutinas jQuery ajax en lugar de la biblioteca jsf ajax pero supongo que no haría ninguna diferencia.

Cuestiones relacionadas