Archive

Posts Tagged ‘Ajax’

Onkeyup delay in JavaScript

18 September 2009 3 comments

In a recent post I used a little script to delay the onkeyup event for a set amount of milliseconds after the key was released.  That way a callback will not be made for every key that gets released, but only once the user stopped typing.  That post was brought up many times by a search for this specific function, so I decided to extract it into its own post.

For this post I will only show an alert message to keep it to the bare minimum.

First we need to add this to our page, preferably in the <head> section.  Have a look here if you are not familiar with XHTML compliant JavaScript, it’s a short and straight to the point post.

<script language="javascript" type="text/javascript">
    //<![CDATA[
    function delayTimer() {
        var timer;
        return function(fun, time) {
            clearTimeout(timer);
            timer = setTimeout(fun, time);
        };
    }
    var delayFunction = delayTimer();

    function showMessage() {
        alert('Delay expired!');
    }
    //]]>
</script>

This is just a timer which restarts itself every time the onkeyup event triggers.  Once it runs out it will execute the function that you specify later.

<input id="txtDelay" type="text" onkeyup="delayFunction(showMessage, 500);" />

This is our input box which uses the onkeyup delay.  We use our delegate that we created and pass in two parameters, the first is the function to call and the second is the delay before doing so.  In this case it will wait 500ms before calling the showMessage function.

That is all you need to get a delay for an event in JavaScript.

NOTE: This does NOT work when pasting text in using the mouse.  Disable right-click on the input box if you rely on this function to execute.

Hope this is clear.  Comment if there is anything unclear or if you have a better way for me to do things.

Update – Passing in a parameter to the function as requested by a comment

<script language="javascript" type="text/javascript">
    //<![CDATA[
    function delayTimer() {
        var timer;
        return function (fun, time) {
            clearTimeout(timer);
            timer = setTimeout(fun, time);
        };
    }

    var delayFunction = delayTimer();

    // Takes parameters to display
    function showMessage(message, sender) {
        alert(message + " - " + $(sender).val());
    }
    //]]>
</script>
<!-- Now passing in a function with parameters -->
<input id="txtDelay" type="text" onkeyup="delayFunction(function() { showMessage('Display this string!', $('#txtDelay')); }, 500);" />

Note that passing in ‘this’ to the function in the onclick event does not send the input through.

Advertisements

jQuery and ajax calling webservice

30 August 2009 Leave a comment

In my previous post I wrote a domain name availability checker.  In this post I will create the front-end for it to display the availability using jQuery and ajax.  Note that I changed the web service slightly for this post.  The service will now return ‘available’ or ‘not available’.

I will not be doing much in the sense of validation and will leave that up to you when implementing code.

First off I will add a new HTML (can do webform) file to my solution.  If you do not have jQuery, get it here and rename the downloaded file from .download to .js, then add them to your solution (right-click on the project and click ‘add existing file’, then browse to your jQuery download and add the file.  See image below).

addFile

You can drag the script files from the solution explorer into the header section of your page or add them yourself.  You should then have something along this line:

<head>
    <title>My domain checker</title>
    <script src="jquery-1.3.2.min.js" type="text/javascript"></script>
</head>

We need a text field where the domain will be entered.  If you are not using a plain HTML input, then you will have to do a clever thing later to get the .NET generated name using <%= TextBox1.ClientId %>, so I recommend using a HTML text input if possible.  Add an onkeyup event, I am using onkeyup="getAvailability(displayAvailability, 500);".  The 500 is the delay in ms after the user stopped typing, but more about this later.

Add the following javascript to the page:

    function getAvailabilityTimer() {
        var timer;
        return function(fun, time) {
            clearTimeout(timer);
            timer = setTimeout(fun, time);
        };
    }
    var getAvailability = getAvailabilityTimer();

This will act as the timer since the user stop typing until the ajax callback is made.  You  can change this time by altering the number (500) in the onclick event for the textbox we created above.

The final function is the one that will be doing all the work.  Here is what mine looks like:

function displayAvailability() {
    var domain = $('#domainName').val();
    var selector = "result";//easy to change later
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "DomainService.asmx/CheckDomain", //our service name with the method
        data: "{'domain' : '" + domain + ".com'}", //parameter for which to pass data
        dataType: "json", //responde type
        success: function(msg, success) {
            if (success == 'success') {
                $('#' + selector).html('Domain is ' + msg.d); //good response
            } else {
                $('#' + selector).html('Not able to check at the moment.  Please try again later.'); //service returned an error
            }
        },
        error: function(msg, success) {
            $('#' + selector).html('Not able to check at the moment.  Please try again later.'); //error with ajax call
        }
    });
}

One last thing before testing, in the web service, make sure to uncomment the [System.Web.Script.Services.ScriptService] attribute.  Then let’s start it up and try it out.

checker

And there you have it, working like a charm…I will leave the nice graphicy stuff to you!

When I was testing it the first time, I ran into some problems.  I used nikhilk’s web developer helper.  It is a MUST have when working with ajax.  The problem was that I forgot to set the ScriptService attribute *blush*.

Here is my whole pages’ source: (is the ‘ used right? hope so :))

<head>
    <title>My domain checker</title>
    <script src="jquery-1.3.2.min.js" type="text/javascript"></script>
    <style type="text/css">
        body 
        {
            line-height: 25px;
            vertical-align: middle;
        }
        label
        {
            padding-right: 5px;
        }
    </style>
    <script type="text/javascript" language="javascript">
        function getAvailabilityTimer() {
            var timer;
            return function(fun, time) {
                clearTimeout(timer);
                timer = setTimeout(fun, time);
            };
        }
        var getAvailability = getAvailabilityTimer();

        function displayAvailability() {
            var domain = $('#domainName').val();
            var selector = "result";//easy to change later
            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "DomainService.asmx/CheckDomain", //our service name with the method
                data: "{'domain' : '" + domain + ".com'}", //parameter for which to pass data
                dataType: "json", //responde type
                success: function(msg, success) {
                    if (success == 'success') {
                        $('#' + selector).html('Domain is ' + msg.d); //good response
                    } else {
                        $('#' + selector).html('Not able to check at the moment.  Please try again later.'); //service returned an error
                    }
                },
                error: function(msg, success) {
                    $('#' + selector).html('Not able to check at the moment.  Please try again later.'); //error with ajax call
                }
            });
        }
    </script>
</head>

<body>
<div id="result"></div>
<label for="domainName">Domain:</label><input id="domainName" type="text" onkeyup="getAvailability(displayAvailability, 500);" />.com
</body>
</html>

All feedback is appreciated.