jQuery autocomplete prevent focus after selection - javascript

Requirement:
I'd like a jQuery autocomplete element that allows the user to pick an item and set the display field and a hidden field with the selected value. But I would also like the field and the hidden field to be cleared when the input field receives focus by the user.
Problem:
The problem I'm facing is that when the user selects an item it's almost like jQuery is executing the onSelect function and then sending the focus to the input field again which fires my focus() event (and therefore clearing my selection).
Problem Browser:
IE8 , works in Chrome. Did not try others.
Attempted fixes:
I have tried setting the focus to another element in the select()
function. It did put the focus on that element but only after
focussing on the input field
Tried both event.preventDefault() and event.stopPropagation() in the
select() method. Did not work.
Blur didnt work either.
Workarounds:
I guess I can change the clearing to be on click instead of on focus, but this is not what I want.
Similar stackoverflow thread:
jquery autocomplete remove focus after suggest
Code:
Here is my code:
$(function () {
$("#autosuggest").autocomplete({
source: "my server path",
minLength: 3,
select: function (event, ui) {
if (ui.item) {
$("#autosuggest").val(ui.item.value);
$("#hidden").val(ui.item.id);
}
}
});
$("#autosuggest").focus(function () {
$("#hidden").val("");
this.value = "";
});
});

The problem is: when you click on an autocomplete suggestion, the focus shifts to that dropdown menu, ever so shortly, to return to your input afterwards. Do you still get this problem if you choose the autocomplete suggestion by using the arrow-down button? If you do not, then this is the problem.
The only way I can see to fix this is not to make it a focus event after all, but I think I know why you don't want to make it a click event: you also want to capture tabbing into the field.
Solution: make it a click handler, and add a 'keyup' handler that executes the click handler handler if the key was a tab (arrow-down etc are still allowed).

I got this from the jQuery forum and it works fabulous!
select: function(event, ui) {
$(event.target).autocomplete("close")
setTimeout(function() {
$(event.target).blur();
})
}
Link: https://forum.jquery.com/topic/autocomplete-input-field-stays-focused-after-selection

Try onSelect function..
$(function () {
$("#autosuggest").autocomplete({
source: "my server path",
minLength: 3,
select: function (event, ui) {
if (ui.item) {
$("#autosuggest").val(ui.item.value);
$("#hidden").val(ui.item.id);
}
},
onSelect: function (suggestion) {
$(this).click();}
});
$("#autosuggest").focus(function () {
$("#hidden").val("");
this.value = "";
});
});

Related

How Can I Triger Change Event For HTML Select (Dropdown)?

My HTML page has a Button and a Select Drop-Down (Combo Box). Drop-Down change event is like this:
$('#DDL_ID').on('change', function (e) {
// Some Code Here
});
When I click the button, I am setting some value to Drop-Down and it is working fine.
$('#BTN_ID').on('click', function (e) {
$('#DDL_ID').val('123');
});
When I click the button, Drop-Down value is getting changed but Drop-Down change event is not firing. Can anyone help me on this?
Please note this is not a duplicate question.
Setting the val() through jquery will not automatically trigger the event on the item... so you need to manually trigger() it...
$('#BTN_ID').on('click', function (e) {
$('#DDL_ID').val('123').trigger('change');
});

Change input text via chrome extension

I'm making a chrome extension, and I made a context menu option.
I want to get the focused input field and change it's text.
That's what I have so far:
function click()
{
var $focused = $(':focus');
$focused.val("test");
}
chrome.contextMenus.create({"title": "Paste", "contexts":["editable"], "onclick" : click});
But it doesn't change the input field's text, what do I need?
I added an alert("test"); to the click() function and it worked.
It is likely that focus is simply being stolen by the plugin button you click :)
Can you try setting a specific field value, using an ID or name select, to check your DOM access? Once you confirm that I suggest you use another event such as
$(document).on('focus', 'input', function(e){
// set field here
$(this).val("test");
});
to catch focus changes.

How to call a function AFTER blur from input?

