ng-blur don't fire event on firefox with input number - javascript

I am trying to use ng-blur with an html input (type=number) element on firefox.
The problem I found is that when using the up and down arrows of the input number neither the blur nor the focus events are fired with firefox whereas with chrome works fine.
You can reproduce the issue in http://jsfiddle.net/chonw54e/
<div ng-app ng-init="focus=false;blur=false;active=false">
<input type="number" ng-class="{ myFocus: focus, myBlur: blur }" ng-focus="focus=true;blur=false;" ng-blur="blur=true;focus=false;">
<p>focus: {{focus}}</p>
<p>blur: {{blur}} </p>
</div>
Just load the page (with both firefox and chrome) and click on the up/down arrows of the html input number
input number
What am I doing wrong?
Thanks for the help!
EDIT: 11/12/2015
#Arg0n's solution fix the problem. However, it looks like a problem of either firefox or angularjs.
I have just created an issue on angular github here
It is not an angular problem. It is due to the firefox's event behaviour which don't focus the input when clicking the arrows inside the input (which in my opinion is a mistake).
EDIT: 14/12/2015
Firefox Issue created in bugzilla: https://bugzilla.mozilla.org/show_bug.cgi?id=1232233

You can fix this with jQuery, see this fiddle:
JavaScript
$(function(){
$("input[type='number']").on("click", function(){
$(this).focus();
});
});
Without jQuery, see this:
JavaScript
document.onreadystatechange = function() {
if (document.readyState == "complete") {
var inputs = document.querySelectorAll('[type="number"]');
for (var i = 0; i < inputs.length; i++) {
inputs[i].onclick = function() {
this.focus();
}
}
}
}
This will force the browser to focus on the input when it's clicked. (Input with type set to number).

A simple onclick="this.focus();" will work as nicely and much simpler if you have one field or using Angularjs's ng-repeat.

Related

Programatically put input in editing state (just like clicked on it with mouse)

Assume there is a regular html input field
<input id="inputEl" type="text">
When I click on it with my mouse, it starts being 'editable' (an editing line at the beginning starts blinking) - just like every input field.
Using jQuery, I am trying to simulate that so without me clicking on it with mouse, it gets on that editing state.
I have tried:
$('#inputEl').click()
$('#inputEl').keydown()
$('#inputEl').focus()
$('#inputEl').focusin()
$('#inputEl').blur()
$('#inputEl').select()
$('#inputEl').trigger('input')
But none seems to do the trick.
What is the proper way of achieving this?
.focus() would be the correct method here, the problem you are facing could be related to other issues.
At least it is working here
http://jsfiddle.net/KN6rs/
The focus() function doesn't work on console because:
$.focus() not working
I tried
setTimeout(function() { $('.js-search-field').focus() }, 3000); works on SO
$(document).ready(function() {
$('#inputEl').focus();
});
This is your solution. You just need to do it when the DOM is loaded. $(document).ready takes care of that.
Looks like you want to simulate click event. You can do it via jQuery using trigger(), like this:
$("#inputEl").trigger("click");
Here is an example:
$("#inputEl").trigger("click");
function wasClicked() {
console.log('Click event was successfully simulated')
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="inputEl" type="text" onclick="wasClicked()">
Or if you want just to focus on this input, here it is:
$("#inputEl").focus()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="inputEl" type="text">

'taphold' event disabled after focus on a textbox

I have been using the jQuery UI mobile library and have the following method bound to an element for 'taphold':
// Apply class to annotations details to initiate animation
$('.detailsDiv').on('taphold', function ()
{
var openingID = $(this).parent().attr("annoID");
var showControls = true;
if ($(".annoEditableTextArea.annoName").length > 0)
$('body').append(pThis._getBlackoutOverlay(id));
}
else
{
$(this).off('mousedown');
pThis.base.annotations._setAnnotationDetailsActive(openingID, showControls);
}
});
This hooks the event just fine. However, on iOS safari if I click on a textbox from here after the 'taphold' event does not fire. I've tried to reattach the event after an unfocus of a textbox but still no luck.
Has anyone had any similar experiences with this sort of behavior?
Many thanks
I could not pin point the exact reason behind this, however I found a similar library from some guys called zauberlabs:
https://github.com/zauberlabs/jquery-tap-and-hold
This was a straight swap, with no extra coding required and solved the problem.
Many thanks,

