Building a Solid Ajax Effect (Part 1)

Much is made about Ajax these days, and why not, when used properly it can effectively elevate your user experience to new levels and keep customers comings back. Furthermore, if you follow the principles of Ajax you can use to increase the availability of your site and its presentation by reducing load on the server thus giving the impression of a highly responsive website.

However, as with any good thing, its no silver bullet.  Improperly using Ajax and/or not understanding how users will interact with your site can drive them away as well. In a recent post, I highlighted the three tenants of Ajax: 1) Less is More, 2) Instant Feedback, 3) Synchronization.  I think its important, whenever developing a user experience that will rely on Ajax, to consider how your code deals with these tenants.  Recently, I added a means to support a many-to-many relationships for my data model using a pretty slick combination of MVC and JQuery and I decided to walk the process of how I validated the tenants.

So lets start with some background information.  My object model consists of three entities: 1) A series entity, 2) a genre entity, 3) a relationship object that supports a series and genre reference and the weight of that entry with respect to the series.DataModel

Lets briefly cover some of our goals for this process:

  1. The user should be able to easily and quickly add “n” Genres to the list
  2. The user should be able to easily delete the entries from the list
  3. The presence of an existing series ID may not be available if we are inserting
  4. We would like to keep all data pertaining to the base entity on the page (basically, we shouldn’t have to use two pages for this operation)

A few notes on the outcome of this effect:

  • We will not enforce distinctness for the entries on the client
  • We will not cover micro-linking a quick add (that will be later)

So some things to see right off the bad.  A web service to update things on the fly will not be acceptable due to condition 3.  We do not wish to duplicate HTML so we should try to use the same block container to reduce code duplication, this to me suggests well need a partial view.  So before we start trying to add our Ajax effect lets get the basics of the form, here is what mine looks like: InitialInterface2

This is very basic, I wont bother explaining it. So this is where we get to be creative and decide how we want to display this to the user.  Remember that we need to allow them to select a single genre (drop down list) and they need to be able to provide a weight. Now we could use a simple text box for them to enter a value, however, I would like to give the interface some zest so I will be using JQuery UI’s Slider control.  Below is my interface, note that I manually added a genre to test the initial load look and feel:

InterfaceWithGenres
(you will not see the slider position preset, this is done in part 2 via JavaScript)

So in this version I have added a dropdown containing all the available genres in the system.  The slider permits the user to easily choose a weight value for the genre as it relates to the series we are editing.  I have also added a delete image to the left of the drop down that we will wire up later.  Also I added a link for adding new genres inline.  Now here is the code for the Genres section:

   1:  <div id="genreContainer">
   2:          <%
   3:              foreach (var item in ViewData.Model.SeriesGenres)
   4:              {
   5:          %>
   6:              <div style="float: left;" class="genreSelect">
   7:          <% Html.RenderPartial("Series/GenreSelect", item, ViewData); %>
   8:              </div>
   9:              <br style="clear: both;" />
  10:          <%
  11:              }
  12:          %>
  13:      </div>
  14:      <a href="#" id="addGenre">Add Another Genre</a>

There is quite a bit going on here, some of which involves MVC and the magic it brings and thus an in-depth explanation of is outside the scope of this post so I will be brief in my summary of these things.

The first thing to look at is Line 2, simply know that ViewData.Model refers to an instance of the Series entity.  Thus we are iterating over each of the existing relationships and passing it to the partial view we are reading on Line 7.  The RenderPartial method allows us to include HTML from an existing View in a “parent” view.  It allows us to define the model that that “partial view” will use along with a ViewData object, so we pass both of these to the partial view.  The path to the partial view is a specific format relative to the folder in Views named for the Controller the Views directly belong to (its an MVC thing).

The following HTML/ASP .NET is found in the partial view:

   1:  <div style="float: left; margin-left: 10px; margin-right: 10px;
   2:      padding-top: 5px;">
   3:      <img src="../../../Content/images/00498f_11x11_icon_close.gif"
   4:               class="removeGenre" alt="Remove Genre" />
   5:  </div>
   6:  
   7:  <div style="float: left; margin-right: 10px;">
   8:      <%= Html.SelectBox("genres", (List)ViewData["Genres"],
   9:                           ViewData.Model.GenreId.ToString()) %>
  10:  </div>
  11:  
  12:  <div style="float: left; padding-top: 4px;">
  13:      <div class="slider" style="width: 200px;">
  14:          <div class="ui-slider-handle">
  15:          </div>
  16:      </div>
  17:  </div>
  18:  <div style="float: left; margin-left: 10px; padding-top: 3px;"
  19:          class="sliderLabel">
  20:      <%= ViewData.Model.Weight.ToString() %></div>
  21:  <%= Html.Hidden("weights", ViewData.Model.Weight.ToString(),
  22:                    new { @class="sliderValue" }) %>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

