I'm currently using Angularjs (version 1.5.8) and I'm developing an application where a series of inputs are generated dynamically, and I want that when you focus an input and you take 5 seconds or more to start writing, appears a tooltip (the tooltip is the same for all inputs), currently I have a tooltip directive that supports trigger events ('click', 'mouseenter', 'focus').
I made a first version of what I want using the click trigger, but sometimes there are unwanted behaviors, any suggestions?
Use the mouseenter event (or focus) and set a timeout to add the title attribute to the input (or create an explicit tooltip component to appear). If the user has any keypress or just plain model input, then cancel the timeout ?
let input = document.getElementById('input');
input.onfocus = function(){
let a = 0;
setTimeout(function(){alert('Please, write something');}, 5000);
};
/* Replaces the function alert('Please ...') with the function that manages your tooltip */
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<input id="input" />
</body>
</html>
`
$scope.focus = function() {
setTimeout(function(){
alert("test"); }, 5000);`
you write tooltip code ...inside of function.
you write custom directive called element.on("focus")
Related
I am writing a Greasemonkey script to interact with orders on Shipstation.com.
The script will select certain values in <select> and <input> elements of the order modal based on certain criteria.
Thus, the script must be able to interact with these elements.
However, I cannot figure out how to do so.
So far, I have tried to do the following and have been unable to trigger a click on the element:
Set the value of the element using JS .value
Set the value of the element using jQuery .val
Trigger a click event on the element using JS .click()
Trigger a click event on the element using this code:
function triggerMostButtons (jNode) {
triggerMouseEvent (jNode, "mouseover");
triggerMouseEvent (jNode, "mousedown");
triggerMouseEvent (jNode, "mouseup");
triggerMouseEvent (jNode, "click");
}
function triggerMouseEvent (node, eventType) {
var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent (eventType, true, true);
node.dispatchEvent (clickEvent);
}
triggerMostButtons(jNode);
It appears that Shipstation is locking the value of <select> and <input> values.
Here are examples of the SO questions I have read to try and figure this out. I haven't been able to trigger a click on these elements using any of these approaches:
"Normal" button-clicking approaches are not working in Greasemonkey script?
How to simulate click in react app using tampermonkey?
Greasemonkey script to automatically select, and click, a specific button with non-English characters in the value/selector?
Choosing and activating the right controls on an AJAX-driven site
Simulating a mousedown, click, mouseup sequence in Tampermonkey?
javascript click a value in dropdown list
How to change a <select> value from JavaScript
How do I programmatically set the value of a select box element using JavaScript?
Set the value of an input field
How else can I trigger a click on these elements?
Alternatively, how can I set the value of these fields using JS? Do I have to find the data model in the JS and edit the value directly? Or find a way to hijack the functions that are triggered when a user clicks on these elements?
Maybe the values are loaded dynamically from the server, so you need to wait until the full page is loaded by adding a load event.
Then grab the select elements by a document.getElementById (or querySelector) and set your desired value (If I understood correctly, you don't need a click event).
You didn't provide an example I can work with, but I tried it with this https://www.shipstation.com/step1/
Notice how after the page loads, the country will be set to Canada:
// ==UserScript==
// #name Unnamed Script 933923
// #version 1
// #grant none
// #match *://*.shipstation.com/*
// ==/UserScript==
window.addEventListener('load', (event) => {
document.getElementById('country').value = "CA";
document.getElementById('howdidyouhearaboutus').value = "Banner Ad";
});
you can select an option by doing this
function selectItemInDropdownList(selectElement, ov) {
const optionToSelect = '' + ov
const options = selectElement.getElementsByTagName('option')
for (const optionEle of options) {
if (optionToSelect === optionEle.innerText || optionToSelect === optionEle.value) {
optionEle.selected = true // selects this option
return true
}
}
return false // failed
}
/*
const dropdownEle = document.getElementById('whatever')
const status = selectItemInDropdownList(dropdownEle, "WHAT")
console.log(status ? 'success' : 'failed')
*/
I think main issue is its a popup form and the select element 'may' not be available in DOM tree at first. so make sure to call this function when its available.
This solution works well in 2022. No jQuery is used.
Auto expand select options in element cb:
cb.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }))
Input focus on element cb (tested on Safari), watch the compatibility note on MDN:
cb.focus()
Below are the working solution for you to copy and run on a browser. (Since input focus feature is failed to run in the code snippet here, while the feature auto expand the select options still works.)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<select id="select-1">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<input id="input-1" type="text"/>
<script>
window.onload = function() {
const select = document.getElementById('select-1');
const input = document.getElementById('input-1');
input.focus();
setTimeout(function() {
select.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
}, 1000);
}
</script>
</body>
</html>
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">
I have a pretty simple form. When the user types in an input field, I want to update what they've typed somewhere else on the page. This all works fine. I've bound the update to the keyup, change and click events.
The only problem is if you select an input from the browser's autocomplete box, it does not update. Is there any event that triggers when you select from autocomplete (it's apparently neither change nor click). Note that if you select from the autocomplete box and the blur the input field, the update will be triggered. I would like for it to be triggered as soon as the autocomplete .
See: http://jsfiddle.net/pYKKp/ (hopefully you have filled out a lot of forms in the past with an input named "email").
HTML:
<input name="email" />
<div id="whatever"><whatever></div>
CSS:
div {
float: right;
}
Script:
$("input").on('keyup change click', function () {
var v = $(this).val();
if (v) {
$("#whatever").text(v);
}
else {
$("#whatever").text('<whatever>');
}
});
I recommending using monitorEvents. It's a function provide by the javascript console in both web inspector and firebug that prints out all events that are generated by an element. Here's an example of how you'd use it:
monitorEvents($("input")[0]);
In your case, both Firefox and Opera generate an input event when the user selects an item from the autocomplete drop down. In IE7-8 a change event is produced after the user changes focus. The latest Chrome does generate a similar event.
A detailed browser compatibility chart can be found here:
https://developer.mozilla.org/en-US/docs/Web/Events/input
Here is an awesome solution.
$('html').bind('input', function() {
alert('test');
});
I tested with Chrome and Firefox and it will also work for other browsers.
I have tried a lot of events with many elements but only this is triggered when you select from autocomplete.
Hope it will save some one's time.
Add "blur". works in all browsers!
$("input").on('blur keyup change click', function () {
As Xavi explained, there's no a solution 100% cross-browser for that, so I created a trick on my own for that (5 steps to go on):
1. I need a couple of new arrays:
window.timeouts = new Array();
window.memo_values = new Array();
2. on focus on the input text I want to trigger (in your case "email", in my example "name") I set an Interval, for example using jQuery (not needed thought):
jQuery('#name').focus(function ()
{
var id = jQuery(this).attr('id');
window.timeouts[id] = setInterval('onChangeValue.call(document.getElementById("'+ id +'"), doSomething)', 500);
});
3. on blur I remove the interval: (always using jQuery not needed thought), and I verify if the value changed
jQuery('#name').blur(function ()
{
var id = jQuery(this).attr('id');
onChangeValue.call(document.getElementById(id), doSomething);
clearInterval(window.timeouts[id]);
delete window.timeouts[id];
});
4. Now, the main function which check changes is the following
function onChangeValue(callback)
{
if (window.memo_values[this.id] != this.value)
{
window.memo_values[this.id] = this.value;
if (callback instanceof Function)
{
callback.call(this);
}
else
{
eval( callback );
}
}
}
Important note: you can use "this" inside the above function, referring to your triggered input HTML element. An id must be specified in order to that function to work, and you can pass a function, or a function name or a string of command as a callback.
5. Finally you can do something when the input value is changed, even when a value is selected from a autocomplete dropdown list
function doSomething()
{
alert('got you! '+this.value);
}
Important note: again you use "this" inside the above function referring to the your triggered input HTML element.
WORKING FIDDLE!!!
I know it sounds complicated, but it isn't.
I prepared a working fiddle for you, the input to change is named "name" so if you ever entered your name in an online form you might have an autocomplete dropdown list of your browser to test.
Detecting autocomplete on form input with jQuery OR JAVASCRIPT
Using: Event input. To select (input or textarea) value suggestions
FOR EXAMPLE FOR JQUERY:
$(input).on('input', function() {
alert("Number selected ");
});
FOR EXAMPLE FOR JAVASCRIPT:
<input type="text" onInput="affiche(document.getElementById('something').text)" name="Somthing" />
This start ajax query ...
The only sure way is to use an interval.
Luca's answer is too complicated for me, so I created my own short version which hopefully will help someone (maybe even me from the future):
$input.on( 'focus', function(){
var intervalDuration = 1000, // ms
interval = setInterval( function(){
// do your tests here
// ..................
// when element loses focus, we stop checking:
if( ! $input.is( ':focus' ) ) clearInterval( interval );
}, intervalDuration );
} );
Tested on Chrome, Mozilla and even IE.
I've realised via monitorEvents that at least in Chrome the keyup event is fired before the autocomplete input event. On a normal keyboard input the sequence is keydown input keyup, so after the input.
What i did is then:
let myFun = ()=>{ ..do Something };
input.addEventListener('change', myFun );
//fallback in case change is not fired on autocomplete
let _k = null;
input.addEventListener( 'keydown', (e)=>_k=e.type );
input.addEventListener( 'keyup', (e)=>_k=e.type );
input.addEventListener( 'input', (e)=>{ if(_k === 'keyup') myFun();})
Needs to be checked with other browser, but that might be a way without intervals.
I don't think you need an event for this: this happens only once, and there is no good browser-wide support for this, as shown by #xavi 's answer.
Just add a function after loading the body that checks the fields once for any changes in the default value, or if it's just a matter of copying a certain value to another place, just copy it to make sure it is initialized properly.
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>
How do I grab the value from an input box as its being entered?
onkeyup will be triggered every time a key is released. While it looks to be the solution it has some problems.
If the user move the cursor with the arrows, it is triggered and you have to check yourself if the field value didn't change.
If the user copy/paste a value in the input field with the mouse, or click undo/redo in the browser, onkeyup is not triggered.
Like in a mac or in google docs, I didn't want a save button to submit forms in our app, here is how I do it.
Any comment, or shortcut is welcome as it is a bit heavy.
onfocus, store the current value of the field, and start an interval to check for changes
when the user moves something in the input, there is a comparison with the old value, if different a save is triggered
onblur, when the user moves away from the field, clear the interval and event handlers
Here is the function I use, elm is the input field reference and after is a callback function called when the value is changed:
<html>
<head>
<title>so</title>
</head>
<body>
<input type="text" onfocus="changeField(this, fldChanged);">
<script>
function changeField(elm, after){
var old, to, val,
chk = function(){
val = elm.value;
if(!old && val === elm.defaultValue){
old = val;
}else if(old !== val){
old = val;
after(elm);
}
};
chk();
to = setInterval(chk, 400);
elm.onblur = function(){
to && clearInterval(to);
elm.onblur = null;
};
};
function fldChanged(elm){
console.log('changed to:' + elm.value);
}
</script>
</body>
</html>
use an onchange event handler for the input box.
http://www.htmlcodetutorial.com/forms/_INPUT_onChange.html
I noticed you used the "jquery" tag. For jQuery, you can use the .keypress() method.
From the API documentation:
Description: Bind an event handler to the "keypress" JavaScript
event, or trigger that event on an
element.
The event will fire every time keyboard input is registered by the browser.
.keydown() and .keyup() are also available. Their behavior is slightly different from .keypress() and is outlined by the API documentation as well.
The nice thing about jQuery is that you can use the same code across Firefox, IE, Safari, Opera and Chrome.