Skip to content

Mix 2011

April 13, 2011
tags: ,

A lot of announcements and new stuff released at Mix 2011 !

Haacked.com has more news and of course Scott Hanselman has more info as well.

The new tools will include modernizr to help asp.net mvc developer step into the age of css3.0 and html5.

My favourite videos: http://tinyurl.com/mvcfavs

Asp.net MVC 2.0 around the corner

February 12, 2010

When you’re reading this article, the fact that Asp.net mvc 2.0 will be released soon won’t come as a surprise. Both Phil Haack and Scott Guthrie amongst others have been blogging about it. I started a new web project recently and was doing the input validation using Xval by Steve Sanderson. I made a leap of faith and upgraded the project to MVC 2.0 because xval had some quirks (or actually the jquery validation plugin did). Luckily those were fixed by MVC’s new build in validation system. The Gu has an excellent post on the subject. I am using the microsoft validation scripts for the client side, and they work very well, even taking culture settings into consideration out of the box.

There is a lot more to MVC 2.0, the templates are nicer. The Html.TextBoxFor(p => p.Id) is very handy, and make the input forms a lot easier to write. The ModelBinding seem to be much better now as well. With 1.0 I sometimes had to some of it by hand, as the binder didn’t grasp what it was supposed to bind. I haven’t run into that in 2.0.

mvc

The attributes for Actions / methods in your controller have been streamlined as well. You only need to put [HttpPost] over actions for Form Posts for example. One thing I haven’t used yet but might come in handy on a big project some day might be the Areas. OdeToCode has a nice article on this new feature.

Over at TekPub, Steve Sanderson and Rob Conery are doing an excellent series on MVC and are also going into the new things of 2.0. If you can spare $28,- I highly recommend watching it.

jqGrid Package

August 8, 2009
tags: ,

A complete package is now available at http://www.jqgrid.com. This was mentioned in a comment on my post about jqgrid, but I thought it was worth a mention here :).

Enjoy !

Devexpress Asp.net MVC Grid

June 22, 2009

At work we work with Devexpress components for our windows applications. And I have used some like the pivotgrid and the reporting tool in asp.net websites. They are very powerful, but sometimes hard to use. They have so many options and properties, it’s sometimes hard to find the right one.

Last week the devexpress blog showed a screenshot of their upcoming asp.net mvc grid. It looks suspisciously like jQuery’s tablesorter plugin. What wasn’t revealed though, is how this grid hooks up with the controller, what actions you have to implement etc. So I wonder how they’re going to implement the model ‘hookup’ so to speak.

I am not really anxious to get these kind of tools and components for asp.net mvc, as you can already do that stuff using jquery and your ORM of choice, but you never know, maybe they will come up with something nice, that isn’t overcomplicated and bloated ;).

Update : Oops that last part suggest that the devexpress components are bloated, but I didn’t intend it that way. They can be a bit complicated to use though, but their support is always willing to send you a bit of example code if you’re stuck.

Anyway I just hope they come up with something that’s ‘in the spirit’ of MVC, if you know what i mean !

Editing in jqGrid with asp.net mvc

May 2, 2009

Phil Haack already posted how to use the jQuery grid ‘jqgrid’ on his blog haacked.com. What wasn’t covered in that tutorial was editing, so I thought it would be nice to add that here.

To be honest it gave me a bit of a headache, as I had created a sample table that had the ID column as primary key/autonumber field and jqgrid posts back an ID as well. Mind you, that is the ROWID and not the ID of your record. In a demo app. this can easily go unnoticed as those two are the same when you just add a few records.

After reading up in the docs, and trying to add an extra parameter to the save call (which accidently broke the whole grid), I simply added a hidden column that contains the primary key.

The table I used for this demo was a simple Employees table with an id, first and lastname.

