dynamic datalist example

This example uses the service provided by http://geo-autocomplete.com/ to generate a dynamic HTML5 datalist. All options of the service are stored as JSON inside of data-datalist attribute, which helps you to generate a clean HTML component.

by Shobhit Sharma

HTML

<script src="http://afarkas.github.com/webshim/demos/js-webshim/minified/extras/modernizr-custom.js"></script>
<script src="http://afarkas.github.com/webshim/demos/js-webshim/minified/polyfiller.js"></script>
<div>
    <p>This example uses the service provided by http://geo-autocomplete.com/ to generate a dynamic HTML5 datalist. All options of the service are stored as JSON inside of data-datalist attribute, which helps you to generate a clean HTML component.</p>
    <label for="country">
        Country
    </label>
    <input list="countrylist" id="country" data-datalist='{"url": "http://geo-autocomplete.com/api/country","dataType": "jsonp","valueMatch": "q","optionMatch": "country_name","data": {"key": "37693c"}}' />
    <datalist id="countrylist">
        <!-- you have to add your option elements inside of a select element for legacy reasons -->
        <select>
        </select>
    </datalist>
</div>

JavaScript

//implement forms (for datalist) and ES5 (for forEach), but only if datalist/es5 is not available (forms would also implement constraint validation etc.)
if (!Modernizr.input.list || !Modernizr.ES5) {
    jQuery.webshims.setOptions('forms', {
        lightweightDatalist: true
    });
    jQuery.webshims.polyfill('forms es5');
}

jQuery(function($) {
    $('input[data-datalist]').each(function() {
        //list property is not a string! it's the DOM-Element
        //we use the select element inside the datalist to fill our datalist
        var dataList = $('select', $.prop(this, 'list'));
        //get all ajaxoptions from data-datalist attribute and add the success callback
        var ajaxOpts = $.extend({
            success: function(data) {
                var options = '';
                if (data && data.forEach) {
                    data.forEach(function(value) {
                        //optionMatch is service-specific in this case = 'country_name'
                        if (value[ajaxOpts.optionMatch]) {
                            options += '<option value="' + value[ajaxOpts.optionMatch] + '" />';
                        }
                    });
                }
                //.htmlPolyfill is equal to the normal .html method, but allows creating dynamic HTML5 content in every browser
                dataList.htmlPolyfill(options);
            },
            data: {}
        }, $(this).data('datalist'));

        $(this).bind('input', function() {
            //valueMatch is service specific in this case 'q'
            if ((ajaxOpts.data[ajaxOpts.valueMatch || 'q'] = $.prop(this, 'value'))) {
                $.ajax(ajaxOpts);
            }
        });
    });
});