Yii-Crear un campo con autocompletar

En este artículo, veremos como implementar en nuestro formulario un campo con autocompletado, utilizando un widget de Yii (CJuiAutoComplete), pensado ya para eso, pero utilizando Ajax para obtener la información desde el servidor.
El ejemplo esta sacado de Javascript and AJAX with Yii , en donde nos presentan una vision mas general del uso de Ajax en este Framework, siendo un artículo muy interesante y que deberiais leer.
En el ejemplo, vamos a completar un campo, a la vez que guardamos en otro (oculto) el id que realmente nos interesa para nuestro formulario. Imaginaros que hablamos de nombres de usuario, pues mientras que nuestro visitante vá tecleando letras, nosotros le ofreceriamos el posible nombre de usuario, mientras que ya iríamos guardando el id de ese usuario, en el campo oculto.

Para ello, primero creamos el campo oculto; por ejemplo:

echo $form->hiddenField($model, 'userId');

A continuación creamos la URL del servicio; utilizamos métodos de Yii para hacerlo y, asi si decidimos cambiar la forma de las URLs con URLManager, nos seguirá funcionando.

$quotedUrl = CJavascript::encode($this->createUrl(array('user/complete')));

Ahora ya estamos preparados para definir los parametros a utilizar por CJuiAutoComplete

$params = array(
    'name' => "userComplete",
    'source' => 'js:function(request, response) {
        $.ajax({
            url: "'. $quotedUrl . '",
            data: { "term": request.term, "fulltext": 1 },
            success: function(data) { response(data); }
        });
}',
    // additional javascript options for the autocomplete plugin
    // See <http://jqueryui.com/demos/autocomplete/#options>
    'options' => array(
        'minLength' => '3', // min letters typed before we try to complete
        'select' => "js:function(event, ui) {
            jQuery('#MyModel_userId').val(ui.item.id);
            return true;
}",
    ),
);

Si os fijáis es un array asociativa en la que rellenamos tres valores:

  • name, para indicar el nombre del campo autocompletado, (el visible sobre el que realizaremos la magia)
  • source, en donde indicarémos de donde vamos a sacar la información, que en nuestro caso, sera una rutina javascript(empieza por js), en donde , utilizando Ajax, enviaremos a nuestro servidor las letras que nuestro visitante haya tecleado (request.term)  y los parámetros que necesitemos.(en el ejemplo, el parametro es «fulltext» y el valor 1, y por último declaramos que cuando vengan los datos (success) se los pase a la función response, que se encargara de situarlos donde convenga.
  • options, para indicarle las funciones del widgets, como la longitud mínima a partir de la que queremos que inicie el autocompletar,(en nuestro ejemplo tres caracteres) y la función con la que realizamos la seleccion.
    Esta función es llamada por «response(data)» que hemos indicado en la llamada Ajax, y recibe como segundo parametro (ui) el valor recibido por Ajax, por lo que aprovechámos para guardar en nuestro campo oculto el valor recibido por id. El nombre a utilizar, lo deberemos comprobar en la página generada, paraver como lo ha construido Yii

Una vez todo preparado, podemos insertar nuestro campo de autocompletar en el formulario con

$this->widget('zii.widgets.jui.CJuiAutoComplete', $params);

Por último vamos a ver la funcion que deberemos incluir en nuestro controlador «userController» para que todo esto funcione:

/**
 * Propose completions for a term (AJAX).
 */
public function actionAjaxComplete()
{
    if (!YII_DEBUG && !Yii::app()->request->isAjaxRequest) {
        throw new CHttpException('403', 'Forbidden access.');
    }
    if (empty($_GET['term'])) {
        throw new CHttpException('404', 'Missing "term" GET parameter.');
    }
    $term = $_GET['term'];
    $filters = empty($_GET['fulltext']) ? null : (int) $_GET['fulltext']);
    header('Content-Type: application/json; charset="UTF-8"');
    echo json_encode(User::completeTerm($term, $filters));
    Yii::app()->end();
}

Como veis es muy sencilla, comprobamos que la llamada se puede hacer y es correcta, y devolvemos los datos que nos entregue User::completeTerm($term, $exclude) que debería ser una array con las etiquetas «id», «value», y «label»

 

Acerca de Miguel Garcia

Programador, Desarrollador web, Formador en distintas areas de informatica y director de equipos multidisciplinares.
Esta entrada fue publicada en Desarrollo Web, Formacion, YII - Generador de codigo PHP y etiquetada , , , . Guarda el enlace permanente.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.