Desert Code Camp

By James at November 15, 2010 21:40
Filed Under:

Last weekend was the Desert Code Camp in Chandler, AZ. This is a great code camp and is put on by my good friend Joe Guadagno. I was honored to be able to present my ASP.NET MVC and Entity Framework presentation, and I had a great time doing so. Fortunately for me, Joe scheduled my session for the last block, which allowed me to ramp up and really be prepared for the group. There were about 20 attendees in the session, with a wide variety of skill sets and experience. One of my favorite comments from an attendee was when I asked the crowd for a definition of an Entity Context. He responded with “an ecosystem” which prompted me to toss one of our infamous Carabineer key chains to him.

The group was great with lots of good questions and a real back and forth experience. Afterwards I got several positive comments and feedback from a few of the attendees, which made me feel like the whole thing was a success. My slides are on Slideshare.net at http://www.slideshare.net/latringo/aspnet-mvc-and-entity-framework-4

The code camp itself was a dead on success and Joe should be congratulated heartedly. Held at Chandler-Gilbert Community College, the Student Commons was the main staging place for both attendees and speakers. Wi-Fi was flowing freely, and there were tons of snacks and drinks during the day to keep everyone charged up. Afterwards was an after party hosted by Joe featuring hors d’oeuvres to gnosh on and some really nice local craft beers. It was a great way to wind down from a fast paced, tech filled day by talking to people I had never met, about all types of things.

Joe, you did a bang up job pulling this off and getting all the sponsors in line! This is one of the best Code Camps around.

Here’s a few pictures

0407.IMAG0021_0470573D 3051.IMAG0023_284908CA
One of the nicest Code Camp banners I’ve ever seen The staging area in the Student Commons
1805.IMAG0022_4C21BA57 0045.IMAG0024_4C5E3D8C
Joe heading off to handle something Attendees taking a break between sessions

I can’t wait for the next one.

James

jQuery and MVC Part 2

By James at November 15, 2010 17:46
Filed Under: JavaScript, MVC, jQuery

In our last episode we went over the basics of JavaScript and the jQuery library. In this installment I will show you the basics of MVC and how it renders HTML differently than Web Forms pages, and finish up showing some basic Ajax with jQuery.

When ASP.NET first arrived it was a good thing. Web Forms allowed developers to build websites in a way that was very similar to how Windows Forms applications where built, with drag and drop of controls and a “code behind” architecture. Web Forms served their purpose for many, many applications in the enterprise, and many commercial applications, both large and small were successfully built using this technology.

When “Web 2.0” arrived, complete with Ajaxy interactions, Microsoft put forth their own brand of controls to handle this, and for the most part this worked, and continues to work well. However the Web Forms framework makes it difficult to build clean, lean web sites, as the technology depends on many different things in the rendered HTML to make it usable when posting back to the server. Two of the main items are ViewState and Control Rendering.

ViewState is sent to the browser as a way to capture what is on the page, and what has been changed when the request is sent back to the browser. For ViewState to work, controls on the page need to be rendered with specifically named ID’s. This makes it difficult to use JavaScript to find elements on the page by their ID. For example adding a button to a page that is using an ASP.NET Master Page will render the following HTML:

Source code:

   1: <asp:Panel ID="Panel1" runat="server">
   2:     <asp:Button ID="btnClick" runat="server" Text="Button" />
   3: </asp:Panel>

Rendered HTML:

   1: <div id="MainContent_Panel1">    
   2:    <input type="submit" name="ctl00$MainContent$btnClick" 
   3:       value="Button" id="MainContent_btnClick" />    
   4: </div>

ViewState:

   1: <div class="aspNetHidden">
   2: <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" 
   3:    value="/wEPDwUJNjE3ODYxMzIwZGQjyMGaAJ/BFAzxJv1b+/lEXPaj4I/hCsdqNKZUozZiyw==" />
   4: </div>

If you notice you will see both the name and the id of the button has been changed to show that it is a child of the asp:Panel which is a child of the ASP.NET MasterPage. The ViewState in this example is fairly lean, but in large pages, it can become very large, and this is data the browser needs to download.

While this is all fine and dandy, trying to access these elements can be difficult, especially when trying to use jQuery’s selector mechanisims. You may think, that if you keep the name the same when traversing the DOM, will keep it good. But if for some reason the ID of the parent element changes in your code, then the names will change. There are some tricks you can use, but they are not the basis of this tutorial.

Now, let’s look at the same page when rendered with MVC:

Source code:

   1: <asp:Panel ID="Panel1" runat="server">
   2:     <input type="submit" value="button" />
   3: </asp:Panel>

Rendered HTML:

   1: <div id="MainContent_Panel1">    
   2:    <input type="submit" value="button" />    
   3: </div>

Now keep in mind that ASP.NET MVC does not typically use ASP.NET controls and in this example I am using a standard HTML input tag for the submit button.

The ASP.NET MVC Framework – What is it?

Now before we get into a big discussion about what is better and what is not, and all the underpinnings of “who moved my cheese”, MVC is yet another way to build web sites using the .NET Framework. It is a web application framework which implements the model-view-controller pattern of development. It is based on ASP.NET and allows the development of a web application to be built using three roles; Models – the data coming into and out the application, Views – the displayed pages, and Controllers – which handle the traffic coming in for HttpRequest and HttpResponse.

