Thursday, 25 July 2013

Creating a simple autocomplete control with Bootstrap for with a remote JSON service

I have worked a bit with the Twitter Bootstrap javascript library / framework and testet out the TypeAhead control. I could not find a complete example of how to get the autocomplete items from a remote JSON service, so I testet it out myself. Let's first define a web service (ASP.NET) which will return the list of sovereign states in the world:
//using System;
//using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;

namespace TestBootstrapCss
{
    /// <summary>
    /// Summary description for CountryService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    public class CountryService : System.Web.Services.WebService
    {

        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public Country[] GetCountries(string query)
        {
            if (cachedCountryList == null)
                cachedCountryList = GetCountryList();

            var result = cachedCountryList.Where(c => c.Name.StartsWith(query, System.StringComparison.CurrentCultureIgnoreCase)).ToArray();
            return result;
        }

        public class Country
        {
            public int Id { get; set; }

            public string Name { get; set; }

            public int Population { get; set; }

            public double WorldPercentage { get; set; }

        }

        private static Country[] cachedCountryList = null; 

        public Country[] GetCountryList()
        {
            return new Country[] {
                new Country { Id =1,Name = "China",Population = 1354040000 ,WorldPercentage = 19.07 },
                new Country { Id =2,Name = "India",Population = 1210569573 ,WorldPercentage = 17.05 },
                new Country { Id =3,Name = "United States",Population = 316318000 ,WorldPercentage = 4.45 },
                new Country { Id =4,Name = "Indonesia",Population = 237641326 ,WorldPercentage = 3.35 },
                new Country { Id =5,Name = "Brazil",Population = 193946886 ,WorldPercentage = 2.73 },
                new Country { Id =6,Name = "Pakistan",Population = 183766000 ,WorldPercentage = 2.59 },
                new Country { Id =7,Name = "Nigeria",Population = 173615000 ,WorldPercentage = 2.45 },
                new Country { Id =8,Name = "Bangladesh",Population = 152518015 ,WorldPercentage = 2.15 },
                new Country { Id =9,Name = "Russia",Population = 143400000 ,WorldPercentage = 2.02 },
                new Country { Id =10,Name = "Japan",Population = 127350000 ,WorldPercentage = 1.79 },
                new Country { Id =11,Name = "Mexico",Population = 118419000 ,WorldPercentage = 1.67 },
                new Country { Id =12,Name = "Philippines",Population = 98100000 ,WorldPercentage = 1.38 },
                new Country { Id =13,Name = "Vietnam",Population = 88780000 ,WorldPercentage = 1.25 },
                new Country { Id =14,Name = "Ethiopia",Population = 86613986 ,WorldPercentage = 1.22 },
                new Country { Id =15,Name = "Egypt",Population = 83661000 ,WorldPercentage = 1.18 },
                new Country { Id =16,Name = "Germany",Population = 80493000 ,WorldPercentage = 1.13 },
                new Country { Id =17,Name = "Iran",Population = 76768000 ,WorldPercentage = 1.08 },
                new Country { Id =18,Name = "Turkey",Population = 75627384 ,WorldPercentage = 1.07 },
                new Country { Id =19,Name = "Democratic Republic of the Congo",Population = 67514000 ,WorldPercentage = 0.95 },
                new Country { Id =20,Name = "Thailand",Population = 65926261 ,WorldPercentage = 0.93 },
                new Country { Id =21,Name = "France[9]",Population = 65684000 ,WorldPercentage = 0.92 },
                new Country { Id =22,Name = "United Kingdom",Population = 63181775 ,WorldPercentage = 0.89 },
                new Country { Id =23,Name = "Italy",Population = 59704082 ,WorldPercentage = 0.84 },
                new Country { Id =24,Name = "Myanmar",Population = 53259000 ,WorldPercentage = 0.75 },
                new Country { Id =25,Name = "South Africa",Population = 52981991 ,WorldPercentage = 0.75 },
                new Country { Id =26,Name = "South Korea",Population = 50219669 ,WorldPercentage = 0.71 },
                new Country { Id =27,Name = "Colombia",Population = 47159000 ,WorldPercentage = 0.66 },
                new Country { Id =28,Name = "Spain",Population = 47059533 ,WorldPercentage = 0.66 },
                new Country { Id =29,Name = "Ukraine",Population = 45495252 ,WorldPercentage = 0.64 },
                new Country { Id =30,Name = "Tanzania",Population = 44928923 ,WorldPercentage = 0.63 },
                new Country { Id =31,Name = "Kenya",Population = 44354000 ,WorldPercentage = 0.62 },
                new Country { Id =32,Name = "Argentina",Population = 40117096 ,WorldPercentage = 0.57 },
                new Country { Id =33,Name = "Poland",Population = 38533299 ,WorldPercentage = 0.54 },
                new Country { Id =34,Name = "Sudan",Population = 37964000 ,WorldPercentage = 0.53 },
                new Country { Id =35,Name = "Algeria",Population = 37900000 ,WorldPercentage = 0.53 },
                new Country { Id =36,Name = "Canada",Population = 35141542 ,WorldPercentage = 0.49 },
                new Country { Id =37,Name = "Uganda",Population = 34131400 ,WorldPercentage = 0.48 },
                new Country { Id =38,Name = "Iraq",Population = 33330000 ,WorldPercentage = 0.47 },
                new Country { Id =39,Name = "Morocco",Population = 32973200 ,WorldPercentage = 0.46 },
                new Country { Id =40,Name = "Peru",Population = 30475144 ,WorldPercentage = 0.43 },
                new Country { Id =41,Name = "Malaysia",Population = 29747000 ,WorldPercentage = 0.42 },
                new Country { Id =42,Name = "Uzbekistan",Population = 29559100 ,WorldPercentage = 0.42 },
                new Country { Id =43,Name = "Saudi Arabia",Population = 29195895 ,WorldPercentage = 0.41 },
                new Country { Id =44,Name = "Venezuela",Population = 28946101 ,WorldPercentage = 0.41 },
                new Country { Id =45,Name = "Nepal",Population = 26494504 ,WorldPercentage = 0.37 },
                new Country { Id =46,Name = "Afghanistan",Population = 25500100 ,WorldPercentage = 0.36 },
                new Country { Id =47,Name = "North Korea",Population = 24895000 ,WorldPercentage = 0.35 },
                new Country { Id =48,Name = "Ghana",Population = 24658823 ,WorldPercentage = 0.35 },
                new Country { Id =49,Name = "Yemen",Population = 24527000 ,WorldPercentage = 0.35 },
                new Country { Id =50,Name = "Mozambique",Population = 24366112 ,WorldPercentage = 0.34 },
                new Country { Id =51,Name = "Taiwan[10]",Population = 23340136 ,WorldPercentage = 0.33 },
                new Country { Id =52,Name = "Ivory Coast",Population = 23202000 ,WorldPercentage = 0.33 },
                new Country { Id =53,Name = "Australia",Population = 23096296 ,WorldPercentage = 0.33 },
                new Country { Id =54,Name = "Syria",Population = 21377000 ,WorldPercentage = 0.3 },
                new Country { Id =55,Name = "Madagascar",Population = 20696070 ,WorldPercentage = 0.29 },
                new Country { Id =56,Name = "Angola",Population = 20609294 ,WorldPercentage = 0.29 },
                new Country { Id =57,Name = "Cameroon",Population = 20386799 ,WorldPercentage = 0.29 },
                new Country { Id =58,Name = "Sri Lanka",Population = 20277597 ,WorldPercentage = 0.29 },
                new Country { Id =59,Name = "Romania",Population = 20121641 ,WorldPercentage = 0.28 },
                new Country { Id =60,Name = "Burkina Faso",Population = 17322796 ,WorldPercentage = 0.24 },
                new Country { Id =61,Name = "Niger",Population = 17129076 ,WorldPercentage = 0.24 },
                new Country { Id =62,Name = "Kazakhstan",Population = 17010000 ,WorldPercentage = 0.24 },
                new Country { Id =63,Name = "Netherlands",Population = 16793700 ,WorldPercentage = 0.24 },
                new Country { Id =64,Name = "Chile",Population = 16634603 ,WorldPercentage = 0.23 },
                new Country { Id =65,Name = "Ecuador",Population = 15535800 ,WorldPercentage = 0.22 },
                new Country { Id =66,Name = "Guatemala",Population = 15438384 ,WorldPercentage = 0.22 },
                new Country { Id =67,Name = "Mali",Population = 15302000 ,WorldPercentage = 0.22 },
                new Country { Id =68,Name = "Cambodia",Population = 15135000 ,WorldPercentage = 0.21 },
                new Country { Id =69,Name = "Malawi",Population = 14388600 ,WorldPercentage = 0.2 },
                new Country { Id =70,Name = "Senegal",Population = 13567338 ,WorldPercentage = 0.19 },
                new Country { Id =71,Name = "Zambia",Population = 13092666 ,WorldPercentage = 0.18 },
                new Country { Id =72,Name = "Zimbabwe",Population = 12973808 ,WorldPercentage = 0.18 },
                new Country { Id =73,Name = "Chad",Population = 12825000 ,WorldPercentage = 0.18 },
                new Country { Id =74,Name = "South Sudan",Population = 11296000 ,WorldPercentage = 0.16 },
                new Country { Id =75,Name = "Cuba",Population = 11163934 ,WorldPercentage = 0.16 },
                new Country { Id =76,Name = "Belgium",Population = 11156136 ,WorldPercentage = 0.16 },
                new Country { Id =77,Name = "Guinea",Population = 10824200 ,WorldPercentage = 0.15 },
                new Country { Id =78,Name = "Greece",Population = 10815197 ,WorldPercentage = 0.15 },
                new Country { Id =79,Name = "Tunisia",Population = 10777500 ,WorldPercentage = 0.15 },
                new Country { Id =80,Name = "Portugal",Population = 10562178 ,WorldPercentage = 0.15 },
                new Country { Id =81,Name = "Rwanda",Population = 10537222 ,WorldPercentage = 0.15 },
                new Country { Id =82,Name = "Czech Republic",Population = 10512800 ,WorldPercentage = 0.15 },
                new Country { Id =83,Name = "Somalia[11]",Population = 10496000 ,WorldPercentage = 0.15 },
                new Country { Id =84,Name = "Haiti",Population = 10413211 ,WorldPercentage = 0.15 },
                new Country { Id =85,Name = "Bolivia",Population = 10389913 ,WorldPercentage = 0.15 },
                new Country { Id =86,Name = "Benin",Population = 10323000 ,WorldPercentage = 0.15 },
                new Country { Id =87,Name = "Burundi",Population = 10163000 ,WorldPercentage = 0.14 },
                new Country { Id =88,Name = "Hungary",Population = 9906000 ,WorldPercentage = 0.14 },
                new Country { Id =89,Name = "Sweden",Population = 9588569 ,WorldPercentage = 0.14 },
                new Country { Id =90,Name = "Belarus",Population = 9458700 ,WorldPercentage = 0.13 },
                new Country { Id =91,Name = "Dominican Republic",Population = 9445281 ,WorldPercentage = 0.13 },
                new Country { Id =92,Name = "Azerbaijan",Population = 9235100 ,WorldPercentage = 0.13 },
                new Country { Id =93,Name = "Austria",Population = 8464554 ,WorldPercentage = 0.12 },
                new Country { Id =94,Name = "Honduras",Population = 8385072 ,WorldPercentage = 0.12 },
                new Country { Id =95,Name = "United Arab Emirates",Population = 8264070 ,WorldPercentage = 0.12 },
                new Country { Id =96,Name = "Switzerland",Population = 8058100 ,WorldPercentage = 0.11 },
                new Country { Id =97,Name = "Israel",Population = 8034900 ,WorldPercentage = 0.11 },
                new Country { Id =98,Name = "Tajikistan",Population = 8000000 ,WorldPercentage = 0.11 },
                new Country { Id =99,Name = "Bulgaria",Population = 7282041 ,WorldPercentage = 0.1 },
                new Country { Id =100,Name = "Serbia[12]",Population = 7241295 ,WorldPercentage = 0.1 },
                new Country { Id =101,Name = "Hong Kong (China)",Population = 7173900 ,WorldPercentage = 0.1 },
                new Country { Id =102,Name = "Papua New Guinea",Population = 7059653 ,WorldPercentage = 0.099 },
                new Country { Id =103,Name = "Paraguay",Population = 6672631 ,WorldPercentage = 0.094 },
                new Country { Id =104,Name = "Laos",Population = 6580800 ,WorldPercentage = 0.093 },
                new Country { Id =105,Name = "Jordan",Population = 6467500 ,WorldPercentage = 0.09 },
                new Country { Id =106,Name = "Eritrea",Population = 6333000 ,WorldPercentage = 0.089 },
                new Country { Id =107,Name = "Libya",Population = 6202000 ,WorldPercentage = 0.087 },
                new Country { Id =108,Name = "Togo",Population = 6191155 ,WorldPercentage = 0.087 },
                new Country { Id =109,Name = "El Salvador",Population = 6183000 ,WorldPercentage = 0.087 },
                new Country { Id =110,Name = "Sierra Leone",Population = 6092000 ,WorldPercentage = 0.086 },
                new Country { Id =111,Name = "Nicaragua",Population = 6071045 ,WorldPercentage = 0.086 },
                new Country { Id =112,Name = "Denmark",Population = 5605836 ,WorldPercentage = 0.079 },
                new Country { Id =113,Name = "Kyrgyzstan",Population = 5551900 ,WorldPercentage = 0.078 },
                new Country { Id =114,Name = "Finland",Population = 5434357 ,WorldPercentage = 0.077 },
                new Country { Id =115,Name = "Slovakia",Population = 5410728 ,WorldPercentage = 0.076 },
                new Country { Id =116,Name = "Singapore",Population = 5312400 ,WorldPercentage = 0.075 },
                new Country { Id =117,Name = "Turkmenistan",Population = 5240000 ,WorldPercentage = 0.074 },
                new Country { Id =118,Name = "Norway",Population = 5063709 ,WorldPercentage = 0.071 },
                new Country { Id =119,Name = "Lebanon",Population = 4822000 ,WorldPercentage = 0.068 },
                new Country { Id =120,Name = "Costa Rica",Population = 4667096 ,WorldPercentage = 0.066 },
                new Country { Id =121,Name = "Central African Republic",Population = 4616000 ,WorldPercentage = 0.065 },
                new Country { Id =122,Name = "Ireland",Population = 4585400 ,WorldPercentage = 0.065 },
                new Country { Id =123,Name = "Georgia[13]",Population = 4483800 ,WorldPercentage = 0.063 },
                new Country { Id =124,Name = "New Zealand",Population = 4471380 ,WorldPercentage = 0.063 },
                new Country { Id =125,Name = "Republic of the Congo",Population = 4448000 ,WorldPercentage = 0.063 },
                new Country { Id =126,Name = "Palestine[14]",Population = 4420549 ,WorldPercentage = 0.062 },
                new Country { Id =127,Name = "Liberia",Population = 4294000 ,WorldPercentage = 0.06 },
                new Country { Id =128,Name = "Croatia",Population = 4290612 ,WorldPercentage = 0.06 },
                new Country { Id =129,Name = "Bosnia and Herzegovina",Population = 3839737 ,WorldPercentage = 0.054 },
                new Country { Id =130,Name = "Oman",Population = 3831553 ,WorldPercentage = 0.054 },
                new Country { Id =131,Name = "Puerto Rico (USA)",Population = 3667084 ,WorldPercentage = 0.052 },
                new Country { Id =132,Name = "Kuwait",Population = 3582054 ,WorldPercentage = 0.05 },
                new Country { Id =133,Name = "Moldova[15]",Population = 3559500 ,WorldPercentage = 0.05 },
                new Country { Id =134,Name = "Mauritania",Population = 3461041 ,WorldPercentage = 0.049 },
                new Country { Id =135,Name = "Panama",Population = 3405813 ,WorldPercentage = 0.048 },
                new Country { Id =136,Name = "Uruguay",Population = 3286314 ,WorldPercentage = 0.046 },
                new Country { Id =137,Name = "Armenia",Population = 3031200 ,WorldPercentage = 0.043 },
                new Country { Id =138,Name = "Lithuania",Population = 2960733 ,WorldPercentage = 0.042 },
                new Country { Id =139,Name = "Albania",Population = 2821977 ,WorldPercentage = 0.04 },
                new Country { Id =140,Name = "Mongolia",Population = 2754685 ,WorldPercentage = 0.039 },
                new Country { Id =141,Name = "Jamaica",Population = 2711476 ,WorldPercentage = 0.038 },
                new Country { Id =142,Name = "Namibia",Population = 2113077 ,WorldPercentage = 0.03 },
                new Country { Id =143,Name = "Lesotho",Population = 2074000 ,WorldPercentage = 0.029 },
                new Country { Id =144,Name = "Slovenia",Population = 2060461 ,WorldPercentage = 0.029 },
                new Country { Id =145,Name = "Macedonia",Population = 2059794 ,WorldPercentage = 0.029 },
                new Country { Id =146,Name = "Botswana",Population = 2024904 ,WorldPercentage = 0.029 },
                new Country { Id =147,Name = "Latvia",Population = 2013400 ,WorldPercentage = 0.028 },
                new Country { Id =148,Name = "Qatar",Population = 1963124 ,WorldPercentage = 0.028 },
                new Country { Id =149,Name = "Gambia",Population = 1849000 ,WorldPercentage = 0.026 },
                new Country { Id =150,Name = "Guinea-Bissau",Population = 1704000 ,WorldPercentage = 0.024 },
                new Country { Id =151,Name = "Gabon",Population = 1672000 ,WorldPercentage = 0.024 },
                new Country { Id =152,Name = "Equatorial Guinea",Population = 1622000 ,WorldPercentage = 0.023 },
                new Country { Id =153,Name = "Trinidad and Tobago",Population = 1328019 ,WorldPercentage = 0.019 },
                new Country { Id =154,Name = "Estonia",Population = 1286540 ,WorldPercentage = 0.018 },
                new Country { Id =155,Name = "Mauritius",Population = 1257900 ,WorldPercentage = 0.018 },
                new Country { Id =156,Name = "Swaziland",Population = 1250000 ,WorldPercentage = 0.018 },
                new Country { Id =157,Name = "Bahrain",Population = 1234571 ,WorldPercentage = 0.017 },
                new Country { Id =158,Name = "Timor-Leste",Population = 1066409 ,WorldPercentage = 0.015 },
                new Country { Id =159,Name = "Djibouti",Population = 864618 ,WorldPercentage = 0.012 },
                new Country { Id =160,Name = "Cyprus[16]",Population = 862 ,WorldPercentage = 0.012 },
                new Country { Id =161,Name = "Fiji",Population = 858038 ,WorldPercentage = 0.012 },
                new Country { Id =162,Name = "Réunion (France)",Population = 821136 ,WorldPercentage = 0.012 },
                new Country { Id =163,Name = "Guyana",Population = 784894 ,WorldPercentage = 0.011 },
                new Country { Id =164,Name = "Bhutan",Population = 73674 ,WorldPercentage = 0.01 },
                new Country { Id =165,Name = "Comoros",Population = 7243 ,WorldPercentage = 0.01 },
                new Country { Id =166,Name = "Montenegro",Population = 620029 ,WorldPercentage = 0.0087 },
                new Country { Id =167,Name = "Macau (China)",Population = 582 ,WorldPercentage = 0.0082 },
                new Country { Id =168,Name = "Western Sahara[17]",Population = 567 ,WorldPercentage = 0.008 },
                new Country { Id =169,Name = "Solomon Islands",Population = 561 ,WorldPercentage = 0.0079 },
                new Country { Id =170,Name = "Luxembourg",Population = 537 ,WorldPercentage = 0.0076 },
                new Country { Id =171,Name = "Suri,Name",Population = 534189 ,WorldPercentage = 0.0075 },
                new Country { Id =172,Name = "Cape Verde",Population = 491875 ,WorldPercentage = 0.0069 },
                new Country { Id =173,Name = "Malta",Population = 416055 ,WorldPercentage = 0.0059 },
                new Country { Id =174,Name = "Guadeloupe (France)",Population = 403355 ,WorldPercentage = 0.0057 },
                new Country { Id =175,Name = "Martinique (France)",Population = 394173 ,WorldPercentage = 0.0056 },
                new Country { Id =176,Name = "Brunei",Population = 393162 ,WorldPercentage = 0.0055 },
                new Country { Id =177,Name = "Bahamas",Population = 351461 ,WorldPercentage = 0.0049 },
                new Country { Id =178,Name = "Iceland",Population = 32381 ,WorldPercentage = 0.0045 },
                new Country { Id =179,Name = "Maldives",Population = 31728 ,WorldPercentage = 0.0045 },
                new Country { Id =180,Name = "Belize",Population = 312971 ,WorldPercentage = 0.0044 },
                new Country { Id =181,Name = "Barbados",Population = 2742 ,WorldPercentage = 0.0039 },
                new Country { Id =182,Name = "French Polynesia (France)",Population = 26827 ,WorldPercentage = 0.0038 },
                new Country { Id =183,Name = "Vanuatu",Population = 258213 ,WorldPercentage = 0.0036 },
                new Country { Id =184,Name = "New Caledonia (France)",Population = 255651 ,WorldPercentage = 0.0036 },
                new Country { Id =185,Name = "French Guiana (France)",Population = 22904 ,WorldPercentage = 0.0032 },
                new Country { Id =186,Name = "Mayotte (France)",Population = 2126 ,WorldPercentage = 0.003 },
                new Country { Id =187,Name = "Samoa",Population = 18782 ,WorldPercentage = 0.0026 },
                new Country { Id =188,Name = "São Tomé and Príncipe",Population = 187356 ,WorldPercentage = 0.0026 },
                new Country { Id =189,Name = "Saint Lucia",Population = 166526 ,WorldPercentage = 0.0023 },
                new Country { Id =190,Name = "Guam (USA)",Population = 159358 ,WorldPercentage = 0.0022 },
                new Country { Id =191,Name = "Curaçao (Netherlands)",Population = 150563 ,WorldPercentage = 0.0021 },
                new Country { Id =192,Name = "Saint Vincent and the Grenadines",Population = 109 ,WorldPercentage = 0.0015 },
                new Country { Id =193,Name = "United States Virgin Islands (USA)",Population = 106405 ,WorldPercentage = 0.0015 },
                new Country { Id =194,Name = "Kiribati",Population = 104573 ,WorldPercentage = 0.0015 },
                new Country { Id =195,Name = "Grenada",Population = 103328 ,WorldPercentage = 0.0015 },
                new Country { Id =196,Name = "Tonga",Population = 103036 ,WorldPercentage = 0.0015 },
                new Country { Id =197,Name = "Federated States of Micronesia",Population = 101823 ,WorldPercentage = 0.0014 },
                new Country { Id =198,Name = "Aruba (Netherlands)",Population = 101484 ,WorldPercentage = 0.0014 },
                new Country { Id =199,Name = "Jersey (UK)",Population = 97857 ,WorldPercentage = 0.0014 },
                new Country { Id =200,Name = "Seychelles",Population = 90945 ,WorldPercentage = 0.0013 },
                new Country { Id =201,Name = "Antigua and Barbuda",Population = 86295 ,WorldPercentage = 0.0012 },
                new Country { Id =202,Name = "Isle of Man (UK)",Population = 84497 ,WorldPercentage = 0.0012 },
                new Country { Id =203,Name = "Andorra",Population = 76246 ,WorldPercentage = 0.0011 },
                new Country { Id =204,Name = "Dominica",Population = 71293 ,WorldPercentage = 0.001 },
                new Country { Id =205,Name = "Bermuda (UK)",Population = 64237 ,WorldPercentage = 0.0009 },
                new Country { Id =206,Name = "Guernsey (UK)",Population = 62431 ,WorldPercentage = 0.00088 },
                new Country { Id =207,Name = "Greenland (Denmark)",Population = 5637 ,WorldPercentage = 0.00079 },
                new Country { Id =208,Name = "Marshall Islands",Population = 55548 ,WorldPercentage = 0.00078 },
                new Country { Id =209,Name = "American Samoa (USA)",Population = 55519 ,WorldPercentage = 0.00078 },
                new Country { Id =210,Name = "Cayman Islands (UK)",Population = 55456 ,WorldPercentage = 0.00078 },
                new Country { Id =211,Name = "Saint Kitts and Nevis",Population = 54 ,WorldPercentage = 0.00076 },
                new Country { Id =212,Name = "Northern Mariana Islands (USA)",Population = 53883 ,WorldPercentage = 0.00076 },
                new Country { Id =213,Name = "Faroe Islands (Denmark)",Population = 48244 ,WorldPercentage = 0.00068 },
                new Country { Id =214,Name = "Sint Maarten (Netherlands)",Population = 37429 ,WorldPercentage = 0.00053 },
                new Country { Id =215,Name = "Saint Martin (France)",Population = 36979 ,WorldPercentage = 0.00052 },
                new Country { Id =216,Name = "Liechtenstein",Population = 36842 ,WorldPercentage = 0.00052 },
                new Country { Id =217,Name = "Monaco",Population = 36136 ,WorldPercentage = 0.00051 },
                new Country { Id =218,Name = "San Marino",Population = 32382 ,WorldPercentage = 0.00046 },
                new Country { Id =219,Name = "Turks and Caicos Islands (UK)",Population = 31458 ,WorldPercentage = 0.00044 },
                new Country { Id =220,Name = "Gibraltar (UK)",Population = 29752 ,WorldPercentage = 0.00042 },
                new Country { Id =221,Name = "British Virgin Islands (UK)",Population = 29537 ,WorldPercentage = 0.00042 },
                new Country { Id =222,Name = "Åland Islands (Finland)",Population = 28502 ,WorldPercentage = 0.0004 },
                new Country { Id =223,Name = "Caribbean Netherlands (Netherlands)",Population = 21133 ,WorldPercentage = 0.0003 },
                new Country { Id =224,Name = "Palau",Population = 2077 ,WorldPercentage = 0.00029 },
                new Country { Id =225,Name = "Cook Islands (NZ)",Population = 14974 ,WorldPercentage = 0.00021 },
                new Country { Id =226,Name = "Anguilla (UK)",Population = 13452 ,WorldPercentage = 0.00019 },
                new Country { Id =227,Name = "Wallis and Futuna (France)",Population = 13152 ,WorldPercentage = 0.00019 },
                new Country { Id =228,Name = "Tuvalu",Population = 11264 ,WorldPercentage = 0.00016 },
                new Country { Id =229,Name = "Nauru",Population = 9945 ,WorldPercentage = 0.00014 },
                new Country { Id =230,Name = "Saint Barthélemy (France)",Population = 8938 ,WorldPercentage = 0.00013 },
                new Country { Id =231,Name = "Saint Pierre and Miquelon (France)",Population = 6081 ,WorldPercentage = 0.00006 },
                new Country { Id =232,Name = "Montserrat (UK)",Population = 4922 ,WorldPercentage = 0.00005 },
                new Country { Id =233,Name = "Saint Helena Ascension and Tristan da Cunha (UK)",Population = 4 ,WorldPercentage = 0.00004 },
                new Country { Id =234,Name = "Svalbard and Jan Mayen (Norway)",Population = 2655 ,WorldPercentage = 0.00003 },
                new Country { Id =235,Name = "Falkland Islands (UK)",Population = 2563 ,WorldPercentage = 0.00003 },
                new Country { Id =236,Name = "Norfolk Island (Australia)",Population = 2302 ,WorldPercentage = 0.00002 },
                new Country { Id =237,Name = "Christmas Island (Australia)",Population = 2072 ,WorldPercentage = 0.00002 },
                new Country { Id =238,Name = "Niue (NZ)",Population = 1613 ,WorldPercentage = 0.00002 },
                new Country { Id =239,Name = "Tokelau (NZ)",Population = 1411 ,WorldPercentage = 0.00001 },
                new Country { Id =240,Name = " Vatican City",Population = 800 ,WorldPercentage = 0.00001 },
                new Country { Id =241,Name = "Cocos (Keeling) Islands (Australia)",Population = 550 ,WorldPercentage = 0.000001 },
                new Country { Id =242,Name = "Pitcairn Islands (UK)",Population = 66 ,WorldPercentage = 0.0000000 }
            };

        }

    }

}

