Monday, November 25, 2013

Get Registry key value for 32 and 64 bit machines

0 comments
Here is the snippet that pulls a LOCALMACHINE\SOFTWARE
public static string GetRegistryKey(string keyName) {
string currentKey = String.Empty;
using(RegistryKey key32 = Registry.LocalMachine.OpenSubKey("SOFTWARE\\JobTracker")) {
if (key32 != null) {
currentKey = key32.GetValue(keyName).ToString();
} else {
using(var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
using(var key64 = hklm.OpenSubKey(@ "SOFTWARE\JobTracker")) {
currentKey = key64.GetValue(keyName).ToString();
}
}
}
return currentKey;
}

Read more...

Binding html select using knockoutjs and asp.net mvc

1 comments
Suppose we have a ViewModel like this

model.user = UserManager.GetUserByID(id);
model.locations = Location.GetLocations();

The markup to populate HTML Select should be
<p data-bind="with: user">
Your country:
<select data-bind="options: $root.availableLocations,
optionsText: 'Text',
optionsValue: 'Value',
value: LocationID,
optionsCaption: 'Choose...'">
</select>
</p>
var userObject = @Html.Raw(Json.Encode(Model.user));
var locationsArray = @Html.Raw(Json.Encode(Model.locations));
var vm = {
user: ko.observable(userObject),
availableLocations: ko.observableArray(locationsArray)
};
ko.applyBindings(vm);


Read more...

Tuesday, November 5, 2013

Server side paging, filtering and sorting using datatables

4 comments
Nothing better than writing some code to explain a feature. This post shows how to do server-side paging in a table using datatables.net
The idea is to display a table with a large amount of data (68k rows). As it's not a good practice to load all at once, it' better to implement server-side paging.

First download datatables.net from here and reference them in your html file.

In our sample we are using a table Tasks with 3 fields, ie, TaskID, TaskName, Complete
public class Task
{
public int TaskID { get; set; }
public string TaskName { get; set; }
public bool Complete { get; set; }
public static List&lt;Task&gt; GetAllTasks()
{
//returns all tasks in the table
}
}
//BLL
public class TaskManager
{
public static List&lt;Task&gt; GetAllTasks()
{
return Task.GetAllTasks();
}
}

Lets create the HTML markup first

var oTable = $('#taskTable').dataTable({
"aoColumns": [
{ "sName": "TaskID" },
{ "sName": "TaskName" },
{ "sName": "Complete",
"bSearchable": false,
"bSortable": false
},
{ "sName": "Actions",
"bSearchable": false,
"bSortable": false,
//this is to render custom content in the column
"fnRender": function (oObj) {
var row_button = '<a href="http://www.blogger.com/Tasks/Edit/' + Obj.aData[0] + '">Edit</a> |' +
'<a href="http://www.blogger.com/Tasks/Details/' + Obj.aData[0] + '">Details</a> | ' +
'<a class="deleteTask" data-taskid=" + oObj.aData[0] + " href="">Delete</a>';
return row_button;
}
}
],
"bInfo": false,
"bLengthChange": false,
"bProcessing": true,
"bServerSide": true,
//fires when table initialization completes
"fnInitComplete": function (oSettings, json) {
$("#jQueryAjaxmodal").modal("hide");
},
"sAjaxSource": "/Task/DataTableAjaxHandler",
//enables tooltip on left top of the table
"sDom": '&lt;"toolbar"&gt;frtip',
"sPaginationType": "bootstrap"
});
//adding a button to tool tip
$("div.toolbar")
.html('<a add="" ask="" class="btn btn-primary" href="http://www.blogger.com/@Url.Action(">Add Task</a>')
.css("text-align", "left");
// adding a css class to filter textbox
$(".dataTables_filter input").addClass("form-control");


Now lets wire up datatable to the table

<table id="taskTable">
<thead>
<tr>
<th>Task ID</th>
<th>Task Name</th>
<th>Complete</th>
<th>Actions</th>
</tr>
</thead>
<tbody></tbody>
</table>


Here as you can see TaskID and TaskName are sortable and searchable.
Now, the model that is passed from datatables to server-side

public class DataTablesViewModel
{
/// <summary>
/// Request sequence number sent by DataTable, same value must be returned in response
/// </summary>
public string sEcho { get; set; }
/// <summary>
/// Text used for filtering
/// </summary>
public string sSearch { get; set; }
/// <summary>
/// Number of records that should be shown in table
/// </summary>
public int iDisplayLength { get; set; }
/// <summary>
/// First record that should be shown(used for paging)
/// </summary>
public int iDisplayStart { get; set; }
/// <summary>
/// Number of columns in table
/// </summary>
public int iColumns { get; set; }
/// <summary>
/// Number of columns that are used in sorting
/// </summary>
public int iSortingCols { get; set; }
/// <summary>
/// Comma separated list of column names
/// </summary>
public string sColumns { get; set; }
}


Finally, the controller method

public ActionResult DataTableAjaxHandler(DataTablesViewModel param)
{
var allTasks = TaskManager.GetAllTasks();
IEnumerable<Task> filteredTasks;
if (!string.IsNullOrEmpty(param.sSearch))
{
//Optionally check whether the columns are searchable at all
var isTaskIDSearchable = Convert.ToBoolean(Request["bSearchable_0"]);
var isTaskNameSearchable = Convert.ToBoolean(Request["bSearchable_1"]);
filteredTasks = allTasks.Where(tsk =>
isTaskIDSearchable && Convert.ToString(tsk.TaskID).Contains(param.sSearch.ToLower()) ||
isTaskNameSearchable && tsk.TaskName.ToLower().Contains(param.sSearch.ToLower()));
}
else
{
filteredTasks = allTasks;
}
var isTaskIDSortable = Convert.ToBoolean(Request["bSortable_0"]);
var isTaskNameSortable = Convert.ToBoolean(Request["bSortable_1"]);
var sortColumnIndex = Convert.ToInt32(Request["iSortCol_0"]);
Func<Task, string> orderingFunction = (tsk =>
sortColumnIndex == 0 && isTaskIDSortable ? Convert.ToString(tsk.TaskID) :
sortColumnIndex == 1 && isTaskNameSortable ? tsk.TaskName :
"");
var sortDirection = Request["sSortDir_0"]; // asc or desc
if (sortDirection == "asc")
filteredTasks = filteredTasks.OrderBy(orderingFunction);
else
filteredTasks = filteredTasks.OrderByDescending(orderingFunction);
var displayedTasks = filteredTasks.Skip(param.iDisplayStart).Take(param.iDisplayLength);
var result = from dt in displayedTasks
select new[] {
Convert.ToString(dt.TaskID),
dt.TaskName,
Convert.ToString(dt.Complete),
""
};
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = allTasks.Count(),
iTotalDisplayRecords = filteredTasks.Count(),
aaData = result
},
JsonRequestBehavior.AllowGet);
}

