Jquery autocomplete change event not firing - jquery-ui

I'm using JQuery UI autocomplete feature and I'm facing a problem.
This is my code:
$("#Id").autocomplete({
source: url,
change : function (event,ui){
alert('changed');
}
});
I would like that the change event will fire any time the user type anything in the input text
It's not the case here.
when I type something it does not fire until I'm pressing with the mouse on somewhere else on the screen.
How to handle this scenario?

Try to bind a keypress event to it directly?
$("#Id").autocomplete({
source: url,
change : function (event,ui){
alert('changed');
}
});
$("#Id").bind('keypress',function(){$(this).autocomplete.change});

I solve my problem by using the keypress event separately. instead of using the change event.
The new code:
$("#Id").autocomplete({
source: url
});
$("#Id").keydown(function() {
// Logic goes here
});
This problem occurred because we got out of focus two events were fired the onBlur and the onclick event of some button I have. and this cause inconsistently behavior.
Thanks

Related

jQuery UI dialog binding keydown doesn't always work

I'm writing my own ESC handler because I need to do other actions when ESC is pressed, specifically I need to manage where focus goes for keyboard-only users. I have it working for all menus and some dialogs (both of which are using jQueryUI) but I'm having problems with dialogs that open on top of other dialogs (confirmation dialogs).
I'm using a Backbone View and adding my keydown handler on dialogcreate. this.$el.on('dialogcreate', this.bindKeydownEvent);
My handler:
bindKeydownEvent: function(ev, ui) {
var self = this;
this.$el.dialog().on('keydown', function(evt) {
if(evt.keyCode === $.ui.keyCode.ESCAPE) {
self.$el.dialog("close");
if(self.options.closeFocusEl) {
$(self.options.closeFocusEl).focus();
}
evt.stopPropagation();
}
});
}
I've checked and this.$el.dialog() is the correct dialog when the second dialog calls this.bindKeydownEvent but for some reason the keydown handler is not being triggered no matter what I press in the dialog (Tab, Space, Enter, random letters, etc).
Any idea what I'm doing wrong or have a better way I could bind the keydown event?
EDIT:
I just noticed that this is also happening in some first-level dialogs. It looks like the only difference is the way we get the template and therefore create the interior of the dialog. In our Alert and Confirmation dialog classes, we define the template as an attribute on the object like this: template: _.template("<div><%= o.content %></div>"). In other views (in which the keydown binding works) we build the child elements and add them to the DOM of the dialog, set the template in the initialize function
this.options.template = 'navigation/CreateNewDialog.template';
or set it when we call the dialog
var closeConv = new views.CloseConversationDialogView({
confirm: this.closeConversationConfirmed,
content: i18n.t("closeConversationInput"),
template: "conversation/CloseConversationDialog.template"
});
closeConv.render();
Is there a reason that creating the template inline as an attribute on the view would not bind keydown correctly?
To understand why your event handler isn't being triggered you need first understand how event delegation works.
The key to event delegation in that events bubble up the DOM. So when you bind your event using this.$el.dialog().on('keydown',..., what you basically doing is listening to any keydown event that is triggered on your $el or it's descendants. In this case being that your second dialog isn't a descendant of your $el it's events won't bubble up to it and therefore don't trigger your handler.
To work around this you can either bind directly to your second dialog, or instead bind to a exisitng higher level element like the document. For example
$(document).on('keydown', '.myDialog', function() {...
The only thing my original attempt was missing was "widget". The widget method, according to api.jqueryui.com,
Returns a jQuery object containing the generated wrapper.
I don't see any documentation on what exactly $('.selector').dialog() returns but apparently it is not the same as $('.selector').dialog("widget"). I also changed on('keydown'... to just use the jQuery keydown instead.
bindKeydownEvent: function(ev, ui) {
var self = this;
this.$el.dialog("widget").keydown(function(evt) {
if(evt.keyCode === $.ui.keyCode.ESCAPE) {
self.$el.dialog("close");
if(self.options.closeFocusEl) {
$(self.options.closeFocusEl).focus();
}
evt.stopPropagation();
}
});
}

jQuery Mobile pageinit re-binds on every page load

Adding my bindings to the pageinit event like so:
$('#mypage').on("pageinit", function () {
$('#login-sumbit').on('click', function () {
console.log('button clicked');
});
});
I would expect pageinit to bind the click event once only. But what happens in my single page app is that the button is binding every time the page is loaded even when clicking back.
This results in undesirable multiple duplicate binds. Any ideas on what event to use to bind only once in my single page app, so that loading the page again (back button, loading inline page) in the same session doesn't re-bind?
Looks like I found the answer myself, turns out quite rightly pageinit fires every time the page is loaded even though it's not reloading from the server, otherwise what would fire when a new page is shown.
pageinit is the right event but I need to use .one not .on, .one will bind one time only.
$('#mypage').on("pageinit", function () {
$('#login-sumbit').one('click', function () {
console.log('button clicked');
});
});
Now everything works as expected. Better still I've found you can use .one with the pageinit event for even more control over your bindings and data loads perfect for my requirements.
http://api.jquery.com/one/
You could use:
$('#login-sumbit').off('click').on('click', function(e) {
console.log('button clicked');
});

JQuery passing arguments for On Change for an item added to DOM via AJAX

I have multiple HTML fragments that are inserted into my DOM as the result of AJAX call-backs.
Each of these fragments will contain a text box whose class is "quantity".
What I want to do is to create an "on change" event handler that fires whenever one of these textbox's text value is changed. However, when that event is fired/handled, I need to know WHICH specific textbox was updated.
Okay, using jQuery, I have the following that fires in my "Lists.initHandlers" method:
$(document).on('change', $('#divABC').find(".quantity"), List.quantityChanged);
And my "List.quantityChanged" event handler happily fires when I update the quanity.
The problem is that when I reference "this" within the event handler, I get the whole document, and not the element that triggered the event.
I have tried to capture the element using syntax similar to:
$(document).on('change', $('#divABC').find(".quantity"), {ctrl: this}, List.quantityChanged);
but when I attempt this, the handler is never fired (even when I change the signature to expect an argument).
Any guidance here would be most appreciated.
Thanks
Griff
Try this:
$('.quantity').live('change', function(){
alert('New value: ' + $(this).val());
});
Pass this to your function:
$(document).on('change', $('#divABC').find(".quantity"), function () {
List.quantityChanged(this);
});

jQuery Mobile : replace click event by vclick event

Is there a way to replace all click event by vclick event in jQuery mobile?
The only solution I've found so far is to register a vclick event as below
$('a').bind("vclick", function (ev) {
// Do Some stuff
ev.preventDefault();
});
The problem is that this solution doesn't prevent jQuery mobile click event to fire so clicks are triggered twice
For some reason, I got the following to work:
$('a').bind('vclick click',function(e){
e.preventDefault();
//do some stuff//
})
Without the e.preventDefault() the event fires twice. With it, it only fires once (but it does fire)
This is similar to what you stated, but may be more all encompassing.
$("#elementId").bind('vclick',function(event){
event.preventDefault();
//your code..
});
this is working properly.

jQuery AutoComplete Trigger Change Event

How do you trigger jQuery UI's AutoComplete change event handler programmatically?
Hookup
$("#CompanyList").autocomplete({
source: context.companies,
change: handleCompanyChanged
});
Misc Attempts Thus Far
$("#CompanyList").change();
$("#CompanyList").trigger("change");
$("#CompanyList").triggerHandler("change");
Based on other answers it should work:
How to trigger jQuery change event in code
jQuery Autocomplete and on change Problem
JQuery Autocomplete help
The change event fires as expected when I manually interact with the AutoComplete input via browser; however I would like to programmatically trigger the change event in some cases.
What am I missing?
Here you go. It's a little messy but it works.
$(function () {
var companyList = $("#CompanyList").autocomplete({
change: function() {
alert('changed');
}
});
companyList.autocomplete('option','change').call(companyList);
});
this will work,too
$("#CompanyList").autocomplete({
source : yourSource,
change : yourChangeHandler
})
// deprecated
//$("#CompanyList").data("autocomplete")._trigger("change")
// use this now
$("#CompanyList").data("ui-autocomplete")._trigger("change")
It's better to use the select event instead. The change event is bound to keydown as Wil said. So if you want to listen to change on selection use select like that.
$("#yourcomponent").autocomplete({
select: function(event, ui) {
console.log(ui);
}
});
They are binding to keydown in the autocomplete source, so triggering the keydown will case it to update.
$("#CompanyList").trigger('keydown');
They aren't binding to the 'change' event because that only triggers at the DOM level when the form field loses focus. The autocomplete needs to respond faster than 'lost focus' so it has to bind to a key event.
Doing this:
companyList.autocomplete('option','change').call(companyList);
Will cause a bug if the user retypes the exact option that was there before.
Here is a relatively clean solution for others looking up this topic:
// run when eventlistener is triggered
$("#CompanyList").on( "autocompletechange", function(event,ui) {
// post value to console for validation
console.log($(this).val());
});
Per api.jqueryui.com/autocomplete/, this binds a function to the eventlistener. It is triggered both when the user selects a value from the autocomplete list and when they manually type in a value. The trigger fires when the field loses focus.
The simplest, most robust way is to use the internal ._trigger() to fire the autocomplete change event.
$("#CompanyList").autocomplete({
source : yourSource,
change : yourChangeHandler
})
$("#CompanyList").data("ui-autocomplete")._trigger("change");
Note, jQuery UI 1.9 changed from .data("autocomplete") to .data("ui-autocomplete"). You may also see some people using .data("uiAutocomplete") which indeed works in 1.9 and 1.10, but "ui-autocomplete" is the official preferred form. See http://jqueryui.com/upgrade-guide/1.9/#changed-naming-convention-for-data-keys for jQuery UI namespaecing on data keys.
You have to manually bind the event, rather than supply it as a property of the initialization object, to make it available to trigger.
$("#CompanyList").autocomplete({
source: context.companies
}).bind( 'autocompletechange', handleCompanyChanged );
then
$("#CompanyList").trigger("autocompletechange");
It's a bit of a workaround, but I'm in favor of workarounds that improve the semantic uniformity of the library!
The programmatically trigger to call the autocomplete.change event is via a namespaced trigger on the source select element.
$("#CompanyList").trigger("blur.autocomplete");
Within version 1.8 of jquery UI..
.bind( "blur.autocomplete", function( event ) {
if ( self.options.disabled ) {
return;
}
clearTimeout( self.searching );
// clicks on the menu (or a button to trigger a search) will cause a blur event
self.closing = setTimeout(function() {
self.close( event );
self._change( event );
}, 150 );
});
I was trying to do the same, but without keeping a variable of autocomplete. I walk throught this calling change handler programatically on the select event, you only need to worry about the actual value of input.
$("#CompanyList").autocomplete({
source: context.companies,
change: handleCompanyChanged,
select: function(event,ui){
$("#CompanyList").trigger('blur');
$("#CompanyList").val(ui.item.value);
handleCompanyChanged();
}
});
Well it works for me just binding a keypress event to the search input, like this:
... Instantiate your autofill here...
$("#CompanyList").bind("keypress", function(){
if (nowDoing==1) {
nowDoing = 0;
$('#form_459174').clearForm();
}
});
$('#search').autocomplete( { source: items } );
$('#search:focus').autocomplete('search', $('#search').val() );
This seems to be the only one that worked for me.
This post is pretty old, but for thoses who got here in 2016. None of the example here worked for me. Using keyup instead of autocompletechange did the job. Using jquery-ui 10.4
$("#CompanyList").on("keyup", function (event, ui) {
console.log($(this).val());
});
Hope this help!
Another solution than the previous ones:
//With trigger
$("#CompanyList").trigger("keydown");
//With the autocomplete API
$("#CompanyList").autocomplete("search");
jQuery UI Autocomplete API
https://jsfiddle.net/mwneepop/

Resources