Una aplicación de búsqueda de películas simple con jQuery UI

En este tutorial, estamos utilizando el widget de autocompletar de jQuery UI para crear un formulario de búsqueda de películas AJAX simple. El guión utilizará la API gratuita de TheMovieDatabase.org para proporcionar sugerencias automáticas en una amplia base de datos de títulos de películas.

Para aquellos de ustedes que no estén familiarizados con TMDb.org, esta es una base de datos de películas abierta y dirigida por la comunidad. Es similar a IMDb, del que probablemente hayas oído hablar, pero también proporciona varias API útiles para los desarrolladores.

Requisitos

Antes de poder usar la API, debe obtener una clave de desarrollador gratuita de TMDb después de un registro rápido. Después de esto, recuerda copiar tu clave a movieInfo.php desde el archivo de descarga.

Paso 1 - XHTML

El marcado consta de los dos contenedores div principales:#logo y #titular . El primero contiene el icono y el texto del logotipo en forma de imágenes PNG transparentes (definidas como fondos de los respectivos div), mientras que el segundo contiene el formulario de búsqueda y el botón de envío.

películaApp.html

<div id="page">

    <div id="logo">
        <div id="icon"></div>
        <div id="movieAppLabel"></div>
    </div>

    <div id="holder">
        <form action="http://www.themoviedb.org/search" method="post" target="_blank">
            <fieldset>
                <input type="text" id="movieName" name="search" />
            </fieldset>
        </form>
        <a href="#" class="button">Submit</a>
    </div>

</div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js"></script>
<script src="script.js"></script>

Observe que el atributo de acción del formulario apunta a la página de búsqueda de TMDB. Los términos de búsqueda se pasan a través de POST con el #movieName campo de texto. Puede probarlo completando el nombre de una película y enviando el formulario.

Por último, en la página se incluyen jQuery, jQuery UI y nuestro propio archivo de script. Estamos utilizando el widget de autocompletar de jQuery UI para mostrar una lista desplegable de títulos de películas que se obtienen de la API de TMDb. Puede ver el marcado generado por el widget a continuación.

<input class="ui-autocomplete-input"/>
<ul class="ui-autocomplete ui-menu ui-widget ui-widget-content ui-corner-all">
  <li class="ui-menu-item">
    <a class="ui-corner-all">item 1</a>
  </li>
  <li class="ui-menu-item">
    <a class="ui-corner-all">item 2</a>
  </li>
  <li class="ui-menu-item">
    <a class="ui-corner-all">item 3</a>
  </li>
</ul>

El widget genera automáticamente este código y se agrega antes de la etiqueta del cuerpo de cierre.

Paso 2 - PHP

Cuando comienza a escribir el título de una película en el cuadro de texto del formulario, se envía una solicitud AJAX a moveInfo.php . Este script envía una solicitud de búsqueda a la API de TMDb, con nuestra clave de desarrollador. El servicio devuelve un objeto JSON con títulos de películas adecuados. El script los procesa y los devuelve como respuesta a la solicitud de AJAX.

Echemos un vistazo más de cerca a cómo funciona esto.

información de la película.php

/**
 *  Define your API key below. To obtain one, visit
 *  http://www.themoviedb.org/account/signup
 */

$api_key = '...';

// If the request was not issued by AJAX, or
// the search term is missing, exit:

if(!$_SERVER["HTTP_X_REQUESTED_WITH"] || !$_GET['term']){
    exit;
}

include 'tmdbAPI/TMDb.php';

$tmdb = new TMDb($api_key);

// Send a search API request to TMDb,
// and parse the returned JSON data:

$json = json_decode($tmdb->searchMovie($_GET['term']));

$response = array();

$i=0;
foreach($json as $movie){

    // Only movies existing in the IMDB catalog (and are not adult) are shown

    if(!$movie->imdb_id || $movie->adult) continue;
    if($i >= 8 ) break;

    // The jQuery autocomplete widget shows the label in the drop down,
    // and adds the value property to the text box.

    $response[$i]['value'] = $movie->name;
    $response[$i]['label'] = $movie->name . ' <small>(' . date('Y',strtotime($movie->released)).')</small>';
    $i++;
}

// Presenting the response as a JSON object:

echo json_encode($response);

