RSS
 

Archive for the ‘JavaScript’ Category

Dynamically Populate a Select/Drop Down List using ASP.NET MVC, JQuery and Json

22 Aug

It has been a while since my last blog due to me being flat out at work during the week and snowboarding on the weekends!

Today the weather is terrible up in the alps and I managed to catch the flu so it was a good time to catch up on some personal projects. I was working on an ASP.NET MVC website for my sister and decided to use AJAX to populate a select list based on a selection in another select list. The ASP.NET MVC framework and JQuery makes it very easy to use AJAX to do this.

This is nothing new but very powerful if you want to create a nice fluent forms user interface. For the most part the process was very easy. However I ran into an issue where JQuery was treating the Json returned from the server as a string instead of an object. Thus making if difficult to retrieve the data I wanted. I will explain how I got around this later in the post.

The first thing you need to do create the server side method. This is very easy using ASP.NET MVC! Of course you would probably get your data from a database of some sort, however this is just a nice way of showing how its done. The method below gets a list of Foo objects based on the FooId parameter using LINQ’s Where method.

public class Foo
{
    public int FooId { get; set; }
    public string Name { get; set; }
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GetFooList(int FooId)
{
    var fooList = new List();
    fooList.Add(new Foo { FooId = 1, Name = "One" } );
    fooList.Add(new Foo { FooId = 1, Name = "Two" } );
    fooList.Add(new Foo { FooId = 2, Name = "Three" });
    fooList.Add(new Foo { FooId = 2, Name = "Four" });
    return Json(fooList.Where(foo => foo.FooId == FooId).ToList());
}

Now for the client side code. On my page I have two select lists. One is a list of Id’s and the other is a list of names. When a user selects an id from the first select list the second is populated with the names relating to that id. The lists can be created easily using using the ASP.NET MVC Helpers or writing the HTML yourself.


Finally the JQuery code in order to add the functionality to the page. JQuery makes it easy to execute server side methods and receive Json. The code below binds the AJAX post method to the change event of the IdList select list. The post function has three variables; The sever method to execute, the parameters to pass as Json and the function to execute with the data returned from the server. You can either execute a named or a anonymous function. I chose the latter because I am not doing too much inside the function.

 $(function() {
        $("#IdList").change(function() {
            $.post("/Controller/GetFooList", { FooId: $("#IdList").val() },
            function(fooList) {
                $("#NameList").empty();
                $.each(eval(fooList), function(i, foo) {
                    $("#NameList").append(""+ foo.Name+ "");
                });
            });
        });
    });

The biggest issue I came across was, originally, the FooList Json was being represented as a string therefore the JQuery each method was iterating through each character of the string rather then each object. After a bit reading I came across the JSON.parse method in the JQuery library. This method parses the string to Json which means that the JQuery each method functions as I expected.

There we have it. Like I said nothing new here but interesting never the less.

The only thing I don’t like about this code is the append method in my JQuery. Surly there is a better way of adding options to a select element?

 
 

Executing stored JavaScript anonymous functions

04 Jun

I have been working on a little project where I needed to store a set of functions to be executed within an inner html html element when an event is invoked in its parent page.

After some thought I decided to create a list of events which stores an array of functions to be executed from the parent. So I created the BindEvent function which sits in the parent and simply adds a function to the list of events mapped to the name of the event.

var Events = null;
function BindEvent(event, func) {
    if (Events == null)
        Events = new Array();

    if (Events[event] == null)
        Events[event] = new Array();

    var len = Events[event].length;
    Events[event][len] = func;
}

The next step is to create an invoke function that finds the event in the list and invokes the functions that have been bound to it. Again this was quite simple however it took me some Googling to work out how to execute a JavaScript function that is stored in a variable.

The answer is simple! To execute a JavaScript anonymous function that is stored in a variable: Just  surround the variable name in braces and add a set of function call braces to the end of it! For example the second line here will execute the function:

var func = function () { document.writeln(“Hello World!”); };
(func)();

Ok back to the invoke event function. Here it is:

function InvokeEventFunctions(event) {
    var func = Events[event];
    for (var i = 0; i < func.length; i++) {
        if (func[i] != null) {
            (func[i])();
        }
    }
}

Now, with two simple functions and a multi dimensional array, we have a pretty powerful anonymous function binder and invoker. The beauty of using an anonymous function when binding is that you can call it from anywhere and it will encapsulate all the current variables at the DOM in which the function was created.

So in my case it was perfect as I had a set of processes that needed to be run native to an inner html element when something happens on its parent. The events where bound from the child (document.parent.BindEvent(event, func)) so when the Invoke function is executed in the parent and it in turn executed a function created in the inner html therefore it will use the DOM of the inner html no DOM of the parent page.

For more information and a slightly different method check out Daniel’s answer on StackOverflow here.