Gab Royer
Gab Royer

Reputation: 9806

How do I wait until the user has finished writing down in a text input to call a function?

I'm designing a web site and I would like to be able to call a function 1 second after the last user input. I tried using onKeyUp, but it waited 1 second after the first keystroke.

Does anyone know how would this be possible?

Upvotes: 25

Views: 29055

Answers (7)

Vkl125
Vkl125

Reputation: 138

Here is a spun off version based off of @madx. Included features are add remove listener, key string reading within one second, clearing the key string, comparing the key string with a result string.

const onKeyHandler = function (e) {

          // Init a timeout variable to be used below
          let timeout = null;
          // Clear the timeout if it has already been set.
          // This will prevent the previous task from executing
          // if it has been less than <MILLISECONDS>
          clearTimeout(timeout);

          // Make a new timeout set to go off in 1000ms (1 second)
          timeout = setTimeout(function () {
            //               console.log('Pressed so far:', key.join());
            input.push(e.key)
            console.log(input.join(''))
            if (input.join('') == "ResultString") {
              //remove listener
              window.removeEventListener('keyup', onKeyHandler);
              clearInterval();
            } else {
             
            }
            _.debounce(() => { 
              input = [];
              clearInterval();
            },1000)()
          }, 1000);
      };
      window.addEventListener('keyup', onKeyHandler);

Upvotes: 0

madx
madx

Reputation: 7203

// Get the input box
let input = document.getElementById('my-input');

// Init a timeout variable to be used below
let timeout = null;

// Listen for keystroke events
input.addEventListener('keyup', function (e) {
    // Clear the timeout if it has already been set.
    // This will prevent the previous task from executing
    // if it has been less than <MILLISECONDS>
    clearTimeout(timeout);

    // Make a new timeout set to go off in 1000ms (1 second)
    timeout = setTimeout(function () {
        console.log('Input Value:', input.value);
    }, 1000);
});
<!-- a simple input box -->
<input type="text" id="my-input" />

Credits to: Wait for User to Stop Typing, in JavaScript

Upvotes: 2

Adam Pietrasiak
Adam Pietrasiak

Reputation: 13194

There is some simple plugin I've made that does exacly that. It requires much less code than some proposed solutions and it's very light (~0,6kb)

First you create Bid object than can be bumped anytime. Every bump will delay firing Bid callback for next given ammount of time.

var searchBid = new Bid(function(inputValue){
    //your action when user will stop writing for 200ms. 
    yourSpecialAction(inputValue);
}, 200); //we set delay time of every bump to 200ms

When Bid object is ready, we need to bump it somehow. Let's attach bumping to keyup event.

$("input").keyup(function(){
    searchBid.bump( $(this).val() ); //parameters passed to bump will be accessable in Bid callback
});

What happens here is:

Everytime user presses key, bid is 'delayed' (bumped) for next 200ms. If 200ms will pass without beeing 'bumped' again, callback will be fired.

Also, you've got 2 additional functions for stopping bid (if user pressed esc or clicked outside input for example) and for finishing and firing callback immediately (for example when user press enter key):

searchBid.stop();
searchBid.finish(valueToPass);

Upvotes: 0

syleishere
syleishere

Reputation: 21

Just modify your html input and toss that first line into your existing functions so you're not having to recode anything you have. It will not affect any old code-calling functions either, since if onkeypress is not set then mykeypress will always be < 1.

var mykeypress=0;
var mysleep=1000; //set this higher if your users are slow typers
function mytest(id,text) {
   mykeypress--; if(mykeypress > 0) { return; }
   //anything you want when user stops typing here
   alert("Keypress count at "+mykeypress+" ready to continue 
id is "+id+" arguement is "+text);
}

input type="text" name="blah" id="55" onkeypress="mykeypress++"
onkeyup="myid=this.id;setTimeout(function (){mytest(myid,'a test')},mysleep)"
REVERT to old way seamlessly:
input type="text" name="blah" id="55" onkeyup="mytest(this.id,'a test')"

Upvotes: 0

Gab Royer
Gab Royer

Reputation: 9806

Nevermind, I found a way to do it. I call a function on each onkeyup() which increment a counter and then wait 1 second. After the 1 second elapsed, it decrement the counter and check if it's equal to 0.

var keystrokes = 0;
function askAgain()
{
    ++keystrokes;
    setTimeout(reveal, 1000);
}

function reveal()
{
    --keystrokes;

    if (keystrokes == 0)
        alert("Watch out, there is a snake!");
}

Upvotes: 1

Christian C. Salvad&#243;
Christian C. Salvad&#243;

Reputation: 827366

Another similar approach, without globals:

var typewatch = function(){
    var timer = 0;
    return function(callback, ms){
        clearTimeout (timer);
        timer = setTimeout(callback, ms);
    }  
}();    

...

<input type="text" onKeyUp="typewatch(function(){alert('Time elapsed!');}, 1000 );" />

You can this snippet here.

Upvotes: 47

jimr
jimr

Reputation: 11230

You can use a keyDown (or keyUp) event that sets a function to run in 1 second and if the user types another key within that second, you can clear the timeout and set a new one.

E.g.

var t;    

function keyDown()
{
  if ( t )
  {
    clearTimeout( t );
    t = setTimeout( myCallback, 1000 );
  }
  else
  {
    t = setTimeout( myCallback, 1000 );
  }
}

function myCallback()
{
   alert("It's been 1 second since you typed something");
}

Upvotes: 20

Related Questions