Tag Archive: jquery


How to make a parent/child drop down list using JQuery

If you need to make a drop down list populate based on the selection of another drop down list, here’s one way.

· You’ll want to use a jquery ajax call so it does proper error handling (using the default error delegate we built in a previous email).

· Make sure the datatype of your ajax call is json and that your controller action returns a JsonResult.

· Use jquery show/hide to hide the child drop down list on page load and show it when the user makes a selection from the parent drop down list.

· In the ajax success function, you will:

o Add options to your select control (a.k.a. drop down list) using jquery’s each statement. Note: the “option” object in the each function delegate is not strongly typed, so you will just need to know your CV properties and type them in manually (sorry, no intellisense for that). For example, if you return a List of DDLDispValueCVs in your BLL method, your option object’s properties will be “Disp” and “Value”.

o Then bind a change event handler to your select control that calls the load function for your second select control.

o Wrap the functions with jquery block/unblockUI calls so the user sees a soothing “In Progress…” popup while the ajax calls are filling the drop down lists.

Here’s an example of the view page:

<script type="text/javascript">
    $(document).ready
    (
        function()
        {
            $('#divTransferTo').hide();
            $.ajax
            (
                {
                    url: '<%= Url.Content("~/MyController/GetList") %>',
                    success: function(data) {
                        // fill the ddl with the data from the json call
                        var ddl = $('#ddlTransferFrom');
                        optionArray = [];
                        $.each(data, function(i, option) {
                            optionArray[i] = "<option value='" + option.Value + "'>" + option.Display + "</option>";
                        });
                        ddl.append(optionArray.join(''));
                        // bind an "on selected change" event to the ddl
                        ddl.change
                        (
                            function() {
                                $.blockUI({ message: $('#information'), css: { width: '275px'} });
                                LoadTransferToDDL($(this).val());
                                $.unblockUI();
                            }
                        );
                    },
                    dataType: 'json'
                }
           );
        }
    );
     function LoadTransferToDDL(id)
    {
        $('#divTransferTo').show();
        var transferToUrl = '<%= Url.Content("~/MyController/GetOtherList") %>';
        $.ajax
        (
            {
                url: transferToUrl + '/' + id,
                success: function(data)
                {
                    $('#ddlTransferTo').vis
                                       // fill the ddl with the data from the json call
                    var ddl = $('#ddlTransferTo');
                    optionArray = [];
                    $.each(data, function(i, option)
                    {
                        optionArray[i] = "<option value='" + option.Value + "'>" + option.Display + "</option>";
                    });
                    ddl.append(optionArray.join(''));
                     // bind an "on selected change" event to the ddl
                    ddl.change
                    (
                        function()
                        {
                            $.blockUI({ message: $('#message'), css: { width: '275px'} });
                            alert('You selected this value: ' + $(this).val());
                            $.unblockUI();
                        }
                    );
                },
                dataType: 'json'
            }
       );
    }</script>
<form id="mvcForm" method="post" action="">
    <h2>Reassign Something</h2>
Transfer From:
    <div id="divTransferFrom"><select id="ddlTransferFrom"></select></div>
Transfer To:
    <div id="divTransferTo"><select id="ddlTransferTo"></select></div>
</form>