Microsoft released a CTP version of MVC in December, 2007, MVC version 1 in March 2009 and MVC version 2 in March 2010. They are currently working on version 3.

The default View engine for MVC is the Web Forms view engine and this view engine uses regular .aspx pages to design the layout of the user interaction pieces of the web site or web application. Instead of PostBacks any interactions are routed to the Controllers using a Routing mechanism.

A typical ASP.NET MVC application will have the following directory structure as seen in this figure:

3036.MVC-Folder-Structure_741D04C1

As you can see there are folders for Controllers, Models, and Views. Look closely and you will see that the Controllers names are associated with the folders in the Views folder. AccountController maps to Views\Account while HomeController maps to Views\Home. Views that are shared throughout the application are saved in the Views\Shared folder.

Let’s take a look.

4621.Student-Course-Admin_3568075B

The first part of the application allows the user to look up a student by ID. As we can see from this screen shot the student with an ID of 1 is Jeanine Abbott. There are many steps involved in doing this using HTML, CSS and jQuery, so let’s dive in.

Index.aspx has the following code:

   1: <div class="row">
   2:     Find student by ID
   3:     <input type="text" id="studentId" value=""  class="studentId" />
   4:     <input type="button" id="btnAjax" value="Get Student" />
   5:     <img src="../../Content/Images/ajax-loader.gif" class="ajaxLoader" 
   6:          alt="ajaxloader" />
   7: </div>
   8: <div class="row">
   9:    <div class="errorMessage"></div>
  10:    <div class="studentData">
  11:     <table>
  12:         <thead>
  13:         <tr>
  14:             <th>First Name</th>
  15:             <th>Last Name</th>
  16:             <th>Email</th>
  17:             <th>Submit Date</th>
  18:             <th>Approved</th>
  19:             <th>Approved Date</th>
  20:         </tr>
  21:     </thead>
  22:     <tbody>
  23:         <tr>
  24:             <td class="studentFirstName"></td>
  25:             <td class="studentLastName"></td>
  26:             <td class="studentEmail"></td>
  27:             <td class="studentSubmitDate"></td>
  28:             <td class="studentApproved"></td>
  29:             <td class="studentApprovedDate"></td>
  30:         </tr>
  31:     </tbody>
  32:     </table>
  33:   </div>
  34: </div>

The next piece is in the HomeController where we have a method called GetStudent(int id)

   1: private readonly CourseEntities _db = ModelHelper.CourseEntities;
   2: public JsonResult GetStudent(int id)
   3: {
   4:     var student = (from s in _db.Students
   5:                    where s.Id.Equals(id)
   6:                    select s).FirstOrDefault();
   7:  
   8:     if (student == null) 
   9:         return Json("error:Student not found.", JsonRequestBehavior.AllowGet);
  10:  
  11:     var singleStudent = new SingleStudent
  12:         {
  13:             Id = student.Id,
  14:             FirstName = student.FirstName,
  15:             LastName = student.LastName,
  16:             Email = student.Email,
  17:             SubmitDate = student.SubmitDate.ToShortDateString(),
  18:             Approved = student.Approved.ToString(),
  19:             ApprovedDate = string.Empty
  20:         };
  21:  
  22:     if(student.ApprovedDate.HasValue)
  23:         singleStudent.ApprovedDate = student.ApprovedDate.Value.ToShortDateString();
  24:     
  25:     return Json(singleStudent, JsonRequestBehavior.AllowGet);
  26: }

The third piece of the puzzle is in the CSS. Looking at the ASPX code there are two div elements with classes of “studentData ” and “errorMessage”. In the CSS for this project these two classes have been defined as:

   1: div.studentData{display:none}
   2: div.errorMessage{display:none;color:Red;font-weight:bold;}

This makes these elements, and any elements contained within them to not be displayed when the page is first rendered.

The last piece to come into play is the JavaScript and jQuery. It is important to know that when adding your script references to your page, to make sure they are in the correct order. When you are going to use jQuery in your application and additional JavaScript files, the reference to jQuery needs to be first.

   1: <head id="Head1" runat="server">
   2:     <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
   3:     <script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script>
   4:     <script src="../../Scripts/AppScripts.js" type="text/javascript"></script>
   5: </head>

I have written an additional JavaScript file, “AppScripts.js” and included it in the Scripts folder of the application. And by adding a reference to “jquery-1.4.1-vsdoc.js” to your additional JavaScript files, Visual Studio will provide jQuery Intellisense to make it easier reference the jQuery functions and attributes.

   1: /// <reference path = "/Scripts/jquery-1.4.1-vsdoc.js"/>
   2:  
   3: $(document).ready(function () {
   4:     $("#btnAjax").click(function () { getStudent(); });    
   5: });

