Building A Color Picker Using ASP.NET MVC And jQuery - Update

Posted by: Malcolm Sheridan , on 1/13/2010, in Category ASP.NET MVC
Views: 30664
Abstract: The following article is a update to the article I published on how to build a color picker using ASP.NET MVC and jQuery.
Building A Color Picker Using ASP.NET MVC And jQuery - Update
 
Last week I published an article on Building A Color Picker Using ASP.NET MVC And jQuery. I received allot of good feedback from that article, but one reader asked this question:
I like how people are coming up with alternatives for the Ajax Toolkit but one thing I will say in this case is MVC is intended to separate data from the output. It's a huge no no in my mind to add HTML to your controller. The controller returns a JsonResult which means it should be purely Json and not include HTML. Your script should build and render the HTML client-side.
I did blur what really should be returned from an action. I thought I would update the article so that my action only return a JsonResult and not the HTML table.

 

I've updated the controller to return a list of colors in a generic string collection:
C#
public class ColorController : Controller
{
      [AcceptVerbs(HttpVerbs.Get)]
      public JsonResult FetchColors()
      {
            var colors = new List<Color>();
            foreach (var color in Enum.GetNames(typeof(KnownColor)))
            {
                var colorValue = ColorTranslator.FromHtml(color);
                var html = string.Format("#{0:X2}{1:X2}{2:X2}",
                                    colorValue.R, colorValue.G, colorValue.B);
 
                colors.Add(new Color { Html = html});
            }
            return Json(colors.ToArray());
      }
}
 
public class Color
{
      public string Html { get; set; }
}
VB.NET (Converted)
Public Class ColorController
      Inherits Controller
      <AcceptVerbs(HttpVerbs.Get)> _
      Public Function FetchColors() As JsonResult
             Dim colors = New List(Of Color)()
                  For Each color In System.Enum.GetNames(GetType(KnownColor))
                        Dim colorValue = ColorTranslator.FromHtml(color)
                        Dim html = String.Format("#{0:X2}{1:X2}{2:X2}", colorValue.R, colorValue.G, colorValue.B)
 
                        colors.Add(New Color With {.Html = html})
                  Next color
                  Return Json(colors.ToArray())
      End Function
End Class
 
Public Class Color
      Private privateHtml As String
      Public Property Html() As String
            Get
                  Return privateHtml
            End Get
            Set(ByVal value As String)
                  privateHtml = value
            End Set
      End Property
End Class
Now the action is return purely what the return type is and that is JSON. This means the rendering of the table is in the hands of the front end. Thankfully there's a jQuery library called jTemplates. Quite simply jTemplates is a template engine for jQuery. You create a template and pass it data, and it renders it for you. Sweet! 
Here's the updated View:
<script language="javascript" type="text/javascript" src="http://code.jquery.com/jquery-1.4a2.js"></script>
    <script language="javascript" type="text/javascript" src="http://jtemplates.tpython.com/jTemplates/jquery-jtemplates.js"></script>
    <script language="javascript" type="text/javascript">
        $(function() {
            $("#Colors").hide();
            $("#SelectColor").click(function() {
                $.getJSON("/Color/FetchColors", null, function(data) {
                    $("#Colors").setTemplateURL("Templates/ColorPicker.htm");
                    $("#Colors").processTemplate(data);
                    $("#Colors").show();
                });
            });
 
            $("td").live("mouseover", (function() {
                $("#Sample").css("background-color", $(this).css("background-color"));
                $(this).css("cursor", "pointer");
            }));
 
            $("td").live("click", function() {
                $("#SelectedColor").val($(this).attr("bgcolor"));
            });
        }); 
    </script>    
    <input type="text" id="SelectedColor" name="SelectedColor" readonly="readonly" />
    <img src="/Content/Images/cp_button.png" alt="Pick a color" align="absmiddle" id="SelectColor" />
    <span id="Sample">&nbsp;&nbsp;&nbsp;&nbsp;</span><br /><br />
    <div id="Colors"></div> 
I've modified the code above to use jQuery's $.getJSON function:
 
$.getJSON("/Color/FetchColors", null, function(data) {
 
When data it returned from the server, I pass a template to jTemplates:
 
$("#Colors").setTemplateURL("Templates/ColorPicker.htm");
 
Then I run processTemplate, which basically means render the template now:
 
$("#Colors").processTemplate(data);
 
And finally here's the template file:
<table>
    <tbody>
        <tr>
            {#foreach $T as color}
                <td bgcolor="{$T.color.Html}">&nbsp;</td>
            {#/for}
        </tr>
    </tbody>
</table>
 
Nice and simple. Now the action returns only JSON and the front end renders the HTML. This is a much better way to implement this code. Thanks to you the readers for pointing out pieces that we miss. It makes us all better programmers. The entire source code of this article can be downloaded over here
Give a +1 to this article if you think it was well written. Thanks!
Recommended Articles
Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @malcolmsheridan


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by AJ on Wednesday, January 13, 2010 5:40 AM
Yes this looks neat. Thanks for sharing
Comment posted by Kareem K on Saturday, January 16, 2010 12:01 AM
Thank you boss! This article is very good
Comment posted by D on Wednesday, January 20, 2010 5:26 PM
Nice job! Thanks for responding to my post ;)
Comment posted by Malcolm Sheridan on Thursday, January 21, 2010 4:11 AM
@D
No problem :)
Comment posted by Nikunj Dhawan on Friday, April 9, 2010 6:31 AM
Nice post !!
Comment posted by jerryqian on Friday, April 16, 2010 2:53 AM
thank you very much,
may be your sourcode zip file is broken I counld't open it ,can you email it to me please
Comment posted by Lucky on Monday, July 23, 2012 9:14 AM
Hi, it is not working on my side.....!!! it seems like the template file "Templates/ColorPicker.htm" is not at correct place...

But I have downloaded ur source code and Even it is also not working...
do u have any idea what is going wrong...???
Comment posted by Mark Austen on Thursday, February 20, 2014 3:47 AM
<Pissed>
The sample download code doesn't work because the author screwed it up. The code uploaded does not match the article. If you look at the ColorController you can see that it is from the original article not the updated version.

Wakey, wakey Micheal at least try to get it right.

</Pissed>

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel