Blog from Saravanan Arumugam

Let us talk about Technologies

Tag Archives: jQuery

Working with JSON objects in ASP.NET MVC


In this paper I am going to explain, a simple way of working with javascript, JSON objects to make call to MVC Action through Ajax.

 

A little introduction to Object representations in Javscript

In javascript, a value to an object can be provided in many ways.

1. Simple assignment

rows = 24;

2. Assignment in Json style

“columns” : “12”

3. Representation of Object

 var newBlog = {blogName: "Working with Json", Content: "….", Index: 51 }

Note that braces represent that it contains an object.

4. Instantiating an Object with “new” keyword

var myString = new String();

5. Representation of Array

var styles = [
{Height:”20”, Width: “50” },
{Height: “30”, Width: “50”},
{Height: “10”, Width: “40”}
];

 

Note that the square brackets represent the Array of object/variables.

From javascript object, JSON object can be generated by using JSON.stringify() method. An implementation of JSON.stringify() can be seen in the example at the end of the paper.

 

Planning the Javascript object for MVC call

MVC includes a default support for JSON binding. When you pass a Json object from client side, the MVC runtime makes all its attempts to understand it, and translate that into a CLR object for you.

For example,

To represent the following class in MVC server side

public class RequestPosition
{
	public int RequestID { get; set; }
	public int Position { get; set; }
}

javascript object has to be,

var position = { RequestID : 102, Positon=1 }

Note that the position object has two members and their names (RequestID, Position) are the same as the RequestPosition class’s properties.

 

To receive this javascript object the MVC action should have the following syntax.

public JsonResult ProcessRequestPosition(RequestPosition position)
{…}

Note that the Action has a parameter with the same name as the javascript object we prepared in the client side. When MVC runtime sees a parameter, it looks into the ViewData, query string, Json data etc. to find the value of its parameters.

 

A complete implementation

Code on the client side

$(document).ready(function () {

	$("#Save").on("click", function (){
		var requestSequence = [{ RequestID: "10", Position: 5 },
			{ RequestID: "11", Position: 8}];
		requestSequence[requestSequence.length] = { RequestID: "12",Position: 9};

		$.ajax("/Queue/SaveRequestSequence", {
			type: "application/json; charset=utf-8",
			dataType: "json",
			success: function (message) { alert(message); },
			error: function () { alert('Oops, the operation failed'); }
		});
	});
 
});

 

Note that requestSequence is an array and is initialized with 2 objects first. Then a third object is added using the index based assignment “requestSequence[requestSequence.length]. requestSequence.length in the place of index ensures that you always add the value at the end of the array.

Here $.ajax does the magic of calling the SaveRequestSequence action from client side.

 

Code on the server side

	[HttpPost]
	public JsonResult SaveRequestSequence(RequestPosition[] requestSequence)
	{
		//Save Operation
 
		return Json("Sequence saved successfully!");
	}

Color alternate rows with different color


Most of us prefer to show a table element with alternate rows showing different background colors.

There has been multiple solutions in the history to do that.

One old way is to apply alternate classes to rows and apply different styles to them. Then ASP.Net form’s grids had property settings for achieving that. There’s a javascript way etc.

I am posting here two simpler and newer ways to do it.

 

Using CSS3

With CSS 3 doing this is way simple.

tr:nth-child(odd)
{
    background-color: #eee;
}

Simple isn’t it.

 

For the older browsers like IE8, IE7 etc. this may not work. For them, we can use jQuery to do it.