Going back to the first article in this series, you can see that when the document has been fully loaded into the DOM, with $(document).ready(), the element with the ID of “btnAjax” will have a click event assigned to it. The JavaScript function getStudent() is below.

   1: function getStudent(id) {
   2:     $("img.ajaxLoader").fadeIn(500);
   3:     $("div.errorMessage").fadeOut(500);
   4:     $("div.studentData").fadeOut(500);
   5:     $.ajax({
   6:         url: "/Home/GetStudent/" + $("#studentId").val(),        
   7:         type: "GET",
   8:         success: function (result) {
   9:             if (typeof (result) == "string" && result.indexOf("error:") > -1) {
  10:                 showError(result);
  11:             } else {
  12:                 showStudentData(result);
  13:             }
  14:         }
  15:     });
  16: }

Let’s step through this. Line 1 hides the ajaxLoader image, lines 2 and 3 hide the errorMessage and studentData div tags. Line 4 starts the jQuery ajax function by defining the url, the form action type, and what to do on a successful response. Because I am using a “GET” in the ajax code, I don’t have to include a <form> on the page. Looking back to the GetStudent(int id) method in the Controller, it is expecting a parameter of the type int to be passed in as well. This is done by getting the value of the text field which has an ID of “studentId”;

How the routing is setup with the application, the MVC framework will automatically cast the “1” to an int before it is passed into the method.

The GetStudent () method will take the ID passed in then select the student with a matching ID. If no student is found, GetStudent() will return a string, “error:Student not found.” If a student is found, then the method will return a Json object containing the data of the student.

Using Firebug for Firefox is a good way to see the data which is coming back from the Controller.

When an error is returned, in this case, the student was not found

3036.GetStudent-with-Error_33D6C57A

6557.GetStudent-with-Error-web-page_44028D73

When a student object is returned

5086.GetStudent-with-student_1B83AB5F

5873.GetStudent-with-student-web-page_604FCF93

The success attribute of the $.ajax function will check the type of the result coming back. If it is a string, the showError() function is called. If the type of the result coming back is an object, we know it is a JSON object and the showStudentData() function is called which will display the student’s data.

   1: function showError(result) {
   2:     var msg = result.split(":");
   3:     $("div.errorMessage").html(msg[1]).fadeIn(500);
   4:     $("img.ajaxLoader").fadeOut(500);
   5: }
   6:  
   7: function showStudentData(student) {
   8:     $("td.studentFirstName").html(student.FirstName);
   9:     $("td.studentLastName").html(student.LastName);
  10:     $("td.studentEmail").html(student.Email);
  11:     $("td.studentSubmitDate").html(student.SubmitDate);
  12:     $("td.studentApproved").html(student.Approved.toLowerCase());
  13:     $("td.studentApprovedDate").html(student.ApprovedDate);
  14:     $("div.studentData").fadeIn(500);
  15:     $("img.ajaxLoader").fadeOut(500);
  16: }

Another example

In this project, I want to quickly approve a student for the current course. I could build an Edit Student form and approve them with that, but I don’t want to handle all of that overhead. All I want to do is click the Approved checkbox and go onto the next student.

I can do this by adding a click event to the checkboxes that have been rendered on the page with the following line of jQuery code.

   1: $("input[type=checkbox][name=Approved]").live("click", function () {
   2:     toggleStudentApproval($(this)); 
   3: });

Notice how I am using the “live” event to bind the click event to the checkboxes. What is cool about doing it this way is, the event will be bound to all selected elements now and in the future. So if the page is heavy with elements and long in loading, the $(document).ready() function may fire before all the elements have been rendered. You may also create new DOM elements with jQuery which won’t be available during $(document).ready(), so setting events with the .live() event is a good practice to start.

The JavaScript code:

   1: function toggleStudentApproval(elem) {
   2:     $(elem).siblings("img.ajaxLoader").fadeIn(500);
   3:     var approved = $(elem).attr("checked");
   4:     var studentId = $(elem).prev("input[type=hidden]").val();
   5:     $.ajax({
   6:         url: "/Home/SetStudentApproval/" + approved + "/" + studentId,
   7:         type: "GET",
   8:         success: function (result) {
   9:             showStudentApproval(result);            
  10:         }
  11:     });
  12: }

When the checkbox is clicked the code first shows the animated GIF, “ajaxLoader” that is a sibling of the checkbox. It then sets the variable “approved” to the “checked” attribute of the checkbox, then gets the value of the hidden field “studentId”. Line 6 shows the url which will be sent to the Controller, and line 9 shows the function to be called when the response is received. The request is then sent to the SetStudentApproval method in the Home Controller.

The Controller method, SetStudentApproval

   1: public JsonResult SetStudentApproval(bool approved, int id)
   2: {
   3:     var student = (from s in _db.Students
   4:                     where s.Id.Equals(id)
   5:                     select s).FirstOrDefault();
   6:  
   7:     if (student == null)
   8:         return Json("error:Student not found.", JsonRequestBehavior.AllowGet);
   9:  
  10:     student.Approved = approved;
  11:     student.ApprovedDate = DateTime.Now;
  12:     if (!approved)
  13:         student.ApprovedDate = null;
  14:     _db.SaveChanges();
  15:  
  16:     var singleStudent = new SingleStudent
  17:     {
  18:         Id = student.Id,
  19:         FirstName = student.FirstName,
  20:         LastName = student.LastName,
  21:         Email = student.Email,
  22:         SubmitDate = student.SubmitDate.ToShortDateString(),
  23:         Approved = student.Approved.ToString()
  24:     };
  25:  
  26:     if (student.ApprovedDate.HasValue)
  27:         singleStudent.ApprovedDate = student.ApprovedDate.Value.ToShortDateString();
  28:     
  29:     return Json(singleStudent, JsonRequestBehavior.AllowGet);
  30: }