How to disable 'Paste' in Android browser using JQuery?

I have an input field which I do not want users to paste any values in it. I am using the following jQuery code and it works fine on desktop Browser and iPhone Safari. The problem is it's not working on Android browser.
$('#no_paste').bind("paste", function(e) {
e.preventDefault();
});
Here's the fiddle
I've tested this on Galaxy SIII and Android browser doesn't seem to send the
paste event. However, it still sends the input event after something was pasted.
If user is typing into a field he will fire one input event for each letter. However, if he is pasting, input event will fire only once for the whole string that was pasted. Basing on this observation we can block pasting like this:
$('#ie').bind("input", function() {
var previousValue = $(this).data('old_value') || '',
newValue = $(this).val();
if((newValue.length - previousValue.length) > 1) {
$(this).val(previousValue);
}
$(this).data('old_value', $(this).val());
});
You will find JSFiddle here.
Please note that this will also block autocomplete and all other strange input techniques that work in a similar fashion (I don't know about any).

Mobile Safari: Javascript focus() method on inputfield only works with click?

I have a simple input field like this.
<div class="search">
<input type="text" value="y u no work"/>
</div>​
And I'm trying to focus() it inside a function.
So inside of a random function (doesn't matter what function it is) I have this line …
$('.search').find('input').focus();
This works just fine on every Desktop whatsoever.
However it doesn't work on my iPhone. The field is not getting focused and the keyboard is not shown on my iPhone.
For testing purposes and to show you guys the problem I did a quick sample:
$('#some-test-element').click(function() {
$('.search').find('input').focus(); // works well on my iPhone - Keyboard slides in
});
setTimeout(function() {
//alert('test'); //works
$('.search').find('input').focus(); // doesn't work on my iPhone - works on Desktop
}, 5000);​
Any idea why the focus() wouldn't work with the timeout function on my iPhone.
To see the live example, test this fiddle on your iPhone. http://jsfiddle.net/Hc4sT/
Update:
I created the exact same case as I'm currently facing in my current project.
I have a select-box that should — when "changed" — set the focus to the input field and slide-in the kexboard on the iphone or other mobile devices. I found out that the focus() is set correctly but the keyboard doesn't show up. I need the keyboard to show up.
Actually, guys, there is a way. I struggled mightily to figure this out for [LINK REMOVED] (try it on an iPhone or iPad).
Basically, Safari on touchscreen devices is stingy when it comes to focus()ing textboxes. Even some desktop browsers do better if you do click().focus(). But the designers of Safari on touchscreen devices realized it's annoying to users when the keyboard keeps coming up, so they made the focus appear only on the following conditions:
1) The user clicked somewhere and focus() was called while executing the click event. If you are doing an AJAX call, then you must do it synchronously, such as with the deprecated (but still available) $.ajax({async:false}) option in jQuery.
2) Furthermore -- and this one kept me busy for a while -- focus() still doesn't seem to work if some other textbox is focused at the time. I had a "Go" button which did the AJAX, so I tried blurring the textbox on the touchstart event of the Go button, but that just made the keyboard disappear and moved the viewport before I had a chance to complete the click on the Go button. Finally I tried blurring the textbox on the touchend event of the Go button, and this worked like a charm!
When you put #1 and #2 together, you get a magical result that will set your login forms apart from all the crappy web login forms, by placing the focus in your password fields, and make them feel more native. Enjoy! :)
A native javascript implementation of WunderBart's answer.
function onClick() {
// create invisible dummy input to receive the focus first
const fakeInput = document.createElement('input')
fakeInput.setAttribute('type', 'text')
fakeInput.style.position = 'absolute'
fakeInput.style.opacity = 0
fakeInput.style.height = 0
fakeInput.style.fontSize = '16px' // disable auto zoom
// you may need to append to another element depending on the browser's auto
// zoom/scroll behavior
document.body.prepend(fakeInput)
// focus so that subsequent async focus will work
fakeInput.focus()
setTimeout(() => {
// now we can focus on the target input
targetInput.focus()
// cleanup
fakeInput.remove()
}, 1000)
}
Other References: Disable Auto Zoom in Input "Text" tag - Safari on iPhone
I faced the same issue recently. I found a solution that apparently works for all devices. You can't do async focus programmatically but you can switch focus to your target input when some other input is already focused. So what you need to do is create, hide, append to DOM & focus a fake input on trigger event and, when the async action completes, just call focus again on the target input. Here's an example snippet - run it on your mobile.
edit:
Here's a fiddle with the same code. Apparently you can't run attached snippets on mobiles (or I'm doing something wrong).
var $triggerCheckbox = $("#trigger-checkbox");
var $targetInput = $("#target-input");
// Create fake & invisible input
var $fakeInput = $("<input type='text' />")
.css({
position: "absolute",
width: $targetInput.outerWidth(), // zoom properly (iOS)
height: 0, // hide cursor (font-size: 0 will zoom to quarks level) (iOS)
opacity: 0, // make input transparent :]
});
var delay = 2000; // That's crazy long, but good as an example
$triggerCheckbox.on("change", function(event) {
// Disable input when unchecking trigger checkbox (presentational purpose)
if (!event.target.checked) {
return $targetInput
.attr("disabled", true)
.attr("placeholder", "I'm disabled");
}
// Prepend to target input container and focus fake input
$fakeInput.prependTo("#container").focus();
// Update placeholder (presentational purpose)
$targetInput.attr("placeholder", "Wait for it...");
// setTimeout, fetch or any async action will work
setTimeout(function() {
// Shift focus to target input
$targetInput
.attr("disabled", false)
.attr("placeholder", "I'm alive!")
.focus();
// Remove fake input - no need to keep it in DOM
$fakeInput.remove();
}, delay);
});
label {
display: block;
margin-top: 20px;
}
input {
box-sizing: border-box;
font-size: inherit;
}
#container {
position: relative;
}
#target-input {
width: 250px;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="container">
<input type="text" id="target-input" placeholder="I'm disabled" />
<label>
<input type="checkbox" id="trigger-checkbox" />
focus with setTimetout
</label>
</div>
This solution works well, I tested on my phone:
document.body.ontouchend = function() { document.querySelector('[name="name"]').focus(); };
enjoy
I have a search form with an icon that clears the text when clicked. However, the problem (on mobile & tablets) was that the keyboard would collapse/hide, as the click event removed focus was removed from the input.
Goal: after clearing the search form (clicking/tapping on x-icon) keep the keyboard visible!
To accomplish this, apply stopPropagation() on the event like so:
function clear ($event) {
$event.preventDefault();
$event.stopPropagation();
self.query = '';
$timeout(function () {
document.getElementById('sidebar-search').focus();
}, 1);
}
And the HTML form:
<form ng-controller="SearchController as search"
ng-submit="search.submit($event)">
<input type="search" id="sidebar-search"
ng-model="search.query">
<span class="glyphicon glyphicon-remove-circle"
ng-click="search.clear($event)">
</span>
</form>
I managed to make it work with the following code:
event.preventDefault();
timeout(function () {
$inputToFocus.focus();
}, 500);
I'm using AngularJS so I have created a directive which solved my problem:
Directive:
angular.module('directivesModule').directive('focusOnClear', [
'$timeout',
function (timeout) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var id = attrs.focusOnClear;
var $inputSearchElement = $(element).parent().find('#' + id);
element.on('click', function (event) {
event.preventDefault();
timeout(function () {
$inputSearchElement.focus();
}, 500);
});
}
};
}
]);
How to use the directive:
<div>
<input type="search" id="search">
<i class="icon-clear" ng-click="clearSearchTerm()" focus-on-clear="search"></i>
</div>
It looks like you are using jQuery, so I don't know if the directive is any help.
UPDATE
I also tried this, but to no avail:
$(document).ready(function() {
$('body :not(.wr-dropdown)').bind("click", function(e) {
$('.test').focus();
})
$('.wr-dropdown').on('change', function(e) {
if ($(".wr-dropdow option[value='/search']")) {
setTimeout(function(e) {
$('body :not(.wr-dropdown)').trigger("click");
},3000)
}
});
});
I am confused as to why you say this isn't working because your JSFiddle is working just fine, but here is my suggestion anyway...
Try this line of code in your SetTimeOut function on your click event:
document.myInput.focus();
myInput correlates to the name attribute of the input tag.
<input name="myInput">
And use this code to blur the field:
document.activeElement.blur();
Try this:
input.focus();
input.scrollIntoView()
Please try using on-tap instead of ng-click event. I had this issue. I resolved it by making my clear-search-box button inside search form label and replaced ng-click of clear-button by on-tap. It works fine now.

