MrJoeBlow
MrJoeBlow

Reputation: 466

Customised jQuery autocomplete

I have a customised jQuery autocomplete control that is declared something like this.

$('#SystemCode_Autocomplete').autocomplete({
    source: [{"label":"Access","value":0},{"label":"Documentum","value":0}], //move values
    minLength: 1,
    change: function(event, ui) {// some function},
    select: function(event, ui) {// some function}
});

The change and select events are custom. The problem is if I type something into the textbox then click the submit button (i.e. no tab out, or lost of focus), or if I press the key to submit after typing into the text box, the change event isn't fired and it has to be before I submit.

I was hoping to do it without putting javascript behind the submit button, and to ideally do it from within the autocomplete control itself. I tried adding the change to the blur event.

${'foo').blur(function() { $('bar').trigger('autocompletechange');
// or
${'foo').blur(function() { $('bar').change();

But none of them have worked, anyone have any ideas?

Upvotes: 14

Views: 3372

Answers (5)

MrJoeBlow
MrJoeBlow

Reputation: 466

Ok I completely for to update this to what we actually did to get it to work. Basically we editted the autocomplete .js file to get it to do want we wanted. Specifically we added our own options to the autocomplete then we editted the _response method to something like this

_response: function (content) {
        if (content.length) {
            content = this._normalize(content);
            this._suggest(content);
            this._trigger("open");

            this.options.isInError = false;
            this.element.removeClass("input-validation-error");
        } else {
            this.close();

            if (this.element.val() == '') {
                this.options.hiddenField.val('');
            } else {
                this.options.hiddenField.val('-1');
            }
            if (this.options.mustBeInList) {
                this.options.isInError = true;
                this.element.addClass('input-validation-error');
            }
        }
        this.element.removeClass("ui-autocomplete-loading");
    },

That way we know if the User is entering "rubbish" as they type and the controll goes red and into an "error"mode. To stop them from posting back we do this

case keyCode.ENTER:
                case keyCode.NUMPAD_ENTER:
                    // when menu is open or has focus

                    if (self.options.isInError == true) {
                        return false;
                    }

                    if (self.menu.element.is(":visible")) {
                        event.preventDefault();
                    }
                    //passthrough - ENTER and TAB both select the current element
                case keyCode.TAB:
                    if (!self.menu.active) {
                        return;
                    }
                    self.menu.select(event);
                    break;

Upvotes: 0

Luca Filosofi
Luca Filosofi

Reputation: 31173

$(function() {
var json = [{"label":"Access","value":0},{"label":"Documentum","value":0}];
$('#SystemCode_Autocomplete').autocomplete({
    source: function( request, responce ) {
        responce( $.map( json, function( item ) {
            return { id: item.value, label: item.label, value: item.label }
        }));
        $.each( json, function( i, item ) {
            if ( request.term.toLowerCase() == item.label.toLowerCase() ) { 
                   // do something here, ex.: AJAX call or form submit...
                $('#submit_button').click();
            }
        });   
    },
    minLength: 1,
    change: function(event, ui) { /*alert(ui.item.label + ' ' + ui.item.id)*/ },
    select: function(event, ui) {}
   });
});

Upvotes: 0

David Murdoch
David Murdoch

Reputation: 89312

You can try something like this:

$('#SystemCode_Autocomplete').autocomplete({
    source: [{"label":"Access","value":0},{"label":"Documentum","value":0}], //move values
    minLength: 1,
    change: function(event, ui) {/* some function */},
    select: function(event, ui) {/* some function */}
}).each(function(){
    var self = $(this).closest("form").submit(function(e){
        self.trigger("change");

        // you may not need anything like this...but whatever
        if(!functionToCheckIfFormIsValid()){
            e.preventDefault();
        }
    });
});

Upvotes: 1

jcolebrand
jcolebrand

Reputation: 16035

So your problem is that you have to make sure that action a occurs before action b and you're having trouble reconciling that between two event handlers? That actually sounds like a pretty common UI problem, not something that's limited to jQuery.

How would you solve it in any other circumstance? What if I suggested you to use the jQuery data object to attach to the element and then do some sort of semaphore checking in each method, like setting a flag in the one method, and in the other method checking to see if the flag is set?

That's how I would do it, were it me.

Upvotes: 0

user1217167
user1217167

Reputation: 83

focus function autocomplete

Before focus is moved to an item (not selecting), ui.item refers to the focused item. The default action of focus is to replace the text field's value with the value of the focused item, though only if the focus event was triggered by a keyboard interaction. Canceling this event prevents the value from being updated, but does not prevent the menu item from being focused.

Solve the problem:

    $('#SystemCode_Autocomplete').autocomplete({
        source: [{"label":"Access","value":0},{"label":"Documentum","value":0}], //move values
        minLength: 1,
        focus: function( event, ui ) {
            return false;
        },
        select: function(event, ui) {
            alert('Select Event:'+ui.item.value);
        }
    });

Upvotes: 0

Related Questions