I'm using jquery-ui datepicker as one of my inputs. If a user blurs from an input, I display a relevant message (e.g. "This field is required"). For this purpose I have the following jQuery, which works perfectly fine for simple <select> and <input type="text"> tags:
$("input").blur(function(){
if($(this).val()=="")
$(this).next().text("This field is required.");
else
$(this).next().text("");
});
However, in case of datepicker (where I have to essentially blur to select a date) the error message gets displayed even after I've selected the date (i.e. selection of date is leading to the blur event). This requires that the .blur(function(){}); should be called after the blur event is completed (not simultaneously).
How to solve this situation?
Here's a DEMO.
You could add your validation check to the onClose event of the datepicker, rather than the blur event of the input field:
$("#datepicker").datepicker({onClose: function(selectedDate) {
if(!selectedDate) {
$(this).next().text("This field is required.");
}
}});
Kind of a hack, but you could just delay the check with setTimeout:
$("input").blur(function () {
var $t = $(this);
setTimeout(function () {
if ($t.val() == "") $t.next().text("This field is required.");
else $t.next().text("");
}, 100);
});
http://jsfiddle.net/D4AGz/96/

jQuery UI autocomplete field not submitting when pressing enter

I'm following the Railscast on this topic, and although the autocomplete feature works, I am unable to get it to submit the form when the user selects an item and presses enter. I have this (coffeescript) code but it doesn't seem to work... can anyone see where I'm going wrong please?
jQuery ->
$('#search_bar').autocomplete(
source: $('#search_bar').data('autocomplete-source')
).keydown (e) ->
$('#search_button').trigger "submit" if e.keyCode is 13
Ideally I would like it to submit on selecting an item via a mouse click too - but not sure if that's possible?
Update: I've tried this...
jQuery ->
$('#search_bar').autocomplete
source: $('#search_bar').data('autocomplete-source'),
select: (event, ui) ->
$(this).parents("form").submit()
...and although it now works if you use the keyboard to select an item (and press enter), if you select an item via a mouse click it only sends the string that you had typed and not the complete word from the auto-complete drop-down. (I guess what I need is for the search field to be updated with the contents of the text on mouse-over?)
Update 2: Sorted! Just add this onto the end
focus: (event, ui) ->
$('#search_bar').val(ui.item.value)
Use the select event. documentation here The enter key is caught by autocomplete to close the menu and intentionally does not propagate. The select event will fire for both the enter key and mouse select. However when clicked the form will be submitted before the label has a chance to change, so have to set that value first. Depending on your data source you may want to use item.label instead of item.value.
$('#search_bar').autocomplete({
source: $('#search_bar').data('autocomplete-source'),
select: function(event, ui) {
$(this).val(ui.item.value);
$(this).parents("form").submit(); // this will submit the form.
}
})
I believe the coffeescript would look like this
$('#search_bar').autocomplete(
source: $('#search_bar').data('autocomplete-source'),
select: (event, ui) ->
$(this).val(ui.item.value).parents("form").submit();
)
Don't know much about coffee script, but this is how I would do it in javascript
http://jqueryui.com/demos/autocomplete/
You can use the 'select' event. When the user selects something, do your submit:
$( ".selector" ).autocomplete({
select: function(event, ui) {
$('#theForm').submit();
}
});
I am fairly certain this will take care of both cases for you. Both onEnter and onClick.

Looking for a better workaround to Chrome select on focus bug

