bootstrap typeahead return name and id

41,452

Solution 1

A typical JSON document that contains name/ID pairs is going to look like this:

[
  {
    "id": 1
    "name": "firstName"
  },
  {
    "id": 2
    "name": "secondName"
  }
]

The strategy here is to build an object literal that maps names to IDs as you parse the result, while only using the name to populate the typeahead:

var productNames = new Array();
var productIds = new Object();
$.getJSON( '/getAjaxProducts', null,
        function ( jsonData )
        {
            $.each( jsonData, function ( index, product )
            {
                productNames.push( product.name );
                productIds[product.name] = product.id;
            } );
            $( '#product' ).typeahead( { source:productNames } );
        } );

Once the user selects an item from the typeahead, you can reference the selected item with:

$( '#product' ).val()

and you can get the ID associated with the selected item with:

productIds[$( '#product' ).val()]

From your question, it looks like your JSON document may be structured a little bit differently, so you would change the parsing as appropriate, but the same general strategy applies.

Solution 2

Sorry to "resurect" this post but i was going to be crazy !

If some of you have problems using theses sample codes ( none of them were working, all were returning "Undefined" instead of showing the name

Just add

displayKey: 'name',

Replace of course 'name' by your label var name returned by your remote source

( Quite hard to find up to date samples on it, most of samples found on the net are for the previous version of typeahead and not compatibles with new ones ... )

Solution 3

......updater: function (item) {
        var item = JSON.parse(item);
        console.log(item.name); 
        $('#VehicleAssignedTechId').val(item.id);       
        return item.name;
    }

On updater of the typeahead call you can put as above code which allows you to add selcted value in the textbox or where you have to put its value in other hidden field.

Full ajax call is as below:

$('#VehicleAssignedTechName').typeahead({
    source: function(query, process) {
        var $url =SITE_URL+ 'api/vehicle_techfield_typeahead/' + query + '.json';
        var $items = new Array;
        $items = [""];
        $.ajax({
            url: $url,
            dataType: "json",
            type: "POST",
            success: function(data) {
                console.log(data);
                $.map(data, function(data){
                    var group;
                    group = {
                        id: data.id,
                        name: data.name,                            
                        toString: function () {
                            return JSON.stringify(this);
                            //return this.app;
                        },
                        toLowerCase: function () {
                            return this.name.toLowerCase();
                        },
                        indexOf: function (string) {
                            return String.prototype.indexOf.apply(this.name, arguments);
                        },
                        replace: function (string) {
                            var value = '';
                            value +=  this.name;
                            if(typeof(this.level) != 'undefined') {
                                value += ' <span class="pull-right muted">';
                                value += this.level;
                                value += '</span>';
                            }
                            return String.prototype.replace.apply('<div style="padding: 10px; font-size: 1.5em;">' + value + '</div>', arguments);
                        }
                    };
                    $items.push(group);
                });

                process($items);
            }
        });
    },
    property: 'name',
    items: 10,
    minLength: 2,
    updater: function (item) {
        var item = JSON.parse(item);
        console.log(item.name); 
        $('#VehicleAssignedTechId').val(item.id);       
        return item.name;
    }
});

Solution 4

My solution is:

var productNames = new Array();
var productIds = new Object();
$.getJSON( '/getAjaxProducts', null,
        function ( jsonData )
        {
            $.each( jsonData, function ( index, product )
            {
                productNames.push( product.id + product.name );
                productIds[product.id + product.name] = product.id;
            } );
            $( '#product' ).typeahead( { source:productNames } );
        } );

In my case, product.id is a code, so it is useful to display it in typeahead control. In this way i avoided duplicated names risk.

Share:
41,452
iMoldovean.com
Author by

iMoldovean.com

Updated on July 21, 2022

Comments

  • iMoldovean.com
    iMoldovean.com almost 2 years

    Hy! I'm using twitter bootstraps typeahead:

    I'm calling a page that returns a response with json_encode the page returns a name and an ID,

    I want that the typeahead list will show me the list of names, and when I select one of the name to write the id value to a hidden field.

    the calling works fine, and to write a field should be easy. what i dont know what to do is how to divide the name from the id.

    now, when i search something, in the suggesstion list I can see the returning results like this:

    name1:id1 name2:id2

    i only want to see names but to carry the value of id too.

    how can i do that?

     $(function(){
        $("#typeahead_<? print $key; ?>").typeahead(
            {
            source: function(query, process)
                        {
                        $.ajax({
                            url:    '/getAjaxProducts',
                            type:   'POST',
                            data:   'query=' + query,
                            dataType: 'JSON',
                            async: true,
                            success: function(data)
                                    {
                                    process(data);
                                    }
                                });                 
                        }
            });
    });
    
  • RickardN
    RickardN almost 11 years
    This solution implies that the names are unique. In most cases they probably are, but I felt that I needed to point that out.
  • Dunc
    Dunc over 10 years
    With the latest typeahead.js it's local:productNames rather than source:productNames.
  • Corby Page
    Corby Page over 10 years
    I can't imagine what the use-case would be for a situation where the names are not unique. This means you would have two identical options in the dropdown, with no means for the end-user to differentiate between them. How would the user know what to select?
  • bratsche
    bratsche almost 9 years
    The use case would be a situation where you have people's names, like John James and Bill Johnson. You could differentiate for the user by rendering custom templates with profile pictures (so, your JSON might need to have fields for id, name, and profile pic URL).
  • Cesar
    Cesar over 7 years
    This is the correct approach. Any solution that relies on the displayed string will break easily.
  • Alex Z
    Alex Z over 6 years
    useful, thanks. Just also need add substr method. substr: function(string) { return String.prototype.substr.apply(this.name, arguments); }
  • Jason Liu
    Jason Liu over 3 years
    This solution loaded all the data at once right? As I don't see the query parameter. There would be an issue if the backend only return certain amount of data. I.E. you have to assign query parameter for more specific data.