Matt K
Matt K

Reputation: 7337

Using jQuery Autocomplete, when showing results, how can I start at a particular value?

I have a jQuery autocomplete input box for time. It lists all available times by 15 minute increments starting at 12:00 AM. I'd like to display all results, but have the time closest to now selected. Is there a way to do this?

Here's what I have so far:

var j$ = jQuery.noConflict();

function log(item) { if(j$.browser.mozilla) { console.log(item); } }

function init()
{
    var times = [];
    for (var i=0;i<24;i++) {
        for (var j=0;j<4;j++) {
            var hour = (i>12?(i-12)+"":(i==0?"12":i)+"");
            var mins = "00"; var AMPM = (i>12?" PM":" AM");
            if(j==0) { mins="00"; } 
            if(j==1) { mins="15"; } 
            if(j==2) { mins="30"; } 
            if(j==3) { mins="45"; }
            times.push(hour+":"+mins+AMPM);
        }
    }

    // initialize the autocompletes
    j$("#time")
        .autocomplete({
            source: times,
            minLength: 0,
            delay: 0,
            autoFocus: true
        })
        .bind("focus",function(){
            j$(this).autocomplete("search","");
        });
}

j$(document).ready(init);

Update

I added a jsFiddle for the above code.

Upvotes: 2

Views: 505

Answers (2)

seangates
seangates

Reputation: 1522

(Sorry this is answer and not a comment! Apparently I am not "cool" enough to comment.)

This block currently rolls 12:00 to 13:00:

hours = hours > 12 ? hours - 12 : hours;
minutes = (minutes - minutes % 15) + 15;

if (minutes === 60) {
    minutes = 0;
    hours++;
}

Should be:

minutes = (minutes - minutes % 15) + 15;

if (minutes === 60) {
    minutes = 0;
    hours++;
}

hours = hours > 12 ? hours - 12 : hours;

Now it will correctly roll 12:00 to 1:00.

Upvotes: 0

Andrew Whitaker
Andrew Whitaker

Reputation: 126052

You can accomplish this with the open event and some trickery with the underlying menu widget that autocomplete uses:

j$("#time")
    .autocomplete({
        source: times,
        minLength: 0,
        delay: 0,
        autoFocus: true,
        open: function () {
            var menu = j$(this).data("autocomplete").menu
                , now = new Date()
                , hours = now.getHours()
                , minutes = now.getMinutes()
                , ampm = hours >= 12 ? " PM" : " AM"
                , timeStr
                , $item;

            /* Build a time string for the current time */
            hours = hours > 12 ? hours - 12 : hours;
            minutes = (minutes - minutes % 15) + 15;

            if (minutes === 60) {
                minutes = 0;
                hours++;
            }

            timeStr = hours + ":" + (minutes < 10 ? "0" + minutes : minutes) + ampm;
            $item = menu.element.find(":contains(" + timeStr + ")");

            /* Activate the correct menu item: */
            menu.activate(new j$.Event("mouseover"), $item); 

            /* Scroll to the item: */              
            menu.element.scrollTop(
                $item.offset().top -
                menu.element.offset().top + menu.element.scrollTop());
        }
    });

Example: http://jsfiddle.net/DmJup/

There are some areas for improvement here, such as refactoring the code in open into several methods.

I think allowing an option (via a plugin) that would let you specify a function to determine the option to select would be useful.

Upvotes: 3

Related Questions