problema con el autocompletado

29 views
Skip to first unread message

Jose Puertas

unread,
Sep 10, 2015, 4:04:31 PM9/10/15
to ZnetDK
Tengo un problema al intentar hacer el autocompletado, este es el código del controlador:

static protected function action_Rtecnicos() {
        // Get keyword to find out
        $request = new \Request();
        $keyword = $request->query;

        // Construct the list of suggestions
        $tecnicoDAO = new tecnicoDAO();
        $tecnicoDAO->setSortCriteria('user_name');
         while ($row = $tecnicoDAO->getResult()) {
            $allLang[] = array('label' => $row['user_name']);
        }
        $suggestions = array();
        foreach($allLang as $value) {
            if(stristr($value, $keyword)) {
                $suggestions[]['label'] = $value;
            }
        }        
        // JSON Response
        $response = new \Response();
        $response->setResponse($suggestions);
        return $response;
    }
si que parece que hace la búsqueda, pero no da ningún resultado, a ver dónde me he colado.

Saludos

Pascal Martinez

unread,
Sep 10, 2015, 5:21:35 PM9/10/15
to ZnetDK
Hola José,

He publicado el código fuente de la demo CRUD directamente en el sitio web de demostración (puedes también descargarlo) que ilustra también el widget Autocomplete con una búsqueda en el base de datos.

Creo que te ayudara para desarrollar el código de tu controlador.

Pascal

Jose Puertas

unread,
Sep 11, 2015, 6:29:41 AM9/11/15
to ZnetDK
Hola Pascal, he seguido los pasos del código que has publicado, parece que funciona pero a medias, ya que, cuando ingresas una letra  en lugar de salir reflejados todos los que la contienen, salen todos sin excepción, te paso el código tal como me ha quedado:

controlador:
static protected function action_Rtecnicos() {
        // Get keyword to find out
        $request = new \Request();
        //$keyword = $request->query;

        // Construct the list of suggestions
        $tecnicoDAO = new tecnicoDAO();
        $tecnicoDAO->setNameAsFilter('%' . $request->criteria . '%');
        $tecnicoDAO->setSortCriteria('user_name');
        
        $response = new \Response();
        $previousSuggestion = '';
        $suggestions = array();
        try {
            while($row = $tecnicoDAO->getResult()) {
                if ($row['user_name'] !== $previousSuggestion) {
                    $suggestions[]['label'] = $row['user_name'];
                    $previousSuggestion = $row['user_name'];
                }
            }
            $response->setResponse($suggestions);
        } catch (\PDOException $ex) {
            $response->setFailedMessage("Resultado de la búsqueda", "No se ha podido procesar la consulta (error '" . $ex->getCode() . "')");
        }

        // 3) Return JSON response
        return $response;
    }

modelo:

protected function initDaoProperties() {
$this->useCoreDbConnection();
$this->table = "zdk_users";
$this->IdColumnName = "user_id";
$this->query = "select zdk_users.* from zdk_users ";
                $this->filterClause = "where lower(user_name) like lower(?) and zdk_users.full_menu_access <> 1";
}
        public function setNameAsFilter($name) {
        $this->filterClause = " where lower(user_name) like lower(?) and zdk_users.full_menu_access <> 1";
        $this->setFilterCriteria($name);
    }


Saludos

Pascal Martinez

unread,
Sep 11, 2015, 10:31:42 AM9/11/15
to ZnetDK
José,

Tu código aparece correcto.
Solo no entiendo porque tu DAO no esta precedido del espacio de nombre:

$tecnicoDAO = new \app\model\tecnicoDAO();

Estas seguro que llamas el DAO apropriado ?

También, verifica desde tu navegador Internet en modo desarrollo, que el parámetro POST criteria esta efectivamente transmitido en la petición AJAX y que contiene la valor entrada en tu campo autocomplete.
Si no es el caso, tienes un problema en tu vista.

Dime si funciona mejor con esos elementos.

Pascal 

Jose Puertas

unread,
Sep 11, 2015, 5:52:14 PM9/11/15
to ZnetDK
Hola Pascal, mi DAO no está precedido del espacio de nombres ya que le adjunto la siguiente linea antes de la funcion;