This method is the similar to the GetStudent method earlier in the article. For ease in reading, I copied it and added passing in the “approved” status, then passing back the student object to the JavaScript function.

The additional JavaScript functions

   1: function showStudentApproval(result) {
   2:     var id = result.Id;
   3:     var hid = getHiddenField(id);
   4:     var td = hid.parent("td").prev("td");
   5:     td.html("");
   6:     if (result.ApprovedDate != null)
   7:         td.html(result.ApprovedDate);
   8:     hid.siblings("img.ajaxLoader").fadeOut(500);
   9: }
  10:  
  11: function getHiddenField(id) {
  12:     var hid;
  13:     $("input[type=hidden]").each(function () {
  14:         if ($(this).val() == id) {
  15:             hid = $(this);
  16:             return false;
  17:         }
  18:     });
  19:     return hid;
  20: }

The function showStudentApproval gets the Id of the student, then calls a helper function, getHiddenField to find the matching hidden field. This is so the table cell displaying the Approved Date can be found. The helper function gets an array of all hidden fields in the DOM, and uses the jQuery function .each() to loop through each one checking the value to see if it matches what was passed in. When it finds the correct element, the variable “hid” is set to the hidden field, then the looping is stopped. The hidden field is then sent back to the showStudentApproval function.

For ease, and since only the checkbox is visible, the hidden field, the checkbox and the animated GIF are all in the same table cell. Line 4 finds the table cell which is to the left of the cell holding these elements by traversing the DOM, looking first for the parent(), then parents previous sibling.

8688_nested-table-cell_0500E70B

Line 5 shows that once you have a jQuery object in memory, you don’t have to use the $() syntax to refer to it again. This is a best practice, as using the $() to find elements which you already have in memory will lead to a degradation in performance.

Line 5 clears out the html of the table cell we found by traversing the DOM in line 4. Lines 6 and 7 set the html of the table cell to the student’s ApprovedDate.

Step 1

2287.student-approval-1_63350E79

Step 2

4405.student-approval-2_61F0759A

Step 3

3718.student-approval-3_4BBA5A48

In this article we talked about some of the differences between a Web Forms application and a MVC application. Showed how to include jQuery files, and did some cool things with Ajax and jQuery to streamline an application’s functionality. In the next article, I will show you how to extend jQuery’s functionality with plugins.

Happy Programming,

James

JavaScript delete confirmation with the C1 ASP.NET GridView

By James at November 08, 2010 23:04
Filed Under: JavaScript, C1GridView, ASP.NET

The ComponentOne ASP.NET GridView allows you to add a Delete button to remove a record from the DataTable. However there isn’t a native way to add a confirmation that you really want the record deleted. It’s always best to check for sure when it comes to destructive actions, so I did some spelunking and came up with a way to do it.

1. Add a Template Field column to the grid by using either the property builder, or in the declarative code of your .aspx page.


7587.blog1b_68AFA015

2. Go into source view and add an ItemTemplate, then an asp:ImageButton.

     <cc1:C1TemplateField>
          <ItemStyle Width="25px" VerticalAlign="Top" />
          <ItemTemplate>
               <asp:ImageButton ID="lbDelete" 
                  runat="server" 
                  ImageUrl="~/Images/delete.gif" />
           </ItemTemplate>
      </cc1:C1TemplateField>

3. In the main C1GridView declaration add a method for the OnRowDataBound event. In this case I added the following:

        OnRowDataBound="AddJavaScriptConfirm" 

4. Add your method to the code behind:

   protected void AddJavaScriptConfirm(object sender, C1GridViewRowEventArgs e)
    {
        C1GridViewRow row = e.Row;
        ImageButton imageButton = (ImageButton) row.FindControl("lbDelete");
        if(imageButton != null)
        {
          imageButton.Attributes.Add("onclick", 
          "java-script:return confirm('Are you sure you want to delete this record?')" );
        }
    }

What this does is for every row that is databound it finds the ImageButton with the ID of “imgDelete” then adds the “onclick” attribute to the element when it is rendered as html

     <td class="C1Gtd" valign="top" style="width:25px;">
          <input type="image" name="ctl00$MainContent$C1GridView1$ctl01$ctl07$lbDelete" 
             id="MainContent_C1GridView1_lbDelete_4" src="Images/delete.gif" 
             onclick="java-script:return confirm(&#39;Are you sure you want to 
               delete this record?&#39;);" />
     </td>
 

NOTE: I had to change javascript to java-script as this blog system sees it as a potential threat. If you copy this code, change the java-script back to javascript.

2260.blog1a_57E7F567

6761.blog2a_2E90AD69