As you can see, we make full use of a variety of HTML helpers (note that SelectBox is a custom one that I wrote).  Notice how we use the ViewData.Model here to fill in and pre-select values.  Also, its very important to understand why we are using classes and names.

If you look at this code and remember the context it is being called in you will see that every drop down for genre selection is named: genres.  In fact, you will see that within this effect there are a lot of elements that share names and classes.  This will be crucial when it comes to access our data in the MVC controllers and from JQuery.

So with this we created a clean view that contains no JavaScript and properly loads our existing Genre relationships.

In Part 2, we will cover wiring up the basic effects using JQuery.

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Tip #1: Understanding Cryptic MVC Errors

Some who try to use the Entity Framework with MVC may encounter the following error:

CompileError

If you can see it the error reads:
CS0012: The type ‘System.Data.Objects.DataClasses.EntityObject’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

I spent a good deal of time trying to add this reference to the View. However, for some reason despite I had the assembly in my Reference folder in the Project, it was not in the web.config.  Add the following line to the web.config:

<add assembly="System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Once you add this and rebuild, the error should go away.

Thoughts on ASP .NET MVC Framework + Entity Framework

This weekend I decided to spend some time digging into the MVC framework.  Up to this point the majority of what I knew about it was based off my preexisting knowledge of MVC from Rails as well as what I heard; but I wanted to get a good look for myself.  In addition, I wanted explore methods of supporting the non-automated lazy loading in the Entity Framework. As a test bed for this I decided to start creating a simple data entry interface for my Anime Manager application that I previously wrote using Rails.

So let me give a brief overview of I organized things to permit the lazy loading from the Entity Framework to be fairly simple and contained to the controller.  In my previous attempts I would ended up having to persist the reference to the Context to the View which violates separation of concerns.  To prevent this I structured each Action as such:

   1:  public ActionResult EditSeries(int id)
   2:  {
   3:       using (AnimeManagerEntities Context = new AnimeManagerEntities())
   4:       {
   5:            Series series = Series.GetSeries(Context, s => s.SeriesId == id);
   6:            series.StudioReference.Load();
   7:            series.SeriesGenres.Load();
   8:   

9: ViewData["Studios"] = new SelectList(Studios.GetAllStudios(Context), "StudioId", "Name",

  10:                                                                          series.StudioId);
  11:            ViewData["Genres"] = Genres.GetAllGenres(Context).Select(g => g as IListing).ToList();
  12:   
  13:            return View("Series/Edit", series);
  14:       }
  15:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Notice that we are creating the context, passing it to our data methods, and the disposing of it via the end of the using construct.  The downside of this method is that its not really lazy loading since it is required that we know what will be used in the View and manually load the reference via the Load commands on Lines 6 & 7.  The problem with baking the lazy load into the entities themselves is A) the only good way is to modify the designer file which is overwritten each time we update our schema model. B) Because the using properly disposes of the Context our lazy loading is not able to attach to the original context, which appears to be a prerequisite for the Entity Framework.

I am still looking into this as I find this approach decent, but not what I am looking for. Thankfully, I was introduced to a gentlemen on the SQL team at Microsoft and so I have asked him what Microsoft recommends.

Regarding the MVC Framework, I decided to use Preview 5, even though our standard at RCM is Preview 4.  The reason for this was due to my requirements I needed to submit arrays of control values and Preview 4 did not support this, where Preview 5 did. The following is an example of capturing an array of control values:

   1:  public ActionResult UpdateSeries(int seriesId, 
   2:       string seriesName, int selStudio,
   3:       string[] genres, int[] weights)
   4:  {
   5:       // create the array of GenreWeight objects
   6:       var query = genres.Select((string g, int index) => new GenreWeight()
   7:       {
   8:            GenreId = int.Parse(g),
   9:            Weight = weights[index]
  10:       }).ToArray();
  11:   
  12:       if (Series.Save(seriesId, seriesName, selStudio, query))
  13:            return Index();
  14:       else
  15:            return EditSeries(seriesId);
  16:  }

This is accomplished my assigning the same name to multiple controls in a form (name=”genres” and name=”weights”). In this case I allow the user to add some template HTML via JavaScript which allows me to easily support the many to many relationship between the entities. I will have a post later on utilizing this sort of strategy for gathering user input.