I have the same problem as the user in this question, which is due to this bug in Webkit. However, the workaround provided will not work for my app. Let me re-state the problem so that you don't have to go read another question:
I am trying to select all the text in a textarea when it gets focus. The following jQuery code works in IE/FF/Opera:
$('#out').focus(function(){
$('#out').select();
});
However, in Chrome/Safari the text is selected--very briefly--but then the mouseUp event is fired and the text is deselected. The following workaround is offered in the above links:
$('#out').mouseup(function(e){
e.preventDefault();
});
However, this workaround is no good for me. I want to select all text only when the user gives the textarea focus. He must then be able to select only part of the text if he chooses. Can anyone think of a workaround that still meets this requirement?
How about this?
$('#out').focus(function () {
$('#out').select().mouseup(function (e) {
e.preventDefault();
$(this).unbind("mouseup");
});
});
The accepted answer (and basically every other solution I found so far) does not work with keyboard focus, i. e. pressing tab, at least not in my Chromium 21. I use the following snippet instead:
$('#out').focus(function () {
$(this).select().one('mouseup', function (e) {
$(this).off('keyup');
e.preventDefault();
}).one('keyup', function () {
$(this).select().off('mouseup');
});
});
e.preventDefault() in the keyup or focus handler does not help, so the unselecting after a keyboard focus seems to not happen in their default handlers, but rather somewhere between the focus and keyup events.
As suggested by #BarelyFitz, it might be better to work with namespaced events in order to not accidentally unbind other event handlers. Replace 'keyup' with 'keyup.selectText' and 'mouseup' with 'mouseup.selectText' for that.
Why not simply:
$('#out').focus(function(){
$(this).one('mouseup', function() {
$(this).select();
});
});
Seems to work in all major browsers...
A very slightly different approach would be to separate the focus event from the mouse sequence. This works really nicely for me - no state variables, no leaked handlers, no inadvertent removal of handlers, and it works with click, tab, or programmatic focus. Code and jsFiddle below -
$('#out').focus(function() {
$(this).select();
});
$('#out').on('mousedown.selectOnFocus', function() {
if (!($(this).is(':focus'))) {
$(this).focus();
$(this).one('mouseup.selectOnFocus', function(up) {
up.preventDefault();
});
}
});
https://jsfiddle.net/tpankake/eob9eb26/27/
Make a bool. Set it to true after a focus event and reset it after a mouse up event. During the mouse up, if it's true, you know the user just selected the text field; therefore you know you must prevent the mouse up from happening. Otherwise, you must let it pass.
var textFieldGotFocus = false;
$('#out').focus(function()
{
$('#out').select();
textFieldGotFocus = true;
});
$('#out').mouseup(function(e)
{
if (textFieldGotFocus)
e.preventDefault();
});
$(document).mouseup(function() { textFieldGotFocus = false; });
It's important that you put the mouseup listener that resets the variable on document, since it's not guaranteed that the user will release the mouse button over the text field.
onclick="var self = this;setTimeout(function() {self.select();}, 0);"
Select the text before putting the focus on the input box.
$('#out').select().focus();
digitalfresh's solution is mostly there, but has a bug in that if you manually trigger .focus() using JS (so not using a click), or if you tab to the field, then you get an unwanted mouseup event bound - this causes the first click that should deselect the text to be ignored.
To solve:
var out = $('#out');
var mouseCurrentlyDown = false;
out.focus(function () {
out.select();
if (mouseCurrentlyDown) {
out.one('mouseup', function (e) {
e.preventDefault();
});
}
}).mousedown(function() {
mouseCurrentlyDown = true;
});
$('body').mouseup(function() {
mouseCurrentlyDown = false;
});
Note: The mouseup event should be on body and not the input as we want to account for the user mousedown-ing within the input, moving the mouse out of the input, and then mouseup-ing.
tpankake's answer converted to a reusable jQuery function..
(If you upvote this, please also upvote his answer)
Load the following AFTER loading the jQuery library:
$.fn.focusSelect = function () {
return this.each(function () {
var me = $(this);
me.focus(function () {
$(this).select();
});
me.on('mousedown.selectOnFocus', function () {
var me2 = $(this);
if (me2.is(':focus') === false) {
me2.focus();
me2.one('mouseup.selectOnFocus', function (up) {
up.preventDefault();
});
}
});
});
};
Use it like this:
$(document).ready(function () {
// apply to all inputs on the page:
$('input[type=text]').focusSelect();
// apply only to one input
$('#out').focusSelect();
});

Categories