sábado, janeiro 19, 2013

Dica: Bootstrap typeahead com objeto

O objeto padrão de retorno usado pelo typeahead (http://twitter.github.com/bootstrap/), é um array de String, por exemplo:

{
    "options": [
        "Cliente ABC",
        "Cliente XYZ",
        "Cliente LTDA",
        "Cliente SA",
        "Cliente N"
    ]
}

Imagine que vc está está usando o um webservices como source do typeahead, e além de mostrar o nome do cliente na listagem do typeahead, vc precisa do id desse cliente. A solução que encontrei foi criar uma classe Option com operações semelhantes a um objeto String :

function Option (id, value) {
    this.id = id;
    this.value = value;
    this.toLowerCase = function() {
        return value.toLowerCase();
    };
    this.replace = function(){
        return value.replace();
    };
    this.indexOf = function(){
        return value.indexOf();
    };
    this.toString = function(){
        return value;
    };
    this.getValue = function(){
        return value;
    };
    this.getId = function(){
        return id;
    };
}
O código do typeahead ficaria assim:

$('.typeahead').typeahead({
        minLength: 4,
        items: 7,
        source:function (query, process) {
            return $.ajax({
                url:'/customers.json',
                type:'get',
                data:{search_name:query},
                dataType:'json',
                success:function (json) {
                    var options = new Array;
                    $.each(json, function (i, customer) {
                        var option = new Option(customer.id, customer.name);
                        options.push(option);
                    });
                    return process(options);
                }
            });
        },
        updater:function (item) {
            return item.toString();
        },
        highlighter: function (item) {
            var regex = new RegExp( '(' + this.query + ')', 'gi' );
            return item.toString().replace( regex, "$1" );
        }
    });