Linq for Javascript / jQuery

I recently started writing a webpage where I wanted some information pre-loaded, without the delay of making an ajax call! What I had was the classic case of the content of one drop down list being controlled by another drop down list.

So, in my controller I loaded up all the data into my model …

public class MyController : Controller
{
    private readonly IMyRepository _myRepository;

    public MyController(IMyRepository myRepository)
    {
        _myRepository = myRepository;
    }

    [HttpGet]
    public ActionResult MyAction()
    {
        var parentList = _myRepository
            .GetParentList()
            .ToList()
            .Select(x => new SelectListItem
            {
                Value = x.ID.ToString(),
                Text = x.Description,
                Selected = false
            })
            .ToList();

        var childList = _myRepository
            .GetChildList()
            .ToList()
            .AsQueryable();

        var model = new MyViewModel
        {
            ParentList = parentList,
            ChildList = childList
        };

    return View(model);
    }
}

The GetChildList() method returns a list of items which have a ParentID

This is what my view looks like …

@model MyViewModel

<div class="MyViewClass">
    <h2>Parent/Child Example using jQuery Linq</h2>

    <label for="ParentList">Parent Item</label>
    @Html.DropDownListFor(model => model.ParentList, null, "Please select a Parent item ...", new { @class = "test" })

    <label for="ChildList">Child Item</label>
    <select id="ChildList"></select>
</div>

and finally, here is the javascript (which is also in the view) …

var children;
$(document).ready(function() {
    children = @Html.Raw(Json.Encode(Model.ChildList)) ;

    $('#ParentList').change(ParentChanged);
});

function ParentChanged() {
    var parentID = parseInt($('#ParentList').val(), 10);
    var childItems = $.Enumerable.From(children)
        .Where(function(x) { return x.ParentID == parentID })
        .Select(function(x) { return { value: x.ID, text: x.Description } })
        .ToArray();
    var html = "<option id='-1'>(All Items)</option>";
    $.each(childItems, function(index, value) {
        html += "<option value='" + value.value + "'>" + value.text + "</option>";
    });
    $('#ChildList').empty().html(html);
}

So, all the work is done in the web browser. The dataset is relatively small so shouldn’t cause any memory issues. Obviously for larger datasets using ajax is the way to go, but for this particular case this solution works great.

jQuery control grouping

I recently had a requirement to enable disable a whole bunch of controls based on a checkbox value. The first thing I did was to give each group of controls a css class name which they all share.

HTML

    <input type="checkbox" value="Master Checkbox" id="group1" />
    <input type="checkbox" value="Some option" class="group1" />
    <input type="checkbox" value="Some value" class="group1" />

Next came a little bit of jQuery to set up the groups. This code does the initial enabling/disabling of the group of controls as appropriate and also wires up the click handler for when the user changes the master checkbox value

$.fn.enable = function (value) {
    return this.each(function () {
        if (typeof this.disabled != "undefined") this.disabled = !value;
    });
}

function ConfigureGroup(groupName) {
    EnableGroup(groupName);
    $('#' + groupName).bind('click', function () {
        EnableGroup(groupName);
    });
}

function EnableGroup(groupName) {
    var flag = $('#' + groupName).attr('checked');
    $('.' + groupName).enable(flag);
}

Then in my page startup code I just make calls to ConfigureGroup

function PageStartup() {
    ConfigureGroup('group1');
}

$(document).ready(function () {
    PageStartup();
});

Not the most amazing piece of code ever written, but I was pleased with it as it cut down the javascript in the existing page quite considerably.