That's all to it. Happy coding!

Read more...

Utility function to make an array observable in knockoutjs

0 comments
Suppose we have an array

var employees = [
    { EmployeeID: 1, EmployeeName: "Naveen" },
    { EmployeeID: 2, EmployeeName: "Shebin" }
];

We can make it an observable array by calling it like this

var observableEmployees = ko.observableArray( employees );
But as per knockoutjs documentation,

Simply putting an object into an observableArray doesn’t make all of that object’s properties themselves observable. Of course, you can make those properties observable if you wish, but that’s an independent choice. An observableArray just tracks which objects it holds, and notifies listeners when objects are added or removed.

 This means that any change in array will be remembered. ie, adding and removing elements in an array is observed. But changes to properties are not remembered. That is if employee[0].EmployeeName is changed to Noah, it wont be remembered. To do that we have to make each property ko.observable. Here is a small utility function to do so.

function MakeArrayKoObservableObjectArray(arr) {
    var observableArr = [];
    for (var i = 0; i < arr.length; i++) {
        var observableObj = {}, obj = arr[i];
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                observableObj[prop] = ko.observable(obj[prop]);
            }
        }
        observableArr.push(observableObj);
    }
    return observableArr;
}
Now we can call it like this.

employees = MakeArrayKoObservableObjectArray( employees  );
var observableEmployees = ko.observableArray( employees );

Happy Coding!

Read more...

Monday, November 4, 2013

Remote validation using jQuery Validate

0 comments
This is how jQuery validate is done in ASP.NET MVC

Markup
<form id="manager-form" action="">
    <p>
        <label style="display:inline-block; width: 200px;">Manager Name</label>
        <input type="text" id="Manager" name="Manager" />
    </p>
    <p>
        <input type="submit" id="saveManager" class="btn btn-primary" value="Save Sales Person" />
    </p>
</form>
JavaScript
    function SetValidationRules(){
        $("#manager-form").validate({
            onkeyup: false,
            rules: {
                Manager: {
                    required: true,
                    minlength: 3,
                    remote: {
                        url: '/Manager/IsManagerNameTaken',
                        type: 'POST',
                        dataType: 'json',
                        data: {
                            managerName: function () {
                                return $('#Manager').val();
                            }
                        }
                    }
                }
            },
            messages: {
                Manager: {
                    required: "Manager name is required.",
                    minlength: "Manager name should be 3 atleast characters."
                }
            }
        });
    }
Controller
    public ActionResult IsManagerNameTaken(string managerName)
    {
        var result = ManagerRepository.IsManagerNameTaken(managerName) ?
            "Manager name is already taken. Try another!" : "";
        return Json(result);
    }
Thats all to it. Happy coding!

Read more...

Saturday, November 2, 2013

Overriding jQuery ajaxStart and ajaxStop locally

1 comments
While performing ajax calls, I use to provide provide visual indicators for better user experience.
My preferred method is showing a modal at jQuery.ajaxStart which gets hidden at jQuery.ajaxStop

The code goes like this

    $(document).on("ajaxStart", function () {
        $("#jQueryAjaxmodal").modal("show");
    }).on("ajaxStop", function () {
        $("#jQueryAjaxmodal").modal("hide");
    });

But this causes problem when one uses something like jQuery.autocomplete as ajaxStart fires on every keyup. To override this for a particular page, do this

1. Namespace the ajaxStart and ajaxStop like this

    $(document).on("ajaxStart.myblock", function () {
        $("#jQueryAjaxmodal").modal("show");
    }).on("ajaxStop.myblock", function () {
        $("#jQueryAjaxmodal").modal("hide");
    });
2. Now on the DOM Ready of the page on which you wanna override this behaviour, unbind it

    $(document).on("ready", function () {
        $(document).off(".myblock");
    });
Courtesy: jQuery should I use multiple ajaxStart/ajaxStop handling

Read more...