I'm using the jQuery UI AutoComplete control (just updated to jQuery UI 1.8.1). Whenever the user leaves the text box, I want to set the contents of the text box to a known-good value and set a hidden ID field for the value that was selected. Additionally, I want the page to post back when the contents of the text box are changed.
Currently, I am implementing this by having the autocomplete select event set the hidden id and then a change event on the text box which sets the textbox value and, if necessary, causes a post back.
If the user just uses the keyboard, this works perfectly. You can type, use the up and down arrows to select a value and then tab to exit. The select event fires, the id is set and then the change event fires and the page posts back.
If the user starts typing and then uses the mouse to pick from the autocomplete options though, the change event fires (as focus shifts to the autocomplete menu?) and the page posts back before the select event has a chance to set the ID.
Is there a way to get the change event to not fire until after the select event, even when a mouse is used?
$(function() {
var txtAutoComp_cache = {};
var txtAutoComp_current = { label: $('#txtAutoComp').val(), id: $('#hiddenAutoComp_ID').val() };
$('#txtAutoComp').change(function() {
if (this.value == '') { txtAutoComp_current = null; }
if (txtAutoComp_current) {
this.value = txtAutoComp_current.label ? txtAutoComp_current.label : txtAutoComp_current;
$('#hiddenAutoComp_ID').val(txtAutoComp_current.id ? txtAutoComp_current.id : txtAutoComp_current);
} else {
this.value = '';
$('#hiddenAutoComp_ID').val('');
}
// Postback goes here
});
$('#txtAutoComp').autocomplete({
source: function(request, response) {
var jsonReq = '{ "prefixText": "' + request.term.replace('\\', '\\\\').replace('"', '\\"') + '", "count": 0 }';
if (txtAutoComp_cache.req == jsonReq && txtAutoComp_cache.content) {
response(txtAutoComp_cache.content);
return;
}
$.ajax({
url: 'ajaxLookup.asmx/CatLookup',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: jsonReq,
type: 'POST',
success: function(data) {
txtAutoComp_cache.req = jsonReq;
txtAutoComp_cache.content = data.d;
response(data.d);
if (data.d && data.d[0]) { txtAutoComp_current = data.d[0]; }
}
});
},
select: function(event, ui) {
if (ui.item) { txtAutoComp_current = ui.item; }
$('#hiddenAutoComp_ID').val(ui.item ? ui.item.id : '');
}
});
});
You can solve this by implementing your change event as an autocomplete option, just like select, instead of using jQuery's change() function.
You can see the list of events at the autocomplete demo & documentation page. It states that the change event is always fired after the close event, which I presume is fired after the select event. Have a look at the source for 'combobox' to see an example change event hook.
It worked for me on mouse select when i did this:
focus: function (event, ui) {
$j(".tb").val(ui.item.value);
return true;
}
This causes the TextBox text to change on mouse focus events, just like the way it happens on keyboard events. And when we select an item, it triggers selection changed.
I don't know about preventing the change event from firing, but you could easily throw some conditionals in your change event that makes sure the hidden field has been set and that the TextBox currently has a value.
Related
I'm trying to figure out why my focus remains on an element. This is html from the autocomplete angular plug-in that I'm using:
<autocomplete id="search" ng-model="query" attr-placeholder="" click-activation="true" data="items" on-type="updateItems" on-select="searchItems"></autocomplete>
but every time I press enter no matter if I have my focus on the input field or not, or even on an other field, the on-select function is called every time.
this thing is in the plugin itself, maybe it needs some changes?
document.addEventListener("blur", function (e) {
// disable suggestions on blur
// we do a timeout to prevent hiding it before a click event is registered
setTimeout(function () {
scope.select();
scope.setIndex(-1);
scope.$apply();
}, 150);
}, true);
You could monitor what was the last selected input field with this code :
var lastFocusedElement = '';
// This would catch any input field - so you could add your forms selector too.
// for example : $("#myForm:input")
$(":input").focus(function () {
lastFocusedElement = $(this);
});
Then use the complete callback function from animate :
$("#div_NotificationOuter").animate({ bottom: '+=30px' }, 4000,function(){
if (lastFocusedElement != ''){
lastFocusedElement.trigger('focus');
}
});
I am using bootstrap typeahead. When a user enters an address into a form, a dropdown displays with possible addresses. When they select one, I add a hidden input field with the id of the address from database.
Now when the user removes texts from the input field, well that address is no longer valid, so I want to remove that hidden input field. The problem is how do I detect when a user deletes text from the input field using delete key or using mouse.
I've already tried keypress event, it does not work when using delete key:
var input_changed = false
$('#myid').bind('typeahead:selected', function(obj, datum, name) {
$.ajax({
url: "/lead_profiles/populate_address",
data: {
address : datum
}
// dataType: "script"
}).done(function(data){
var contact = JSON.parse(data)[0];
var $parent = $("#myid").closest(".form-group");
$parent.after('<input name="lead_profile[contact_attributes][id]" type="hidden" value="' + contact.id + '">')
input_changed = true
});
});
$("#myid").on('keypress', function(){
if(input_changed){
alert("Input has changed");
}
})
I need another event besides keypress to determine if text has been removed from input field.
You can use oninput event: { 'keyup paste' for older browsers which don't support it }
$("#myid").on('input', function(){
if(input_changed){
alert("Input has changed");
}
});
I have the below script:
$("#product1").autocomplete({
source: "get_sku_family",
messages: {
noResults: '',
results: function () {}
},
select: function (event, ui) {
var selectedObj = ui.item;
$.post('get_as_09',
{
data: selectedObj.value
},
function (result) {
if (result[0] > 0) {
$('#h09_1').attr('checked', 'checked');
} else {
$('#h09_1').removeAttr('checked');
}
}
});
}
});
This has an autocomplete field that when text is entered provides options from a database. this works. then on clicking an option from the autocomplete, it queries the database with a function(get_as_09) and checks the checkbox based on the result.
Again this works 100%.
What I do want to change though, is that when I enter a new value on the autocomplete, it must clear the checkboxes before applying the new database lookup logic to check the boxes.
I just don't know where to add the $('#h09_1').removeAttr('checked');
Thanks and Regards...
any help appreciated
UPDATE Ripu
if(data:selectedObj.value.length ==0 ){$('#h09_1').removeAttr('checked');};
$.post('get_as_09', {data:selectedObj.value},function(result) {
if(result[0] > 0) {
$('#h09_1').attr('checked','checked');
} else {
$('#h09_1').removeAttr('checked');
}
});
before this line
$.post('get_as_09', {data:selectedObj.value},function(result) {
check if the value of data:selectedObj.value is empty. If it is empty, then you don't need to make a post request, just simply uncheck the checkbox
try to make it on texbox on change event means when you enter the new value in auto complete make it there to clear any thing you want check
Why dont you clear your checkboxes on focus of the auto-complete field.
Here is the documentation about this event http://api.jqueryui.com/autocomplete/#event-focus
as you said just a $('#h09_1').removeAttr('checked'); should suffice.
focus: function( event, ui ) {
$('#h09_1').removeAttr('checked');
}
what if you put before
$.post('get_as_09', {data:selectedObj.value},function(result) {
so everytime before you put smth inside your $('#h09_1') you clean it?
What if you attach an event listener on the element based on the keypress event? Something like this:
$(selectedObj).one('keypress', function (e) {
var checkbox = $('#h09_1');
if (selectObj.val().length > 0) {
checkbox.attr('checked', false);
}
});
This way you know somebody is typing in the field before you clear it. You could bind the event listener after each database lookup. Just an idea.
I can't manage to find out how to initiate a click event by a user clicking on a dropdown. I want to populate the dropdown ONLY if the user clicks the dropdown which will be rare. In addition, it depends on several other values selected on the page. So basically, how do I fire off an event if a user just simply clicks on the dropdown to see the options.
I've tried, $('select').click but to no avail.
It works if you don't have any options. But if there are current options, no luck.
Try using the focus event instead, that way the select will be populated even when targeted using the keyboard.
$('select').on('focus', function() {
var $this = $(this);
if ($this.children().length == 1) {
$this.append('<option value="1">1</option><option value="2">2</option>');
}
});
View simple demo.
UPDATE
Here is a new version that uses unbind to only fire the event handler once. This way you are able to use your alert without adding any option elements to change the outcome of the condition as the previous solution required.
$('select').on('focus', function() {
var $this = $(this);
// run your alert here if it´s necessary
alert('Focused for the first time :)');
// add the new option elements
$this.append('<option value="1">1</option><option value="2">2</option>');
// unbind the event to prevent it from being triggered again
$this.unbind('focus');
});
Hope that is what you are looking for.
It should work. Here I've done it and its working.
$("select").on("click", function() {
$(this).append("<option>1</option><option>2</option>");
});
Updated: http://jsfiddle.net/paska/bGTug/2/
New code:
var loaded = false;
$("select").on("click", function() {
if (loaded)
return;
$(this).append("<option>1</option><option>2</option>");
loaded = true;
});
Getting the dropdown to automatically open after the click is trickier:
// Mousedown is used so IE works
$('#select_id').on('focus mousedown', function (e) {
var data;
$(this).off('focus mousedown');
$.ajax({async: false,
type: 'GET',
url: 'url that returns the options',
success: function (d) { data = d; }
});
$(this).find('option').remove().end().append(data);
// Prevent IE hang by waiting awhile
var t = new Date().getTime(); while(new Date().getTime() < t + 200) {}
return true;
});
Hope that made sense. I have a text input that uses the jQuery UI autoselect feature. The input auto-fills when a user selects, as it should. My problem is if a user inputs something, but then doesn't select from the drop down. This results in the text input value being something that doesn't exist in the list upon a form submit. I want to know if there is a way to perform an action (clear text input value) on the 'change' event but leave it as it is for the 'select' event.
If I'm understanding you correctly, you should be able to leverage the ui parameter that's passed to a change event handler:
$("#auto").autocomplete({
/* options */
change: function (event, ui) {
if (!ui.item) {
this.value = '';
}
}
});
ui.item will be undefined if nothing is selected from the autocomplete candidate list.
Example: http://jsfiddle.net/ZBzpF/
Inside the change event handler, check if the current value is in the source, if not, reset it. Something like:
var sourceArray = ["a", "b", "c"],
$autocomplete = $('#autocomplete');
$autocomplete.autocomplete({
source: ,
change: function(e, ui) {
if ($.inArray($autocomplete.val(), sourceArray) === -1) {
//change the value
}
})
}