Prevent keyUp event when onPaste event is triggered - javascript

I have the following input field:
<input onPaste={pasteFunction} keyUp={keyupFunction} />
I want either the pasteFunction or keyupFunction to run, NOT both. But when a user pastes text into this field both events get triggered and both run.
Is there a way to prevent keyUp if something was pasted into the field?
I tried to set a flag and reset it:
function pasteFunction() {
pasteInProgress = true;
//etc...
pasteInProgress = false;
}
function keyupFunction() {
if (pasteInProgress) return;
//etc...
}
But this doesn't work as pasteInProgress is set to false before keyupFunction is triggered.

You could try storing the time instead, for example.
function pasteFunction() {
lastPaste = Date.now();
//etc...
}
function keyupFunction() {
//less than one second has passed.
if (Date.now()-lastPaste<1000) return;
//etc...
}
Maybe try experimenting with different times depending on the application, but it is still a "hacky" way to solve it. I think there could be better ways.

Is there a way to prevent keyUp if something was pasted into the field?
Assuming you are using a ui library (react?), you could store a value in the component state when something was pasted into the field.
this.state = {
hasPasted: false;
}
function pasteFunction() {
this.state.hasPasted = true; // could also be a timestamp if you need granularity
}
function keyupFunction(e) { // assuming you can pass event here
if (this.state.hasPasted){
// you may want to preventDefault() here
e.preventDefault();
return;
};
}
Without you sharing more context/code, this should do it.

Related

Call function on lose focus or timeout Javascript

I have multiple inputs where the user can change the value.
I have a code that works well with a timeout but I want to fire it whether the timeout has passed or when the user loses the focus, here is my code :
const WAIT_INTERVAL = 500;
changeValue(personal, e){
let self = this;
e.persist();
if(this.state.typingTimeout){
clearTimeout(this.state.typingTimeout);
}
this.setState({
typingTimeout: setTimeout(function(){
self.props.updatePersonal(personal, e.target.value);
}, WAIT_INTERVAL),
})
}
I don't want it to be fire twice and I don't know how to apply this case.
How to apply this code when the focus is lost?
Thanks you!

How to know if keypress was a real user action [duplicate]

I have a handler attached to an event and I would like it to execute only if it is triggered by a human, and not by a trigger() method. How do I tell the difference?
For example,
$('.checkbox').change(function(e){
if (e.isHuman())
{
alert ('human');
}
});
$('.checkbox').trigger('change'); //doesn't alert
You can check e.originalEvent: if it's defined the click is human:
Look at the fiddle http://jsfiddle.net/Uf8Wv/
$('.checkbox').change(function(e){
if (e.originalEvent !== undefined)
{
alert ('human');
}
});
my example in the fiddle:
<input type='checkbox' id='try' >try
<button id='click'>Click</button>
$("#try").click(function(event) {
if (event.originalEvent === undefined) {
alert('not human')
} else {
alert(' human');
}
});
$('#click').click(function(event) {
$("#try").click();
});
More straight forward than above would be:
$('.checkbox').change(function(e){
if (e.isTrigger)
{
alert ('not a human');
}
});
$('.checkbox').trigger('change'); //doesn't alert
Currently most of browsers support event.isTrusted:
if (e.isTrusted) {
/* The event is trusted: event was generated by a user action */
} else {
/* The event is not trusted */
}
From docs:
The isTrusted read-only property of the Event interface is a Boolean
that is true when the event was generated by a user action, and false
when the event was created or modified by a script or dispatched via
EventTarget.dispatchEvent().
I think that the only way to do this would be to pass in an additional parameter on the trigger call as per the documentation.
$('.checkbox').change(function(e, isTriggered){
if (!isTriggered)
{
alert ('human');
}
});
$('.checkbox').trigger('change', [true]); //doesn't alert
Example: http://jsfiddle.net/wG2KY/
Accepted answer didn't work for me. It's been 6 years and jQuery has changed a lot since then.
For example event.originalEvent returns always true with jQuery 1.9.x. I mean object always exists but content is different.
Those who use newer versions of jQuery can try this one. Works on Chrome, Edge, IE, Opera, FF
if ((event.originalEvent.isTrusted === true && event.originalEvent.isPrimary === undefined) || event.originalEvent.isPrimary === true) {
//Hey hooman it is you
}
Incase you have control of all your code, no alien calls $(input).focus() than setFocus().
Use a global variable is a correct way for me.
var globalIsHuman = true;
$('input').on('focus', function (){
if(globalIsHuman){
console.log('hello human, come and give me a hug');
}else{
console.log('alien, get away, i hate you..');
}
globalIsHuman = true;
});
// alien set focus
function setFocus(){
globalIsHuman = false;
$('input').focus();
}
// human use mouse, finger, foot... whatever to touch the input
If some alien still want to call $(input).focus() from another planet.
Good luck or check other answers
I needed to know if calls to the oninput handler came from the user or from undo/redo since undo/redo leads to input events when the input's value is restored.
valueInput.oninput = (e) => {
const value = +valueInput.value
update(value)
if (!e.inputType.startsWith("history")) {
console.log('came from human')
save(value)
}
else {
console.log('came from history stacks')
}
}
It turns out that e.inputType is "historyUndo" on undo and "historyRedo" on redo (see list of possible inputTypes).
You can use onmousedown to detect mouse click vs trigger() call.
I would think about a possibility where you check the mouse position, like:
Click
Get mouse position
Overlaps the coords of the button
...

Two dom events that call the same function should call the function only once if happening in the same time

