Sunday, September 27, 2015

PowerForms update – 0.3.5.3906

If you are new to PowerForms then please checkout previous posts about PowerForms here and here.  This post explains about a new update to PowerForms 0.3.5.3906 which you can download through nuget.  So let’s dive into few new features added to PowerForms.

1. Adding ListBoxFor support to PowerForms and it is similar to how you would use ComboBoxFor

            var form = new PowerForm();
var dt = form.ListBoxFor("Fruits", new string[] { "Apple", "Orange" }).Display();

System.Console.WriteLine(dt["Fruits"].ToString());

System.Console.Read();

2. Adding SelectedIndexChanged event support for ComboBox and ListBoxFor

            var form = new PowerForm();
var dt = form.ListBoxFor("Fruits", new string[] { "Apple", "Orange" }, (o,e) =>
{
System.Console.WriteLine("Inside SelectedIndexChanged Event");
}).Display();

System.Console.WriteLine(dt["Fruits"].ToString());

System.Console.Read();

3.  Adding ButtonFor support. Earlier if you wanted to submit information second time you would have to close the form and run the program again. With ButtonFor you can now add your own Button for which you can specify a custom click action. On the click event you can do other things with the form, for example new GetFormOutput method on the form which gives you the same dictionary<string, object> for submitted form values. You can also close the PowerForm using form.Close() method added to form inside the click event.

	  var form = new PowerForm();

var dt = form.TextBoxFor("FirstName")
.ButtonFor("Click me", (object o, EventArgs e) =>
{
var rs = form.GetFormOutput();
System.Console.WriteLine(rs["FirstName"].ToString());
form.Close();
}).Display();

System.Console.WriteLine(dt["FirstName"].ToString());
System.Console.Read();


4. Adding CheckBoxFor support allows you to add a CheckBox to the form. It gives you out as a boolean if the field is checked or not.

 
var form = new PowerForm();

var dt = form.CheckBoxFor("Yes")
.CheckBoxFor("No")
.Display();
System.Console.WriteLine(dt["Yes"].ToString());
System.Console.WriteLine(dt["No"].ToString());
System.Console.Read();

5. You can now tell the form not to include the default Submit button if you wish to inside the SubmitButton method.

            var form = new PowerForm();

var dt = form.TextBoxFor("FirstName")
.SubmitButton(false).Display();

dt["FirstName"].ToString().ToConsole();
System.Console.Read();

Friday, September 25, 2015

Creating a very simple Ajax Form in ASP.NET MVC 4

In this post, I am going to demonstrate how to create a simple Ajax Form in ASP.NET MVC 4 application using Visual Studio.  I am using Visual Studio 2015 but this should work with VS 2013 too. We are going to submit information about a person using some ajax and with minimum use of javascript.  There is javascript used but we are taking advantage of the wonderful tooling and template benefits of ASP.NET MVC4.  I assume you know some basics of ASP.NET MVC 4 but to get started you create a default asp.net mvc 4 application inside visual studio.

Before diving right into code you may want to check the pre-requisites section below.

PREREQUISITES

Packages.

 You will need if not already installed jQuery, jQuery.UI.Combined, jQuery.Validation, Microsoft.jQuery.Unobtrusive.Ajax, Microsoft.jQuery.Unobtrusive.Validation. Below is how my packages look like.

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Antlr" version="3.4.1.9004" targetFramework="net451" />
  <package id="bootstrap" version="3.0.0" targetFramework="net451" />
  <package id="EntityFramework" version="6.1.1" targetFramework="net451" />
  <package id="jQuery" version="1.10.2" targetFramework="net451" />
  <package id="jQuery.UI.Combined" version="1.11.2" targetFramework="net451" />
  <package id="jQuery.Validation" version="1.13.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Identity.Core" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Identity.EntityFramework" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Identity.Owin" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Mvc" version="5.2.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.Razor" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net451" />
  <package id="Microsoft.AspNet.WebPages" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.jQuery.Unobtrusive.Ajax" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.Owin" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Cookies" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Facebook" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Google" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.MicrosoftAccount" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.OAuth" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Twitter" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net451" />
  <package id="Modernizr" version="2.6.2" targetFramework="net451" />
  <package id="Newtonsoft.Json" version="6.0.3" targetFramework="net451" />
  <package id="Owin" version="1.0" targetFramework="net451" />
  <package id="Respond" version="1.2.0" targetFramework="net451" />
  <package id="WebGrease" version="1.5.2" targetFramework="net451" />
