Justin Toth's Blog

Justin is a web developer living in Maryland

ASP.NET MVC + Dojo's Dijit.Form for Form Validation and Submission

clock April 25, 2010 20:03 by author Justin Toth

One of the major hurdles when you switch over from ASP.NET web forms to ASP.NET MVC is deciding how to handle your submission forms. You no longer have all of the input controls and the nice validation controls, so you may be a little lost as to how to proceed. Doing server-side validation isn't enough anymore in the ajax world we live in. Writing custom javascript code to handle all of the validation would be a huge undertaking. Luckily, Dojo comes to the rescue with its Dijit.Form widgets. Below is what a login form would look like using dojo:


 
<div dojoType="dijit.form.Form" jsId="loginForm" 
            encType="multipart/form-data" action="" method="">
            <script type="dojo/method" event="onSubmit">
                if (this.validate()) {
                    SubmitLoginForm(loginForm.getValues());
                }
                return false;
            </script>
 
            <table cellspacing="0">
                <tr>
                    <td class="label">Username:</td>
                    <td class="input mediumfield">
                        <input id="tbUsername" name="tbUsername" type="text" size="20"
                            dojoType="dijit.form.ValidationTextBox"
                            required="true"
                            promptMessage="Enter Username."
                            invalidMessage="Username is required." />
                    </td>
                </tr>
                <tr>
                    <td class="label">Password:</td>
                    <td class="input mediumfield">
                        <input id="tbPassword" name="tbPassword" type="password" size="20"
                            dojoType="dijit.form.ValidationTextBox"
                            required="true"
                            promptMessage="Enter Password."
                            invalidMessage="Password is required." />
                    </td>
                </tr>
            </table>
 
            <table id="buttons" class="buttons" cellspacing="0">
                <tr>
                    <td class="center">
                        <button dojoType="dijit.form.Button" type="submit" value="Submit">Login</button>
                    </td>
                </tr>
            </table>
 
        </div>
 

 

As you can see, you create a dijit.form.Form widget, which will act as our <form> element normally would. When the login button is clicked, it'll validate all of the controls within the form and then call a javascript method called SubmitLoginForm. You'll notice that my dojo method for onSubmit returns false. Normally you would have it return false if the form was invalid and true otherwise, but this would actually submit the form and do a server-side postback. Seeming that we're using purely ajax to make our calls in this example, we're returning false regardless of if the form is valid or not so that it won't postback to the server.

Next we need to write our javascript to submit the login form using ajax:


    dojo.require("dojo.parser");
    dojo.require("dijit.form.Form");
    dojo.require("dijit.form.ValidationTextBox");
    dojo.require("dijit.form.Button");
    dojo.addOnLoad(SetFocus);
    function SetFocus() {
        //find controls.
        var tbUsername = dojo.byId("tbUsername");
        //set focus.
        tbUsername.focus();
    }
    function SubmitLoginForm(fields) {
        //ajax call.
        var request = { "userName": fields.tbUsername, "password": fields.tbPassword };
        Post("login/validate/", request, FormResult);
    }
    function FormResult(result) {
        if (result.indexOf("Error") > -1) {
            //TODO: show error.
        }
        else {
            //redirect.
            window.location = result;
        }
    }
 

 

The cool part is that when you call loginForm.getValues(), it returns an object containing the values of all of the form fields. Within the SubmitLoginForm method we're able to easily create an ajax request and post it back to the server. Above I omitted the function declaration for Post, so below I'm showing what mine looks like. It can be a lot simpler if you only want to make one ajax call, but my example below will try up to 5 times to make the ajax call, in case there are some sort of flukey issues that cause your ajax requests to fail every now and then:

 


 
var maxAjaxCalls = 5;
var currentAjaxCalls = new Array();
 
function Post(path, request, callbackFunction) {
    //increment current ajax calls.
    currentAjaxCalls[currentAjaxCalls.length] = path;
    //make sure hasn't gone over max ajax calls.
    var numAjaxCall = NumAjaxCalls(path);
    if (numAjaxCall <= maxAjaxCalls) {
        if (numAjaxCall > 1) {
            console.debug("Invoking " + path + " ajax call for try #" + numAjaxCall);
        }
        dojo.xhrPost({
            url: baseUrl + path,
            handleAs: 'json',
            timeout: 60000,
            content: request,
            contentType: "application/x-www-form-urlencoded",
            load: function(result) { PostSuccess(result, path, callbackFunction); },
            error: function(error, args) { AjaxError(error, args, path, request, callbackFunction); }
        });
    }
    else {
        console.debug("Tried to make " + path + " ajax call " + maxAjaxCalls + " times but failed!");
    }
}
 