use app\model\tecnicoDAO;

y pienso que el error debe estar en el were;

where lower(user_name) like lower(?) and zdk_users.full_menu_access <> 1

al usar el and, aunque lo he probado y no me soluciona nada, necesito ese and para que no se pueda ver el usuario administrador de la aplicación.

Respecto al modo desarrollo, no puedo usarlo ya que lo tengo alojado en un servidor externo porque no he podido hacerlo funcionar en local con xampp.



Saludos

Pascal Martinez

unread,
Sep 12, 2015, 10:33:54 AM9/12/15
to ZnetDK
Hola José,

OK para el espacio de nombre.
No veo problema en tu condición con el 'AND', para mi tendría que funcionar bien.

El modo desarrollo se activa desde tu navegador web pulsando la clave F12.
Puedes también probar que funciona tu controlador sustituyendo la linea siguiente:

$tecnicoDAO->setNameAsFilter('%' . $request->criteria . '%');

Por:

$tecnicoDAO->setNameAsFilter('%o%');

Asi, el widget AutoCompletion tendría que mostrar sistemáticamente una lista de usuarios que contienen la letra "o" en su nombre.

Hasta luego,

Pascal


 

Jose Puertas

unread,
Sep 12, 2015, 11:30:06 AM9/12/15
to ZnetDK
Hola Pascal, cambiando la linea si que funciona, entonces el problema está cuando hace el $request->criteria de donde criteria ¿seria el nombre del input? te muestro el modelo y la vista:

modelo:
protected function initDaoProperties() {
$this->useCoreDbConnection();
$this->table = "zdk_users";
$this->IdColumnName = "user_id";
$this->query = "select zdk_users.* from zdk_users ";
                $this->filterClause = "where lower(user_name) like lower(?) and zdk_users.full_menu_access <> 1";
}
        public function setNameAsFilter($name) {
        $this->filterClause = " where lower(user_name) like lower(?) and zdk_users.full_menu_access <> 1";
        $this->setFilterCriteria($name);
    }

vista:

<div class="zdk-filter-rows">
    <form id="buscar_tecnicos_form" class="zdk-form" style="margin-bottom: 10px;">
        <fieldset>
            <legend>Buscar Entrenador</legend>
            <label>Nombre</label>
            <input type="text" name="critere" class="zdk-autocomplete" 
                   data-zdk-action="tecnicosctrl:Rtecnicos">
        </fieldset>
        <fieldset>
            <button class="zdk-bt-clear" type="reset">Borrar</button>  <button class="zdk-bt-search">Buscar</button>
        </fieldset>
    </form>
</div>

Saludos

Pascal Martinez

unread,
Sep 12, 2015, 3:50:26 PM9/12/15
to ZnetDK
José,

Tienes que cambiar en tu controlador la linea siguiente:
$tecnicoDAO->setNameAsFilter('%' . $request->criteria . '%');
Por
$tecnicoDAO->setNameAsFilter('%' . $request->query . '%');

Pascal

Jose Puertas

unread,
Sep 12, 2015, 4:05:58 PM9/12/15
to ZnetDK
Hola, lo acabo de cambiar todo y sigue igual te copio los modelo, vista controlador:

modelo:
namespace app\model;

class tecnicoDAO extends \DAO {

   protected function initDaoProperties() {
$this->useCoreDbConnection();
$this->table = "zdk_users";
$this->IdColumnName = "user_id";
$this->query = "select zdk_users.* from zdk_users ";
                //$this->query .= "where zdk_users.full_menu_access <> 1";
      $this->filterClause = "where lower(user_name) like lower(?) and zdk_users.full_menu_access <> 1";
}
        public function setNameAsFilter($name) {
        $this->filterClause = " where lower(user_name) like lower(?) and zdk_users.full_menu_access <> 1";
        $this->setFilterCriteria($name);
    }
       
}

vista