</packages>

Bundles

 public class BundleConfig
{
// For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*",
"~/Scripts/jquery.unobtrusive-ajax*"));

bundles.Add(new ScriptBundle("~/bundles/jqueryui")
.Include("~/Scripts/jquery-ui-*"));

bundles.Add(new StyleBundle("~/Content/jquerycss")
.Include("~/Content/themes/base/datepicker.css"));

bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));

bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"));

bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));

// Set EnableOptimizations to false for debugging. For more information,
// visit http://go.microsoft.com/fwlink/?LinkId=301862
BundleTable.EnableOptimizations = true;
}
}

Let’s dive in.


First we create a person class i.e model in the models folder inside your application. Notice the data annotations used to trigger form validation. These will be triggered on the client side when the user enters invalid information. Most of them are self explanatory however special mention to the confirm password field. It is so easy to do password confirmation here.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace AspNetAjaxForm.Models
{
public class Person
{
[Required()]
[DataType(DataType.Text)]
[StringLength(50, MinimumLength = 3)]
public string FirstName { get; set; }

[Required()]
[DataType(DataType.Text)]
[StringLength(50, MinimumLength = 3)]
public string LastName { get; set; }

[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }

[Required]
public DateTime BirthDate { get; set; }

[DataType(DataType.Text)]
[StringLength(50,MinimumLength=6)]
[Required]
public string Username { get; set; }

[DataType(DataType.Password)]
[StringLength(255, MinimumLength = 8)]
[Required]
public string Password { get; set; }

[Compare("Password")]
[DataType(DataType.Password)]
[StringLength(255, MinimumLength=8)]
public string ConfirmPassword { get; set; }
}
}

Next we will create Register.cshtml page as shown below inside Views/Home folder.  For explanation see paragraph below code

@model AspNetAjaxForm.Models.Person
@{
ViewBag.Title = "Register";
}
<h2>Register</h2>
<div id="register-main">
<div id="register-main-loading-img">
<img id="loading-img" alt="loading" src="~/Content/loadingAnimation.gif">
</div>
@Html.Partial("_RegisterForm",Model)
</div>
@section scripts
{
<script type="text/javascript">
$(document).on('focus', '[data-date="birthdate"]', function () {
$(this).datepicker({
changeMonth: true,
changeYear: true
});
});
</script>
}

In the code above we specify that this form will take in strongly typed model Person. In the register-main div we have two things, one is loading image which is a spinning .gif image that you can easily get from internet and the other is a Partial view called _RegisterForm.cshtml that accepts our Model object. We will create _RegisterForm in the next step.  In the Scripts section we use Jquery to configure our date picker to show month and year field to select Birthdate. Lets’ create _RegisterForm view using the create template with Person as strongly typed object.  Now I have modified the form to use Ajax.BeginForm.  See description of the code below.

@model AspNetAjaxForm.Models.Person

