Combo autocompletar

2012-02-29
2013-04-15
  • Jairo Buitrago

    Jairo Buitrago - 2012-02-29

    Cordial saludo!

    Teniendo un combo (lista) cuyos valores puedo traer de la BD a través de estereotipo o de una Referencia!

    Quisiera saber cómo puedo modificarlo para que funcione con autocompletar. Me explico que el usuario pueda digitar un texto en el combo y que ese texto sea utilizado para filtrar los valores que se presentan en el combo.

    Existe una alternativa diferente para lograr este efecto? Otro componente de la vista?

    Básicamente tengo una lista con Nombres de empresas quiero que el usuario digite parte del nombre en el combo y la lista se filtre por lo que ha digitado!

     
  • Jairo Buitrago

    Jairo Buitrago - 2012-03-07

    Bueno pues bamos a intentarlo!  cualqueir consulta te molestare!  empesare por estudiar el tema!

     
  • Carlos

    Carlos - 2013-04-05

    Hola,

    He visto este post de hace algún tiempo. Quiero implementar una función de autocompletar para seleccionar un elemento de una lista bastante grande.
    He visto de que va y si no ha habido avance lo implementaría yo.
    Sé como crear mi propio editor para referencias y ahí podría meterle el javascript que hiciese la búsqueda en la base de datos cuando se metiesen algunos datos. Como openxava utiliza jquery he pensado en algo parecido a lo que hay en

    http://jqueryui.com/autocomplete/#remote-jsonp

    Sin embargo, mi duda está en como llevar a cabo la conexión desde el javascript del editor de referencias a la base de datos, para traer los registros que contienen lo que hasta ahora ha tecleado el usuario.

    A lo mejor hay una forma mejor de hacerlo, pero no se me ocurre.

     
  • Javier Paniza

    Javier Paniza - 2013-04-09

    Hola Carlos,

    llevar a cabo la conexión desde el javascript del editor de referencias a la
    base de datos

    Utilizando AJAX. Yo personalmente para estas cosas uso DWR, pero puedes hacerlo con otra librería si lo prefieres.


    Ayuda a otros en este foro como yo te ayudo a ti.
    ¿Necesitas más ayuda? Usa el soporte profesional de OpenXava

     
  • Carlos

    Carlos - 2013-04-11

    Hola,

    Siguiendo las indicaciones de Javier he utilizado DWR para hacer un combo con autocompletar.
    Dejo aquí lo que hago, por si le puede servir a alguien.

    Lo que tengo que meter en el combo es una relación de diagnósticos del CIE-10, que tienen un codigo y una descripcion.

    La entidad se llama Diagnostico.

    1- Para DWR creo un filtro. En mi caso me interesa filtrar por una cadena (para que presente todos los casos que coinciden con una cadena). También añado un valor concreto para que me lo añada a lo que filtre para el caso en que ya se haya seleccionado un valor para diagnóstico

    package org.cibs.ssresi.util;
    
    import java.util.*;
    
    import javax.persistence.*;
    
    import org.cibs.ssresi.modelo.*;
    import org.openxava.jpa.*;
    
    public class DiagFilter {
        public Collection<Diagnostico> getDiagnosticos(String str, int valorSeleccion) {
    
            System.out.println("Petición de filtrado con "+str+" y "+valorSeleccion);
            Query query = XPersistence.getManager().createQuery("select d FROM Diagnostico d WHERE UPPER(d.descripcion) LIKE  :filter or d.id=:value").setParameter("filter","%" + str.toUpperCase() + "%").setParameter("value",valorSeleccion);
            return query.getResultList();
    
        }
    
    }
    

    2- (lo que menos me gusta) Modifico el archivo dwr.xml que está en OpenXava y declaro el filtro y la clase que se devuelve. ¿Habría alguna forma de no tener que modificar el dwr.xml de OpenXava?

    <create creator="new" javascript="DiagFilter">
      <param name="class" value="org.cibs.ssresi.util.DiagFilter"/>
    </create> 
     ....
    
    <convert converter="bean" match="org.cibs.ssresi.modelo.Diagnostico"/>
    

    3- Añado a editores.xml y lo asocio al modelo correspondiente a la entidad

           <editor url="diagnosticoEditor.jsp">
              <para-referencia modelo="Diagnostico"/>
           </editor>
    

    4- Creo el editor, con todo su javascript. En mi caso lo que me viene bien es un cuadro de tecto en el que se mete un texto. Solo cuando tiene longitud 4 o mayor se dispara la búsqueda en la base de datos, para evitar la sobrecarga de la misma. Además, si hay algún valor seleccionado (porque estemos cargando una valor elegido previemante) este valor lo incluímos en la petición para que lo añada al resultado del filtro

            <%@page import="java.util.Iterator"%>
            <%@page import="org.cibs.ssresi.modelo.Diagnostico"%><%
    
            String propertyKey = request.getParameter("propertyKey");
            Object value = request.getAttribute(propertyKey + ".value"); // Podemos usar propertyKey + ".value" (2)
            if (value == null) value = 0;
    
            %>
    
            <script type='text/javascript' src='/SSResi/dwr/interface/DiagFilter.js'></script>
            <script type='text/javascript' src='/SSResi/dwr/engine.js'></script>
            <script>
            searchDiag("srcDiag","selDiag",<%=value%>)
            function searchDiag(campo_src,campo,valor) {
    
                  var input=document.getElementById(campo_src).value.toUpperCase();
                  if (input.length<4) {
                      input="*%IMPOSIBLE++";
                  }
                  var select=document.getElementById(campo)
                  for (var no=select.options.length-1;no>0;no--) {
                      select.remove(no);
    
                  }
                  var c=0;
    
                  DiagFilter.getDiagnosticos(input,valor,function(opciones) {
                      for (var i=0;i<opciones.length;i++) {
                          var descripcion=opciones[i].descripcion.substring(0,81);
                          select.options[i+1]=new Option(opciones[i].codigo+" "+descripcion,opciones[i].id)
                          if (valor==opciones[i].id) {
                              select.options[i+1].selected=true;
                          }
                      }
                  });
                }
    
            </script>
    
            Buscar <input type="text" id="srcDiag" onkeyup="searchDiag('srcDiag','selDiag',<%=value%>)">
    
            <select id="selDiag" name="<%=propertyKey%>">
    
            <option value="0" <%=value.equals(0)?"selected":""%>>
    
            </select>
    
     
  • Javier Paniza

    Javier Paniza - 2013-04-15

    Hola Carlos,

    muchas gracias por poner tu código aquí, seguro que es útil para otros.
    Con un poco más de esfuerzo podrías hacerlo lo suficientemente genérico como poder poner esto en cualquier referencia:

    @Editor("Autocomplete")
    @ManyToOne
    MiEntidad miReferencia
    

    De esta forma si lo necesitas en otra parte de tu aplicación no tienes que cortar y pegar, sólo tienes que anotar la nueva referencia y ya está. Pero ademas, podrías contribuir tu código y lo añadiariamos en OpenXava para que todo el mundo lo pudiera usar fácilmente.

    En cuanto a tener tu propio dwr.xml sí es posible, leete esto:
    http://directwebremoting.org/dwr/documentation/server/configuration/servlet/multiconfig.html


    Ayuda a otros en este foro como yo te ayudo a ti.
    ¿Necesitas más ayuda? Usa el soporte profesional de OpenXava

     

Log in to post a comment.