That’s it. Easy, peasy, nice and cheesy.

Happy programming,

James

Silverlight Grid for Easy Data Visualization

By at October 28, 2010 15:09
Filed Under: Entity Framework, FlexGrid

My recorded webinar, "Silverlight Grid for Easy Data Visualization" is up on Vimeo. You can see it here, http://www.vimeo.com/16241316. And as promised I've uploaded the Slides and Code. You can get them in the attachments.

Thanks for listening.... Happy Programming,

James

 

jQuery and MVC–Part 1

By at October 27, 2010 07:27
Filed Under: JavaScript, MVC, jQuery

This is the first in a four-part series on using the JavaScript library jQuery with the ASP.NET MVC framework.

Introduction

In the beginning there was static HTML and it was good. The World Wide Web was in its infancy and anyone with a computer, a text editor, an FTP program and a connection to the internet – more than likely dial-up – could create and publish web pages. But quickly these pages became boring, as they were after all, static, and web publishers began clamoring for something to make their pages zing.

Then along came a scripting language called JavaScript, and changed the way web pages and sites looked and acted, creating new ways to provide interactivity between the user and the web server. It was first released by Netscape as LiveScript in September 1995, and was renamed to JavaScript in December 1995 when it was included in the release of the Netscape browser.

As a programming language it is dynamic, weakly typed, prototype-based and supports closures and higher order functions. Not to be confused with the Java language it does have some similarities in its syntax with curly braces “{}” and semi-colons “;” and copies many names and naming conventions. However like Java, it does have a fairly steep learning curve. Because of this, JavaScript “scripts” started to become more and more popular on web development sites, allowing for easy copy and pasting. While this made JavaScript to quickly become one of the most popular languages for web development, in some circles it gained the reputation of being a “kiddie” language.