As you can see, we must tag the service with the ScriptService and tag the WebMethod with the ScriptMethod attribute, specifying the JSON responseformat. We also need to add some to our web.config:

<?xml version="1.0"?>

<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />

    <webServices>
      <protocols>
        <add name="HttpGet" />
        <add name="HttpPost"/>
      </protocols>
    </webServices>

  </system.web>

</configuration>


We also need some GUI here to test out the TypeAhead control:


<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head<
    <title></title>
    <link href="Content/bootstrap.css" rel="stylesheet" />
    <link href="Content/bootstrap-responsive.css" rel="stylesheet" />
</head>
<body>

    <div class="row">

    <div class="span12">
    <input type="text" id="tbCountries" /> 
   

    </div class="row">
   
    <script src="Scripts/jquery-2.0.3.js"></script>
    <script src="Scripts/bootstrap.js"></script>
    <script src="Scripts/underscore.js"></script>

    <script type="text/javascript">

        $(function () {
         

            var countries;

            $("#tbCountries").typeahead({
                source: function (query, process) {
                    return $.ajax({
                        type: "POST",
                        url: 'http://localhost:52523/CountryService.asmx/GetCountries',
                        data: JSON.stringify({query: query }),
                        contentType: "application/json; charset=utf-8",
                        dataType: "json",
                        success:
                        function (data) {
                            countries = data.d; 
                            var countryIds = _.map(countries, function(c){
                                return c.Id; 
                            }); 
                            return process(countryIds);
                        }
                    });
                },
                matcher: function (item) {
                    return true;
                },
                sorter: function (items) {
                    return items;
                },
                highlighter: function (id) {
                    var country = _.find(countries, function (c) {
                        return c.Id == id;
                    });
                    return country.Name + " Population: " + country.Population; 
                },
                updater: function (id) {
                    var country = _.find(countries, function (c) {
                        return c.Id == id;
                    });
                    return country.Name;
                }
            });

        });

    </script>