Here’s what the javascript looks like:

   var lastsel;
   jQuery("#list").jqGrid({
      url: '/GridDemo/GetGridData',
      datatype: 'json',
      mtype: 'GET',
      colNames: ['IdNr','Id', 'FirstName', 'LastName'],
      colModel: [
          { name: 'IdNr', index: 'IdNr', width: 40, align: 'left',
              editable: true, editrules: { edithidden: true }, hidden: true },
          { name: 'Id', index: 'Id', width: 40, align: 'left',
              editable: false },
          { name: 'FirstName', index: 'FirstName', width: 200, align: 'left', editable: true, edittype: 'text', editoptions: { size: 20, maxlength: 30} },
          { name: 'LastName', index: 'LastName', width: 300, align: 'left', editable: true, edittype: 'text', editoptions: { size: 20, maxlength: 30}}],
      onSelectRow: function(id) {
        if (id && id !== lastsel) {
          jQuery('#list').restoreRow(lastsel);
          jQuery('#list').editRow(id, true);
          lastsel = id;
        }
      },
      editurl: "/GridDemo/GridSave",
      pager: jQuery('#pager'),
      rowNum: 10,
      rowList: [5, 10, 20, 50],
      sortname: 'Id',
      sortorder: "desc",
      viewrecords: true,
      imgpath: '/content/themes/steel/images',
      caption: 'Employees'
    });
  });     

The IdNr is the hidden field, with the edithidden: true editrules you make sure it gets posted once a row has been edited. I choose for inline editing, there are other forms of editing in the jqgriddocs.

As you can see the editurl is where the data that has been edited will be posted to. That controller action looks like this (using linq2sql, but ofcourse any type of model will do) :

public ActionResult GridSave(int id,int idnr, string firstName, string lastName)
{
  jQueryGridModelDataContext db = new jQueryGridModelDataContext();

  Employee e = db.Employees.SingleOrDefault(p => p.ID == idnr);
  if (!(e == null))
  {
      e.FirstName = firstName;
      e.LastName = lastName;
      db.SubmitChanges();
      return Content("true");
  }
  else
  {
      return Content("false");
  }
}

And that’s it, your grid now has editing functionality ! Ofcourse some validation is required in the GridSave function. The javascript could use the callback function after saving and check for the true or false that gets returned from the GridSave action.

Let me know in the comments if you have any questions or if I made some sort of horrible mistake :).

kick it on DotNetKicks.com

jQuery Search box and Asp.net MVC

April 9, 2009

This is a simple run through on how to create a fancy search box, that has suggestions underneath the input box, and that also can do autocomplete. For this example I used the Chinook database from codeplex and the Artists table and the autocomplete jquery plug-in that you can find at pengoworks.com.

There are plenty of jQuery plug-ins that do the same thing, I picked this one as it’s very easy to use. As the docs show, the only thing you need to do is hook your input text box up to autocomplete and provide the url where it gets it’s data from. The view looks like this.

<asp:Content ID="headerContent" ContentPlaceHolderID ="headerPlaceHolder" runat ="server">
  <script type="text/javascript" src="../../Scripts/jquery.autocomplete.js"></script>
  <link href="../../Content/jquery.autocomplete.css" rel="stylesheet" type="text/css" />

  <script type="text/javascript">

    $(document).ready(function() {
      $("#searchTerm").autocomplete("/Artists/getAjaxResult/");
    });

  </script>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Look for an artist</h2>

    <form action="/Artists/Search" method="post" id="searchForm">
      <input type="text" name="searchTerm" id="searchTerm" value="" size="10" maxlength ="30" />
      <input type ="submit" value="Search" />
    </form>
    <br />

</asp:Content>

As you can see I usually have a container in the header of the master page where javascript and custom css files go. Note that you should use the Url.Content method so you get the proper urls when you deploy this on a ‘real server’.

Now for the backend, we need an action that returns a string of results to the autocomplete call.

        public ActionResult getAjaxResult(string q)
        {

            string searchResult = string.Empty;

            var artists = (from a in _db.Artists
                           where a.Name.Contains(q)
                           orderby a.Name
                           select a).Take(10);

            foreach (Artist a in artists) {
                searchResult += string.Format("{0}|\r\n", a.Name);
            }

            return Content(searchResult);
        }

By using linq to sql I get the top 10 results from the database from the Artists table and return that as a string to the autocomplete call. The user’s input string is a string called q that is put into the action as a url parameter like this: artists/getAjaxResult/?q=symphony. In order to make that work, you need to add a route to the routes table.


            routes.MapRoute(
                "ArtistSearch",
                "Artists/Search/{searchTerm}",
                new { controller = "Artists", action = "Search",
                            searchTerm = "" }
            );
            routes.MapRoute(
                "ArtistAjaxSearch",
                "Artists/getAjaxResult/",
                new { controller = "Artists", action = "getAjaxResult" }
            );

