Twitter Bootstrap Typeahead - Add a "loading" class to the input when search begins

BadHorsie picture BadHorsie · May 16, 2013 · Viewed 7.7k times · Source

How do I change the class of a typeahead input when the ajax request is triggered, and remove the class when the request is complete? I don't know if I'm using the correct events, and I think I have the object scope wrong by using $(this) to reference the input.

$('.iof-subject').typeahead({
    source: function(typeahead, query) {
        $.ajax({
            url: window.app.ROOT + 'subjects/ajax/search_name',
            data: {name: query},

            // Add loading class to the text input (.iof-subject) when
            // the ajax request begins
            beforeSend: function() {
                $(this).addClass('loading');
            },

            // Remove loading class from text input (.iof-subject) when
            // the ajax request is complete
            complete: function() {
                $(this).removeClass('loading');
            },

            success: function(data) {
                return typeahead.process($.parseJSON(data));
            }
        })
    }
});

Answer

bottens picture bottens · May 16, 2013

When you are inside of the $.ajax call, this refers to $.ajax, not .iof-subject

What i would do is this.

source: function(typeahead, query) {
    //Create a copy of this, so code in $.ajax can access the variables
    var that = this;
    $.ajax({
        url: window.app.ROOT + 'subjects/ajax/search_name',
        data: {name: query},

        beforeSend: function() {
            //that.$element is a variable that stores the element the plugin was called on
            that.$element.addClass('loading');
        },

        complete: function() {
            that.$element.removeClass('loading');
        },

        success: function(data) {
            return typeahead.process($.parseJSON(data));
        }
    })
}

that will refer to this. And the plugin stores the element as a variable inside the object named $element.