Capture this event : typing in input field stops for more than 3s on unchanged value

Hello,

I’d like to capture the following event: when the user has started typing something in an input field, stopped typing for more than 3 seconds, with the value not having changed during these 3 seconds.

It can be pure javascript or jQuery based.

Stephane

At a guess, the following should do that.


inputField.onkeypress = function () {
    if (this.timer) {
        clearTimeout(this.timer);
    }
    if (this.value) {
        this.timer = setTimeout(promptUser, 3000);
    }
}
inputField.onchange = function () {
    if (this.timer) {
        clearTimeout(this.timer);
    }
}

Hopefully the onchange event will also ensure that the timer gets cleared when the person clicks on something else too.

Hi Paul,

Thanks for the update. In fact, I’ve been trying to find a new angle at my UI issue.

Indeed, I’m faced with this: how to call a javascript function when the user leaves an input field except when he clicks on an on-line keyboard.

The page displays an on-line keyboard with some letters that the user might not have on his actual keyboard.

When the user has the cursor in the input field, he can type in and also click on some letters of the on-line keyboard, which acts as if the user had typed in these letters.

The on-line keyboard works fine.

But, if I want to implement an onchange event handler on the input field, the handler is called even if the user clicks on a letter of the on-line keyboard.

I wonder if there would not be a way, with jQuery probably, to capture the onchange event and wait to see if a click on the on-line keyboard letter has not happened, before actually firing up the validation method.

A bit tricky… :slight_smile:

Stephane

This demonstrates one way of doing it.

<!DOC HTML>
<html>
<head>
<title> Test </title>
</head>
<body>
<form action = '#' >
 <input id='tf'>< Monitored field<br>
 <input><br>
 <input><br>
</form>
<span style='border:solid 1px #000;padding:1em;line-height:2em' id='kb'><a href='#'>A</a> <a href='#'>Z</a></span> < "Keyboard"

<script type="text/javascript">

function installHandler( obj, evt, func )
{
  window.attachEvent ? obj.attachEvent(evt,func) : obj.addEventListener( evt.replace( /^on/i, "" ), func, false);
}

installHandler( document, 'onclick', function( evt )
{
  var srcElem = evt.srcElement || evt.target,
      kBoard = document.getElementById( 'kb' ),
      field = document.getElementById( 'tf' );      
    
  if( srcElem === field )
    field.lastFocused = true;
  else
    if( field.lastFocused )
    {      
      while( srcElem && srcElem !== kBoard )
        srcElem = srcElem.parentNode;
     
      alert( "Keyboard" + ( srcElem ? "" : " not" ) + " clicked when leaving text field"  );       
    
      field.lastFocused = false;  
    }      
});

</script>
</body>
</html>

A simple way is for the onchange event to use setTimeout to trigger its function. The timeout could be just for 50ms, but even that is a small amount of time for the online keyboard to cancel that timeout event.

Awesome ! Dominating !

Thanks :slight_smile: Really nice.

Thanks to you Paul, really nice !

Nice article, thanks whisher. I shall also use that throttle function in some other validation.

Sorry guys, but I’m going slowly on that one…

Here is the current state of affairs:

var keyboardClicked = 0;
$(‘.elearning_exercise_page_keyboard’).bind(“click”, function (event) {
alert(“Keyboard clicked”);
keyboardClicked = 1;
});
function getInstantFeedbackIfNoKeyboardClick(elearningQuestionId, fieldValue) {
keyboardClicked = 0;
alert(“In getInstantFeedbackIfNoKeyboardClick”);
setTimeout(function() {
alert("keyboardClicked: " + keyboardClicked);
if (keyboardClicked == 0) {
getInstantFeedback(elearningQuestionId, fieldValue);
}
}, 500);
alert(“After setTimeout”);
}

$handler .= “getInstantFeedbackIfNoKeyboardClick('” . $elearningQuestion->getId() . “', document.getElementById(‘input_$uniqueQuestionId’).value);”;

<input class=‘elearning_question_answer_input’ type=‘text’ name=‘$uniqueQuestionId’ id=‘input_$uniqueQuestionId’ size=‘$inputSize’ maxlength=‘255’ value=‘$participantAnswer’ onfocus=‘focusElement(this);’ onchange=\“$handler\” />

But the alert “Keyboard clicked” never shows up.

DO you have a test page that demonstrates the problem?
If not, you can use jsfiddle.net to come up with a temporary test page

Hi Paul,

i used the jsfiddle at:

But in there I have trouble even calling the function from the onchange and onblur handler.

Cheers,

Stephane

Your fiddle has the code in an onload event, which means that functions like getInstantFeedbackIfNoKeyboardClick() are not visible from the HTML inline attribute events.
Use “no wrap (body)” instead and you will see better results.

Even better than that though is to assign the onblur event from within the script itself.


$('#input_uniqueQuestionId').blur(getInstantFeedbackIfNoKeyboardClick);

It seems to work the way I want it now :slight_smile:

This jsfiddle is a good idea.

Thanks Paul !

Hi Paul,

I have a similar issue, kindly help. I need to capture the value from an input field and on blur the value has to be stored in a variable for me to write into a database. Pl find my code below, it is not storing the value i typed in the textbox.

<html>
<head>
<style>

p { color:blue; margin:8px; }
</style>
<script src=“http://code.jquery.com/jquery-latest.js”></script>
</head>
<body>

<input type=“text” id=“txt_name” />

<script type=“text/javascript”>
var value = $(“#txt_name”).val();
alert(value);
</script>

</body>
</html>

Capture the input fields blur event, and put that code in there.


$('#txt-value').blur(function () {
    ...
});

I had to improve a bit the script so as to handle the case when the user leaves a field right after having clicked on a keyboard letter…

<script type=“text/javascript”>
var keyboardClicked = 0;
var latestChangedField;
$(‘.elearning_exercise_page_keyboard’).bind(“click”, function (event) {
keyboardClicked = 1;
if (latestChangedField) {
latestChangedField.focus();
}
});

$(document).ready(function() {
$(‘#input_$uniqueQuestionId’).focus(function() {
latestChangedField = $(‘#input_$uniqueQuestionId’);
});
$(‘#input_$uniqueQuestionId’).blur(function() {
setTimeout(function() {
if (keyboardClicked == 0) {
if (“$displayInstantFeedback” > 0) {
getInstantFeedback(‘$elearningQuestionId’, document.getElementById(‘input_$uniqueQuestionId’).value);
}
if (“$elearningAssignmentId” > 0) {
saveLiveAssignment(‘$elearningAssignmentId’, ‘$elearningQuestionId’, document.getElementById(‘input_$uniqueQuestionId’).value);
}
} else {
keyboardClicked = 0;
}
}, 500);
});
});
</script>