In 1999, Microsoft released the IXMLHTTPRequest interface as part of their Outlook Web Access for Microsoft Exchange Server. The Mozilla Foundation developed a wrapper to use this interface through a JavaScript object which was called XMLHttpRequest. In April, 2006 the World Wide Web Consortium published a working draft to “document a minimum set of interoperable features based on existing implementations, allowing Web developers to use these features without platform specific code”. The last revision to the specification was in November, 2009. (http://en.wikipedia.org/wiki/Xmlhttp)

With the advent of Ajax (Asynchronous JavaScript and XML) in 2005, JavaScript had begun to be looked on more favorably by the programming community, and as a more full-featured language.

The Pros and Cons

As with all languages there are many pros and cons, likes and dislikes, friends and foes. JavaScript is no different and some of the most common are:

Pros Cons
Dynamic
Easy to develop with and debug with the appropriate tools
Similar, comfortable syntax to Java, C#, C
Browsers seem to have their own JavaScript engine
Can be difficult to have the same behaviors act the same across browsers

The Development Experience

You get into the learning curve, and spend all your waking hours writing the most unique and elegant piece of JavaScript code, and test it in your favorite browser. It works just how you planned, until you open your site in a different browser. Ugh, events are different, you can’t seem to get to the correct DOM element, nothing just seems to work between browsers, let alone platforms. You pour over your trusty JavaScript manuals, scour forums, Google on Bing for obscure error messages, and generally get frustrated. You just feel like giving up, so what do you do?

JavaScript Libraries to the rescue

JavaScript libraries are pre-written snippets of code and controls which usually form a much larger JavaScript Framework. These libraries allow for the easier development of JavaScript intensive applications, as the majority of them handle the problems of cross-browser, cross-platform issues. Numerous libraries are available including, but not limited to, Dojo, Echo, Ext, Google Web Toolkit, jQuery, MochiKit, MooTools, Prototype, qooxdoo, Rico, script.aculo.us, Spry, and Yahoo! UI Library.

While each library has it’s good and bad points, it’s pros and cons, the rest of this series will focus the jQuery library, found at www.jquery.com

jQuery

In January 2006 John Resig, released the first version of jQuery at BarCamp NYC, as a free, open source, dual-licensed (MIT and GNU) library. According to http://trends.builtwith.com, jQuery is the most popular JavaScript library; with 38.62% of web sites tested using some form of the code. Some of the main features of jQuery are:

  1. Its syntax makes it easier to navigate the DOM (Document Object Model)
  2. Easily handles and binds events to any DOM element
  3. Creates both simple and complex animations
  4. Has a complete suite of Ajax grooviness baked in
  5. Easy extensibility with plug-ins
  6. Unobtrusive
  7. Microsoft bundles jQuery with ASP.NET Web Applications and ASP.NET MVC

That’s right. Microsoft has jumped on the jQuery bandwagon, and gives it full support, even committing code back into source control. In fact, you can call Microsoft Support and get help with jQuery.

Syntax

The learning curve for getting up to speed with jQuery is not terribly steep. In only a short time you can easily grok the basics, and in a few hours, do some really nifty things with jQuery.

The jQuery syntax is easy to learn with all statements starting off with a “$”. One of the cool things about jQuery is since other libraries may use the $ as well, to prevent collisions, you can use the literal “jQuery” instead. For example:

$(“some element”); or jQuery(“some element”);

DOM elements are selected by either their ID, or a className that has been assigned to them.

$(“#myElement”); returns the only ID in the DOM, “myElement”
$(“div.myElement”); returns all div elements having a class assigned of “myElement”

jQuery makes it very easy to traverse through the children of each element as well.

$(“div.main ul li”); returns all li tags within the div tag with a class of “main”

Whereas

$(“div.main”).find(“li”); returns the same collection as above.

You can select specific elements in the collection with special selectors such as :odd, :even, :first, :last, :not(), etc.

$(“div.main”).find(“li:odd”);
     returns all odd (zero-based) li tags inside the div with a class of “main”

$(“div.main”).find(“li:even”);
     returns all even (zero-based) li tags inside the div with a class of “main”

$(“div.main”).find(“li:first”);
     returns the first li tag

$(“div.main”).find(“li:last”);
     returns the last li tag

$(“div.main”).find(“li:not(li.someDifferentClass)”);
     returns all li tags that don’t have the “someDifferentClass” assigned to them

Unobtrusive JavaScript

How many times have we added our own “BLOCKED SCRIPTonclick(doSomething();)” code directly in our elements. It makes it difficult to maintain and debug, and rails against the philosophy of separation of concerns. jQuery helps us to get away from this by using selectors and assigning events to the elements we have found.

Additionally, unless you have written some really terrible jQuery/JavaScript, if there is an error in your jQuery syntax, jQuery will fail gracefully. This means there won’t be any pesky little JavaScript error icons in your browser or JavaScript console.

Events

It is very easy to assign an event (click, focus, blur, etc.) to any DOM element with jQuery, and there are two main methods to do this.

The first is to wait until the DOM is fully loaded, which is checked by the jQuery event, .ready(). This event is fired when the DOM is complete and has been loaded into the memory of the browser.

$(document).ready(function() {
    $(“myElement”).click(function() { doSomething(); });
});

The second method is to attach a “live” event to the element with

$(“myElement”).live(“click”, function(){ doSomething(); });

The differences between these two methods are slight, but important. In the first example, we are assuming there will be an element called “myElement” in the DOM. This could be an element that is hard coded in the HTML, a button, text field, image, div or p tag. However, with jQuery’s dynamic DOM manipulation, it is possible that you would reference an element that has not been created yet.

The .live() event attaches the function you want to call to all matched elements in the selector, regardless of if they have or have not been created yet.

In the examples above, the “doSomething()” is referencing a separate JavaScript function. Another method is to replace the “doSomething()” with more jQuery functions.

$("ul.demo li:odd").each(function (index) {
     var targ = this;
     setTimeout(function () {
       $(targ).addClass("liSelected");
     }, index * 500);
   });
}

jQuery functions can have standard JavaScript functions in them as well. Can you look at the code above and figure out what this event will do?

First, all of the odd li elements in the ul element with a className of “demo” are selected. Second, the jQuery .each() function loops through the collection, setting a brief timer. Third when the timer is hit, the li element has the class of “liSelected” assigned to it.

jQuery’s silent error handling will not show any indication of something going wrong, just since the element hasn’t been created it won’t be able to have the click event attached to it.

Chaining

Once an element has been found, a reference to the element is kept in memory. So, instead of the following:

$(“div.myElement”).hide();
$(“div.myElement”).html(“howdy”);
$(“div.myElement”).addClass(“red”);
$(“div.myElement”).fadeIn(“slow”);

You can chain the actions like so:

$(“div.myElement”).hide().html(“howdy”).addClass(“red”).fadeIn(“slow”);

This makes for much cleaner or succinct code writing and will help with memory as well.

Stuff you can do

As this series progresses, we will dive deeper into all the jQuery goodness. Here is a sampling:

  • Selectors – find elements in the DOM
  • Attributes – get/set attributes of found elements
  • Traversing – moving up/down elements in the DOM
  • Manipulation – get/set contents of found elements
  • CSS – get/set style attributes of found elements
  • Events – fire on click, hover, load, etc. of found elements
  • Effects – fadeIn/Out, slideIn/Out, hide/show
  • Ajax – full and complete Ajax capabilities
  • Utilities – inArray, isArray, makeArray, etc.

Benefits

In closing the benefits of using jQuery are incredibly apparent. It is a solid, standardized JavaScript library, which allows for fast development, and gracefully fails with no glaring errors or frozen pages. Because of its popularity, there are lots and lots of examples, and it is very easy to get ramped up and understand its simplicity.

Check back next week when we will dive deeper into jQuery, and how you can easily spiff up your sites. Take a look at the attached demos, and send me some comments and questions.

James

So Cal Code Camp–USC

By James at October 25, 2010 21:12
Filed Under:

I love code camps, especially the So Cal Code Camps. Yup, that’s plural as Southern California is lucky enough to have three per year. Last weekend, October 23-24 was So Cal Code Camp – USC and I was lucky enough to get the chance to present again. I gave the same presentation as what I did at Silicon Valley Code Camp three weeks ago – ASP.NET MVC and Entity Framework 4 – but this time it went a whole lot smoother. The room was ready, the projector was working correctly, and the audience was right on. Just about 50 attendees with standing room only and five people sitting on the floor. I brought along six of our C1 beanies which I tossed out during my talk to people who made good comments, pointed out different ways to do things, and laughed at my jokes.

I also manned the ComponentOne booth during the day and had a great time talking to the wide variety of Code Campers about our products, passing out literature, key chain carabineers, and our magic “wear these and you’ll never write bad code again” sunglasses.

Thanks to Art Villa and everyone who helped to put on a successful event. It’s a lot of work and they all deserve a big round of applause. And a special thanks to my wife, Carmina, (my own personal booth babe) who took over for me when I went to present.

7215.sccc1_418F1F563678.sccc2_3DC154B9

5165.sccc4_2521919C8372.sccc3_730A671E

My slides are at http://www.slideshare.net/latringo/mvc-and-entity-framework-4, and if you happened to be in attendance, please take a few minutes to tell me what you thought of my presentation at http://speakerrate.com/latringo

James

Watch your Azure Account

By James at April 29, 2010 03:57
Filed Under: Microsoft, Life in General, MVP

The other night, Carmina and I were at our computers taking care of business and stuff, when the following conversation took place.

Carmina: “James, what did you buy from Microsoft today?”

Me: “Um, nothing”

Carmina: “Microsoft just withdrew $315 from our checking account”

The transaction had a phone number so I called the next day. It was for my Azure account I had setup to play around with and do presentations on. When I started the account, I was asked to enter a credit card number as proof of identification, and since I have a MSDN account with my MVP, and that gives me 750 compute hours a month, I thought I was good.

Last month I received a notice from Microsoft Online Services that there had been a problem with my credit card. Wondering what that was all about, since I hadn’t been using the services I logged into the site to see what was going on. This is what I saw…

image  and I clicked on Subscriptions

image

then Actions, which had the following options, “View subscription details, Edit service details, Opt in to auto renew, and Edit billing information”. No where did I see anything to check on activity.

Back to the phone call. I was told in addition to Compute Hours there are also Upload charges and Storage charges, and even if an application is suspended on Azure, i.e. not active, it is still accruing storage charges. In addition, SQL Azure charges of $10 per month, are not included in the 750 hours/month which comes with my MSDN subscription.

Windows Azure Compute charges: $0.12 per hour
Windows Azure Storage charges: $0.15 per hour Yes, $0.15 per hour just to store the files even if the app is not running.

The moral of the story. Azure is a great platform, and I recommend you dive in and get comfortable with it. BUT, remember to take down your apps when you are done testing. Don’t leave them up there.

Oh yeah. Also take the time to look a little further on the portal. I didn’t see the tiny text the other times I was one the site.

image

Time to get a second job,

James

Hey! I’m an INETA Community Champion!

By James at April 05, 2010 10:39
Filed Under: Inland Empire .NET UG, Life in General

Wow. I woke up this morning to a terrific email…

James,

We would like to extend our thanks for your participation in the INETA Community Champions program and your commitment to the developer community. You were nominated by your local Developer Evangelist Lynn Langit.  You faced some challenging competition yet your accomplishments speak for themselves.  The Community Champions team is thrilled to inform you that you are one of our top winners for Q1 2010.  Congratulations!  INETA will be announcing the winners in our next INETA Newsletter as well as posting announcements on our web site. 

I had worked with the INETA Community Champs committee a few years ago, but never thought I would be a recipient.

Thanks everyone, especially Lynn (my own developer champion)!

And just so everyone knows I’m not kidding… here’s the proof.

INETA Community Champions Badge

Time to get crackin’.

James

Interview questions – Change for a dollar

By James at March 22, 2010 12:19
Filed Under: Inland Empire .NET UG, Life in General, Technology in General

So, in my quest to become gainfully employed, I am going through the interview process, mainly technical interviews with hands-on developers. Unfortunately, they seem to want people that 1) either *just* graduated from Computer Science school, or 2) can memorize obscure bits of code, and recite the Visual Studio help files verbatim.