$(“tr:odd”).css(“background-color”, “#eee”);

The code above can do the trick for us.

jQuery validation on hidden form elements


I recently wrote a code where I will have a wizard like page with multiple tabs. Each tab is a Div element, on clicking on a tab, one div will be visible while hiding the other divs, an usual design.

I implemented an unobtrusive validation on the web page, and it all worked well.

 

After I upgraded my jquery.validation.js, my web page’s validation was not as expected. Then I compared the two versions of jquery.validation.js files (1.8.1 and 1.9).

image

In the comparison it was evident that by default the jquery validator ignores all the hidden elements in 1.9 version, whereas 1.8 does validate every control in the page, no matter they are visible or invisible.

 

Of course validating only the visible controls is an useful feature, but not in my case. So I had to override the default value.

I wrote the following code in the page to instruct the validator not to ignore the hidden controls.

<script type="text/javascript" language="javascript">
$.validator.setDefaults({ ignore: [] });
</script>

Setting the default has to happen right when we include the scripts on the page. This would not work if we do it after the page load in any control’s event handle.

Simple jQuery enabled Menu


This paper explains a simple HTML based Menu written with the help of jQuery and CSS.

I have implemented the menu in a MVC 3 application’s default template. However this menu is not specific to MVC 3, its applicable in any Html page.

 

Step 1: Create the Menu and Sub-Menu items

Create the root menu and menu items using <ul> element or with <div> and <table> elements. For simplicity I have made the menu items with hyperlinks pointing to either Home or About page (Home and About pages are created by default with MVC 3)

<nav>
    <ul id="menu">
        <li id="Home">
            @Html.ActionLink("Home", 
                "Index", "Home")
        </li>
        <li id="About">
            @Html.ActionLink("About", 
                "About", "Home")
        </li>
    </ul>
    <ul parentmenu="Home">
        <li>
            @Html.ActionLink("Go to About",
                "About", "Home")
        </li>
        <li>
            @Html.ActionLink("Go to About again",
                "About", "Home")
        </li>
    </ul>
    <ul parentmenu="About">
        <li>
            @Html.ActionLink("Go Home", 
                "Index", "Home")
        </li>
        <li>
            @Html.ActionLink("Go Home Again", 
                "Index", "Home")
        </li>
    </ul>
</nav>

Note that parentmenu attribute is specified on the <ul> element to indicate that it is a sub menu of another menu item. Obviously the <ul> list element not having the parentmenu is the root menu.

In case of MVC 3, this is to be written in Views/Shared/_Layout.cshtml. In Web forms, the code above should be written in the master page.

 

Step 2: Hide the Sub-Menu’s in the default view

We don’t want the submenu to be visible in the default view. To hide it, I used the CSS stylesheet.

ul[parentMenu]
{
    display: none;
    position: fixed;
    z-index: 1;
}

 

Step 3: Set the style for the Menu and Sub-Menus

ul#menu, ul[parentMenu]
{
    clear: left;
    border-bottom: 1px #5C87B2 solid;
    padding: 0 0 0 0;
    position: relative;
    margin: 0;
    text-align: left;
}
 
ul#menu li
{
    display: inline;
    list-style: none;
}
 
ul#menu li#greeting
{
    padding: 10px 20px;
    font-weight: bold;
    text-decoration: none;
    line-height: 2.8em;
    color: #fff;
}
 
ul#menu li a
{
    padding: 10px 20px;
    font-weight: bold;
    text-decoration: none;
    line-height: 2.8em;
    background-color: #666666;
    color: #EFEFEF;
    border-radius: 8px 8px 0 0;
    -webkit-border-radius: 8px 8px 0 0;
    -moz-border-radius: 8px 8px 0 0;
}
 
ul#menu li a:hover
{
    background-color: #9B9B9B;
    text-decoration: none;
}
 
ul#menu li a:active
{
    background-color: #a6e2a6;
    text-decoration: none;
}
 
ul#menu li.selected a
{
    background-color: #fff;
    color: #000;
}
 
ul[parentMenu]
{
    display: none;
    position: fixed;
    z-index: 1;
}
 
ul[parentMenu] li
{
    list-style: none;
    border: 1px solid #e8eef4;
    border-width: thin thin 0 thin;
    background-color: #666666;
    color: #EFEFEF;
    padding: 5px 20px 5px 20px;
}
 
ul[parentMenu] li a
{    
    border-width: thin thin 0 thin;
    background-color: inherit;
    color: #EFEFEF;    
    font-weight: bold;
    text-decoration: none;    
}
 
ul[parentMenu] li:hover
{
    background-color: #9B9B9B;
    text-decoration: none;
}
 
ul[parentMenu] li:active
{
    background-color: #a6e2a6;
    text-decoration: none;
}

 

Step 4: Script to activate the menu

Here’s a full code listing. Code is explained in detail below the listing.

$(document).ready(function () {
    $("ul#menu li").hover(
        function () {
            //1. Slide up any existing menu
            if ($("ul[parentmenu]:visible").length > 0 &&
                $("ul[parentmenu]:visible:first")
                    .attr("parentmenu") != this.id) 
            {
                
                $("ul[parentmenu]:visible").slideUp(200);
            }
 
            //2. Show the Menu
            var subMenu = $("ul[parentmenu='" 
                + this.id + "']");
            subMenu.slideDown(200);
 
            //3. Position the sub menu
            var currentMenuPosition = $(this).offset();
 
            if (currentMenuPosition) {
                subMenu.offset({
                    left: currentMenuPosition.left,
                    top: $("ul#menu").offset().top + $("ul#menu").height()
                });
            }
        },
    //Don't do anything on the hover out
    function () { }
    );
});
 
$(document).click(function () {
    $("ul[parentmenu]").slideUp(200);
});
 
$(document).scroll(function () {
    $("ul[parentmenu]").hide();
});

 

Step 4.1: Handle the hover event for the menu items

$(document).ready(function () {
    $("ul#menu li").hover(
        function () {

$(document).ready() registers a handler to document’s load event.

Next thing to do is to handle hoverin and hoverout of menu list items. $(“ul#menu li”) selects the list items within the <ul> with the name “menu”. hover() method helps handle both the hover in and hover out events. In our case we do nothing in the hover out.

 

Step 4.2: Hide any other visible menu

//1. Slide up any existing menu
if ($("ul[parentmenu]:visible").length > 0 &&
    $("ul[parentmenu]:visible:first")
        .attr("parentmenu") != this.id) 
{
                
    $("ul[parentmenu]:visible").slideUp(200);
}

When the mouse is hovered over the menu name, first thing we do is hide any other menu that is actively visible at the moment. $(“ul[parentmenu]:visible”) selects the visible sub menu (we identify the submenu by searching for a <ul> element with the parentmenu attribute).

 

Step 4.3: Identify and display the menu

//2. Show the Menu
var subMenu = $("ul[parentmenu='" 
    + this.id + "']");
subMenu.slideDown(200);

slideDown() displays the subMenu by sliding it down. 200 is the milliseconds, which indicates the speed of the slide transition.

 

Step 4.4: Position the menu at its place

//3. Position the sub menu
var currentMenuPosition = $(this).offset();
 
if (currentMenuPosition) {
    subMenu.offset({
        left: currentMenuPosition.left,
        top: $("ul#menu").offset().top + $("ul#menu").height()
    });
}

$(this).offset() provides the current position of the menu’s list item. Based on its placement, position the submenu dynamically by setting the submenu’s offset value.

 

Step 4.5: Hide the menu if any click or scroll happens on the page

$(document).click(function () {
    $("ul[parentmenu]").slideUp(200);
});
 
$(document).scroll(function () {
    $("ul[parentmenu]").hide();
});

 

Output

image

Select All check box with jQuery


Select All check box is usually the checkbox at the top of grid, checking which would check every checkbox in the table/grid. I am going to talk about the check box (imagine check boxes in place of the first column with X) with gray background at the top of the following table.

X Shift Date Employee ID Code Duration Status
x 12/1/2011 232 Read-only User 3 years Active
x 12/1/2011 12 Super User 7 years Active

When I check the Select All checkbox, it should check all the checkboxes in every row. When I uncheck the Select All checkbox, all the checkboxes in the table should be unchecked.

Let me present the code here first and give the explanation below.

    $("input[type='checkbox'].checkAll").bind('change', function () {
        var checkAll = $(this).prop('checked');
 
        $("table:has(input[type='checkbox'].checkAll) input[type='checkbox']")
        .each(function (index, domElement) {
            if ($(domElement).is("input[type='checkbox']")) {
                $(domElement).prop('checked', checkAll);
            }
        });
    });

The script is kept in the shared js file.

The html of the Select All check box is,

<input class=”checkAll” id=”checkAll” name=”checkAll” type=”checkbox” value=”true” /><input name=”checkAll” type=”hidden” value=”false” />

Note that the checkbox never refers to any script. But the script refers to the checkbox by recognizing its class name “checkAll”.

 

Code Explanation

Step 1. Identify the Check All checkbox

$(“input[type=’checkbox’].checkAll”)

The first line of the code starts with a selector ($() is referred to be a selector. It selects the controls that matches its parameters). The selector parameter conveys 3 messages.

  1. input – The selected object should be an input element.
  2. [type=’checkbox’] – The selected object should have an attribute called type and its value should be ‘checkbox’.
  3. .checkAll – The selected object should have the class name checkAll.

The selector usually follows the same syntax that CSS use to identify elements.

 

Step 2. Attach an event handler for onchanged event of Select All checkbox

.bind(‘change’, function () { }

bind() method attaches an event handler to an element’s event. First parameter to the bind() method is the event name and the second parameter is the event handler delegate.

 

Step 3. Store the current state of the Select All checkbox

var checkAll = $(this).prop(‘checked’);

The code above gets the current state (true/false to represent checked/unchecked state) of Select All check box.

$(this) represents the control for which containing function is delegated to. In our case, this refers to the Select All checkbox.

 

Step 4. Select all the checkboxes contained in the table where Select All is housed

$(“table:has(input[type=’checkbox’].checkAll) input[type=’checkbox’]”)

By writing a selector with $(“input[type=’checkbox’]”) we can select all the checkboxes on the page. But we don’t want to check or uncheck something that doesn’t belong to the table containing the Select All checkbox. So in the selector, precede the input[type=’checkbox’] with table:has(input[type=’checkbox’].checkAll). By doing this, we are saying that the container for the input is a table, and the table has the checkbox with the class name checkAll.

 

Step 5. Iterate through all the elements and assign the checked status

.each(function (index, domElement) {

         if ($(domElement).is(“input[type=’checkbox’]”)) {

                 $(domElement).prop(‘checked’, checkAll);

         }

});

Note that each() method takes a function having 2 parameters. As their name suggest, the first one is the index of the element and the second one is the element itself.

if() condition is written just to double check the type of the element, but this is optional at this point.

prop() method is capable of both checking and assigning a value. We are using the prop method on the element to assign the value to the checked property.