0

I have an AJAX form that I need to submit every time a user types something in a textbox.

The following code works:

<% using (Ajax.BeginForm("myAction", "myController", null, new AjaxOptions() { InsertionMode = InsertionMode.Replace, UpdateTargetId = "resultDiv" }, new { id = "myForm" }))
   {%>

<script type="text/javascript" language="javascript">
    jQuery("#myForm").keyup(function() { $('#myForm').trigger('onsubmit'); });
</script>

Search: <input type="text" id="myTextField" />

<%} %>

I've been trying to update the code so that there is a delay of 1sec in submitting the form. The delay would allow for the form to be submitted only when the user stops typing for the one second interval. This code does not work:

<% using (Ajax.BeginForm("myAction", "myController", null, new AjaxOptions() { InsertionMode = InsertionMode.Replace, UpdateTargetId = "resultDiv" }, new { id = "myForm" }))
   {%>

<script type="text/javascript" language="javascript">
    var timerid;
    jQuery("#myForm").keyup(function() {
        clearTimeout(timerid);
        timerid = setTimeout(function() { $('#myForm').trigger('onsubmit'); }, 1000);
    });

</script>

Search: <input type="text" id="myTextField" />

<%} %>

Any suggestions on how to delay the ajax form from being submitted until a user stops typing for a short period of time?

UPDATE: Using Chrome, I found that the script stops somewhere in MicrosoftAjax.js in a caught exception. I don't know how to find what the exception is exactly.

For debugging purposes, I rewrote the code as follows:

    var timerid;

    jQuery("#myForm").keyup(submitWithTimeout);

    function submitWithTimeout() {
        clearTimeout(timerid);
        timerid = setTimeout(submitAjaxForm, 2000);
    }

    function submitAjaxForm() {
        $('#myForm').trigger('onsubmit');
    }

The code executes both lines in "submitWithTimeout" function, and accurately waits for 2 secs. It reaches the submitAjaxForm function, and stops at a caught exception in MicrosoftAjax.js file, as mentioned before.

UPDATE 2: I am now using the debug version of MicrosoftAjax.js and found the source of the error. Using the expression watcher in Chrome, I was able to narrow it down to the following issue: the "eventObject" variable is null while MicrosoftAjax.js is executing. What I gather from the source code is that the onsubmit code's "event" is null when using the timer to submit the form. Any ideas why?

<form action="myAction" id="myForm" method="post" onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, updateTargetId: 'myResult' });">

The new Sys.UI.DomEvent(event) has a null value for the "event" parameter when using the timeout method.

Remus
  • 1,433
  • 3
  • 14
  • 24
  • what does "does not work" mean? Error? Isn't cancelled? something else? Probably should not clearTimeout on an uninitialized variable -- other than that, would expect it to work. – Lou Franco Jan 17 '11 at 19:52
  • No, no error. In fact, nothing happens that I can see. JavaScript errors list is clear, no call reaches the action method in MVC. I'm guessing there's a javascript issue somewhere, but I can't find it. Any idea how to deal with ClearTimeout? The code is an adaptation from http://stackoverflow.com/questions/2006870/submit-form-with-delay-while-entering-data-into-input-field. – Remus Jan 17 '11 at 20:31
  • @Lou: the error was caught, which is why I didn't see it, though I still don't know what the error is, I know where it comes from... see update for details. It doesn't seem to have an issue with ClearTimeout. – Remus Jan 18 '11 at 22:59

2 Answers2

1

I would recommend you using the TypeWatch jquery plugin which will allow you to achieve this very easily. Your code might simply look like this:

$("#myForm input").typeWatch({ 
    callback: function() { 
        $('#myForm').trigger('onsubmit');
    },
    wait: 1000,
    highlight: true,
    captureLength: 3
});
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I'm trying to use this plugin, but i'm getting a similar issue where nothing happens. I wonder if the issue isn't from the "trigger" method. – Remus Jan 17 '11 at 20:47
  • It looks like the issue comes from the MicrosoftAjax.js file, regardless of whether I use the code I had or the TypeWatch code you mentioned. See my updates for more details... – Remus Jan 18 '11 at 23:39
  • Please see my own answer to this question. As far as I could tell there is a scope issue whereby an AJAX form request requires an 'event' variable that is no longer set once the onsubmit method is triggered. That is probably the reason that the TypeWatch plugin doesn't work for my scenario. +1 if you update your answer so that it works on an AJAX form. – Remus Jan 19 '11 at 17:55
0

There seems to be a special requirement when trying to submit an AJAX form after a certain delay.

As mentioned in my last update (see question), the issue comes from the event variable being unassigned when the MicrosoftAjax.js library is executed, trying to submit the form. The event variable has the KeyboardEvent (or MouseEvent, I imagine) that triggered the submission of the form. This event variable is assigned when the "keyup" event is fired, but is no longer available after the timeout expires, probably because the scope is lost.

My workaround is to store the values in a global variable in order to reset the event data to the state when the key is pressed.

As such, the code becomes the following:

var timerid;
var timerEvent;

jQuery("#myForm").keyup(submitWithTimeout);

function submitWithTimeout() {
    clearTimeout(timerid);
    timerEvent = event;
    timerid = setTimeout(function() { submitAjaxForm(); }, 2000);
}

function submitAjaxForm() {
    event = timerEvent;
    $('#myForm').trigger('onsubmit');
}
Remus
  • 1,433
  • 3
  • 14
  • 24