At my last interview, I walked in – after a two-hour car ride, and trying to find a parking spot – to a “Hi, let’s write some code on the white board” situation. Ok, I say to myself, “let’s give this a try”. Their first question, “write code to calculate the optimum number of coins to return when giving change after a purchase.”

Hmm, I think. And I stumbled around for a bit, eventually ending up writing some pseudo-code that involved some long division. The Inland Empire .NET User’s Group’s next meeting was the following Tuesday, and I decided to ask them the same question – however they had the luxury of being in a friendly environment with soda and pizza in their fiery little bellies.

Below are the two answers that UG members sent to me, and it got me to thinking. What I would like to do is have you write your code in the comments, so I can see how many different ways there are to write this method.

From member Daniel Lopez, “Just for grins. If you have suggestion on how to make it better, let me know.”

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GiveChange
{
      class Program
      {
            static void Main(string[] args)
            {
                  DoChange(8.92);
            }

            private static void DoChange(double Tendered)
            {
                  double _DecimalPart = Math.Round(1-( Tendered - Math.Floor(Tendered)),2);
                  do
                  {
                        if (_DecimalPart >= .25)
                        {
                              Change.Quarters += 1;
                              _DecimalPart -= .25;
                        }
                        else if (_DecimalPart >= .10)
                        {
                              Change.Dines += 1;
                              _DecimalPart -= .1;
                        }
                        else if (_DecimalPart >= .05)
                        {
                              Change.Nickles += 1;
                              _DecimalPart -= .05;
                        }
                        else 
                        {
                              Change.Pennies += (int)(_DecimalPart * 100);
                              _DecimalPart -= _DecimalPart;
                        }
                  }
                  while (_DecimalPart > 0);

                  StringBuilder sb = new StringBuilder();

                  sb.Append(string.Format( "Quarters: {0}", Change.Quarters));
                  sb.AppendLine();
                  sb.Append(string.Format("Dines: {0}", Change.Dines));
                  sb.AppendLine();
                  sb.Append(string.Format("Nickles: {0}", Change.Nickles));
                  sb.AppendLine();
                  sb.Append(string.Format("Pennies: {0}", Change.Pennies));

                  Console.WriteLine(sb.ToString());
                  Console.ReadLine();            
            }      
      }

      public  static  class Change
      {
            public static int Quarters { get; set; }
            public static int Dines { get; set; }
            public static int Nickles { get; set; }
            public static int Pennies { get; set; }
      }
}

