Tuesday, March 8, 2011

MVC3 Webgrid Html Helper (sorting)

Tuesday, March 08, 2011 Posted by Andre Broers , , , , , 8 comments
As we saw in my previous post about the webgrid sorting is enabled by default. In the following screenshot we can see the defaults of the webgrid control:

We can turn it of by setting the parameter canSort to false. It is also possible to use the canSort property on the individual fields. Which will enable/disable sorting on individual fields.
@model IEnumerable<MvcApplicationDemo.Models.Person>

@{
  ViewBag.Title = "Index";
  var grid = new WebGrid(source: Model, canSort: false);  
}

<h2>Index</h2>

<p>
  @Html.ActionLink("Create New", "Create")
</p>
@grid.GetHtml(columns: grid.Columns(
    grid.Column(
header: "",
style: "text-align-center",
format: (item) => new HtmlString(Html.ActionLink("Edit", "Edit", new { id = item.id }).ToString() + " | " +
Html.ActionLink("Details", "Details", new { id = item.id }).ToString() + " | " +
Html.ActionLink("Delete", "Delete", new { id = item.id }).ToString()
)
),
    grid.Column("name"),
    grid.Column("age")
  )
)

As you can see, in the initialization of the grid the canSort is disabled and the sorting is disabled in the grid:


I re-enable the sorting again and notice (in the screenshot of the previous blogpost that the sorting is done by clicking the column headers. We can sort Ascending and Descending. But wouldn’t it be nice if we had some ascending and descending arrows next to the column headers? Look at the sample below where I introduce the small arrows. (thanks to Alexander Prokofyev)
@model IEnumerable<MvcApplicationDemo.Models.Person>

@{
  ViewBag.Title = "Index";
  var grid = new WebGrid(source: Model, canSort: true);  
}

<h2>Index</h2>

<p>
  @Html.ActionLink("Create New", "Create")
</p>
@grid.GetHtml(columns: grid.Columns(
    grid.Column(
header: "",
style: "text-align-center",
format: (item) => new HtmlString(Html.ActionLink("Edit", "Edit", new { id = item.id }).ToString() + " | " +
Html.ActionLink("Details", "Details", new { id = item.id }).ToString() + " | " +
Html.ActionLink("Delete", "Delete", new { id = item.id }).ToString()
)
),
    grid.Column("name"),
    grid.Column("age")
  )
)

@{
  if (!string.IsNullOrWhiteSpace(grid.SortColumn))
  {
    <script type="text/javascript">
      $('thead > tr > th > a[href*="sort=@grid.SortColumn"]').parent().append('@(grid.SortDirection == SortDirection.Ascending ? "^" : "v")');
    </script>
  }
}

Result is looking as the image below. It’s up to you to make some nice icons.


Have fun…

8 comments:

  1. That was very nice.
    But can you help me how can i put icon/image of arrows instead of "˄" and "˅".
    You can directly mail me the answer on my mail g12garg@gmail.com

    Thanks
    Gaurav Garg

    ReplyDelete
  2. Thank you for this - exactly what I needed. Total life-saver.

    I wound up using CSS classes instead so I could tinker with positioning a bit differently:


    $(document).ready(function() {
    $('thead > tr > th > a[href*="sort=@grid.SortColumn"]').parent().addClass('@(grid.SortDirection == SortDirection.Ascending ? "grid_sort_asc" : "grid_sort_desc")');
    });


    th.grid_sort_asc
    {
    color:Green;
    background-image:url("/Content/images/silk_icons/arrow_up.png");
    background-repeat:no-repeat;
    background-position:right;

    }

    th.grid_sort_desc
    {
    color:Red;
    background-image:url("/Content/images/silk_icons/arrow_down.png");
    background-repeat:no-repeat;
    background-position:right;
    }

    ReplyDelete
  3. $(document).ready function not working if we do AJAX call.

    ReplyDelete