<div id="znetdk_user_actions" class="zdk-action-bar"
     data-zdk-dialog="user_dialog"
     data-zdk-datatable="users_datatable">
    <button class="zdk-bt-add" title="Nuevo técnico"><?php echo LC_BTN_NEW; ?></button>
    <button class="zdk-bt-edit" title="modificar técnico"
            data-zdk-noselection="<?php echo LC_MSG_WARN_ROW_NOTSELECTED; ?>"
            ><?php echo LC_BTN_MODIFY; ?>
    </button>
    <button class="zdk-bt-remove" title="Eliminar técnico"
            data-zdk-noselection="<?php echo LC_MSG_WARN_ROW_NOTSELECTED; ?>"
            data-zdk-action="tecnicosctrl:remove"
            data-zdk-confirm="<?php echo LC_MSG_ASK_REMOVE . ':' . LC_BTN_YES . ':' . LC_BTN_NO; ?>"
            ><?php echo LC_BTN_REMOVE; ?>
    </button>

    <!-- Number of rows per page -->
    <select class="zdk-select-rows" title="Filtro">  
        <option value="10">10</option>
        <option value="20">20</option>
        <option value="100">Todo</option>
    </select>
    <div class="zdk-filter-rows" id="buscar_tecnicos_form">
                      <input  name="critere" class="zdk-autocomplete" placeholder ="Buscar..." 
                   data-zdk-action="tecnicosctrl:Rtecnicos">
                  <button class="zdk-bt-clear" type="reset">Borrar</button>  <button class="zdk-bt-search" 
                                                                               data-zdk-novalue="Por favor, Introduzca un criterio de búsqueda.">Buscar</button>
        </div>
</div>

controlador

namespace app\controller;

use app\model\tecnicoDAO;

class tecnicosctrl extends \AppController {

    static protected function action_Rtecnicos() {
        // Get keyword to find out
        $request = new \Request();
        $keyword = $request->query;

        // Construct the list of suggestions
        $tecnicoDAO = new tecnicoDAO();
        $tecnicoDAO->setNameAsFilter('%' . $request->query . '%');
        $tecnicoDAO->setSortCriteria('user_name');
        $tecnicoDAO->setLimit(0, 10);
        
        $response = new \Response();
        $previousSuggestion = " ";
        $suggestions = array();
        try {
            while($row = $tecnicoDAO->getResult()) {
                if ($row['user_name'] !== $previousSuggestion) {
                    $suggestions[]['label'] = $row['user_name'];
                    $previousSuggestion = $row['user_name'];
                }
            }
            $response->setResponse($suggestions);
        } catch (\PDOException $ex) {
            $response->setFailedMessage("Resultado de la búsqueda", "No se ha podido procesar la consulta (error '" . $ex->getCode() . "')");
        }

        // 3) Return JSON response
        return $response;
    }

y aqui es donde lo tengo colgado por si quieres probarlo en acción:


user :  isidro
pass:  isidroe1

Saludos

Pascal Martinez

unread,
Sep 12, 2015, 4:55:45 PM9/12/15
to ZnetDK
José,

En tu vista, tienes que suprimir el atributo class="zdk-autocomplete" porque el widget 'ActionBar' lo crea ya para ti:

<div class="zdk-filter-rows" id="buscar_tecnicos_form">
<input  name="critere" class="zdk-autocomplete" placeholder ="Buscar..."
               data-zdk-action="tecnicosctrl:Rtecnicos">
      <button class="zdk-bt-clear" type="reset">Borrar</button>
      <button class="zdk-bt-search"
          data-zdk-novalue="Por favor, Introduzca un criterio de búsqueda.">Buscar</button>
</div>

Es por este razón que dos "autocompleciones" se muestran cuando introduzca una letra.
Hace falta que añadas la clase 'zdk-autocomplete' solo dentro un formulario ZnetDK (con la clase "zdk-form").

Pascal

Pascal Martinez

unread,
Sep 13, 2015, 6:34:13 AM9/13/15
to ZnetDK
José,

Ademas, dado que usas el widget 'ActionBar', tienes finalmente que leer en tu controlador el parámetro POST 'criteria', no el parámetro 'query'.

Tendría que funcionar ahora.

Pascal.

Jose Puertas

unread,
Sep 13, 2015, 4:25:17 PM9/13/15
to ZnetDK
Muchas gracias pascal por tu tiempo, ahora funciona perfectamente.

Saludos
Reply all
Reply to author
Forward
0 new messages