element2.focus() fired after element1.onblur() not working in Fx/Chrome/Safari - Salesforce

I am on Salesforce (visualforce) and using a custom autocomplete Javascript. My requirement is to trigger auto complete search on a text field element2 as soon as a selection is made from suggestions on another text field element1.
Since I need to be able to scroll through the auto suggestions list using a keyboard, I need to have focus on the particular field. Am currently doing a element2.focus() just after a selection is made on element1 and triggering the auto suggest search on element2.
Also, on these fields, when the search is running and the user manually focuses on the field, the auto suggestion collapses - this is an indication of cancelling the search. Because of this, I cannot trigger the search and then call element2.focus()
Here's what am experiencing in different browsers:
Chrome/Firefox 3.5, 4/Safari 5.0.3:
Select an option from suggestions under element1
Value in field changes
Suggestions collapse
Field blurs, but not sure where focus goes. Probably window
IE 8:
Select an option from suggestions under element1
Value in field changes
Suggestions collapse
Field blurs and element2 takes focus
Search fires for this field
Also, the above difference in behaviour is only when am selecting using a mouse click. When using a keystroke (up/down then enter) this works as expected in all browsers. The same set of javascript methods are executed on both mouse and keyboard selection.
An interesting 'fix' I found for this is calling element2.focus() after, say, 100 ms using setTimeout(). Am guessing this is because element1's onblur is disrupting element2.focus() but am not really happy using this.
Well, any ideas?
Code Samples:
//mouseclick handler
function handleMouseClick(event){
element1.value = (event.target)?event.target.textContent:event.srcElement.innerText;
callback();
// kills the children and hides the div containing the suggestions
hideAutoComplete();
}
function callback() {
element2.value = '';
element2.focus();
}
Can you use a framework? They really take the pain out of cross-browser compatibility for events. Here's a short example using jQuery that seems to do what you want. Any of the major frameworks would probably work just as well for this.
<html>
<head>
<title>Testing some JS behavior</title>
</head>
<body>
<form id="fooForm">
<label for="a">A: </label><input id="a"/><br />
<label for="b">B: </label><input id="b"/><br />
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script>
$('#b').focus(function(e) {
alert("Focusing on b now.");
});
$('#a').blur(function(e) {
alert("Doing my business on element A.");
$('#b').focus();
// Stop bubbling, just in case this got triggered by them clicking into B
return false;
});
</script>
</body>
</html>

Categories

Resources