Here’s an example of the controller actions used by the ajax calls. Notice that the Json method built into MVC.Controller automagically converts your list of cvs into json:

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetList()
{
 try 
{
  return Json(myBLL.GetList());
 }
 catch (Exception ex)
 {
  return HandleError(ex, null);
 }
}

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetOtherList(object id)
{
 try 
{
  return Json(myBLL.GetOtherList(Convert.ToInt64(id)
 }
 catch (Exception ex)
 {
  return HandleError(ex, null); 
}
}

How to setup intellisense for javascript files (like JQuery) in Visual Studio 2008

Visual Studio 2008 already shows intellisense for javascript if you have the javascript embedded in the page, but if you want to get intellisense on javascript in js files referenced in your master page, you’ll need to make some mods. In the four steps detailed below, you’ll get javascript intellisense for external js files like jquery.

Making the mods

First, you’ll need to install SP1 for Visual Studio 2008 from here: http://www.microsoft.com/downloads/details.aspx?FamilyId=FBEE1648-7106-44A7-9649-6D9F6D58056E&displaylang=en . This service pack adds a lot of enhancements to intellisense and other features of visual studio, so it’s useful even if you don’t want js file intellisense.

Then you need to install Microsoft’s hotfix for Visual Studio 2008 from here: http://code.msdn.microsoft.com/KB958502 . This hotfix makes Visual Studio automatically load vs-doc.js files as long as they are in the same folder as the dependent js file.
Place any vs-doc.js files in the same folder as their dependent js file, if you don’t have the vs-doc file for jquery, you can download it here: http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.3.2-vsdoc2.js (you’ll need to remove the 2 at the end of the file name or Visual Studio won’t see it). For example, if you are using jquery-1.3.2.js, be sure to have the jquery-1.3.2-vsdoc.js file in the same folder. But if you’re using jquery-1.3.2.min.js, you’ll need the jquery-1.3.2.min-vsdoc.js file instead.
So far, pretty straightforward. Here’s the hacky part: You’ll need to put this code block into your Site.Master and any other master page you want to derive from and get javascript intellisense:

<!--Load javascript into intellisense, but do not render it on the user page. 
Note: this must be in the master page, not an include file, and it must use absolute reference, not dynamic Url.Content. 
Only some js files will load in intellisense; 
some js files cause all the js files to fail to load into intellisense. --->
<!--if (false){-->
<script src="~/Assets/JavaScript/jquery-1.3.2.js" type="text/javascript"></script>
<script src="~/Assets/JavaScript/jquery.blockUI.js" type="text/javascript"></script>
<script src="~/Assets/JavaScript/json2.js" type="text/javascript"></script>
<!---->

Here’s why: The Visual Studio hotfix won’t see the intellisense info for your js files in an MVC environment because of the way we need to dynamically fetch the runtime url. You will need to add an absolute url reference, which is why we can’t use the MVC Url.Content method. Additionally, you don’t want that reference to get rendered to the client, hence the “if false” clause the always prevents it from rendering on the client, but tricks Visual Studio into seeing the reference for intellisense. Furthermore, VS2008 won’t see js file references in include files like MasterHeadElement.ascx, it only sees the ref if it is in the master page itself.

One warning: I found that some of the js file references fry the system and prevent all of the js files from loading into intellisense. I’m not sure why, but so far I know that jquery, jquery.blockUI, and json2 always work, but some other js files don’t.

Easy way to setup default error handling for your JQuery ajax calls

If you don’t want to keep copy/pasting the same error function for your jquery ajax calls over and over again, here’s a quick way to set up error handling in one place.
Add this javascript block below your jquery library links (such as in your MasterHeadElement.ascx control or master pages):

<script type="text/javascript">
// THIS MUST BE LEFT AT THE BOTTOM OF THE HEAD ELEMENT...the code below needs to have the jquery libraries loaded
// setup all jquery ajax calls to use this error function by default (this can be overridden simply by specifying the error property as normal in the ajax call).
$().ready(function() {
    $.ajaxSetup({
        // put your favorite error function here:
        error: 
            function(XMLHttpRequest, textStatus, errorThrown) {
                // release any existing ui blocks
                $.unblockUI;
                var errorObj = JSON.parse(XMLHttpRequest.responseText);
                // send the user to the system error page if system error, otherwise popup the user error div
                if (!errorObj.Success) {
                    if (errorObj.ErrorType != "system") {
                        $('#UserError').html(errorObj.Message);
                        $.blockUI({ message: $('#UserErrorWrapper'), 
                        css: { width: '400px', height: '300px', overflow: 'scroll' }
                     });
                }
                else {
                    window.location = errorObj.ErrorPageUrl;
                }
            }
        }
    });
});
</script>

Now all ajax calls in your app will default to this error function. All you have to do is leave out the error delegate in your ajax calls (i.e. include the url, success, datatype, and other properties on your $.ajax call, but leave out the error property). Like this:

$.ajax({
    url: // some link,
    success: function(data){
        // do something
    },
    dataType: 'json'
});

If you want to use a different error function on an ajax call, simply write in the error function into that ajax call as normal, the global default error function will be ignored. Like this:

$.ajax({
    url: // some link,
    success: function(data){
        // do something},
    dataType: 'json',
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert("Oh noes!");
    }
});
© 2018 Robert Corvus