<div id="ajaxForm">
@using (Ajax.BeginForm("Register", "Home", null,
new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.ReplaceWith,
UpdateTargetId = "ajaxForm",
LoadingElementId = "register-main-loading-img"
}))
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
<h4>Person</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.BirthDate, htmlAttributes: new { @class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.BirthDate, new { htmlAttributes = new { @class = "form-control", data_date = "birthdate" } })
@Html.ValidationMessageFor(model => model.BirthDate, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Username, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>

In the above code, first line is obvious it takes in Person object. We wrap everything into ajaxForm div. The key parts here are as follows:


1. Using Ajax.BeginForm allows us submit form using Ajax.  The parameters say that when I click on the submit button please post this form using “Register” action on the “Home” controller which accepts “POST” request. After the form is submitted replace the contents of “ajaxForm” div with result of request and while you process the request display the loading image we specified earlier. 


2. Everything inside div form-horizontal is created using create a new asp.net mvc 4 view with a strongly typed model of type person. I modified the Birthdate field to take in the jquery ui date picker pay attention to the data_date attribute eg. data_date = "birthdate" we had inside the Register page.


Now we are going to see how everything clubs together. Until now you may be a bit lost. So lets check out our controller.  In the home controller create following methods.

           [HttpGet]
public ActionResult Register()
{
return View(new Person());
}

[HttpPost]
public async Task<PartialViewResult> Register(Person person)
{
await Task.Delay(1000);
if ((new string[] {"mitul1","mitul11","mitul12","mitul13"}).Contains(person.Username))
{
ModelState.AddModelError("Username", String.Format("username {0} is already taken", person.Username));
}
if (ModelState.IsValid)
{
return PartialView("_RegistrationResult");
}
return PartialView("_RegisterForm", person);
}

When you run the application and navigate to /Home/Register page it will hit the first Register method and display the Register.cshtml view. And inside Register.cshtml we have _RegisterFrom.cshtml partial view which will ultimately render the form.  After filling the form out when you click on the submit button the second Register method is called that takes in a Person object. This register method returns a PartialView in both the cases 1. if the form is successful 2. if the form has errors. Lets’ understand the second Register method in a little bit more detail.


1. This method uses async and await since you may be submitting the form to a database or checking validation against a web service asynchronously.  Special notice – See the async keyword on the method signature and because of that we cannot just return PartialViewResult we have decorate the method signature with Task<PartialViewResult>.  For demo purposes, I am using await Task.Delay(1000) instead of an async web call.


2. The first if statement checks if the username is already taken or not. This is just for demo purpose but you may have some complex validation on the server side and if any field is invalid then you want to throw that error back and the user should see it below that field. See the image below. You do that by using the ModelState.AddModelError method which takes in field name and error message. In our case we wanted to display that this username is already taken so we have specified ModelState.AddModelError(“username”,String.Format(”username {0} is already taken”,person.username);  Because of this statement our person model that was submitted by the user is invalidated and we return the same _RegisterForm.cshtml Partial view with person model.


image


3. If the model was valid then we enter into the second if statement and submit our person to a database or call a web service. Based upon you business logic you can do other things like if the form was unsuccessful show different message etc. In our case we are showing a partial view called _RegistrationResult.cshtml. You can modify this view to display either confirmation or error message.


Last but not the least to show stuff properly I am using following CSS.

#register-main{
position:relative;
border:3px solid green;
z-index:10;
}
#register-main-loading-img{
display:none;
position:absolute;
z-index:1;
top:0px;
left:0px;
width:100%;
height:100%;
border:3px solid orange;
background-color:rgba(216, 213, 213, 0.89);
}
#loading-img{
border:3px solid blue;
display:block;
position:relative;
width:100px;
height:100px;
margin-left:auto;
margin-right:auto;
top:50%;
}

 

So that’s about it. If you like this post of have any comments leave in the comments section.

 

 

Friday, September 18, 2015

Visual Studio Extension of the Week: Inline Color Picker

If you are a web developer then most modern IDE’s have this feature and thanks to Web Essentials and ReSharper I am used to seeing color next to their hex code counterpart inside Visual Studio. But if you are working in XAML then by default Visual Studio does not have this feature. In this post I want to mention a visual studio extension Inline Color Picker that displays actual color next to the hex code inside your XAML file. It allows you to pick a color of your choice using a color picker. I wonder why XAML team at Microsoft doesn’t add this feature.

image

image

Note this Extension has been there for Visual Studio 2015, 2013, 2012, 2010 all along.  Go download it if you are working with XAML.

Wednesday, September 2, 2015

Debugging your CSS selectors using Ctrl + F in F12 Chrome Developer Tools

Every once in a while I find myself writing a CSS selector and wonder why that style wasn’t applied to a particular element. While it is easy to just apply style attribute on that element and get the desired style you want but that isn’t recommended. Typically you want to be as specific as possible and the more specific you go, making sure you use the right CSS selector becomes very important.  The find element by CSS selector feature should be there in all modern browsers but I use Chrome for development so I will stick to Chrome.  This is not a new feature and most people should know already. 

Open Chrome developer tools window by pressing F12 while using Chrome on the site you are stuck debugging.  By default Element pane opens up and here you can do Ctrl + F and a very small textbox comes up. I wish this textbox was bigger and more prominent. See screenshot below.

Without find box.

image

With find box using Ctrl + F

image

Start typing your CSS selector and it will get highlighted in yellow as your element gets selected. In the screenshot below I am searching element with id=”main” as #main.

image

The most difficult CSS selectors to work with I have found are the ones which are nested and I don’t know why sometimes > sign will work or not. My personal rule of thumb is if I am doing a complex CSS selector then first try to find it in this textbox. If I can’t find my element highlighted here then don’t bother doing browser refresh exercise.  Another example

image

I may be showing really trivial examples here but it has helped me debug some complex CSS selectors with ease. If you know any tricks you love of F12 developer tools then please share in the comments section below.