The basic premise of the MVC framework is that you define your routes to get your users to an area of your site and then you create parameter names for the actions that match your elements name attribute value.  Overall, I have found MVC to be quite nice, though regrettably, given the scope of what I set out to do I have not yet leveraged it fully, although I can see quite a bit of potential for when I start to really construct the various screens for the Anime Manager.  More posts are definitely forthcoming.


 
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Using JQuery Load with MVC Framework

I decided to spend this weekend digging into the Framework and seeing how I could leverage JQuery features to create a better user experience.  One of the more notable things I have come across to this point is the use of the JQuery Load function in place of User Control string generation.

One of my favorite techniques for loading Server driven content via JavaScript is to create an ASCX with the appropriate HTML template and then load its HTML via JavaScript from a web service based request.  JQuery makes it very easy to append the HTML you get back and you can really encapsulate a lot of the heavy lifting inside the user control.

There really is no problem with this approach and I will still continue to use it for many things, however, with the routing mechanism that MVC offers you can greatly simplify the process by which this dynamic content is generated and gain greater flexibility for generating it.  Let me explain:

I wont give a long overview of how routing works, if your interested, I invite you to read this blog post by Scott Guthrie for more information.  Needless to say, I have a very basic routing setup with the following rule:

routes.MapRoute(
     "Default",
     "{controller}/{action}/{id}",
     new { controller = "Home", action = "Index", id = 0 }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

If we wanted to use the Action Link ‘/Test/EditSeries/14’ to follow this route, we can expect to create a method EditSeries in our TestController which takes a single parameter for the ‘id’.  The method would then designate which view to use once the controller method completes its execution.

As for applying this to the Load method provided by JQuery, we have to simply understand that Load will make an HTTP request which will invoke the routing.  Here is the JavaScript I am currently using:

$("#addGenre").click(function() {
        $("#genreContainer").append("
"
); $("#genreContainer").append("
"
); $("#genreContainer > .genreSelect:last").load("/Test/GenreSelect", null, function() { // setup the new slider SetupSlider($(this).find(".slider"), 0); SetupCloseIcon($(this).find(".removeGenre")); $(this).css("display", "block"); }); });

You will notice that I am passing a valid MVC routing path to Load, this will cause the routing to invoke the GenreSelect method of the TestController class.  I also defined GenreSelect.ascx in the same location as the View whose JavaScript is calling this “user control view”.  Thus my controller code for this operation looks like such:

public ActionResult GenreSelect()
{
     ViewData["Genres"] = Genres.GetAllGenres(Context);
      return View("Series/GenreSelect");
}

Notice how simple this code is, and this is all that needs to be done to prepare the “partial” view.

The basic premise of this posting is to show how you can leverage some of the automated content loading features of JQuery and the MVC routing system to simplify this sort of an operation. It also makes more sense given the premise of what we are doing.

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

JQuery and the Modern Web

Matt Brickner and I recently gave a Lunch and Learn session here at RCM on JQuery and its impact on the modern web.  The presentations primary goal was to introduce those who hadn’t seen JQuery to the syntax and what it can do, increase the awareness of solutions outside the standard Microsoft stack, and finally to get the ball rolling on revamping some of the methodologies and principles we develop web applications with.

JavaScript has a strange story to tell.  It was the subject of much ridicule throughout the early part of its existence and was considered to be a “dead” language prior to the rise of Ajax in the early 2000s.  Since then it has advanced considerably through the development of plugins, libraries, and frameworks.  So important is JavaScript to the Web 2.0 movement that we are seeing major companies like Google and Mozilla releasing new engines for processing JavaScript.  In fact, it may not be long till we see compiled and typed JavaScript.  A listing below describes the browsers and the code name of their JavaScript engines:

  • Chrome (V8)
  • TraceMonkey (Firefox 3.1)
  • SquirrelFish (Safari)

Along with JavaScript is the emergence of Semantic Markup design principles for HTML and the idea of Interaction Design as an integral part of the development design process.

Interaction design consists of designing how a user will interact with your website and being able to coherently label what should be Ajax and what should not.  Web 2.0 application cannot simply be considered prettier versions of their 1.0 counterparts.  Web 2.0 requires a change of thinking because the pages can do so much more and be so much more interactive.  For example, most people would agree that adding an item to a shopping cart should likely be done in an Asynchronous matter, however, if I click the ‘About Us’ link in your main navigation, should that be synchronous or asynchronous.

In addition, having a proper Interaction design process allows you to understand the interactive elements on your page and makes coding your JavaScript easier and more straightforward. It also allows for you to plan the degradation of your JavaScript should the technology not be available.  Depending on the feature you may choose to implement in also synchronously, or simply state that the feature is not available.  These are decisions that should be made during design and not as you are coding.

Interaction design obviously rests on Ajax and JavaScript in the end.  To that end, understanding how to properly implement Ajax based functionality is critical.  When I code up Ajax solutions I tend to follow the three tenants of Ajax:

  • Less is More
    • Ajax is designed as a means limit the amount of bandwidth the site is using. To that end, Ajax calls should only include what is absolutely needed for the service to carry out its task. And the service should only return what the JavaScript needs to update the view.  This is the primary tenant violated by the ASP .NET Ajax framework’s Update Panel
  • Instance Feedback
    • Since the operations you will be engaging in will not elicit the standard progress indication mechanism within the browsers. Most users are going to be looking for this. Communicating to them that something is happening is essential to creating a positive user experience
  • Synchronization
    • We should be transmitting data between the client and the server. However, the server should never be ahead of the client in terms of state and errors with storage on the server should be communicated and reflected on the client

Obviously there are some points here I am forgetting, such as the back button and history maintenance, but I want to leave those for ad-hoc conversations. The one point I do want to make is that, regardless of whether your client is thin or fat, expect to write a lot more JavaScript.  And face it, at least right now, not many people really enjoying writing standard JavaScript.  It is for that reason that frameworks exist, in any language.

JavaScript has many problems, from its long list of incompatibilities to the differing implementations of DOM traversal/manipulation between browsers.  Often times event he simplest operations require large amounts of code to get around type errors or account for browser variances.  This difficulty makes it hard to properly code JavaScript in an unobtrusive way.  Frameworks, like JQuery, are designed to address these problems, as well as bring structure to the JavaScript coding process.

Here at RCM we are making JavaScript a standard part of our development toolbox and including it on all projects where we can use it. We have even started researching and discussing patterns for development so we can create a standard look and feel for our JavaScript code to decrease ramp-up time for new team members.

So now that you understand why JQuery is important and why using a framework such as it is paramount in the modern web, lets look at some basic syntax examples:

$(".entry").css("color", "red");

This is a very basic example of JQuery.  We are using CSS definition notation to select elements.  This statement effectively says: select all elements whose use the class entry.  Set the color css style the value of red.  For ids its very similar:

     $("#lblName").css("color", "blue");

So in this case JQuery is doing the following: select the element whose id is lblName and set its color style to blue.  There is an important distinction here.  ID is singular, class is plural.  That means if you need to store something that you will be looping through, use a class, if its something that has one instance on the page, use an ID.

JQuery also makes it very easy to wireup events for elements.  The most common one you will see will be the ready event, which fires when the DOM is ready and is the most acceptable time to begin DOM manipulation via JavaScript.  A sample is below:

$(document).ready(function() {
   $("a.nav").each(function() {
      var elem = $(this);
      elem.bind("click", function() {
           alert($(this).attr("href"));
      });
   });
});

So this is a bit more complex, but it demonstrates the ready event as well as two ways to bind events to elements.  So to describe what this block does: When the DOM is ready select all with a class of nav and bind their click event to an anonymous function.  This function, when invoked, should look at the current linked being clicked and alert back its href attribute value.  Some important notes for this block:

  • ready event – fired when the DOM is ready.  Is the standard script initiation event in JQuery.
  • $(this) – refers to the current item the JQuery block refers to
  • attr – function to get/set attributes of the selected element
  • each – iterator statement to loop through an array of JQuery results

In addition to making DOM traversal and manipulation much easier JQuery’s core also boasts some great UI effects available right out of the box.  The block below demonstrates an example of collapsing a sibling via header text:

$(".header").click(function() {
     $(this).next().slideToggle("slow");
});

So here we look for all elements with the class header.  For each one in the listings we attach the click event so that when clicked it will look at its immediate downward sibling and slide it up or down depending on its present state.  This is a prime example of how you can achieve a highly attractive an interactive effect in JQuery is a few lines.  Some important notes for this block:

  • next – refers to the next sibling in the HTML.  Its counterpart is prev
  • slideToggle – combines slideUp and slideDown with statement management.  It take as a parameters: fast, slow, medium, or a numeric entry for the duration the effect should take

In addition to its proficiency with handling DOM traversal and maniulation JQuery is also fully capable of handling Ajax.  This is done, primarily, through the .ajax and .load functions.  .load is the jack of all trades enabling you to load a pages HTML content through Ajax.  This would be most useful for contextual switches within websites where you are loading pages in a template based design.  The following code block demonstrates this:

     $(".entry:first").load("HelloWorld.html")

This will basically load the HTML content of HelloWorld.html into the first element with the class entry.  Some important notes for this block:

    • load – takes a relative file path and delivers the HTML body content from the file if it is found

    • :first – JQuery selector specifier.  Designates to work with ONLY the first instance returned

    The alternative, and more low level, approach to performing Ajax is the .ajax function.  The following code block demonstrates using a web service to return XML:

    $.ajax({
       type: "POST",
       url: "BookService.asmx/GetBook",
       data: '{}',
       success: function() {
         alert("yeah");
       },
       error: function() {
          alert("bah");
       }
    });

    I am not going to dive in and talk about this in too much depth.  It should be clear what is being done. The only thing I want to make note of is the data parameters and how we are passing an empty object. Because we are working with Microsoft Web Services, this practice is required due to security considerations on the backend.

    So that explains some of the basics of JQuery and should give you some ideas on what you could do with this and how you could potentially use this to make your interaction code better.  I want to stress, however, that I dont see JQuery as a replacement for ASP .NET Ajax; merely an augmentation, a new tool in my toolbox.  The two can be combined quite successfully to form an application that can be developed quickly and easily with a high level of performance.

    To conclude, Web 2.0 is not just about Pastels and Rounded corners.  Its not about making an application using standard web technologies pretty. Its about understanding a new process for getting closer to the user.  Its about understanding and anticipating your user and deliver an experience that will keep them coming back.  The web has changed and the expectations our users have changed as well.  JavaScript is paramount for achieving the level of interaction that users and craving, clients are desiring, and developers are excited to provide. Frameworks like JQuery can make the implementation of the features very easy and clean by providing a rich and robust way of select elements and groups of elements in an unobtrusive fashion

    Interaction design will continue to be at the forefront of changing the way companies like RCM deliver our solutions. I believe the best way to move forward and take the next step beyond the simple adoption of JQuery is identify what processes you are having to do over and over again and encapsulate them into functions/libs supported by JQuery.  Again, having a standard framework like JQuery for all projects will reduce the amount of code you have to write as well as help people get ramped up on new projects faster: its a win win.

    I am including a zip file below here.  This contains the Power Point presentation and the application that was used to demo JQuery on the fly.

    http://cid-18f9d8896416d2fb.skydrive.live.com/embedrowdetail.aspx/BlogFiles/JQuerySampleDemonstratiion.zip

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    History’s Strongest Disciple: Kenichi

    Recently I decided to take a trip down memory lane and revisit an Anime series that I originally watched when I was studying abroad in Japan; History’s Strongest Disciple Kenichi (Shijō Saikyō no Deshi Kenichi).keinichi The reason I find this series interesting is because underneath the cover of fan service and some flashy effects, there is actually a decent story.

    The story begins with a focus on our main character Shirahama Kenichi, a lonely first year high school student who has trouble making friends and is bullied constantly. He longs to learn martial arts as a means to defend himself and the beliefs he wishes to uphold. One day while walking to school he meets a beautiful young girl named Furinji Miu. After seeking to defend her against the gangs of Ragnarok he learns that she is a master of mixed martial arts. She agree’s to take him to the dojo where her grandfather, Furinji Hayato, lives: Ryouzanpaku.  Coincidentally this is also the home of several masters of marital arts: 100th Level Black Belt Shio Sakaki, Death God of the Muay Thai Underworld Apachai Hopachai, Master of all forms of Chinese Kempo Ma Kensei, the Philosophical Jyujitsu Master Kouetsuji Akisame , Master of the handling of all weapons Kouska Shigure.

    Under their hellish (and comedic) tutelage Kenichi begins the train for martial arts. He eventually is able to overcome his first fight with a fellow classmate who bullies him in the karate club. However, upon this victory Kenichi comes to understand that people will want to challenge him constantly and from this point on he must train harder then ever to prepare for the ever increasing difficulty of the fights ahead of him.

    Eventually, through intense training and the confidence gained from victories and the lessons learned from defeats Kenichi begins to gain new allies as people start to find against untamed violence and for the sake of wanting to be at peace. Eventually the Shinpaku Alliance is formed with former strong members of Ragnarok at its core. In the final showdown Kenichi must face down his old friend Asamiya Ryuto who because of a promise made between the two (and numerous psychological issues) has become the leader of Ragnarok and intent on destroying any person he deems weak.  Their final fight is fierce and deadly by eventually Kenichi emerges the victor and a true testament that hard work can overcome talent in martial arts.

    The anime stops at this point, but the manga continues on exploring the organization that Ryuto’s master, Ogata Ishinsai is a member of (Yami).  As word begins to spread of this Strongest Disciple Kenichi, members of Yomi (Yami’s Disciple group) seek to kill Kenichi and take the title for themselves.

    This series has many aspects that I like, for one it has an underlying love story that actually shows potential to be fulfilled, unlike many of these “implicit relationships” we see in Anime that dont ever actually manifest themselves. Especially later in the manga when Kenichi must fight to protect a sick Miu against a far superior opponent. Additionally, the aspect of a normal person working hellishly hard to fight on equal ground with those who have talent is something that I think many people can relate to.  Many people have dreams, and sometimes they dont have the talent to accomplish through that alone, but many work hard to achieve their goal.  Kenichi is told many times, in particular by his Masters, that he has no talent for martial arts and that the only way he can and will advance is through hard work and believing in himself.

    The story flows pretty well throughout the anime with very few “filler” episodes in which nothing happens, aside from a couple fan service episodes that occur at random times throughout the series. I do like how near the end of the first story arc we find out that Ryuto, Kenichi, and Miu all met at one time long ago when they were young, it was a good way to give the final fight between Ryuto and Kenichi additional meeting, though frankly Ryuto clearly needs therapy.

    I really do hope that at some point a decision is made to create a second season for the anime as after reading the manga for the time after the fight with Ryuto it is a something I would love to see, so far at this time I have seen as high as 194 volumes of Kenichi that have been scanned into English.  I am up to 188 and I can say that the anime ended at volume 142ish which was roughly three volumes per episode which would only equate to about 17 episodes.  So my thought is they could be waiting until the manga is deeper to release the second season, though there has been no mention.

    In conclusion, Kenichi is a fine series so long as you are able to look past at some of its more cheesier aspects.  Its a good story about how hard work, determination, and having your head on straight can help you do good things. I think its a series worth watching and I hope us fans of the series will be rewarded with a second series of animation in the near future.

    Introducing LINQ to XSD

    As many of know, I am a huge fan on LINQ, and I regularly get to experiment with the various variants such as Linq to Entities, Linq to SQL, and Linq to XML. Among these I am most dissatisfied with Linq to XML due to the lack of type of safety within the queries.  The following is an example of a Linq to XML query as seen within the current release of .NET 3.5:

    var query = from bo in bookRoot.Elements("Book")
                select new Book
                {
                     BookId = int.Parse(bo.Attribute("id").Value),
                     ISBN = bo.Element("ISBN").Value,
                     Publisher = bo.Element("Publisher").Value,
                     Title = bo.Element("Title").Value,
                     Authors = (from a in bo.Element("Authors").Elements("Author")
                                select new Author() { Name = a.Value }).ToList()
                 };

    For the most part this query is alright, but there is something I would like to point out. This query is not typed. In fact, we are more or less guessing at where elements are within the document based on our pre-existing knowledge of the document. The reason for this is because XML, by its very nature, is not typed. This means that we have to make calls to do casting both on the values as well as the node groupings.

    If you recall, Microsoft’s chief goal for bringing the Linq syntax to .NET was to make querying a first class citizen within .NET and bring safe typing to those same queries. With Linq to XML they have certainly made building and retrieving XML easier and this can certainly work well with any type of XML document. However, what if we want a strongly typed version of this query.

    Linq to XSD (available here) allows us to accomplished typed XML querying by basing entity objects off an XSD. XML Schema Definition (XSD) is the standard meant to replace Document Type Definition (DTD) for defining the structure of XML documents and the types supported. Using Ling to XSD the above query could be rewritten as such:

    var query = from bo in books.Book
                    select bo;

    Much simpler right.  If you were to access the variable bo you would fine all the same properties as with the custom object construction above.  The type of bo is BookLocalType and is generated from reading the XSD file.

    To begin with you will need to download the installer, available here.  Once you install this, open up Visual Studio 2008, a new project type will be available, see below:

    projectSelect

    I am selecting LINQ to XSD Console Application, but as you can see there is three types available here.  Since its not yet backed into .NET you will not easily be able to use it outside of these project templates.

    Our approach here will be to create XML and then use the built in XSD generator to generate the XSD file.  Here is some of our sample XML, of course feel free to use your own:

    <?xml version="1.0" encoding="utf-8"?>
    <Books>
      <Book id="1">
        <Authors>
          <Author>Micheal Mahemoff</Author>
        </Authors>
        <Publisher>O'Reilly</Publisher>
        <Title>Ajax Design Patterns</Title>
        <ISBN>0-596-10180-5</ISBN>
      </Book>
      <Book id="2">
        <Authors>
          <Author>Micheal Howard</Author>
          <Author>David LeBlanc</Author>
        </Authors>
        <Publisher>Microsoft Press</Publisher>
        <Title>Writing Secure Code</Title>
        <ISBN>0-7356-1722-8</ISBN>
      </Book>
    </Books>

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: arial;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    Using the built in generate you get the following schema definition:

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="Books">
        <xs:complexType>
          <xs:sequence>
            <xs:element maxOccurs="unbounded" name="Book">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="Authors">
                    <xs:complexType>
                      <xs:sequence>
                        <xs:element maxOccurs="unbounded" name="Author" type="xs:string" />
                      </xs:sequence>
                    </xs:complexType>
                  </xs:element>
                  <xs:element minOccurs="0" name="Publisher" type="xs:string" />
                  <xs:element minOccurs="0" name="Title" type="xs:string" />
                  <xs:element minOccurs="0" name="ISBN" type="xs:string" />
                </xs:sequence>
                <xs:attribute name="id" type="xs:int" use="required" />
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: arial;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    You dont need to understand this syntax.  The next step is to right click on the XSD file in the Solution Explorer and select Properties. You will need to set the ‘Build Action’ of the XSD file to LinqToXsdSchema. The picture below shows:

    Properties

    Using this Build Action will generate our class files, although they will remain a part of the XSD file and not appear in the Solution Explorer.  The way to ensure they exist is to use the Object Browser, as such:

    ObjectBrowser

    If you see these classes (or similar) then you are now ready to program against them use Linq to XSD.  The download packages comes with a host of files for documentation and understanding.  The above query is a small sample.  At this point in time the library does not support defaults if elements are missing.  That is trying to access a property that is not defined within the XSD will result in an exception being thrown during enumeration.

    To conclude, Linq to XML is a fantastic means for querying and building XML documents in a very readable form.  Linq to XML allows us to represent the structure our document within code in a easy and concise manner.  However, because Linq to XML is designed as a generic means to work with XML it does not contain the means to be type safe like the Linq to SQL and Linq to Entities variants of Linq.  Linq to XSD overcomes this by utilizing an XSD file describing the structure of the document and what is expected.  This can be a powerful and clean means to reduce the amount of casting code your write.

    Linq to XSD is only Alpha at the time of this writing so its usefulness in production code is limited. However, I think this is an idea that could be very useful in the future.  I hardly think I am the only person who desires type safety in all of my Linq variants.

    Entity Framework and Entity LINQ : First Thoughts

    Recently over the last week I have had some time to get Visual Studio Service Pack 1 installed on my machine and a chance to play with the Entity Framework and Linq to Entities.  I had very high hopes for the Entity framework.  The ability to create custom mappings that could even span multiple database has the potential to make many of the difficulties that are faced when designing data oriented system obsolete. In addition, combined with the set manipulation powers of Linq we would be able to write cleaner more compact code that would still give us enough control to make the SQL as efficient as needed for the project at hand.

    Sadly, Microsoft has seemingly not delivered on all of these promises for the first version.  While I had no false aspirations that the support for spanning multiple database’s with associations would be in place, I had thought that the basic mapping support would be in place.  For example, if I have two Entities (Series and Studio) which are related via the foreign key relationship, that One Studio has Many Series, one would think that if I wanted to create a new Entity VerboseSeries which contained only the information that I needed (SeriesName and StudioName) you would easily be able to.

    However, after going around in circles for hours and reading as much as I can from the limited amount of information available from Microsoft I have not been able to find anything above the basics of using the wizard to automatically create the models.  Hence, I am forced to rely on the old means of adding custom properties to the objects represented by the modals: partial classes.

    The other thing that I have noticed is that to the uninitiated the Linq to Entity side of things is not quite as clear as it should be.  For example, give the scenario I described above with the two Entities (Series and Studio) one may be inclined to use Linq code from DLinq as shown below to retrieve the data:

    var series = from s in dc.Series
                 where s.StudioId == studioId
                 select s;
    However, with the EDM model it would look like this:
    var series = from s in em.Series
                 where s.Studio.StudioId == studioId
                 select s;

    Not as straight forward as the DLinq version in my book, though they both generate identical SQL with the minor difference being the join type (Entity uses a LEFT join and DLinq uses an Inner join).  I will leave it to the SQL community to decide which is the more efficient means of obtaining correlated information.  The upside to this is that from the basic example I created it would appear that Linq to Entity query generation is more efficient then Linq to SQL.

    Based on this information, I am still optimistic about the Entity Framework, though I am disappointed that it is so difficult to do even basic mapping.  I continue to have high hopes for the framework, though I certainly will not be recommending it over our framework anytime soon.  To help spread the knowledge I am including links to all the pages with information on the Entity Framework and Linq to Entities:

    I am hoping that I am merely doing something incorrectly which is causing me the level of difficulty I am experiencing with the mapper.

     

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    InfoPath 2007 Task Edit Form : Reading Responded Data

    Recently, I got the chance to get my hands dirty with SharePoint Workflow.  It was quite the challenge, in particular because of some oddities that, given all products were Microsoft based, I had a hard time understanding why certain things were so out of sync.  One of these was the reason that the XML transmitted on the update operation from the InfoPath Task Edit form was not a document, but rather a fragment.  And why the SharePoint API was ill-equipped to handle this.  In the end, as with many things within our solution, this required custom code to appease both InfoPath and SharePoint.

    Below is the code for completing this operation

       1:  XmlReaderSettings set = new XmlReaderSettings();
       2:  set.ConformanceLevel = ConformanceLevel.Fragment;
       3:   
       4:  using (XmlReader reader = XmlReader.Create(

    5: new StringReader(afterProperties.ExtendedProperties["TakeOwnership"].ToString()), set)

       6:  )
       7:  {
       8:       while (reader.Read())
       9:       {
      10:            switch (reader.LocalName)
      11:            {
      12:                case REMAININGDAYS_LOCAL_NAME:
      13:                     if (reader.Read())
      14:                          if (int.TryParse(reader.Value, out daysRemaining))
      15:                               reader.Read();
      16:                     break;
      17:                case ISTAKEOWNERSHIP_LOCAL_NAME:
      18:                     if (reader.Read())
      19:                          if (bool.TryParse(reader.Value, out isTakeOwnership))
      20:                               reader.Read();
      21:                     break;
      22:                case CHANGEREMAININGWORKDAYS_LOCAL_NAME:
      23:                     if (reader.Read())
      24:                          if (int.TryParse(reader.Value, out changeRemainingDays))
      25:                               reader.Read();
      26:                     break;
      27:            }
      28:       }
      29:  }

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    I choose this example because it also shows a means to parse out multiple values coming back.  The key to code is is Line #2.  We are telling the XMLReader that this XML is a fragment and not a whole document, which is the default expectation.  From there, knowing that the XML reader is a SAX based XML parser, we do reads checking various properties.  The logic is essentially as follows:

    • Perform a Read
    • Check the Local (tag) name
    • For a match, perform another read to get to the internal value
    • If the value is not empty and parses to what we expect, perform another read to get to the end element
    • When the loop comes back around, it will either be at the end of the document, or the next read will take it to the next element

    This is not the most efficient means to read this XML, but it does get the job done.  If there is no value passed, the Try call will fail. The code will continue to iterate until it comes to a node with a name it is expecting, at which point it will again try to read the value, or the document ends and the loop terminates.

    Minimalism

    This is more or less a rant on something that has always bugged me: cell phones. Perhaps not in general, or the way people use them (though that rant might be too long), its more or less about features, or the abundance there of. Let me explain.

    For some reason it has suddenly become necessary a phone to do everything, except go to the bathroom for you, though I suspect that day is not far off. As December approaches and many of the cell companies realize my contract with Verizon is up soon and theyll get a shot at me as a customer I constantly am asked what phone I want. I do take some amount of joy when I ask for a flip phone with NO features. Thats right nothing, I hate phones that make themselves out to be the swiss army knife of phones, yet cant even get a signal everywhere I go. For me its more important that I get service everywhere then my phone being able to play a movie off of YouTube.

    I have always said, if I want to watch a video I will wait till I get home and use one of my four computers. If I want to take a picture Ill use a real camera and not settle for trying to use my phone. I am a minimalist, but more then that, I am about being able to do something well consistently before you move on to bigger things. I try to do my job well so when I got to buy that TV I know Ill have a constant stream of money to pay for it. Before I create a fancy data access application, I learn how to do data access properly.

    Now I am not saying that phones should do nothing, I think GPS is quite interesting and I am sure the information you can get from the internet is useful in some cases, movies times, weather, etc. But I do need to see some guy breaking his nuts on skateboard on YouTube. We have devices for this which are far from complete, yet we seem to want to through everything together and worry about making it work properly later.

    Some may wonder about my commitment to technology, and as someone who works with technology everyday, I can find far more interesting things to worry about rather then what features my cell phone has and doesnt have. I just dont like being forced to buy what I really dont need. I would have no problem if a wide range of phones were kept around so that I could have a choice, but because Americans are so superficial and the retail industry is driven by demand, to buy a decent phone I have to spend $300 or be locked into some obscenely long contract with a carrier that could turn to be terrible.

    So right now I am searching the internet for my perfect phone – no camera, no mp3 capability, flip phone, gps and internet ready, and with a powerful attena, maybe Ill find a good one and Ill be able to avoid getting raped when I go to determine my new plan, cause I am not going with my current carrier