I've come across some kind of bug I believe with angular and chrome and I am not quite sure what the solution is, my angular application has custom input controls and these inputs do some stuff on focus (focus)="someEvent($event). These inputs are the username and password field so chrome stores the values. Upon loading the page again, chrome will apply the stored values, if a user clicks elsewhere on the screen (NOT on the input components), both of the input components fire the focus event.
I could understand if this happened on page load as chrome may cycle through the inputs and apply the stored values, however this happens after the first mouse click anywhere on the page.
Is there a way to interpret that these focus events were cause by the autofill feature and not the user focusing on the input manually?
I have some code on these events that do event.target.select() to select all text, and oddly enough.. the 2 inputs end up getting stuck in a focus loop. The first gets focused then the second then the first then the second forever until a user presses tab.
HTML:
<input [ngClass]="inputClass" [type]="this.type" [readOnly]="this.readonly || (this.ParentPanel && this.ParentPanel.readonly)" [ngStyle]="inputStyle" [disabled]="disabled || (this.ParentPanel && this.ParentPanel.disabled)" [(ngModel)]="value" (change)="Event_change($event)" (keyup)="Event_keyup($event)" (keydown)="Event_keydown($event)" (focus)="Event_focus($event)" maxlength="512"/>
TS:
Event_focus(event) {
console.log('focus event' , event);
if (this.selectAllOnFocus) {
setTimeout(() => { // required to work with Edge (OnFocus happens before some browser properties are set)
event.target.select();
});
}
this.OnFocus.emit(event);
}
Thanks.
I figured this out, Before the code gets called - I have it check whether or not the control is the documents activeElement.
if (this.selectAllOnFocus && this.element && this.element.nativeElement === document.activeElement) { //do rest here }
These appears to work and resolve my issue.
Related
I've been trying to find my way out of the dead end that apple created by stripping down autofocus on iOS. I get it, it creates problems for some cases.
However, I'm still trying to find a proper way to focus an item without clicking the item itself.
I've tried auto-focusing;
myInput.on('blur', function () {
setTimeout(function () {
myInput.focus();
}, 0);
});
I've tried focusing on document-click (anywhere in the document);
document.body.onclick = function () {
s.focus();
};
Both solutions didn't work. Therefore, I'm needing a way to focus the field/input automatically (on page load) or by clicking anywhere on the page (instead of limiting the click to only one item).
I have a single input field that has to be filled in my case. So I don't mind having a lock on that input field (that's actually what I would prefer!).
Any ideas?
I want to show certain content within an HTML document if the user clicks into a certain form field within this document, and I want to hide that certain content if the user leaves that form field (either by activating another one or by clicking somewhere else onto the page).
I have tried to implement that behavior using the focus and blur events. This works in principle, but there is a problem: The blur event on the respective field is fired not only when the user moves the focus within the same document, but as well when another window (which could be from a different application) becomes activated (gets focus).
How could I avoid that? I don't want to see any changes in the page if the focus goes to a different application (or another browser window or tab).
Thank you very much!
Guard the blur event handler with if ( document.activeElement === this ) { return; }.
The next step will be to prevent the focus event handler from activating when the window regains focus. This can be done using a small pattern:
function onFocus(e) {
if ( this._isFocused ) { return; }
this._isFocused = true;
...
}
function onBlur(e) {
if ( document.activeElement === this ) { return; }
this._isFocused = false;
...
}
Maybe this could work:
function onFocus(element) {
document.getElementById('element').doStuffHere('whateverYouWant');
}
function onBlur(element) {
if (document.hasFocus()) {
document.getElementById('element').doStuffHere('whateverYouWant');
} else {
alert('Please come back!')
}
}
The onBlur() function is executed as soon as the element loses focus and first checks if the document still has the focus. If yes it does the elementLostFocus tasks (I'll call them like that here to make it easy), otherwise it (at least in this example) alerts the user, or you can make it do nothing or just the same elementLostFocus tasks or anthing you want.
The only problem with that solution is that you don't do the elementLostFocus tasks when the window regains focus by clicking outside the desired element after it lost the focus directly from the desired element to another window. But here's a fix for that:
document.onfocus = function() {
if (document.getElementById('element').hasFocus() == false) {
document.getElementById('element').doStuffHere('whateverYouWant');
}
}
It can be that that code doesn't work but it should. At least it should give you an idea based on which you can solve the problem yourself.
I have this code, basically I have <input id="register_username" type="text" name="username"> and I want to check if the users already exist in the database or not. The code works perfectly when the user type a username, but sometimes some browsers (for example Firefox) gives the user drop down menu and let them choose some values they already entered in the past (such as their name). The problem is when the chose the username from the drop down menu, the keyup function does not work. How can I fix this problem ?
$("#register_username").live('keyup', function() {
$.post('scripts/register/register_check.php', {
checkusername: $('#register_username').val()
}, function(data) {
if (data == "good") {
//do something
} else {
//do the other thing
}
});
});
I don't think all browers if any triggers an event after choosing an option from an autocomplete dropdown.
Your best bet is to use .change() which will trigger after the element loses focus. For example, when the user chooses an autocomplete option and move on to the next field.
I would use the onblur event to fire whenever the field loses focus.
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>
I have some text inputs which I'm validating when a user tabs to the next one. I would like the focus to stay on a problematic input after showing an alert. I can't seem to nail down the correct syntax to have JQuery do this. Instead the following code shows the alert then focuses on the next text input. How can I prevent tabbing to the next element after showing an alert?
$('input.IosOverrideTextBox').bind({
blur: function(e) {
var val = $(this).val();
if (val.length == 0) return;
var pval = parseTicks(val);
if (isNaN(pval) || pval == 0.0) {
alert("Invalid override: " + val);
return false;
}
},
focus: function() {
$(this).select();
}
});
I don't like forced focus, but can't you just focus after the blur takes place?
element.focus();
If doing that in the blur event doesn't always work (I'm not sure exactly when it fires, before or after the actual blur takes place), a redundant timeout will do, as well: setTimeout(function () { element.focus() }, 0).
But please don't do this. Heck, you should never be using alert or any kind of modal dialog for a web interface, either. How about adding a invalid class to the form field, putting a message off to the side of it, and disabling submit until all fields are valid? That's a much less invasive solution that allows me to fill out the form in whatever way is best for me, rather than whatever way is simplest for you.
You can do this with the validation plugin by default.
focusInvalid default: true
Focus the last active or first invalid element on submit via validator.focusInvalid(). The last active element is the one that had focus when the form was submitted, avoiding to steal its focus. If there was no element focused, the first one in the form gets it, unless this option is turned off.
Then you'd only need to have the focus event handler do your select and let the plugin handle validation.