<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>RAD for N-Tier web apps in .NET</title>
	<atom:link href="http://xlib.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://xlib.wordpress.com</link>
	<description>Trials and tribulations while building the framework for quickly developing N-Tier applications in .NET environment</description>
	<lastBuildDate>Sat, 25 Jul 2009 14:54:08 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='xlib.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/1e7e533998834a05c47e393ae538ad0d?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>RAD for N-Tier web apps in .NET</title>
		<link>http://xlib.wordpress.com</link>
	</image>
			<item>
		<title>ASP.NET MVC Grid – Part 7 – Reusable control</title>
		<link>http://xlib.wordpress.com/2009/07/25/asp-net-mvc-grid-%e2%80%93-part-7-%e2%80%93-reusable-control/</link>
		<comments>http://xlib.wordpress.com/2009/07/25/asp-net-mvc-grid-%e2%80%93-part-7-%e2%80%93-reusable-control/#comments</comments>
		<pubDate>Sat, 25 Jul 2009 14:53:48 +0000</pubDate>
		<dc:creator>Eric P</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://xlib.wordpress.com/?p=363</guid>
		<description><![CDATA[At this point all the features I planned in Part 1 have been implemented.  It is time to make grid re-usable.
You can see demo here:
http://samples.entechsolutions.com/MvcGridSample/Part7
Code is available here:
http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part7.zip

So how does one make a grid into reusable control.   There is no standard approach in MVC to separate both Logic and Presentation, similar to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=363&subd=xlib&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>At this point all the features I planned in <a href="http://xlib.wordpress.com/2009/06/25/asp-net-mvc-grid-part-1/">Part 1</a> have been implemented.  It is time to make grid re-usable.</p>
<div id="attachment_432" class="wp-caption alignright" style="width: 310px"><a href="http://xlib.wordpress.com/2009/07/25/asp-net-mvc-grid-%e2%80%93-part-7-%e2%80%93-reusable-control/mvc_grid_products_list/" rel="attachment wp-att-432"><img src="http://xlib.files.wordpress.com/2009/07/mvc_grid_products_list.png?w=300&#038;h=145" alt="Click on image to view the whole screenshot" title="Mvc_Grid_Products_List" width="300" height="145" class="size-medium wp-image-432" /></a><p class="wp-caption-text">Click on image to view the whole screenshot</p></div>
<p>You can see demo here:<br />
<a href="http://samples.entechsolutions.com/MvcGridSample/Part7">http://samples.entechsolutions.com/MvcGridSample/Part7</a></p>
<p>Code is available here:<br />
<a href="http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part7.zip">http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part7.zip</a></p>
<p><code><br /></code></p>
<p>So how does one make a grid into reusable control.   There is no standard approach in MVC to separate both Logic and Presentation, similar to User Controls in web forms.   I hope one will be provided in MVC 2, but for now it is up to a developer to pick from several options.</p>
<p>A found a good article on consolidating HTML for re-usability here:  <a href="http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=487#start">http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=487#start</a>.  It includes various approaches and strengths and weaknesses of each one.   </p>
<p>I considered the following options that would allow me to separate both Grid logic and UI.<br />
<em><br />
<strong>a.  Extending HtmlHelper</strong></em></p>
<p>An example of using HtmlHelper to generate a simple pager is here: http://blogs.taiga.nl/martijn/?s=pager<br />
I think helpers are to be better left for building very small HTML pieces, like action links.   Even a pager in the example above may be too complex for HtmlHelper.</p>
<p><em><strong>b.  RenderAction</strong></em></p>
<p>This was mentioned by Rob Connery here:<br />
<a href="http://blog.wekeroad.com/blog/asp-net-mvc-preview-4-componentcontroller-is-now-renderaction/">http://blog.wekeroad.com/blog/asp-net-mvc-preview-4-componentcontroller-is-now-renderaction/</a></p>
<p>This approach mimics User Control in WebForms, but instead of code behind &#8211; you need provide a separate controller to handle Grid Actions.  There are some reservations to using this approach described here:<br />
<a href="http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=487#start">http://haacked.com/archive/2008/07/16/aspnetmvc-codeplex-preview4.aspx</a></p>
<p>Some people comment that this is not a &#8220;Valid&#8221; MVC approach, since view would have knowledge of Controllers.</p>
<p>This approach works best for controls like Login form which exist on multiple pages or master page, but the functionality is always the same.  In case of the Grid control &#8211; the functionality will be custom depending on the entity being desplayed, so RenderAction doesn&#8217;t exactly fit here (even though it could work).</p>
<p><em><strong>c.  Partial views</strong></em><br />
In this approach partial views are used to encapsulate common HTML.   All the logic goes into the parent controller.  <strong>This approach may be the best option for now</strong>.</p>
<p><code><br /></code></p>
<h3>Implementation</h3>
<p>The first thing to do to make control re-usable is &#8220;Find What Is Varying and Encapsulate It&#8221;.  The simplest way to do that is to create another grid for a different entity.   Then look for code duplication and encapsulate it  into shared views/classes.</p>
<h4>Add Product Entity</h4>
<p>I created a new Product entity that looks like this:</p>
<pre class="brush: csharp;">

public class Product
{
	[Required(ErrorMessage = &quot;Required.&quot;)]
	public int ID { get; set; }

	[Required(ErrorMessage = &quot;Required.&quot;)]
	public string Name { get; set; }

	[Required(ErrorMessage = &quot;Required.&quot;)]
	[StringLength(10, ErrorMessage = &quot;Must be 10 characters.&quot;, MinimumLength = 10)]
	public string SKU { get; set; }

	public string Description { get; set; }

	[Required(ErrorMessage = &quot;Required.&quot;)]
    public decimal Price { get; set; }
}
</pre>
<p>Then I created ProductService class, ProductController and all the Views to List and Edit products</p>
<blockquote>
<pre>
\Models
     Product.cs
     ProductService.cs -  Add/Update/GetByID for product

\Controllers
     ProductController.cs

\Views
    \Product
        List.aspx
        Edit.aspx
        _Grid.aspx
</pre>
</blockquote>
<h4>Finding what varies</h4>
<p>In Each Grid &#8211; the following pieces will work and look the same:</p>
<ul>
<li>Keyword Search and switching search modes</li>
<li>Pager navigation and size</li>
<li>Sorter</li>
<li>CSS and JS</li>
</ul>
<p><img src="http://xlib.files.wordpress.com/2009/07/mvc_grid_samepieces.png?w=1024&#038;h=486" alt="Mvc_Grid_SamePieces" title="Mvc_Grid_SamePieces" width="1024" height="486" class="aligncenter size-large wp-image-426" /><br />
And the following pieces will vary:</p>
<ul>
<li>Column and row data in grid table</li>
<li>Advanced Search form</li>
</ul>
<p><img src="http://xlib.files.wordpress.com/2009/07/mvc_grid_variedpieces.png?w=1024&#038;h=512" alt="Mvc_Grid_VariedPieces" title="Mvc_Grid_VariedPieces" width="1024" height="512" class="aligncenter size-large wp-image-427" /></p>
<p>Here is the screen shot of product list for comparison<br />
<img src="http://xlib.files.wordpress.com/2009/07/mvc_grid_products_list.png?w=1024&#038;h=495" alt="Mvc_Grid_Products_List" title="Mvc_Grid_Products_List" width="1024" height="495" class="aligncenter size-large wp-image-432" /></p>
<h4>Extracting Partial views</h4>
<p>To incapsulate common UI, while allowing users to only implement pieces that vary I separated Grid html  into 4 partials:</p>
<p>_Grid.aspx &#8211; generic grid display<br />
_SearchForm.aspx &#8211; generic search form<br />
_GridData.aspx &#8211; custom display of Grid Data<br />
_AdvancedSearchForm.aspx &#8211; custom advanced search form</p>
<p>The Views directory structure looks like:</p>
<blockquote>
<pre>

\Views
    \Customer
        List.aspx  - includes RenderPartial for _Grid and _SearchForm in /Views/Shared
        Edit.aspx
        _GridData.aspx - data table for displaying Customer entries
        _AdvancedSearchForm.aspx - avanced search fields to find Customers

    \Product
        List.aspx
        Edit.aspx
        _GridData.aspx - data table for displaying Product entries
        _AdvancedSearchForm.aspx - avanced search fields to find Products

    \Shared
        _Grid.aspx
             - generic grid display - that provide Grid structure with header and paging,
                but leaves it up to custom  _GridData (for ex. in \Views\Customer) to display columns and rows
        _SearchForm.aspx
             - generic search form with Keyword search and link to switch to Advanced.  For custom Advanced Search it
               will use _AdvancedSearchForm located in appropriate Views directory like (Views\Customer)
        _Pager.aspx -  to be able to repeat pager on top and bottom of the grid
</pre>
</blockquote>
<h4>Passing view models</h4>
<p>To be able to pass information from \Customer\List.aspx to \Shared\_Grid.asmx and then back to \Customer\_GridData.aspx &#8211; I created an interface that would allow me to box and un-box grid data.  I extracted IGrid interface from Grid and  passed to shared views:</p>
<pre class="brush: csharp;">
public interface IGrid
{
	Pager Pager { get; set; }
	Sorter Sorter { get; set; }
	GridAction GridAction { get; set; }
	bool IsEmpty { get; }
	SelectList PageSizeSelectList();
	string PageNavActionLink(string linkText, int page);
	string SortActionLink(string linkText, string sortField);
}
</pre>
<p>Here is the whole workflow:</p>
<p>a. Customer\List.aspx renders two partial views &#8220;_SearchForm.aspx&#8221; and &#8220;_Grid.aspx&#8221;</p>
<pre class="brush: xml;">
&lt;%@ Page Title=&quot;&quot; Language=&quot;C#&quot; MasterPageFile=&quot;~/Views/Shared/Site.Master&quot; Inherits=&quot;System.Web.Mvc.ViewPage&lt;CustomerGrid&gt;&quot; %&gt;
...
&lt;div id=&quot;search-form&quot;&gt;
	&lt;% Html.RenderPartial(&quot;_SearchForm&quot;, Model.SearchForm); %&gt;
&lt;/div&gt; &lt;!-- search-form --&gt;

&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;div id=&quot;grid&quot;&gt;
	&lt;% Html.RenderPartial(&quot;_Grid&quot;, Model); %&gt;
&lt;/div&gt;  &lt;!-- grid --&gt;
...
</pre>
<p>b. _Grid.aspx takes IGrid as ViewModel and passes it on to \Shared\_Pager.ascx and \Customer\_GridData.ascx</p>
<pre class="brush: xml;">
&lt;%@ Control Language=&quot;C#&quot; Inherits=&quot;System.Web.Mvc.ViewUserControl&lt;IGrid&gt;&quot; %&gt;
...
&lt;div class=&quot;pager-nav&quot;&gt;
	&lt;% Html.RenderPartial(&quot;_PagerNav&quot;, Model); %&gt;
&lt;/div&gt;
...
&lt;div id=&quot;grid-data&quot;&gt;
	&lt;% Html.RenderPartial(&quot;_GridData&quot;, Model); %&gt;
&lt;/div&gt; &lt;!-- data --&gt;
...
</pre>
<p>c.  Partial Customer\_GridData.ascx automatically unboxes IGrid into CustomerGrid</p>
<pre class="brush: xml;">
&lt;%@ Control Language=&quot;C#&quot; Inherits=&quot;System.Web.Mvc.ViewUserControl&lt;CustomerGrid&gt;&quot; %&gt;
...
</pre>
<h4>d. Move the search logic outside of controllers</h4>
<p>When going through ProductController and CustomerController code &#8211; I noticed that both contained a lot of LINQ search logic.  For better separation of concerns, I moved the search logic into Model/Domain classes: CustomerCriteria and ProductCriteria.  This leaves controllers to do what they do best:  display logic.</p>
<p><code><br /></code></p>
<h3>Observations</h3>
<ul>
<li>
MonoRail has nice functionality called sections.  It is described here:<br />
<a href="http://ayende.com/Blog/archive/2006/12/10/BuildingReusableUIComponentsInMonoRail.aspx">http://ayende.com/Blog/archive/2006/12/10/BuildingReusableUIComponentsInMonoRail.aspx</a></p>
<p>It would be great if this functionality would exist in MVC, but right now  the only way to replicate it is by using several partial views.
</li>
</ul>
<h3>Conclusion and what is next&#8230;</h3>
<p>In this part, I  was able to re-use the Grid for both Customers and Products by moving all the common functionality into shared partial views.  </p>
<p>There is still a bit of code that needs to go into the Controller to fill Grid data and save/load grid state.  I was thinking of moving this code into base controller class, but this could introduce some coupling.  I would like to see if RenderAction may be a better solution.</p>
<p>In the near future I will be using Grid control in several client projects. That will be a great opportunity to smooth out any rough edges.  I also plan to introduce some of the more advanced features like: Batch Actions with check boxes, multi-column sorting and inline editing.  So stay tuned&#8230;</p>
<p>In the near future I will add the following bug fixes/enhancements:<br />
1. Use namespace for Grid&#8217;s javascript  to provide for a better encapsulation<br />
2. Fix a bug where user can&#8217;t switch to advanced search if JS is disabled<br />
3. Fix a bug where server side errors are not displayed for Advanced Search, when date or numeric fields are invalid<br />
4. Introduce unit tests for grid actions (other then Paging which already has unit tests)<br />
5. CSS Bug fix: There is a  white dot that appears in FireFox right under header row.  </p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xlib.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xlib.wordpress.com/363/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/xlib.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/xlib.wordpress.com/363/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/xlib.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/xlib.wordpress.com/363/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/xlib.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/xlib.wordpress.com/363/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/xlib.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/xlib.wordpress.com/363/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=363&subd=xlib&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://xlib.wordpress.com/2009/07/25/asp-net-mvc-grid-%e2%80%93-part-7-%e2%80%93-reusable-control/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c7e75c155f179bec67f269874d30ead?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Eric</media:title>
		</media:content>

		<media:content url="http://xlib.files.wordpress.com/2009/07/mvc_grid_products_list.png?w=300" medium="image">
			<media:title type="html">Mvc_Grid_Products_List</media:title>
		</media:content>

		<media:content url="http://xlib.files.wordpress.com/2009/07/mvc_grid_samepieces.png?w=1024" medium="image">
			<media:title type="html">Mvc_Grid_SamePieces</media:title>
		</media:content>

		<media:content url="http://xlib.files.wordpress.com/2009/07/mvc_grid_variedpieces.png?w=1024" medium="image">
			<media:title type="html">Mvc_Grid_VariedPieces</media:title>
		</media:content>

		<media:content url="http://xlib.files.wordpress.com/2009/07/mvc_grid_products_list.png?w=1024" medium="image">
			<media:title type="html">Mvc_Grid_Products_List</media:title>
		</media:content>
	</item>
		<item>
		<title>ASP.NET MVC Grid – Part 6 – Advanced Search, AJAX, Users with Javascript Disabled</title>
		<link>http://xlib.wordpress.com/2009/07/17/asp-net-mvc-grid-%e2%80%93-part-6-%e2%80%93-advanced-search-ajax-users-with-javascript-disabled/</link>
		<comments>http://xlib.wordpress.com/2009/07/17/asp-net-mvc-grid-%e2%80%93-part-6-%e2%80%93-advanced-search-ajax-users-with-javascript-disabled/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 13:06:27 +0000</pubDate>
		<dc:creator>Eric P</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://xlib.wordpress.com/?p=324</guid>
		<description><![CDATA[In this part I will implement:

advanced search 
using AJAX for grid actions
support for users with Javascript disabled
separate grid.css and grid.js

You can see demo here:
http://samples.entechsolutions.com/MvcGridSample/Part6
Code is available here:
http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part6.zip
Implementation
1.  Advanced Search
Advanced Search differs from Keyword Search in a way that users can search for customers using one or more fields, for example &#8211; find all customers [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=324&subd=xlib&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In this part I will implement:</p>
<ul>
<li>advanced search </li>
<li>using AJAX for grid actions</li>
<li>support for users with Javascript disabled</li>
<li>separate grid.css and grid.js</li>
</ul>
<p><div id="attachment_369" class="wp-caption alignright" style="width: 309px"><a href="http://xlib.wordpress.com/2009/07/17/asp-net-mvc-grid-%e2%80%93-part-6-%e2%80%93-advanced-search-ajax-users-with-javascript-disabled/mvc_grid_withajax/" rel="attachment wp-att-369"><img src="http://xlib.files.wordpress.com/2009/07/mvc_grid_withajax.png?w=299&#038;h=152" alt="Click image to view the full screenshot" title="Mvc_Grid_WithAjax" width="299" height="152" class="size-medium wp-image-369" /></a><p class="wp-caption-text">Click image to view the full screenshot</p></div><br />
You can see demo here:<br />
<a href="http://samples.entechsolutions.com/MvcGridSample/Part6">http://samples.entechsolutions.com/MvcGridSample/Part6</a></p>
<p>Code is available here:<br />
<a href="http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part6.zip">http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part6.zip</a></p>
<h3>Implementation</h3>
<p>1.  <strong>Advanced Search</strong><br />
Advanced Search differs from Keyword Search in a way that users can search for customers using one or more fields, for example &#8211; find all customers with first name &#8220;John&#8221; and with last order placed in the last month.</p>
<p>To implement advanced search I extended SearchForm class to include fields like First Name, Last Name, Phone, etc&#8230;</p>
<pre class="brush: csharp;">

public class SearchForm
{
	//Properties
	public bool IsAdvanced { get; set; }
	public string Keyword { get; set; }
}

public class CustomerSearchForm : SearchForm
{
	public string FirstName { get; set; }
	public string LastName { get; set; }
	public string Email { get; set; }
	public string Phone { get; set; }

	public DateTime? FromDateOfLastOrder { get; set; }
	public DateTime? ToDateOfLastOrder { get; set; }
}
</pre>
<p>To be able to access Advanced search fields in View through a model, I passed CustomerSearchForm as generic when declaring grid:</p>
<pre class="brush: csharp;">

public class CustomerController : Controller
{
        private Grid&lt;Customer, CustomerSearchForm&gt; _grid;
        ...
}

public class Grid&lt;TEntity, TSearchForm&gt; where  TSearchForm : SearchForm, new()
{
	private Pager _pager;
	private Sorter _sorter;
	private TSearchForm _searchForm;
</pre>
<p>This way I could use:</p>
<pre class="brush: xml;">
&lt;td&gt;
	First Name&lt;br /&gt;
	&lt;%= Html.TextBox(&quot;SearchForm.FirstName&quot;, null, new { @style = &quot;width: 100px&quot;, @maxlength = &quot;20&quot; })%&gt;
&lt;/td&gt;
</pre>
<p>otherwise binder had issue binding to correct properties.</p>
<p>Then I added some animation with help of JQuery &#8211; to switch between Keyword and Advanced searches.  See more about this in &#8220;Observations&#8221; section.</p>
<p>2. <strong>AJAX for Grid Actions</strong><br />
This functionality was very easy to implement in Web Forms.  You just had to put UpdatePanel around the GridView and all paging and sorting would be asynchronous.</p>
<p>In MVC, it is a little more complicated, but with a benefit of a more control and flexibility.   I moved Grid html (without search form) into a partial class &#8220;_Grid.aspx&#8221;.   Then I used JQuery AJAX functionality and BlockUI plugin to perform all page actions without refreshing the whole page.</p>
<pre class="brush: jscript;">

jQuery(document).ready(function() {

	initGrid();

 	//Intercept form submit and do submission with AJAX
	$(&quot;#grid&quot;).parents(&quot;form:first&quot;).submit(function() {
		submitFormWithAjax();
		return false;
	});
...
}); 

function submitFormWithAjax() {

	var form = $(&quot;#grid&quot;).parents(&quot;form:first&quot;);
	var formData= form.serialize();         //Serialize form control values to be passed asynchronously

	block();   //use BlockUI to display &quot;Processing ... &quot; popup

	$.ajax({
		type: &quot;POST&quot;,
		url: &quot;_Grid&quot;,           //Partial view
		data: formData,
		success: function(newHtml) {
			//Use timeout of half a second to see &quot;Processing...&quot; animation, otherwise it goes by too quickly.
			setTimeout(function() {
							$(&quot;#grid&quot;).html(newHtml);

							initGrid();
							unblock(); }, 500);
		},

		error: function(request, textStatus, errorThrown) {
			alert(&quot;AJAX error: &quot; + request.statusText);
			unblock();
		}
	});
}

function block() {
	$('#grid #grid-data').block({
		message: '&lt;div class=&quot;blockUI-message&quot;&gt;Processing...&lt;/div&gt;',
		css: { border: 'none', width: 'auto' },
		overlayCSS: { backgroundColor: '#C0C0C0' }
	});
}

function unblock() {
	$('#grid #grid-data').unblock();
}
</pre>
<p>3. Support for users <strong>with javascript disabled</strong><br />
This feature allows users with Javascript disabled to use most of the Grid&#8217;s functionality. Surprisingly, there are still 5% of users who have JS disabled for variety of reasons (http://www.w3schools.com/browsers/browsers_stats.asp). </p>
<p>For Paging and Sorting, I previously submitted the form using javascript, so the links would look like:</p>
<pre class="brush: xml;">
//paging
&lt;a href=&quot;#&quot; onclick=&quot;goToPage(2)&quot;&gt;&amp;gt;&lt;/a&gt; 

//sorting
&lt;th&gt;
	&lt;a href=&quot;#&quot; class=&quot;&quot; onclick=&quot;sort('FirstName', 'Asc');&quot;&gt;First Name&lt;/a&gt;
&lt;/th&gt;

//with javascript used to set appropriate hidden variables and grid action, then submit the form
function goToPage(pageIndex) {
	$(&quot;#Pager_CurrentPage&quot;).val(pageIndex);
	$(&quot;#GridAction&quot;).val(&quot;GoToPage&quot;);

	submitForm();
}

function sort(sortField, sortDirection) {
	$(&quot;#GridAction&quot;).val(&quot;Sort&quot;);

	$(&quot;#Sorter_SortField&quot;).val(sortField);
	$(&quot;#Sorter_SortDirection&quot;).val(sortDirection);

	submitForm();
}
</pre>
<p>For this to work with JS disabled, i replaced &#8220;#&#8221; in href attribute with a url containing the whole grid state as well as appropriate paging/sorting action.  So now, paging and sorting links look like:</p>
<pre class="brush: xml;">

//Paging
&lt;a href=&quot;/Customer/List?Pager.CurrentPage=2&amp;Pager.PageSize=5&amp;Sorter.SortField=ID&amp;Sorter.SortDirection=Asc&amp;SearchForm.IsAdvanced=False&amp;SearchForm.Keyword=&amp;GridAction=GoToPage&quot; onclick=&quot;goToPage(2); return false;&quot;&gt;&amp;gt;&lt;/a&gt;

//Sorting
&lt;a class=&quot;&quot; href=&quot;/Customer/List?Pager.CurrentPage=1&amp;Pager.PageSize=5&amp;Sorter.SortField=FirstName&amp;Sorter.SortDirection=Asc&amp;SearchForm.IsAdvanced=False&amp;SearchForm.Keyword=&amp;GridAction=Sort&quot; onclick=&quot;sort('FirstName', 'Asc'); return false;&quot;&gt;First Name&lt;/a&gt;
</pre>
<p>Notice that onclick now has a &#8220;return false;&#8221; statement.  This suppresses default link action &#8211; which is to go to URL specified in HREF.</p>
<p>Internally this is implemented using Grid.GetQueryString and Grid.GenUrl methods, that are called from methods used to generate links &#8211; Grid.PageNavActionLink(&#8230;) and Grid.SortActionLink(&#8230;).</p>
<p>One nice side-effect from using this approach is that a Search Engine crawler like Google crawler should be able to crawl all the data in the grid using page/sort URLs.</p>
<p>For Page Size, I added &#8220;Refresh&#8221; button which is only displayed if JS is disabled:</p>
<pre class="brush: xml;">
&lt;noscript&gt;&lt;input type=&quot;submit&quot; id=&quot;refresh-button&quot; value=&quot;refresh&quot; /&gt;&lt;/noscript&gt;
</pre>
<p>One feature that doesn&#8217;t work yet for &#8220;JS disabled&#8221; mode is switching Search to Advanced Form.  I will get it to work in next part.</p>
<p>4. Separate <strong>grid.js and grid.css</strong><br />
It is usually a bad practice to keep big chunks of javascript and CSS inline on the actual page.  To correct this issue, I moved all grid javascript and styles into separate files.</p>
<p>JS is now in &#8216;/Scripts/grid.js&#8217;.<br />
CSS is now in &#8216;/Content/grid.css&#8217;.</p>
<p>This will also help with re-usability.  </p>
<h3>Observations</h3>
<ul>
<li>
When adding conditions for Advanced search I discovered that C# String.Contains method doesn&#8217;t have an option for case-insensitive comparison.  To do that I added string extensions from the following link:<br />
http://schleichermann.wordpress.com/2009/02/24/c-stringcontains-case-insensitive-extension-method/</p>
<pre class="brush: csharp;">
public static class StringExtensions
{
	public static bool Contains(this String source, String value, StringComparison comparison)
	{
		return source.IndexOf(value, comparison) != -1;
	}

	public static bool ContainsCaseInsensitive(this String source, String value)
	{
		return Contains(source, value, StringComparison.CurrentCultureIgnoreCase);
	}
}
</pre>
</li>
<li>
When I worked on animation for hiding/showing advanced search, I noticed that animations ran asynchronously, so sometimes it would fully skip the first animation if the second animation was called right away.</p>
<p>Originally the code looked like this:</p>
<pre class="brush: xml;">
$(&quot;#search-form #advanced-link&quot;).click(function() {

	//Hide keyword search form using slide up animation
	$(&quot;#search-form&quot;).slideUp(&quot;medium&quot;);

	//Hide/show appropriate links and form fields
	...

	//Display advanced search form using slide down animation
	$(&quot;#search-form&quot;).slideDown(&quot;medium&quot;);

	...
});
</pre>
<p>Since slideUp was asynchronous,  slideDown would get called even before slideUp would get started, so all I would see was the Keyword form disappearing (without animation) and Advanced search appearing with animation.</p>
<p>To make sure that slideUp animation finished before calling slideDown &#8211; I changed the code to call slideDown in slideUp&#8217;s callback argument.  Final code looks like this:</p>
<pre class="brush: xml;">
$(&quot;#search-form #advanced-link&quot;).click(function() {
	$(&quot;#search-form&quot;).slideUp(&quot;medium&quot;, function() {
		...
		$(&quot;#search-form&quot;).slideDown(&quot;medium&quot;);
	});

	...
});
</pre>
</li>
</ul>
<h3>Coming up&#8230;</h3>
<p>Next will be the biggest task of them all.  Making grid into re-usable control&#8230;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xlib.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xlib.wordpress.com/324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/xlib.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/xlib.wordpress.com/324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/xlib.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/xlib.wordpress.com/324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/xlib.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/xlib.wordpress.com/324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/xlib.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/xlib.wordpress.com/324/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=324&subd=xlib&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://xlib.wordpress.com/2009/07/17/asp-net-mvc-grid-%e2%80%93-part-6-%e2%80%93-advanced-search-ajax-users-with-javascript-disabled/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c7e75c155f179bec67f269874d30ead?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Eric</media:title>
		</media:content>

		<media:content url="http://xlib.files.wordpress.com/2009/07/mvc_grid_withajax.png?w=299" medium="image">
			<media:title type="html">Mvc_Grid_WithAjax</media:title>
		</media:content>
	</item>
		<item>
		<title>ASP.NET MVC Grid – Part 5 &#8211; Persisting Grid State</title>
		<link>http://xlib.wordpress.com/2009/07/10/asp-net-mvc-grid-%e2%80%93-part-5-persisting-grid-state/</link>
		<comments>http://xlib.wordpress.com/2009/07/10/asp-net-mvc-grid-%e2%80%93-part-5-persisting-grid-state/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 13:14:36 +0000</pubDate>
		<dc:creator>Eric P</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://xlib.wordpress.com/?p=239</guid>
		<description><![CDATA[In this part I will implement the following items:

persist the state of the grid 
update UI with row striping and row click actions
handle a &#8220;last customer on page&#8221; edge case 
add status/notifications line  when customer is added/deleted/modified
validate edit form

You can see demo here:
http://samples.entechsolutions.com/MvcGridSample/Part5
Code is available here:
http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part5.zip
Implementation
1.  Persist state of the grid
A common use [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=239&subd=xlib&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In this part I will implement the following items:</p>
<ul>
<li>persist the state of the grid </li>
<li>update UI with row striping and row click actions</li>
<li>handle a &#8220;last customer on page&#8221; edge case </li>
<li>add status/notifications line  when customer is added/deleted/modified</li>
<li>validate edit form</li>
</ul>
<div id="attachment_338" class="wp-caption alignright" style="width: 310px"><a href="http://xlib.wordpress.com/2009/07/10/asp-net-mvc-grid-%e2%80%93-part-5-persisting-grid-state/mvc_grid_withpersistence/" rel="attachment wp-att-338"><img src="http://xlib.files.wordpress.com/2009/07/mvc_grid_withpersistence.png?w=300&#038;h=107" alt="Click on the image to view the whole screenshot." title="Mvc_Grid_WithPersistence" width="300" height="107" class="size-medium wp-image-338" /></a><p class="wp-caption-text">Click on the image to view the whole screenshot.</p></div>
<p>You can see demo here:<br />
<a href="http://samples.entechsolutions.com/MvcGridSample/Part5">http://samples.entechsolutions.com/MvcGridSample/Part5</a></p>
<p>Code is available here:<br />
<a href="http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part5.zip">http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part5.zip</a></p>
<h3>Implementation</h3>
<p>1.  <strong>Persist state of the grid</strong><br />
A common use case for any grid control &#8211; is remembering the state of the grid when user comes back to the list page.  So if grid is currently on page 2 and sorted by phone and user clicks on Edit &#8211; then saves customer and goes back to grid &#8211; the grid will still be on page 2 and sorted by phone. </p>
<p>To implement this functionality I created a new service class GridStateService with methods<br />
Save(key, Grid)<br />
Grid Load(key)<br />
bool Exists(key);</p>
<p>This service uses session to save/load grid&#8217;s state, so while the person is using the site and his/her session hasn&#8217;t expired, the grid state (current page, page size, etc&#8230;) persists.  If needed, it should be simple to change the persistence mechanism to store grid state in the cookie or the database.  In those cases, whenever user would come back to the site, his/her last  preferences (like sorting by &#8220;Phone&#8221; or page-size=50) would remain.</p>
<p>Here is how GridStateService is used in CustomerController.List:</p>
<pre class="brush: csharp;">

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult List()
{
	string key = GetGridKey();   //This function returns current url used to uniquely identify the grid
	if (_gridStateService.Exists(key))
	{
		_grid = _gridStateService.Load(key);
	}
	else
	{
		_grid = new Grid&lt;Customer&gt;
					(
						new Pager {CurrentPage = 1, PageSize = 5},
						new Sorter(&quot;ID&quot;, SortDirection.Asc)
					);
	}

	UpdateGridData();

	return View(_grid);
}
</pre>
<p>Here is the code the saves last state of the grid.</p>
<pre class="brush: csharp;">

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult List(Grid&lt;Customer&gt; grid)
{
	_grid = grid;

	_grid.ProcessAction();

	UpdateGridData();

        //Check if there is data in the grid
	if (_grid.Data.Count() &gt; 0)
		SaveGridState();

	return View(_grid);
}

private void SaveGridState()
{
	string key = GetGridKey();
	_gridStateService.Save(key, _grid);
}
</pre>
<p>2.<strong>Row striping and row click</strong></p>
<p>The row striping and highlighting (which allows for better readability) was implemented using approach described in the following article:<br />
<a href="http://webdevdotnet.blogspot.com/2009/06/aspnet-mvc-jquery-part-2-zebra-striping.html">http://webdevdotnet.blogspot.com/2009/06/aspnet-mvc-jquery-part-2-zebra-striping.html</a></p>
<p>As for row-clicking &#8211; I added onlcick handler to data row&#8217;s tr tag:</p>
<pre class="brush: xml;">
&lt;tr onclick=&quot;onRowClick(&lt;%= item.ID %&gt;)&quot;&gt;
     &lt;td&gt;
</pre>
<p>When user clicks on the row they will be taken to customer edit screen.  This is handled by JS function:</p>
<pre class="brush: jscript;">
function onRowClick(id) {
	document.location = &quot;/Customer/Edit/&quot; + id;
}
</pre>
<p>3.  Edge case for <strong>deleting last customer on the page</strong></p>
<p>If I am using 5 rows per page with 6 customers and I deleted sixth customer on the second page,  the grid should automatically switch to page 1 instead of showing page 2 with no customers.</p>
<p>This condition was handled in pager using the following code:</p>
<pre class="brush: csharp;">
//handle a case when user deleted all rows on last page
if (_currentPage &gt; _totalPages)
    _currentPage = _totalPages;
</pre>
<p>4.   <strong>Status line</strong>  when customer is added/deleted/modified</p>
<p>This functionality is related to operations triggered in the grid page.<br />
Previously,  if I deleted a customer  there would be no indication that customer was deleted.   The grid would get refreshed, but there would be no explicit notification that customer was actually deleted.  </p>
<p>I used TempData functionality on the MasterPage to display such messages/notifications.  All operations, add/edit/delete, that are successfully performed on the customer are now followed by a status line message (yellow box) on the grid page.<br />
This message fades out after 5 seconds (ain&#8217;t JQuery great). </p>
<p>5.  <strong>Validate add/edit form</strong><br />
This functionality is not really grid-related, but I thought it would be important to have it for sample completeness.   It is not very realistic to add a customer with all fields empty.  It will  also help when I implement inline editing.</p>
<p>I used Data Annonations approach described here:<br />
<a href="http://www.asp.net/learn/mvc/tutorial-39-cs.aspx">http://www.asp.net/learn/mvc/tutorial-39-cs.aspx</a></p>
<p>I update UI a little to display error message right next to the input fields which are invalid. </p>
<h3>Observations</h3>
<ul>
<li>
Data annotations has a property <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.datatype.aspx">DataType</a> which takes DataType enumeation consisting of members like &#8220;Currency&#8221;, &#8220;Email Address&#8221;, etc&#8230;   I originally thought it would validate my fields according to the type I pass, but that doesn&#8217;t work.  But it doesn&#8217;t work this way.  In one of the comments to article <a href="http://www.aspworkshops.com/blog/archive/2008/09/10/asp-net-mvc-tip-43-use-data-annotation-validators.aspx">http://www.aspworkshops.com/blog/archive/2008/09/10/asp-net-mvc-tip-43-use-data-annotation-validators.aspx</a> it states:</p>
<blockquote><p>The DataType attribute are not validators.<br />
So DataType(DataType.Email) will not validate a string for being an email address. These are ui type hint sttributes. </p></blockquote>
<p> GRRRRRRReat&#8230;   I guess I will need a reg expression validator or custom validator for Email/Phone validations.</p>
</li>
<li>
When messing with Data Annotations, I discovered another error.  Even though it worked ok when binding simple models, I started getting NullReferenceException when binding to complex models (with sub objects).  I discovered the fix here:</p>
<p><a href="http://stackoverflow.com/questions/820468/how-does-dataannotationsmodelbinder-work-with-custom-viewmodels">http://stackoverflow.com/questions/820468/how-does-dataannotationsmodelbinder-work-with-custom-viewmodels</a>
</li>
<li>
One more thing related to validation.   Looks like there is no way to provide custom error messages for data type conversions during binding.  So if user enters some text into &#8220;Orders Placed&#8221; field &#8211; the error message is always:</p>
<blockquote><p>The value &#8216;SOME VALUE&#8217; is not valid for the Orders Placed field.</p></blockquote>
<p>This is confirmed by Scott Gu in one of the comments to the following article:<br />
<a href="http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx">http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx</a></p>
<blockquote><p>
# re: ASP.NET MVC Preview 5 and Form Posting Scenarios<br />
Wednesday, September 03, 2008 11:39 PM by ScottGu</p>
<p>Hi Florian,</p>
<p>&gt;&gt;&gt;&gt;&gt;&gt;&gt; I very much like the approach, cannot wait until this stuff is baked.  One question &#8211; is there a way to intercept input validation and specify custom ErrorMessages?</p>
<p>&gt;&gt;&gt;&gt;&gt;&gt;&gt; E.g. in your example where the user enters a random string instead of the decimal number required by the model field you&#8217;re auto-generating an error message (&#8216;.. invalid value ..&#8217;).</p>
<p>&gt;&gt;&gt;&gt;&gt;&gt;&gt; Is there a way to customize (and localize) this message, without inspecting and changing ModelState explicitely?</p>
<p>Unfortunately with Preview 5 you need to manipulate the ModelState dictionary directly to enable this (either that or override the ModelBinder behavior to customize your own message).</p>
<p>Hope this helps,</p>
<p>Scott
</p></blockquote>
<p>NOTE TO SELF: Add custom binder with a way to override type conversion error message.
</li>
</ul>
<h3>Coming up&#8230;</h3>
<p>There are a couple of items left before I will make the grid generic and re-usable.  For the next part I will work on:</p>
<ul>
<li>Making grid work if Javascript is disabled. This was brought to my attention by a <a href="http://xlib.wordpress.com/2009/07/01/asp-net-mvc-grid-%E2%80%93-part-3-sorting/#comments">comment in Part 3</a>.  Thank you, sironfoot.</li>
<li>Advandced search form &#8211; which will include fields &#8220;First Name&#8221;, &#8220;Last Name&#8221;, &#8220;Email&#8221;, date range for &#8220;Date of Last Order&#8221;, etc&#8230;</li>
<li>AJAX implementation so the whole page doesn&#8217;t refresh. Will work similar to how GridView worked in ASP.NET web forms if you put UpdatePanel around it.</li>
</ul>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xlib.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xlib.wordpress.com/239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/xlib.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/xlib.wordpress.com/239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/xlib.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/xlib.wordpress.com/239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/xlib.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/xlib.wordpress.com/239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/xlib.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/xlib.wordpress.com/239/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=239&subd=xlib&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://xlib.wordpress.com/2009/07/10/asp-net-mvc-grid-%e2%80%93-part-5-persisting-grid-state/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c7e75c155f179bec67f269874d30ead?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Eric</media:title>
		</media:content>

		<media:content url="http://xlib.files.wordpress.com/2009/07/mvc_grid_withpersistence.png?w=300" medium="image">
			<media:title type="html">Mvc_Grid_WithPersistence</media:title>
		</media:content>
	</item>
		<item>
		<title>ASP.NET MVC Grid – Part 4 &#8211; View Models, Unit Testing, Keyword Search</title>
		<link>http://xlib.wordpress.com/2009/07/06/asp-net-mvc-grid-%e2%80%93-part-4-view-models-unit-testing-keyword-search/</link>
		<comments>http://xlib.wordpress.com/2009/07/06/asp-net-mvc-grid-%e2%80%93-part-4-view-models-unit-testing-keyword-search/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 05:00:58 +0000</pubDate>
		<dc:creator>Eric P</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://xlib.wordpress.com/?p=198</guid>
		<description><![CDATA[In this part, I decided to take a step back and do some refactoring.  At the same time I would like to keep moving forward, by adding new Keyword Search functionality as well as an Auto Complete control to quickly find/edit a customer.
You can see demo here:
http://samples.entechsolutions.com/MvcGridSample/Part4
Code is available here:
http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part4.zip
Implementation
1. Use View Model (instead [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=198&subd=xlib&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In this part, I decided to take a step back and do some refactoring.  At the same time I would like to keep moving forward, by adding new Keyword Search functionality as well as an Auto Complete control to quickly find/edit a customer.<br />
<div id="attachment_273" class="wp-caption alignright" style="width: 310px"><a href="http://xlib.wordpress.com/2009/07/06/asp-net-mvc-grid-%e2%80%93-part-4-view-models-unit-testing-keyword-search/mvc_grid_with_keyword/" rel="attachment wp-att-273"><img src="http://xlib.files.wordpress.com/2009/07/mvc_grid_with_keyword.png?w=300&#038;h=126" alt="Click image to view full screenshot" title="Mvc_Grid_With_Keyword" width="300" height="126" class="size-medium wp-image-273" /></a><p class="wp-caption-text">Click image to view full screenshot</p></div></p>
<p>You can see demo here:<br />
<a href="http://samples.entechsolutions.com/MvcGridSample/Part4">http://samples.entechsolutions.com/MvcGridSample/Part4</a></p>
<p>Code is available here:<br />
<a href="http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part4.zip">http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part4.zip</a></p>
<h3>Implementation</h3>
<p>1. <strong>Use View Model (instead of ViewData) </strong>to organize Grid variables</p>
<p>As I mentioned in last couple of posts, ViewData was being used for too many variables.  Such variables in ViewData  are not strongly typed and result in verbose code which could be error-prone (for example null errors).</p>
<p>Instead I introduce the following class structure for Grid View Model:</p>
<pre class="brush: csharp;">
class Grid
{
	Pager
		CurrentPage
		TotalPages
		RowStats
		...

	Sorter
		SortField
		SortDirection

	SearchCriteria	- new functionality for keyword search
		Keyword

	GridAction - enumeration with items like &quot;Sort&quot;, &quot;GoToPage&quot;, ...
}
</pre>
<p>Using this class feels a lot cleaner then ViewData.  In the code below Model is of class Grid.</p>
<pre class="brush: xml;">
&lt;div id=&quot;gridHeader&quot;&gt;
			&lt;table&gt;
				&lt;tr&gt;
					&lt;td id=&quot;rowStats&quot;&gt;
						&lt;%= Model.Pager.RowStats %&gt;
					&lt;/td&gt;

					&lt;td id=&quot;pagerNav&quot;&gt;
						&lt;% if (Model.Pager.IsNavVisible) { %&gt;
							&lt;table&gt;
								&lt;tr&gt;
									&lt;td&gt;
										&lt;% if (Model.Pager.IsFirstPage) { %&gt;
											&lt;span class=&quot;disabled&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;
										&lt;% } else { %&gt;
											&lt;a href=&quot;#&quot; onclick=&quot;goToPage(&lt;%= Model.Pager.FirstPage %&gt;)&quot;&gt;&amp;lt;&amp;lt;&lt;/a&gt;
										&lt;% } %&gt;
									&lt;/td&gt;
...
</pre>
<p>2. <strong>Write unit tests for pager</strong>.    When creating a Pager class, I decided to follow TDD methodology and wrote unit tests first.  Through this approach I discovered a lot of errors before actually integrating Pager into UI. </p>
<p>Here is a couple of unit tests&#8230;  That check cases when Pager navigation should be visible and not visible.</p>
<pre class="brush: csharp;">
namespace MvcGridSample.Tests.ViewModels.Shared
{
	[TestClass]
	public class PagerTest
	{

	       [TestMethod]
		public void Nav_Not_Visible_If_One_Page()
		{
			var pager = CreateAndInitPager(1, 10, 5);
			Assert.IsFalse(pager.IsNavVisible);
		}

		[TestMethod]
		public void Nav_Visible_If_More_Then_One_Page()
		{
			var pager = CreateAndInitPager(1, 10, 15);
			Assert.IsTrue(pager.IsNavVisible);

		}
               ...
</pre>
<p>3. <strong>Add Keyword search</strong>.  This functionality allows user to search data  by keyword which is matched against First Name, Last Name, Email or Phone.  It can be expanded to search through other fields too (for ex. Customer Address &#8211; if one would exist).</p>
<p>The keyword search criteria was added to LINQ query using the following code:</p>
<pre class="brush: csharp;">
private IQueryable&lt;Customer&gt; AddQuerySearchCriteria(IQueryable&lt;Customer&gt; query, SearchCriteria searchCriteria)
{
	if (!String.IsNullOrEmpty(searchCriteria.Keyword))
	{
		string keyword = searchCriteria.Keyword.ToLower();
		query = query.Where(customer =&gt; customer.FirstName.ToLower().Contains(keyword)
		                                || customer.LastName.ToLower().Contains(keyword)
						|| (customer.Email != null &amp;&amp; customer.Email.Contains(keyword))
						|| (customer.Phone != null &amp;&amp;  customer.Phone.Contains(keyword)));
	}

	return query;
}
</pre>
<p>Note that I had to ensure that Email and Phone were not null, before checking them against keyword.  Otherwise there were some &#8220;object reference is null&#8221; exceptions.</p>
<p>4. <strong>Add Auto Complete </strong> on Keyword.  This is for a common use case when you would like to quickly find a record and perform certain operation on it.  To try it out &#8211; start typing name of existing customer in keyword box.  After first couple of letters you will see auto-complete drop down with a list of matching customers (by first name and last name).</p>
<p>If you select the customer in the list and click enter or click on it with a mouse &#8211; you will be taken to Edit Customer page.</p>
<p>To implement this functionality I used a JQuery auto-complete plugin from here:<br />
<a href="http://docs.jquery.com/Plugins/Autocomplete">http://docs.jquery.com/Plugins/Autocomplete</a></p>
<p>For this to work I created a method on controller that would return list of customer names in JSON format:</p>
<pre class="brush: csharp;">
public ActionResult GetKeywordAutoCompleteData(string q, int limit)
{
	string keyword = q;

	IQueryable&lt;Customer&gt; query = _customerService.GetQueryable();
	query = query.Where(customer =&gt; customer.FirstName.ToLower().StartsWith(keyword)
	                                || customer.LastName.ToLower().StartsWith(keyword))
					.Take(10)
					.OrderBy(customer =&gt; customer.FirstName)
					.ThenBy(customer =&gt; customer.LastName);

	var list = query.Select(customer =&gt; new {
												customer.ID,
												Name = customer.FirstName + &quot; &quot; + customer.LastName});

	return Json(list);
}
</pre>
<p>Then call this method from client side using JQuery auto-complete plugin functionality:</p>
<pre class="brush: jscript;">
jQuery(document).ready(function() {

	$(&quot;#SearchCriteria_Keyword&quot;).autocomplete(
		&quot;/Customer/GetKeywordAutoCompleteData&quot;,
        {
        	dataType: 'json',
        	parse: function(data) {
        		var rows = new Array();

        		for (var i = 0; i &lt; data.length; i++) {
        			rows[i] = { data: data[i], value: data[i].Name, result: data[i].Name };
        		}
        		return rows;
        	},
        	formatItem: function(row, i, n) {
        		return row.Name;
        	},
        	width: 260,
        	selectFirst: false
        }
    );
    ....
</pre>
<h3>Observations</h3>
<ul>
<li>
         When HtmlHelper functions generate HTML controls &#8211; control IDs replace character  &#8220;.&#8221; with &#8220;_&#8221;.  For ex, if I want to use the following control in Jquery:</p>
<pre class="brush: xml;">
     &lt;%= Html.Hidden(&quot;Sorter.SortDirection&quot;)%&gt;
</pre>
<p>I need to call it like this:</p>
<pre class="brush: jscript;">
     $(&quot;#Sorter_SortDirection&quot;).val(someVal);
</pre>
</li>
<li>  Coming from Web Forms world, it seemed natural to me to create /App_Code directory to put all the utility classes.<br />
It has been working fine till now, but all of a sudden I started receiving compilation error:</p>
<blockquote><p>Compiler Error Message: CS0433: The type &#8216;MvcGridSample.StringFormatter&#8217; exists in both &#8216;c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\752a9979\7f1c3889\assembly\dl3\da179bc1\70581e2e_8ff9c901\MvcGridSample.DLL&#8217; and &#8216;c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\752a9979\7f1c3889\App_Code.nzexrw9-.dll&#8217;</p></blockquote>
<p>The reason for this issue is explained on the following page:<br />
<a href="http://weblogs.asp.net/meligy/archive/2008/08/03/converting-vs-2008-website-to-web-application.aspx">http://weblogs.asp.net/meligy/archive/2008/08/03/converting-vs-2008-website-to-web-application.aspx</a></p>
<blockquote><p>During the conversion, VS 2008 renames your &#8220;App_Code&#8221; to &#8220;Old_App_Code&#8221;. This new name sounds ugly, but DO NOT RENAME IT BACK. In the &#8220;web application&#8221; model, all code will be in one assembly. In runtime, the web server does not know what web project type you are using. It does take all code in &#8220;App_Code&#8221; folder and create a new assembly for it. This way, if you have code in folder named &#8220;App_Code&#8221;, you&#8217;ll end up with RUNTIME compilation errors that the same types exist in two assemblies, the one created by VS, and the one created by IIS / ASP.NET Development Server.</p></blockquote>
<p>So to fix the issue  I renamed the folder to &#8220;App_Code_&#8221;</p>
</li>
</ul>
<h3>Coming up for part 5&#8230;</h3>
<p>In part 5, I will implement  grid persistance.  Currently, if I am on page 3 of the grid sorted by phone number and I click on &#8220;Edit&#8221; next to one of the customers &#8211; when I save the customer and go back to grid &#8211; the grid returns to its default state of  Page 1 and sorted by ID.</p>
<p>Grid persistence &#8211; will remember the state of the grid when user goes to another page, so that when user will come back to the page with the grid, it will be in the state that it was left in.</p>
<p>I will also add more JQuery functionality to format alternative rows, change row color on hover and provide &#8220;status line&#8221; notifications of user actions like created new customer, deleted customer, etc&#8230;.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xlib.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xlib.wordpress.com/198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/xlib.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/xlib.wordpress.com/198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/xlib.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/xlib.wordpress.com/198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/xlib.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/xlib.wordpress.com/198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/xlib.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/xlib.wordpress.com/198/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=198&subd=xlib&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://xlib.wordpress.com/2009/07/06/asp-net-mvc-grid-%e2%80%93-part-4-view-models-unit-testing-keyword-search/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c7e75c155f179bec67f269874d30ead?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Eric</media:title>
		</media:content>

		<media:content url="http://xlib.files.wordpress.com/2009/07/mvc_grid_with_keyword.png?w=300" medium="image">
			<media:title type="html">Mvc_Grid_With_Keyword</media:title>
		</media:content>
	</item>
		<item>
		<title>ASP.NET MVC Grid – Part 3 &#8211; Sorting</title>
		<link>http://xlib.wordpress.com/2009/07/01/asp-net-mvc-grid-%e2%80%93-part-3-sorting/</link>
		<comments>http://xlib.wordpress.com/2009/07/01/asp-net-mvc-grid-%e2%80%93-part-3-sorting/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 16:57:52 +0000</pubDate>
		<dc:creator>Eric P</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://xlib.wordpress.com/?p=157</guid>
		<description><![CDATA[For this part I implemented server side sorting. 
You can see demo here:
http://samples.entechsolutions.com/MvcGridSample/Part3
Code is available here:
http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part3.zip
Implementation
1. Started by adding sort links for ID column

	&#60;th&#62;
	     ID
	     &#60;a href=&#34;#&#34; onclick=&#34;sort('id', 'asc');&#34;&#62;asc&#60;/a&#62;
	     &#60;a href=&#34;#&#34; onclick=&#34;sort('id', 'desc');&#34;&#62;desc&#60;/a&#62;
	&#60;/th&#62;

2.  Added javascript and hidden fields to pass sorting information [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=157&subd=xlib&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>For this part I implemented server side sorting. </p>
<div id="attachment_215" class="wp-caption alignright" style="width: 310px"><a href="http://xlib.wordpress.com/2009/07/01/asp-net-mvc-grid-%e2%80%93-part-3-sorting/mvc_grid_withsorting/" rel="attachment wp-att-215"><img src="http://xlib.files.wordpress.com/2009/07/mvc_grid_withsorting.png?w=300&#038;h=80" alt="screenshot" title="Mvc_Grid_WithSorting" width="300" height="80" class="size-medium wp-image-215" /></a><p class="wp-caption-text">click image to see full screenshot</p></div>
<p>You can see demo here:<br />
<a href="http://samples.entechsolutions.com/MvcGridSample/Part3">http://samples.entechsolutions.com/MvcGridSample/Part3</a></p>
<p>Code is available here:<br />
<a href="http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part3.zip">http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part3.zip</a></p>
<h3>Implementation</h3>
<p>1. Started by <strong>adding sort links </strong>for ID column</p>
<pre class="brush: xml;">
	&lt;th&gt;
	     ID
	     &lt;a href=&quot;#&quot; onclick=&quot;sort('id', 'asc');&quot;&gt;asc&lt;/a&gt;
	     &lt;a href=&quot;#&quot; onclick=&quot;sort('id', 'desc');&quot;&gt;desc&lt;/a&gt;
	&lt;/th&gt;
</pre>
<p>2.  <strong>Added javascript and hidden fields</strong> to pass sorting information to controller</p>
<pre class="brush: jscript;">
	&lt;script type=&quot;text/javascript&quot;&gt;
 	 	...

		function sort(sortField, sortDirection) {
			$(&quot;#gridAction&quot;).val(&quot;Sorted&quot;);

			$(&quot;#sortField&quot;).val(sortField);
			$(&quot;#sortDirection&quot;).val(sortDirection);

			submitForm();
		}    

		function submitForm() {
			var form = $(&quot;#grid&quot;).parents(&quot;form:first&quot;);
			form.submit();
		}
	&lt;/script&gt; 

...

&lt;%= Html.Hidden(&quot;sortField&quot;) %&gt;
&lt;%= Html.Hidden(&quot;sortDirection&quot;) %&gt;
</pre>
<p>3.  <strong>Modified CustomerController</strong> to handle sorting</p>
<pre class="brush: csharp;">
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult List(int currentPage, int pageSize, string sortField, string sortDirection, string gridAction)
{
	if (gridAction == &quot;PageSizeChanged&quot; || gridAction == &quot;Sorted&quot;)  //Resetting currentPage on Sorted action
		currentPage = 1;

	IQueryable&lt;Customer&gt; query = _customerService.GetQueryable();
	int totalRows = query.Count();
	if (totalRows==0)
		return View(new List&lt;Customer&gt;());

	//Update query with order by clause
	if (!String.IsNullOrEmpty(sortField))
		query = AddQuerySorting(query, sortField, sortDirection);

	int totalPages = (int)Math.Ceiling((double)totalRows / (double)pageSize);
	if (totalPages != 1)
		query = AddQueryPaging(query, pageSize, currentPage);

	//Update ViewData with new sort params
	UpdateSorterViewData(sortField, sortDirection);
	UpdatePagerViewData(totalPages, totalRows, currentPage, pageSize);

	List&lt;Customer&gt; customers = query.ToList();
	return View(customers);
}

private IQueryable&lt;Customer&gt; AddQuerySorting(IQueryable&lt;Customer&gt; query, string sortField, string sortDirection)
{
	//Used approach from http://www.singingeels.com/Articles/Self_Sorting_GridView_with_LINQ_Expression_Trees.aspx
	//instead of a long switch statement
	var param = Expression.Parameter(typeof(Customer), &quot;customer&quot;);
	var sortExpression = Expression.Lambda&lt;Func&lt;Customer, object&gt;&gt;
							(Expression.Convert(Expression.Property(param, sortField), typeof(object)), param);

	if (sortDirection == &quot;Asc&quot;)
		query = query.OrderBy(sortExpression);
	else
		query = query.OrderByDescending(sortExpression);

	return query;
}

private void UpdateSorterViewData(string sortField, string sortDirection)
{
	ViewData[&quot;sortField&quot;] = sortField;
	ViewData[&quot;sortDirection&quot;] = sortDirection;
}
</pre>
<p>4. Changed UI to only display asc/desc image next to column being sorted.  Also changed column heading labels to links.  Used the following CSS to display ASC or DESC image next to link that was sorted.</p>
<pre class="brush: css;">
#grid #data .asc{
	background: transparent url('../Content/Images/asc.png') center right no-repeat ;
}

#grid #data .desc{
	background: transparent url('../Content/Images/desc.png') center right no-repeat;
}
</pre>
<p>5. Made all columns sortable.  Moved some of the sorting display logic to controller to prevent too much duplication.</p>
<p>Html was simplified to look like this:</p>
<pre class="brush: xml;">
&lt;th&gt;
	&lt;a href=&quot;#&quot; class=&quot;&lt;%= CustomerController.GetGridThClass(ViewData, &quot;FirstName&quot;) %&gt;&quot;
				onclick=&quot;&lt;%= CustomerController.GetGridThOnClick(ViewData, &quot;FirstName&quot;)%&gt;&quot;&gt;
		First Name&lt;/a&gt;
&lt;/th&gt;
</pre>
<p>The new methods in CustomerController are:</p>
<pre class="brush: csharp;">
public static string GetGridThClass(ViewDataDictionary&lt;IEnumerable&lt;Customer&gt;&gt; viewData, string sortField)
{
	if ((string)viewData[&quot;SortField&quot;] != sortField)
		return &quot;&quot;;

	if ((string)viewData[&quot;SortDirection&quot;] == &quot;Asc&quot;)
		return &quot;asc&quot;;

	return &quot;desc&quot;;
}

public static string GetGridThOnClick(ViewDataDictionary&lt;IEnumerable&lt;Customer&gt;&gt; viewData, string sortField)
{
	if ((string)viewData[&quot;SortField&quot;] == sortField &amp;&amp; (string)viewData[&quot;SortDirection&quot;] == &quot;Asc&quot;)
		return &quot;sort('&quot; + sortField + &quot;', 'Desc');&quot;;

	return &quot;sort('&quot; + sortField + &quot;', 'Asc');&quot;;
}
</pre>
<h3>Observations</h3>
<ul>
<li>Discovered a nice way to post code in WordPress using &#8217;sourcecode&#8217; tag here: http://support.wordpress.com/code/</li>
<li>ViewData is starting to remind me of a ViewState.  With all the hidden variables it is basically the same thing.  Of course without being bloated and encoded and not usable from JS. </li>
</ul>
<h3>Coming up&#8230;</h3>
<p>At this point we have a grid with server side paging and server side sorting.</p>
<p>For next part I will create a Grid class/data structure with all the Pager and Sorter properties and pass it as a View model instead of using the non-strong typed ViewData[...].<br />
I will also add keyword search with auto-complete.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xlib.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xlib.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/xlib.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/xlib.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/xlib.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/xlib.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/xlib.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/xlib.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/xlib.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/xlib.wordpress.com/157/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=157&subd=xlib&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://xlib.wordpress.com/2009/07/01/asp-net-mvc-grid-%e2%80%93-part-3-sorting/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c7e75c155f179bec67f269874d30ead?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Eric</media:title>
		</media:content>

		<media:content url="http://xlib.files.wordpress.com/2009/07/mvc_grid_withsorting.png?w=300" medium="image">
			<media:title type="html">Mvc_Grid_WithSorting</media:title>
		</media:content>
	</item>
		<item>
		<title>ASP.NET MVC Grid – Part 2 &#8211; Paging</title>
		<link>http://xlib.wordpress.com/2009/06/29/asp-net-mvc-grid-%e2%80%93-part-2-paging/</link>
		<comments>http://xlib.wordpress.com/2009/06/29/asp-net-mvc-grid-%e2%80%93-part-2-paging/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 14:08:10 +0000</pubDate>
		<dc:creator>Eric P</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://xlib.wordpress.com/?p=81</guid>
		<description><![CDATA[For Part 2 &#8211; I implemented server side paging.
You can see demo here:
http://samples.entechsolutions.com/MvcGridSample/Part2
Code is available here:
http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part2.zip
Implementation
To add server side paging to grid I made the following changes:
1. Add page navigational controls to the View.  For this I used a simple &#8220;&#60;&#60;  &#62;&#62;&#8221; approach.   The HTML for this was pretty straight forward.
2. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=81&subd=xlib&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>For Part 2 &#8211; I implemented server side paging.<a href="http://xlib.wordpress.com/2009/06/29/asp-net-mvc-grid-%e2%80%93-part-2-paging/mvc_grid_withpaging/" rel="attachment wp-att-92"><img src="http://xlib.files.wordpress.com/2009/06/mvc_grid_withpaging.png?w=300&#038;h=152" alt="Mvc_Grid_WithPaging" title="Mvc_Grid_WithPaging" width="300" height="152" class="alignright size-medium wp-image-92" /></a></p>
<p>You can see demo here:<br />
<a href="http://samples.entechsolutions.com/MvcGridSample/Part2">http://samples.entechsolutions.com/MvcGridSample/Part2</a></p>
<p>Code is available here:<br />
<a href="http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part2.zip">http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part2.zip</a></p>
<h3>Implementation</h3>
<p>To add server side paging to grid I made the following changes:</p>
<p>1. <strong>Add page navigational controls</strong> to the View.  For this I used a simple &#8220;&lt;&lt;  &gt;&gt;&#8221; approach.   The HTML for this was pretty straight forward.</p>
<p>2.  <strong>Add page size control</strong>. For this task I used a drop down  populated using a function on CustomerController:</p>
<p>html was:</p>
<pre class="brush: xml;">
&lt;%= Html.DropDownList(&quot;pageSize&quot;, CustomerController.PageSizeSelectList(), new { onchange = &quot;onPageSizeChange()&quot; })%&gt; rows per page
</pre>
<p>and function on CustomerController</p>
<pre class="brush: csharp;">
public static SelectList PageSizeSelectList()
{
	var pageSizes = new List {&quot;1&quot;, &quot;2&quot;, &quot;5&quot;, &quot;10&quot;, &quot;100&quot;};
	return new SelectList(pageSizes, &quot;Value&quot;);
}
</pre>
<p>3. <strong>Add JS code</strong> to make paging navigation and page size operational</p>
<pre class="brush: jscript;">
//Set hidden variable to go to next/prev/last/first page and submit the form
function goToPage(pageIndex) {
	$(&quot;#currentPage&quot;).val(pageIndex);
	$(&quot;#gridAction&quot;).val(&quot;CurrentPageChanged&quot;);

	submitForm();
}

//Set action performed in hidden variable. When PageSize changes - PageIndex needs to be
//reset to 1. This logic will go on the server side.
function onPageSizeChange(pageIndex) {
	$(&quot;#gridAction&quot;).val(&quot;PageSizeChanged&quot;);
	submitForm();
}                   

function submitForm() {
	var form = $(&quot;#grid&quot;).parents(&quot;form:first&quot;);
	form.submit();
}    
</pre>
<p>4. <strong>Update CustomerController to perform paging</strong> using LINQ.   </p>
<pre class="brush: csharp;">

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult List(int currentPage, int pageSize, string gridAction)
{
        //Do logic depending on what action was performed
	if (gridAction == &quot;PageSizeChanged&quot;)
		currentPage = 1;

        //Check if there are no results.  In this case return empty list.
	IQueryable query = _customerService.GetQueryable();
	int totalRows = query.Count();
	if (totalRows==0)
		return View(new List());

	int totalPages = (int)Math.Ceiling((double)totalRows / (double)pageSize);
	if (totalPages != 1)
	{
		//use LINQ to perform paging
		query = query.Skip((currentPage - 1) * pageSize)
						.Take(pageSize);
	}

        //Update ViewData collection to display pager stats and pager controls
	UpdatePagerViewData(totalPages, totalRows, currentPage, pageSize);

	List customers = query.ToList();
	return View(customers);
}
</pre>
<p>5. <strong>Cleanup CSS and table structure.</strong>  This part took majority of the time.  At first I was thinking of just using CSS and Divs for pager, but after having some issues with getting navigational control positioned in the middle,  I decided to go with a table approach.  In the end I ended up using a combination of Divs and CSS.</p>
<h3>Observations</h3>
<ul>
<li>Using ViewData to pass information from Controller to View is getting heavy.  I am currently passing 5-10 variables just for the pager.  I think it makes sense to create data structure GridModel/Grid to hold all the variables.  This approach has the following advantages:<br />
1.  Strong typing using &#8220;<em>if (gridModel.IsFirstPage) then </em>&#8221; instead of &#8220;<em>if (bool)ViewState(&#8220;IsFirstPage&#8221;)</em>&#8220;<br />
2.  Can keep call CustomerController.List(&#8230;) clean by using &#8220;<em>UpdateModel(gridModel);</em>&#8221; instead of passing more and more arguments to CustomerController.List(&#8230;);<br />
3.  Will be able to compartmentalize Pager and Sorter using object hierarchy.  For ex. GridModel.Pager.PageIndex,  GridModel.Sorter.SortField, etc&#8230;
</li>
<li>
            Noticed something weird  in CSS.  Using CSS class like:</p>
<pre class="brush: css;">
#grid #pager #navButtons table tr td .disabled {
			color: #C0C0C0;
			text-align: center;
		}
</pre>
<p>does not work.  But if I change it to:</p>
<pre class="brush: css;">
#grid #pager #navButtons  .disabled {
			color: #C0C0C0;
			text-align: center;
		}
</pre>
<p>it will work.  I wonder if CSS selectors don&#8217;t allow for matching &#8220;id tag class&#8221;.
       </li>
</ul>
<h3>For Part 3</h3>
<p>In upcoming <a href="http://xlib.wordpress.com/2009/07/01/asp-net-mvc-grid-%E2%80%93-part-3-sorting/">part 3</a>, I will implement server side sorting.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xlib.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xlib.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/xlib.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/xlib.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/xlib.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/xlib.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/xlib.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/xlib.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/xlib.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/xlib.wordpress.com/81/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=81&subd=xlib&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://xlib.wordpress.com/2009/06/29/asp-net-mvc-grid-%e2%80%93-part-2-paging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c7e75c155f179bec67f269874d30ead?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Eric</media:title>
		</media:content>

		<media:content url="http://xlib.files.wordpress.com/2009/06/mvc_grid_withpaging.png?w=300" medium="image">
			<media:title type="html">Mvc_Grid_WithPaging</media:title>
		</media:content>
	</item>
		<item>
		<title>ASP.NET MVC Grid &#8211; Part 1</title>
		<link>http://xlib.wordpress.com/2009/06/25/asp-net-mvc-grid-part-1/</link>
		<comments>http://xlib.wordpress.com/2009/06/25/asp-net-mvc-grid-part-1/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 13:29:10 +0000</pubDate>
		<dc:creator>Eric P</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://xlib.wordpress.com/?p=49</guid>
		<description><![CDATA[I have been looking for a grid control for ASP.NET MVC.   In the olden days of ASP.NET Web forms &#8211; I have been using a customized GridView which had the following features:

Paging (server side)
Sorting (server side)
AJAX &#8211; using update panel around grid
Page size 
External Filters
Remembering the state of the Grid (page, sorting, etc&#8230;) [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=49&subd=xlib&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I have been looking for a grid control for ASP.NET MVC.   In the olden days of ASP.NET Web forms &#8211; I have been using a customized GridView which had the following features:</p>
<ol>
<li>Paging (server side)</li>
<li>Sorting (server side)</li>
<li>AJAX &#8211; using update panel around grid</li>
<li>Page size </li>
<li>External Filters</li>
<li>Remembering the state of the Grid (page, sorting, etc&#8230;) so if user goes to page 2, clicks on &#8220;Edit&#8221; to modify one of the items and then goes back to grid &#8211; it will still be on Page 2</li>
</ol>
<p>It looks like this:<br />
<img src="http://xlib.files.wordpress.com/2009/06/mvc_grid_old_grid3.png?w=742&#038;h=751" alt="Mvc_Grid_Old_Grid" title="Mvc_Grid_Old_Grid" width="742" height="751" class="aligncenter size-full wp-image-182" /></p>
<p>U can see a demo of it here:<br />
<a href="http://www.codeplex.com/MVCContrib/Wiki/View.aspx?title=Grid">http://demos.entechsolutions.com/XWebSiteTemplate/Admin  </a><br />
Login: demo/demo</p>
<p>There are several options available for ASP.NET MVC:</p>
<p><strong>1.  MvcContrib Grid </strong>- <a href="http://www.codeplex.com/MVCContrib/Wiki/View.aspx?title=Grid">http://www.codeplex.com/MVCContrib/Wiki/View.aspx?title=Grid</a>.<br />
I really like fluent interface, but there are some issues with this control:</p>
<ul>
<li>Only supports paging out of the box.  If you want to add AJAX or sorting &#8211; have to do it yourself</li>
<li>Can end up with a mess of code mixed with HTML.  I noticed that even with simple HTML.  I think MVC should expose as much HTML as possible and only use inline code when needed.  Otherwise &#8211; it would be a lot like Web Forms.</li>
<li>It doesn&#8217;t seem like the control has been updated for a while.</li>
</ul>
<p><strong>2. Using one of the client side grids </strong>and writing an AJAX layer for server-side paging, sorting, etc..<br />
I have looked and jqGrid, extJs grid, flexiGrid and several others.   </p>
<p>Each one has pluses and minuses, but one issue that I found in most, is that you are pretty much stuck with the UI they provide.  There are themes and custom styles available for most, but it is extremely difficult to do any of the following</p>
<ul>
<li>move the pager to a different position </li>
<li>
replace the pager look from &#8216;&lt;&gt;&#8217; to &#8216;1 2 3 &#8230;&#8217;</li>
<li>change the way sorting works (use up down errors instead of links or use a drop down)</li>
<li>modify how inline editing works</li>
<li>&#8230;</li>
</ul>
<p>In most cases you will be stuck with whatever look the Grid has out of the box.  In many of my projects &#8211; customer has very specific requirements about how they want the grid to look and feel, so picking one of the grids above would make it difficult to use in many circumstances.</p>
<p><strong>3. Roll my own grid. </strong> This is the most flexible solution, but will probably take the most time.  I am planning to use JQuery for javascript as well as any JQuery plugins that simplify client side development without restricting UI.  I would like to expose as much HTML as possible to allow front end developers free reign on look and feel.</p>
<p>I plan to start with 6 features that I had in my ASP.NET web forms grid.  I would also like to add the following features depending on how much time I have available:</p>
<ul>
<li>check boxes for batch actions (like delete)</li>
<li>multi column sorting</li>
<li>hide/show columns</li>
<li>move columns around</li>
<li>provide a drop down menu in the column header (kinda like ExtJs)</li>
<li>inline row editing</li>
<li>expand row to display more information</li>
</ul>
<p>Many of these features will be handled as separate samples (or add-ons) instead of being built-in into generic grid control.  </p>
<p>As a first step I created a simple MVC web site and used MVC templates to create &#8220;List&#8221; and &#8220;Edit&#8221; pages.<a href="http://xlib.wordpress.com/2009/06/25/asp-net-mvc-grid-part-1/mvc_grid_simplegrid/" rel="attachment wp-att-61"><img src="http://xlib.files.wordpress.com/2009/06/mvc_grid_simplegrid.png?w=300&#038;h=184" alt="Mvc_Grid_SimpleGrid" title="Mvc_Grid_SimpleGrid" width="300" height="184" class="alignright size-medium wp-image-61" /></a><br />
For data I used an List of objects which will be re-created for any new user session.  I plan to use LinqToObjects to perform various filtering/paging/sorting operations.</p>
<p>You can see the site here:<br />
<a href="http://samples.entechsolutions.com/MvcGridSample/Part1">http://samples.entechsolutions.com/MvcGridSample/Part1</a></p>
<p>The code is available here:<br />
<a href="http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part1.zip">http://samples.entechsolutions.com/Downloads/MvcGridSample/MvcGridSample_Part1.zip</a></p>
<p>The next step will be adding server side paging.  <a href="http://xlib.wordpress.com/2009/06/29/asp-net-mvc-grid-%E2%80%93-part-2-paging/">Here it is in Part 2.</a></p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xlib.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xlib.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/xlib.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/xlib.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/xlib.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/xlib.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/xlib.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/xlib.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/xlib.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/xlib.wordpress.com/49/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=49&subd=xlib&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://xlib.wordpress.com/2009/06/25/asp-net-mvc-grid-part-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c7e75c155f179bec67f269874d30ead?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Eric</media:title>
		</media:content>

		<media:content url="http://xlib.files.wordpress.com/2009/06/mvc_grid_old_grid3.png" medium="image">
			<media:title type="html">Mvc_Grid_Old_Grid</media:title>
		</media:content>

		<media:content url="http://xlib.files.wordpress.com/2009/06/mvc_grid_simplegrid.png?w=300" medium="image">
			<media:title type="html">Mvc_Grid_SimpleGrid</media:title>
		</media:content>
	</item>
		<item>
		<title>Web Sites vs Web Applications &#8211; build times</title>
		<link>http://xlib.wordpress.com/2009/05/14/web-sites-vs-web-applications-build-times/</link>
		<comments>http://xlib.wordpress.com/2009/05/14/web-sites-vs-web-applications-build-times/#comments</comments>
		<pubDate>Thu, 14 May 2009 15:01:23 +0000</pubDate>
		<dc:creator>Eric P</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://xlib.wordpress.com/?p=45</guid>
		<description><![CDATA[The enterprise-level application I am currently working on has several web projects built using &#8220;ASP.NET Web Site&#8221; model.
For a while now, I have been thinking of converting one of them to &#8220;Web Application&#8221; and see if it improves my compilation/build times.  I took one of the smaller projects consisting of about 500 web pages [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=45&subd=xlib&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>The enterprise-level application I am currently working on has several web projects built using &#8220;ASP.NET Web Site&#8221; model.<br />
For a while now, I have been thinking of converting one of them to &#8220;Web Application&#8221; and see if it improves my compilation/build times.  I took one of the smaller projects consisting of about 500 web pages and converted it to Web Application.  </p>
<p>Results are as follows (using VS2008, cleaned solution before each build)</p>
<p>Web Site: <strong>1 minute 20 seconds</strong><br />
Web Application:<strong> 2 secs</strong></p>
<p>That&#8217;s a 60 times improvement.  AMAZING.</p>
<p>There are definitely some drawbacks to switching to Web Application:<br />
1. Not sure how to deal with namespaces.  By default when you convert to &#8220;Web Application&#8221; &#8211; the code behind classes and classes in App_Code stay the same as before &#8211; no namespaces are added.  But any new classes will have the namespaces.    This type of inconsistency can be a bit confusing.<br />
2. Namespaces introduce some naming conflicts, since some of my directory names match class name.  For ex.<br />
\UserControls\Order\UCViewOrder.ascx<br />
The namespace will be &#8220;&#8230;UserControls.Order.UCViewOrder&#8221;  which will conflict with my domain&#8217;s &#8220;Order&#8221; class.<br />
Need to come up with some convention for this one.</p>
<p>These issues seem pretty small compared to <strong>SIXTY TIMES</strong> speed up in compilation time.  </p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xlib.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xlib.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/xlib.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/xlib.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/xlib.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/xlib.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/xlib.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/xlib.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/xlib.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/xlib.wordpress.com/45/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=45&subd=xlib&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://xlib.wordpress.com/2009/05/14/web-sites-vs-web-applications-build-times/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c7e75c155f179bec67f269874d30ead?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Eric</media:title>
		</media:content>
	</item>
		<item>
		<title>OOP vs Structured/Procedural programming (or DDD vs ADM)</title>
		<link>http://xlib.wordpress.com/2009/01/29/oop-vs-structuredprocedural-programming-or-ddd-vs-adm/</link>
		<comments>http://xlib.wordpress.com/2009/01/29/oop-vs-structuredprocedural-programming-or-ddd-vs-adm/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 17:26:04 +0000</pubDate>
		<dc:creator>Eric P</dc:creator>
				<category><![CDATA[DDD]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://xlib.wordpress.com/?p=29</guid>
		<description><![CDATA[I think I may have succeeded in creating a headline with most Jargon evar&#8230;   It is almost as bad as the name of my blog.
I have been having this dilemma.  I have an enterprise level application written using OOP and ActiveRecord.  It utilizes many OOP concepts such as Inheritance and Polymorphism. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=29&subd=xlib&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I think I may have succeeded in creating a headline with most Jargon evar&#8230;   It is almost as bad as the name of my blog.</p>
<p>I have been having this dilemma.  I have an enterprise level application written using OOP and ActiveRecord.  It utilizes many OOP concepts such as Inheritance and Polymorphism.   Recently I have been looking into making the system more friendly for Unit Testing. I talked about it to some developers working on the system and I had an interesting revelation: <strong> most of the developers prefer Structured/Procedural programming over OOP.</strong></p>
<p>Here is the general overview of Procedural programming and OOP.<br />
From <a href="http://www.umsl.edu/~subramaniana/concepts1.html">http://www.umsl.edu/~subramaniana/concepts1.html</a></p>
<p><strong>Procedural/Structured programming</strong></p>
<ul>
<li>Procedural Approach Data Structures can be represented as a network of associated structures, referring to one another.</li>
<li>Procedures can be represented as a network of routines which call one another, i.e., &#8220;call tree&#8221; </li>
</ul>
<p><strong>OOP</strong></p>
<ul>
<li>Object Oriented Approach Collection of discrete objects that incorporate data structures and behavior.</li>
<li>Each data structure has, combined with it, the procedures which apply to that data structure.
</li>
<li>Contrasts with conventional programming in which data structures and behavior are only loosely connected
</li>
<li>These entities, called objects, can be associated to one another in one network, rather than two.
</li>
</ul>
<p>DDD is based on OOP, while Anemic Domain Model is all about procedural programming.</p>
<p>Back to Dilemma.  As much as Anemic Domain Model is an anti-pattern &#8211; it has one really nice thing going for it &#8211; <strong>it is simple and it makes sense to most developers and non-developers</strong>.  How can Order ship itself, how can cake bake itself?  Instead order and cake are just data and you have some OrderService and CakeService operating on them.  With SOA even many business people can easily think in procedural terms.</p>
<p>My current system is written using OOP &#8211; objects have both data and actions.  So I was hoping that switching to DDD would make OOP even more central to future development.  The problem is that separating Active Record Entities into Repositories, Domain Entities and Application Services layer is confusing other developers on my team.  Many of them come from procedural programming (aka Java EJB), so as soon as they see Entities and Services &#8211; then all logic goes into Services while Entities are just data structures.</p>
<p>Here is an example of what I have in my system:</p>
<pre>
<code>
Order
{
     OrderStatus _status;  (InProgress, Paid, Shipped)
     List _orderLines;

     Customer _customer;
     OrderBilling _billing; //Includes ShippingAddress and payment info
     OrderShipping _shipping;  

     DateCreated _dateCreated;

     AddOrderLine(product, quantity)
     RemoveOrderLine(orderLine)

     CalculateTotal();

     TakePayment();
     Ship();
}
</code>
</pre>
<p>Here is the same code written using ADM/Procedural:</p>
<pre>
<code>
Order
{
     OrderStatus _status;

     List _orderLines;
     Customer _customer;
     OrderBilling _billing;
     OrderShipping _shipping;  //Includes ShippingAddress and payment info
     DateCreated _dateCreated;
}

OrderService
{
     AddOrderLine(order, product, quantity)
     RemoveOrderLine(order, orderLine)

     CalculateTotal(order);

     TakePayment(order);
     Ship(order);
}
</code>
</pre>
<p>So what are the benefits of OOP vs ADM:<br />
1. In OOP all the methods that operate on Entity are part of entity (or delegated to appropriate command/domain services by entity), while in Procedural &#8211; the code can be dispersed through many different services.</p>
<p>2. OOP is better for code re-use.  Will need some examples for this one.</p>
<p>3. When refactoring, can use OOP Design Patterns like State Pattern for switching Order status.  </p>
<p>But saying all this is not enough.  There is only one way to make a convincing argument in Software Development:</p>
<p><strong>SHOW ME THE CODE</strong></p>
<p>In the upcoming blog entries, I will try to provide a real world coding example for each one of the points above&#8230;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xlib.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xlib.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/xlib.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/xlib.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/xlib.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/xlib.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/xlib.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/xlib.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/xlib.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/xlib.wordpress.com/29/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=29&subd=xlib&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://xlib.wordpress.com/2009/01/29/oop-vs-structuredprocedural-programming-or-ddd-vs-adm/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c7e75c155f179bec67f269874d30ead?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Eric</media:title>
		</media:content>
	</item>
		<item>
		<title>One class per file or multiple classes in one file</title>
		<link>http://xlib.wordpress.com/2009/01/28/one-class-per-file-or-multiple-classes-in-one-file/</link>
		<comments>http://xlib.wordpress.com/2009/01/28/one-class-per-file-or-multiple-classes-in-one-file/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 14:10:11 +0000</pubDate>
		<dc:creator>Eric P</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://xlib.wordpress.com/?p=15</guid>
		<description><![CDATA[I browsed the internet for an answer to this question and the best I could find was:
&#8220;The primary benefit of a class per file is for source control and concurrent access: Why deal with the inevitable human error of code merges if each developer is really dealing with the separate classes.&#8221;
In my case there are [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=15&subd=xlib&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I browsed the internet for an answer to this question and the best I could find was:</p>
<blockquote><p>&#8220;The primary benefit of a class per file is for source control and concurrent access: Why deal with the inevitable human error of code merges if each developer is really dealing with the separate classes.&#8221;</p></blockquote>
<p>In my case there are several really small classes that seem like they can go into one file or be separated.  As a personal style it seems best to put each class into separate file.  This way I can easily see/find all the classes through solution explorer. </p>
<p>On the other hand it seems more like a stylistic argument, since I couldn&#8217;t find any evidence that it actually improves performance.  I could also use VS diagramming tool to create a nice diagram for all the classes in a module.</p>
<p>So some possible guidelines for development team that can come out of this are:</p>
<ol>
<li>Allow including several classes in file only if each class is max of 10 lines of code.</li>
<li>Classes in the same file must belong to the same Module (DDD Module)</li>
<li>Enums should go in .cs file that uses them.  If there are several classes that use enum &#8211; pick one.</li>
</ol>
<p>Found another good reason for keeping classes in separate files:</p>
<blockquote><p>&#8220;Also you&#8217;ll find many errors/diagnostics are reported via file name (&#8220;Error in Myclass.cpp, line 22&#8243;) and it helps if there&#8217;s a one-to-one correspondence between files and classes. &#8220;<br />
From: <a href="http://stackoverflow.com/questions/28160/multiple-classes-in-a-header-file-vs-a-single-header-file-per-class">http://stackoverflow.com/questions/28160/multiple-classes-in-a-header-file-vs-a-single-header-file-per-class</a>
</p></blockquote>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xlib.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xlib.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/xlib.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/xlib.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/xlib.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/xlib.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/xlib.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/xlib.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/xlib.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/xlib.wordpress.com/15/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xlib.wordpress.com&blog=176936&post=15&subd=xlib&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://xlib.wordpress.com/2009/01/28/one-class-per-file-or-multiple-classes-in-one-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c7e75c155f179bec67f269874d30ead?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Eric</media:title>
		</media:content>
	</item>
	</channel>
</rss>