function NumAjaxCalls(path) {
    var numAjaxCalls = 0;
    for (var k = 0; k < currentAjaxCalls.length; k++) {
        if (currentAjaxCalls[k] == path) {
            numAjaxCalls++;
        }
    }
    return numAjaxCalls;
}
 
function PostSuccess(result, path, callbackFunction) {
    //remove path from array.
    for (var k = 0; k < currentAjaxCalls.length; k++) {
        if (currentAjaxCalls[k] == path) {
            currentAjaxCalls.splice(k, 1);
            k--;
        }
    }
    //invoke callback function.
    callbackFunction(result);
}
 
function AjaxError(error, args, path, request, callbackFunction) {
    //show error message.
    //console.debug("ajax error: " + error.message + " " + error.responseText);
    //console.debug(error);
    //try ajax call again in 1 second.
    window.setTimeout(function() { Post(path, request, callbackFunction); }, 1000);
}
 

 

The last step would be to create your LoginController and create a method called Validate:

 

//GET: /Login/Validate/

        public ActionResult Validate(string userName, string password, string returnUrl)

        {

            string result = String.Empty;

            try

            {

                if(IsAuthenticated)//TODO: check if they're authenticated.

                    result = "someurltoredirectto";

                }

                else

                {

                    result = "Error: Authentication failed, check your Username and Password.";

                }

            }

            catch (Exception ex)

            {

                result = "Error: " + ex.Message;

            }

            return Json(result);

        }

 

 

Pretty simple stuff. In this way you're able to save yourself from having to write a lot of code, letting dojo do the majority of the heavy lifting. If you were to use this example, you'd obviously want to make sure you took care of server-side validation as well, in case someone disabled javascript.



Clean up your JavaScript Code with Dojo

clock December 19, 2009 19:39 by author Justin Toth

You may have heard of Dojo, the javascript toolkit found at http://www.dojotoolkit.org/. The difference between it and its competitors such as jQuery and Ext JS is that it's much more than a toolkit, it's a full-fledged javascript framework. It provides things such as object-oriented programming (who would've thought you'd ever be able to have class inheritance in javascript?!), template-based widgets (you can dynamically create widgets in javascript that have html templates rather than having to dynamically create the tr's and td's with DOM manipulation), and basic utility functionality.

I've been using the more complex features of dojo, such as OO and template-based widgets, for some years but I never bothered with the basic utility functionality until today. It's pretty cool what dojo lets you do and it makes me sad that I was writing manual javascript code for years to do the same things. Here are a few of the cooler things that dojo lets you do:

1. Finding and looping through DOM elements

dojo.forEach(
                dojo.query("#myDiv img"),
                function(element) {
                    dojo.attr(element, { src: "_images/test.png" });
                }
            );

You can see the use of 3 dojo functions here: dojo.forEach, dojo.query, and dojo.attr. This will loop through all img elements that are children of the element with id "myDiv" and set the src of each image. Dojo.query is very powerful and can let you easily select the element(s) that you want from the page or from a specific parent node.

2. Creating DOM elements

var imgArrow = dojo.create("img", { src: "_images/arrow.png", title: "my arrow!" }, divContainer);

This code creates an image, sets the src and title of it, and appends it to a div, all in 1 line of code!

3. Clearing DOM elements

 dojo.empty(divContainer);

Dojo.empty clears all child elements of the element inputted, no more grabbing all child elements, looping through them, and doing childNode.parentNode.removeChild(childNode).

I've barely scratched the surface of what you can do with dojo but you can go a long way with just these 3 concepts...



Introduction

clock May 3, 2009 19:30 by author Justin Toth

This is my first post and I'm excited to start blogging!! It seems like every day I run into some sort of issue and once I figure out how to solve it, it makes me wish I had a blog so I could post the solution so that others won't have to spend as much time on it as I did.

This blog will be related to .NET development, and more specifically front-end web development. I used to consider myself an ASP.NET developer but I feel like we've come upon a crossroads. Straight ahead is ASP.NET, to the left is pure javascript development, and to the right is Silverlight. You look further down the ASP.NET road and see that there's another branch up beyond this one, ASP.NET going to the left and ASP.NET MVC going to the right. Which road to take??



About the author

Justin

Justin is a senior developer who has been working with .NET since 2003. His main focus is building highly-interactive web applications using ASP.NET MVC and Dojo or jQuery. Visit his company's site at http://tothsolutions.com.

Page List

    Sign in