The first route is used once the user has pressed the submit button, the ArtistAjaxSearch is used for the autocomplete script.

So what happens when the user presses the submit button, whether or not he picked an item from the autocomplete results ?

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Search(string searchTerm)
        {
            if (searchTerm == string.Empty)
            {
                return View();
            }
            else
            {
                // if the search contains only one result return details
                // otherwise a list
                var artists = from a in _db.Artists
                              where a.Name.Contains(searchTerm)
                              orderby a.Name
                              select a;

                if (artists.Count() == 0) {
                    return View("notfound");
                }

                if (artists.Count() > 1)
                {
                    return View("List", artists);
                }
                else
                {
                    return RedirectToAction("Details",
                        new { id = artists.First().ArtistId });
                }
            }
        }

As you can see, when a single result is found the details view is shown to the user, by using a redirect to the details method. If there is more than one result, the list of artists is shown. When nothing is found, a simple message is shown. You can of course move the search term to that view as well, to show the user what input he did etc., but that is straightforward stuff.

Another way to do this, would be to insert the artist table as an array and let the autocomplete script use those values for it’s magic, all on the client side. This would be doable as long as that table wouldn’t get too long. If there are 1000s of records, this wouldn’t be a very good solution ;).

Hope this helps someone out there :), feel free to add any comments or questions !

kick it on DotNetKicks.com

jQuery-Ui Tabs and Asp.net MVC

March 17, 2009

Clay made a comment on my previous post and asked how I would use asp.net mvc with jQuery-UI’s tabs. I have slapped together an example project that shows how you could implement the tabs in an asp.net mvc web site. I created an ajax and a regular tab example.

Tab Example jQueryUi

Tab Example jQueryUi

Basically I use a partial view for each tab. This partial view is then also used for the ajax response.

<div id="tabs">
<ul>
	<li><a href="#tabs-1">Text 1</a></li>
	<li><a href="#tabs-2">Text 2</a></li>
	<li><a href="#tabs-3">Text 3</a></li>
</ul>
<div id="tabs-1">
            < % Html.RenderPartial("_tab1", Model);  %></div>
<div id="tabs-2">
	        < % Html.RenderPartial("_tab2", Model);  %></div>
<div id="tabs-3">
	        < % Html.RenderPartial("_tab3", Model);  %></div>
</div>

There is no database access in the example project, I sort of simulated a database by using a service model that provides the viewmodel that holds the texts that are displayed in the three tabs.

Regarding the ajax controller method, it would of course be better to not get the entire viewmodel in a real world situation and then pass that on to the view, but since this is a brief demo I thought I could get away with this in this example ;).


        public ActionResult getAjaxTab(int id)
        {
            string viewName = string.Empty;

            TabExample.Services.tabTextService serv = new TabExample.Services.tabTextService();
            tabViewModel myModel = serv.getTabViewModel();

            switch (id)
            {
                case 1:
                    viewName = "_tab1";
                    break;
                case 2:
                    viewName = "_tab2";
                    break;
                case 3:
                    viewName = "_tab3";
                    break;
                default:
                    viewName = "_error";
                    break;
            }

            System.Threading.Thread.Sleep(1000);   

            return PartialView(viewName, myModel);
        }

I am using this js function to update the tabs.


        function getContentTab(index) {
            var url='< %= Url.Content("~/Home/getAjaxTab") %>/' + index;
            var targetDiv = "#tabs-" + index;
            var ajaxLoading = "<img id='ajax-loader' src='<%= Url.Content("~/Content") %/>/ajax-loader.gif' align='left' height='28' width='28'>";

            $(targetDiv).html("
" + ajaxLoading + " Loading...
"); 

            $.get(url,null, function(result) {
                $(targetDiv).html(result);
            });
        }

There is a select event on the tabs that you can hook into as well, I just find it easier to just use the onclick event of the tab div’s.

Hope this is some help to anybody out there, it was fun to create this small project. If anyone has any suggestions, or questions let me know in the comments !

Download TabExample Project Link