Afortunadamente para nosotros, hay una clase de PHP disponible que maneja toda la comunicación con la API de TMDb. Solo necesitamos incluirlo en la página y proporcionar la clave API de desarrollador que recibimos de TMDb. Los términos de búsqueda que el usuario ha ingresado en el cuadro de búsqueda están disponibles en $_GET['term'] . Llamar a searchMovie() con estos términos, generará un objeto JSON, que contiene todo tipo de información sobre las películas que coinciden con nuestros criterios de búsqueda. Puede ver una respuesta de muestra a continuación.

[{
    "score": 8.750235,
    "popularity": 3,
    "translated": true,
    "adult": false,
    "language": "en",
    "name": "The Hitchhiker's Guide to the Galaxy",
    "alternative_name": "The Hitchhikers Guide to the Galaxy",
    "movie_type": "movie",
    "id": 7453,
    "imdb_id": "tt0371724",
    "url": "http://www.themoviedb.org/movie/7453",
    "rating": 6.8,
    "certification": "PG",
    "overview": "Mere seconds before the Earth is to be demolished by an alien construction crew, Arthur Dent is swept off the planet by his friend Ford Prefect, a researcher penning a new edition of \"The Hitchhiker's Guide to the Galaxy.\"",
    "released": "2005-04-20",
    "posters": [{
        "image": {
            "type": "poster",
            "size": "original",
            "height": 1000,
            "width": 675,
            "url": "http://hwcdn.themoviedb.org/posters/16e/4bcc96cd017a3c0f2600016e/the-hitchhiker-s-guide-to-the-galaxy-original.jpg",
            "id": "4bcc96cd017a3c0f2600016e"
        }
    }],
    "version": 22,
    "last_modified_at": "2010-07-19 22:59:02"
}]

La respuesta contiene el título de la película, una resumen , fecha de lanzamiento , un ID de IMDB correspondiente e incluso carteles y fan art . No necesitamos la mayor parte de esta información, por lo que PHP la reduce solo a un título y un año de lanzamiento, después de lo cual la genera en forma de un objeto JSON, listo para ser utilizado por el autocompletado. Esto nos lleva al siguiente paso.

Paso 3:jQuery

Como sabe, jQuery viene con muchas funciones útiles en forma de complementos. También hay una extensión dedicada de la biblioteca, para crear interfaces de usuario, conocida como jQuery UI. Brinda a los desarrolladores widgets, que están listos para usar y son fáciles de personalizar. Uno de estos widgets es el nuevo widget de autocompletar, introducido en las versiones más recientes de la biblioteca.

Echemos un vistazo a cómo se usa.

secuencia de comandos.js

$(document).ready(function(){

    // Caching the movieName textbox:
    var movieName = $('#movieName');

    // Defining a placeholder text:
    movieName.defaultText('Type a Move Title');

    // Using jQuery UI's autocomplete widget:
    movieName.autocomplete({
        minLength   : 5,
        source      : 'movieInfo.php'
    });

    $('#holder .button').click(function(){
        if(movieName.val().length && movieName.data('defaultText') != movieName.val()){
            $('#holder form').submit();
        }
    });
});

// A custom jQuery method for placeholder text:

$.fn.defaultText = function(value){

    var element = this.eq(0);
    element.data('defaultText',value);

    element.focus(function(){
        if(element.val() == value){
            element.val('').removeClass('defaultText');
        }
    }).blur(function(){
        if(element.val() == '' || element.val() == value){
            element.addClass('defaultText').val(value);
        }
    });

    return element.blur();
}

Para crear un autocompletar, solo necesitamos llamar al autocompletar() método. Toma una serie de parámetros opcionales. Los más importantes son minLength (que evita que se envíe una solicitud al servidor antes de que se haya escrito una cierta cantidad de caracteres) y fuente, que determina los datos que se muestran en la lista desplegable.

Fuente puede tomar una matriz con cadenas, una URL (a la que se enviará una solicitud AJAX) o una función de devolución de llamada. En nuestro caso, la URL de movieInfo.php será suficiente.

Aquí hay una respuesta de muestra, que es devuelta por movieInfo.php (este objeto JSON se compiló después de una solicitud a la API de TMDb para "Guía del autoestopista ").