And from member Henry Vander Leest, "Hi James, Was thinking about the comments you made at the meeting about the interview you had the the question about the code to make change. Well, here's my solution... I don't believe I could have written this in 5 minutes under stressful circumstances. Live Long and prosper."

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ChangeMaker1
{
    class Program
    {
        static void Main(string[] args)
        {
            //takes command line arg from 1 to 99 to make change for a dollar
            int quarters;
            int dimes;
            int nickels;
            int pennies;
            int tendered = 100;
            int cost = Convert.ToInt32(args[0]);
 
            int change = tendered - cost;
            quarters = change / 25;
            change -= quarters * 25;
 
            dimes = change / 10;
            change -= 10 * dimes;
 
            nickels = change / 5;
            change -= nickels * 5;
 
            pennies = change;
 
            Console.WriteLine("Quarters {0}, Dimes {1}, Nickels {2},  Pennies {3}, 
This is the change for item costing {4} cents",
quarters, dimes, nickels, pennies, cost ); } } }

I tested both, and they work like a champ. Now I just need to memorize these for my next round of interviews. So tell me, how would you do this “simple” exercise.

Time to work…

James

.NET Rocks is on the Road Again!

By James at March 18, 2010 03:46
Filed Under: Inland Empire .NET UG, Life in General

Man am I excited! Richard Campbell and Carl Franklin from .NET Rocks are going on the road again, and are making special plans to come out and visit the Inland Empire .NET User’s Group!

I’ve been working with – well he’s been doing all the work – Jim Barry at ESRI in Redlands to host the event there, and he has really come through for us. We will be having the event in the new Auditorium, which means the Inland Empire leg of the road trip will make all the other venues look like rickety old shelters.

(Update. I got so excited, I forgot the date)

Thursday, April 22, 2010 from 6:00 to 9:00-ish

Here’s a peek of what I’m talking about.

ESRI Auditorium

Go IE!

Here’s the “official” word from Richard and Carl…

.NET Rocks is on the Road Again!

Carl and Richard are loading up the RV and driving to your town again to show off the latest and greatest in Visual Studio 2010! And to make the night even more fun, we’re going to bring a rock star of the Visual Studio world to the event and interview them for a special .NET Rocks Road Trip show series. Along the way we’ll be giving away some great prizes, showing off some awesome technology and having a ton of laughs.

And one lucky person at the event will win “Ride Along with Carl and Richard” and get to board the RV and ride with the boys to the next town on the tour (don’t worry, we’ll get you home again!)

So come out to the most fun you can have in a geeky evening – and find out what’s new and cool in Visual Studio 2010!

Thanks Jim for all your help!

Keep an eye on http://www.iedotnetug.org/sf/dotnetrocksroadshow/ to RSVP for the event

Time to get planning.

About the author

James James is a five time and current Microsoft MVP in Client App Development, a Telerik Insider, a past Director on the INETA North America Board, a husband and dad, and has been developing software since the early days of Laser Discs and HyperCard stacks. As the Founder and President of the Inland Empire .NET User's Group, he has fondly watched it grow from a twice-a-month, early Saturday morning group of five in 2003, to a robust and rambunctious gathering of all types and sizes of .NET developers.

James loves to dig deep into the latest cutting edge technologies - sometimes with spectacular disasters - and spread the word about the latest and greatest bits, getting people excited about developing web sites and applications on the .NET platform, and using the best tools for the job. He tries to blog as often as he can, but usually gets distracted by EF, LINQ, MVC, ASP, SQL, XML, and most other types of acronyms. To keep calm James plays a mean Djembe and tries to practice his violin. You can follow him on twitter at @latringo.

And as usual, the comments, suggestions, writings and rants are my own, and really shouldn't reflect the opinions of my employer. That is, unless it really does.

James Twitter Feed

Recent Comments

Comment RSS

Month List