I have one input and one button. When I blur from the input and the input has changed, the price() function should be called. Also, when I click the button, the price() function should be called.
The problem is that when a user modifies the value of the input and clicks the button, the price() function is called twice. I don't want this to happen.
I tried the old-fashioned way, setting a variable "inPriceFunction" to true while entering and checking if it is not set before entering. This didn't worked because the two events (blur and click) are executed in the exact same time, the if and the variable set didn't had the time to occur.
How can I avoid that?
What I have tried:
<div>
<input type=text onchange="price();" />
</div>
<button onclick="price();" />test</button>
<script>
called = 0;
function price() {
if(called == true){
return;
} else {
called = true;
}
console.log("called");
called=false;
}
</script>
Underscore has you covered: http://underscorejs.org/#throttle
throttle will prevent your function being called twice within a
specified length of time.
once will prevent your function being called twice at all.
The click and change event do not happen at the same time. They happen one after another.
First, the "change" event is fired, setting called = true, then execute console.log("called"); and set called=false again.
Then, the "click" event is fired, but called == false, so it sets called = true; and then execute console.log("called"); and set called=false again.
Here's a jsfiddle that will do the job. You shouldn't use global variables, of course:
http://jsfiddle.net/SZe26/
var clicktimer = null;
function clickfunc() {
var BLOCK_TIME = 500;
function handleclick() {
console.log("Pressed!");
}
if (clicktimer) {
console.log("Skipping handling of click!");
} else {
handleclick();
clicktimer = setTimeout(function() {
clicktimer = null;
}, BLOCK_TIME);
}
}
The sim^pliest way to handle that might be to store a datetime whenver Price is called and use it to check if it has been called too recently.
if (refDate > new Date(10000 + (new Date())) { // 1 second delay?
return;
}
refDate = new Date();
It's likely that two calls to Date return the exact same date though (so no date manipulation would be required).
add a timeout, something like this
function schedludePrice() {
if(myTimeOut){
clearTimeout(myTimeOut);
}
myTimeOut = setTimeout('price()', 10);
}
this way if the function gets called twice in a short time by your blur and click event, the Price function will only be called once.

Trigger event of auto popup list selection via javascript

I have previously entered value 1111, 1222, and 1333 into a HTML text input. Now if I enter 1 to the text input, it should popup a list with value 1111, 1222, and 1333 as available options. How do you trigger an event when any one of these options is selected?
I have a javascript function that performs a calculation on values entered into the text input via "onkeyup" event. This works very well if the user just enter value via keyboard. However, it does not work if the user is selecting a previously entered value from the auto popup list.
I know we can turn off the auto popup list by adding autocomplete="off" to the form/text input. But is there any solution to make it work with the auto popup list? I have tried all available event options including "onchange", but none of those works.
The HTML code is very simple:
<input id="elem_id_1" name="output" type="text" value="0" onkeyup="update();"/>
The js function is very simple too:
function update() {
var a = $('elem_id_1').value;
$('elem_id_2').value = a / 100;
}
Have you tried the onchange event? I'm not sure if it fires for auto-complete selection, but you could also try the onpropertychange event and check for the value property:
textInput.onpropertychange = function ()
{
if (event.propertyName == "value")
doCalculation();
}
This would also work on right-click->paste or right-click->cut, which wouldn't fire your calculation using your current method.
EDIT
It looks like you might have to use a combination of events and timers. Set an interval on focus of the edit and clear it on blur. I'd also use the onpropertychange for IE to make it more efficient and keep the keyup event to make it rather quick too.
//- If it's IE, use the more efficient onpropertychange event
if (window.navigator.appName == "Microsoft Internet Explorer")
{
textInput.onpropertychange = function ()
{
if (event.propertyName == "value")
doCalculation();
}
}
else
{
var valueCheck, lastValue = "";
textInput.onkeyup = function ()
{
doCalculation();
}
textInput.onfocus = function ()
{
valueCheck = window.setInterval(function ()
{
// Check the previous value against (and set to) the new value
if (lastValue != (lastValue = textInput.value))
doCalculation();
}, 100);
}
textInput.onblur = function ()
{
window.clearInterval(valueCheck);
}
}
If your calculation routine is tiny (like a simple mathematical equation), I would just leave out the previous value check and run the calculation every 100ms.

ASP.NET Post-Back and window.onload

I got a function which checks if some input fields are changed:
var somethingchanged = false;
$(".container-box fieldset input").change(function() {
somethingchanged = true;
});
And a function which waits on window.onload and fires this:
window.onbeforeunload = function(e) {
if (somethingchanged) {
var message = "Fields have been edited without saving - continue?";
if (typeof e == "undefined") {
e = window.event;
}
if (e) {
e.returnValue = message;
}
return message;
}
}
But if I edit some of the fields and hit the save button, the event triggers, because there is a post-back and the fields have been edited. Is there anyway around this, so the event does not fire upon clicking the save button?
Thanks
When I do this pattern I have a showDirtyPrompt on the page. Then whenever an action occurs which I don't want to go through the dirty check I just set the variable to false. You can do this on the client side click event of the button.
The nice thing about this is that there might be other cases where you don't want to prompt, the user you might have other buttons which do other post backs for example. This way your dirty check function doesn't have to check several buttons, you flip the responsability around.
<input type="button" onclick="javascript:showDirtyPrompt=false;".../>
function unloadHandler()
{
if (showDirtyPrompt)
{
//have your regular logic run here
}
showDirtyPrompt=true;
}
Yes. Check to see that the button clicked is not the save button. So it could be something like
if ($this.id.not("savebuttonID")) {
trigger stuff
}

Categories