[{
    "value": "Hachiko: A Dog's Story",
    "label": "Hachiko: A Dog's Story <small>(2009)<\/small>"
},
{
    "value": "Teenage Hitch-hikers",
    "label": "Teenage Hitch-hikers <small>(1975)<\/small>"
},
{
    "value": "The Hitchhiker's Guide to the Galaxy",
    "label": "The Hitchhiker's Guide to the Galaxy <small>(2005)<\/small>"
},
{
    "value": "The Hitch-Hiker",
    "label": "The Hitch-Hiker <small>(1953)<\/small>"
}]

Cada objeto en la matriz contiene un valor y una etiqueta propiedad. La etiqueta solo se muestra en la lista desplegable, mientras que el valor se inserta en el cuadro de texto una vez que se selecciona el elemento.

Paso 4 - CSS

Ahora que se generó todo el marcado y está en su lugar, es hora de comenzar a embellecer.

estilos.css - Parte 1

#page{
    width:600px;
    margin:150px auto 0;
}

/* Logo */

#logo{
    width:380px;
    position:relative;
    height:90px;
    margin:0 auto;
}

#icon{
    width:80px;
    height:86px;
    background:url('img/icon.png') no-repeat;
    float:left;
}

#movieAppLabel{
    width:268px;
    height:58px;
    background:url('img/logo_txt.png') no-repeat;
    position:absolute;
    right:0;
    top:18px;
}

/* The Search Box & Holder */

#holder{
    width:530px;
    height:145px;
    background:url('img/holder.png') no-repeat center center;
    margin:30px auto;
    position:relative;
}

#holder fieldset{
    position:absolute;
    top:52px;
    left:40px;
    border-bottom:1px solid #fff;
}

#holder input{
    font-family:'Myriad Pro',Arial,Helvetica,sans-serif;
    border:none;
    border-bottom:1px solid #bbb;
    background:none;
    color:#8D8D8D;
    font-size:20px;
    padding:4px 0;
    width:250px;
    text-shadow:1px 1px #fff;
    outline:none;
}

En la primera parte del código, le damos estilo al #logo y el #titular divs. El icono del obturador y el texto del logotipo se definen como fondos para el #icono y #movieAppLabel div respectivamente. El posicionamiento relativo se aplica al #titular para que sea más fácil colocar el cuadro de entrada y el botón de enviar.

estilos.css - Parte 2

fieldset{
    border:none;
}

/* The Blue Button */

a.button{
    background:url('img/buttons.png') no-repeat;
    width:105px;
    height:37px;
    position:absolute;
    top:52px;
    right:42px;
    text-indent:-9999px;
    overflow:hidden;
    border:none !important;
}

a.button:hover{
    background-position:left bottom;
}

/* Styling the markup generated by the autocomplete jQuery UI widget */

ul.ui-autocomplete{
    width:250px;
    background-color:#f5f5f5;
    border:1px solid #fff;
    outline:1px solid #ccc;
}

ul.ui-autocomplete li{
    list-style:none;
    border-bottom:1px solid #e0e0e0;
    border-top:1px solid #fff;
}

ul.ui-autocomplete li:first-child{
    border-top:none;
}

ul.ui-autocomplete li:last-child{
    border-bottom:none;
}

ul.ui-autocomplete li a{
    color:#999;
    border:none !important;
    text-decoration:none !important;
    padding:10px 17px;
    display:block;
}

#ui-active-menuitem{
    background-color:#fff;
    color:#666;
    cursor:pointer;
}

jQuery UI viene con sus propios estilos, sin embargo, son bastante torpes y no encajan bien en el diseño actual. Es por eso que estamos aplicando una serie de reglas (a partir de la línea 23), que aplican un diseño personalizado al widget de autocompletar. La estructura del widget es básicamente una lista desordenada, en la que cada uno de los elementos sugeridos es un hipervínculo en un li elemento. Con esto en mente (y después de buscar los nombres de clase apropiados del código en el paso uno), podemos diseñar la lista desplegable de manera segura y combinarla perfectamente con el resto del diseño.

¡Con esto, nuestra aplicación de búsqueda simple de películas está completa!

Para terminar

Puede modificar este script para usar cualquier tipo de API y datos. Esta puede ser una herramienta poderosa, ya que podría ayudar a los usuarios a escribir términos de búsqueda que normalmente no pensarían en ellos mismos. Por ejemplo, proporcionar los nombres de sus productos como sugerencias de búsqueda puede ser una táctica efectiva para exponer más de su mercancía y mejorar las ventas.

¿Qué opinas? ¿Cómo mejorarías esta aplicación?