From the image, is it possible to identify the iOS 'Done' button click event using javascript/jQuery? The iOS keyboard click events can identify using 'onkeypress' function for the text-area.
If that field is part of the form, Done will trigger "onsubmit" event of the form.
One approach is to set a timeout, which occurs on every form element's onblur (which is dispatched) and is cleared on every element's onfocus.
Brief example in jQuery as an explanation:
var blurOccurred;
$("input")
.on("blur", function(evt) {
blurOccurred = window.setTimeout(function() {
alert('Done button clicked');
}, 10);
})
.on("focus", function(evt) {
window.clearTimeout(blurOccurred);
});
By doing this, clicking "done" is detected with 10ms delay. And if it's just navigating to prev / next form field, whole timeout won't be executed.
I'll hope this get you started.
Edit: on iOS7 there is event.relatedTarget property, which is null when "done" is clicked - otherwise it's the input element where the focus is set on. Also this can be used for detecting whether done is clicked (or keyboard is closed).
Related
I have a form with two input elements that are somewhat intertwined. In element#1 (element #2 is right after element#1 in the tabindex order), once the user tries to leave that field, I run an ajax call to check if the value entered is already in the database and if so, use the javascript confirm dialog to ask the user a question. The second element, upon gaining focus, automatically pops up a modal window with choices the user can make. I am using Jquery.
I would like to run the "Does this data exist" ajax call as soon as the user leaves the first element. the Blur event seemed to be what I wanted as this existing data check is needed whether the user made a change or not.
My problem using blur, though, is that its handler runs AFTER the first element loses focus and focus jumps to element#2. So, the blur handler from element #1 pops up the confirm screen at the same time element #2's focus handler pops up the choices modal and I now have 2 popups open at the same time.
I would like to give the user the chance to answer the question in the confirmation alert before the choices for the element#2 pop up.
Is there a Jquery event similar to blur, but that runs just BEFORE focus is actually lost? Or, is there a way to prevent the next element from gaining focus until the blur handler from the first element completes?
Trying to stop propagation or preventDefault() in the Blur handler does nothing because the focus on element#2 has already happened before the blur handler runs.
I've tried setting the tabindex of element#2 to -1 and then programmatically focusing on that element when needed, but tabbing away from this element becomes a problem, and reverse tabbing skips it (jumping straight to element#1) - I still want that element in tabindex ordering, but just don't want it to gain focus until element#1 completes its handler that needs to run when it loses focus.
I have tried setting status variables as well but when I add code to handle the transition between the two elements, I end up with similar issues and it presents additional edge cases complexity. I've also tried messing with mousedown and keydown events and trying to prevent the default processing, but that added significant complexity and room for error as well.
Any ideas would be welcome. Thank you.
This solution is a bit of a hack, but accomplishes your goal. The trick is to place what amounts to a "no-op" element that accepts the focus on blur. Then controlling the tab after the AJAX request.
Upon each "blur" event, we test to ensure we capture the correct <input> element (I'll leave those details to you).
After the AJAX request has completed, then focus on the next <input>.
For this demo, type 2 in the second input, then tab. I added a short delay so you can see that it works.
$("input").on('blur', function(e){
if(this.value == 2) {
console.log("do ajax request");
setTimeout((function(){
$(this).next().next('input').focus();
}).bind(this), 500);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input tabindex="1" />
<input tabindex="2" />
<div tabindex="3"></div>
<input tabindex="3" />
Would something like this do the trick?
Have a variable that indicates if it's okay to show the second popup
let allowSecondPopup = true;
Have a variable that indicates whether showing the second popup was postponed
let secondPopupPostponed = false;
Set the variable when the first input receives focus
$("#input1").on("focus", fuction () {
allowSecondPopup = false;
});
Send ajax on blur
$("#input1").on("blur", function () {
//$("#input1").disabled(true);
//$("#input2").disabled(true);
$.post("https://example.com", { }, fuction (response) {
if (secondPopupPostponed) {
// Only show second popup after the ajax-call has finished
showSecondPopup();
allowSecondPopup = true;
secondPopupPostponed = false;
}
});
});
And when the second input receives focus, check the variable
$("#input2").on("focus", fuction () {
if (allowSecondPopup) {
showSecondPopup();
} else {
// We're still waiting for the ajax-call to complete.
// When the ajax-call completes, the callback will show the second popup.
secondPopupPostponed = true;
}
});
i have:
<input type="text" />
and
$('input').blur(function(){
alert('stay focused!');
});
I want to prevent the blur function running when I'm "blurring" by clicking on an anchor element.
I.E. if i tab to another input, click somewhere on the page etc i want the blur to fire, but if i click a link, I don't want it to fire.
Is this easily achievable, or do i need to hack about with delegates and semaphores?
Thanks
I had to solve this problem myself today, too. I found that the mousedown event fires before the blur event, so all you need to do is set a variable that indicates that a mousedown event occurred first, and then manage your blur event appropriately if so.
var mousedownHappened = false;
$('input').blur(function() {
if(mousedownHappened) // cancel the blur event
{
alert('stay focused!');
$('input').focus();
mousedownHappened = false;
}
else // blur event is okay
{
// Do stuff...
}
});
$('a').mousedown(function() {
mousedownHappened = true;
});
Hope this helps you!!
If you want to keep the cursor at its position in a contenteditable element, simply:
$('button').mousedown(function(){return false;});
Delay the blur a bit. If the viewer clicks a link to another page, the page should change before this code gets a chance to run:
$('input').blur(function(){
setTimeout(function() {alert('stay focused!');}, 1000);
});
You can experiment with what delay value for the timeout seems appropriate.
You can get this behavior by calling preventDefault() in the mousedown event of the control being clicked (that would otherwise take focus). For example:
btn.addEventListener('mousedown', function (event) {
event.preventDefault()
})
btn.addEventListener('click', function(ev) {
input.value += '#'
input.setSelectionRange(ta.value.length, ta.value.length)
})
See live example here.
Some clarification that was too long to put in a comment.
The click event represents both pressing the mouse button down, AND releasing it on a particular element.
The blur event fires when an element loses focus, and an element can lose focus when the user "clicks" off of the element. But notice the behavior. An element gets blurred as soon as you press your mouse DOWN. You don't have to release.
That is the reason why blur gets fired before click.
A solution, depending on your circumstances, is to call preventDefault on mousedown and touchstart events. These events always (I can't find concrete documentation on this, but articles/SO posts/testing seem to confirm this) fire before blur.
This is the basis of Jens Jensen's answer.
From the image, is it possible to identify the iOS 'Done' button click event using javascript/jQuery? The iOS keyboard click events can identify using 'onkeypress' function for the text-area.
If that field is part of the form, Done will trigger "onsubmit" event of the form.
One approach is to set a timeout, which occurs on every form element's onblur (which is dispatched) and is cleared on every element's onfocus.
Brief example in jQuery as an explanation:
var blurOccurred;
$("input")
.on("blur", function(evt) {
blurOccurred = window.setTimeout(function() {
alert('Done button clicked');
}, 10);
})
.on("focus", function(evt) {
window.clearTimeout(blurOccurred);
});
By doing this, clicking "done" is detected with 10ms delay. And if it's just navigating to prev / next form field, whole timeout won't be executed.
I'll hope this get you started.
Edit: on iOS7 there is event.relatedTarget property, which is null when "done" is clicked - otherwise it's the input element where the focus is set on. Also this can be used for detecting whether done is clicked (or keyboard is closed).
I am trying to create to popup div when pressing enter key, while the div contains a button (that I script to focus when it fired up) that will close the div when you press enter again. I receive the enter key from binding keypress and keydown, end up having different results.
Binding 'keypress'
Things work properly, with first enter key fires up a popup box and another enter key to dismiss the popup box.
Refer this JSFiddle.
Binding 'keydown'
This doesn't work correctly, as it fires up and dismiss the popup box immediately (which you won't see) with only one enter key.
Refer this JSFiddle.
My question is why would keydown generate odd behavior, it is like firing enter key twice for me, but the truth it wasn't. If I remove the button focus(), it will works correctly. That's puzzled me.
Tested with firefox and chrome.
You're rebinding the click event every single time the popup opens, so each time you click the close button it'll fire it multiple times which will cause unexpected behaviour.
Eg:
var Popup = function(){
$('#ok-button').live('click',function(){
$('#popup').remove();
});
};
This code means every time you create a new Popup instance, every single $('#ok-button') that exists will have another click event bound to it.
As for the reason why it immediately closes when you use keydown vs keypress, that's due to the fact that the moment the popup is opened you've set the focus to the button.
The two key events work differently (firing at slightly different times during the key process). It appears that with keydown, you're changing the focus in the middle of the actual action (pressing the button on the keyboard) which then continues and triggers the focused click.
Removing the focus stops the weird double trigger behaviour because you're no longer binding another click event.
I'd suggest changing your click event:
$('#ok-button').live('click', function(){
$('#popup').remove();
});
var Popup = function(){
// Whatever
};
I'd also suggest looking at jQuery's on event instead of using live.
I'm wondering if there's a way to capture the iPhone's virtual keyboard's done button event, using JavaScript?
Basically, I just want to be able to call a JS function when the user clicks done.
I was unable to track the 'done' button being clicked. It didn't register any clicks or keypresses. I had to addEventListeners for change, focusout and blur using jquery (because the project already was using jquery).
You need to do some kind of this:
$('someElem').focusout(function(e) {
alert("Done key Pressed!!!!")
});
It worked for me, hope it will help you as well.
After searching and trying this solution
basically is say:
document.addEventListener('focusout', e => {});
tested on IPhone 6s
This question is kinda old, but I've found a hacky way recently to make this working.
The problem with the 'blur', 'focusout' events is that they fire even if user just tapped outside the input/textarea, and did not press the 'Done' button, in my case, UI should behave differently depending on what exactly have happened.
So to implement it, I've done the next thing:
After showing the keyboard (the input received the focus), add click handler on the window via the addEventListener function. When user clicks on the window, remember the timestamp of the click in the variable (let's call it lastClick = Date.now())
In the blur event handler, set a timeout for 10-20 ms to allow other events happening. Then, after the timeout, check if the blur event happened in a time difference lower for example than 50-100 ms than the lastClick (basically Date.now() - lastClick < 50). If yes, then consider it as a 'Done' button click and do corresponding logic. Otherwise, this is a regular 'blur' event.
The key here is that tapping on keyboard controls (including Done button) does not trigger the click event on the window. And the only other way to make keyboard hide is basically tap on other element of the page and make the textarea lose focus. So by checking when the event happened, we can estimate whether that's a done button click or just blur event.
The answer by oron tech using an event listener is the only one that works cross platform.
document.getElementById("myID").addEventListener("focusout", blurFunction);
function blurFunction() { // Do whatever you want, such as run another function
const myValue = document.getElementById("myID").value;
myOtherfunction(myValue);
}
"Change" event works fine
document.querySelector('your-input').addEventListener('change',e=>
console.log('Done button was clicked')
);
attach a blur event to the text box in question. The done fire will fire this event.
The done key is the same as the enter key. So you can listen to a keypress event. I'm writing this using jQuery and i use it in coffee script so I'm trying to convert it back to js in my head. Sorry if there is an error.
$('someElem').bind("keypress", function(e){
// enter key code is 13
if(e.which === 13){
console.log("user pressed done");
}
})