</body>
</html>


To sum up, to make the TypeAhead control work in my example, I had to implement stub implementations of matcher, sorter, highlighter (must be implemented such that the custom Country object instances return in JSON object is visible, this is a display template in other words) and updater (will update the text field with the autocomplete / TypeAhead feature). Source also sets a global variable countries here for simplicity, and continues processing the ids, you can see that we use Underscore.Js here for the array processing. The highlighter and updater method uses the find method of Underscore.js to find the relevant country. The end result is a functioning auto complete example for the Bootstrap TypeAhead control that uses a remote JSON service. I am not sure why the data.d variable was returned from the service. I did not specify "data.d" anywhere in my code, but this is where I could find the returned JSON data. It is not very elegant to set the countries to a global variable, we could of course encapsulate this better using a "provider" to encapsulate the data for encapsulation and consistency protection. But the key point of this article was to help others getting started with the TypeAhead control in Bootstrap with remote JSON calls returning objects with properties and not just simple string arrays. I find the Bootstrap documentation from Twitter as good, but not exemplary. It is sometimes hard to find good programming examples on the different controls. The end result is an autocomplete control that looks nice and can display compound data:

1 comment:

  1. Of course, in production, you would not point to localhost or similar in the Url. If you know how I can avoid the data.d here and use data.options instead and in addition avoid the global countries variable here, feel free to provide corrections. Of course, we could have a provider in a separate JS file and use for example the revealing module pattern to encapsulate the countries variable, that would be a natural improvement.

    ReplyDelete