Combobox != DropDownList

January 10th, 2009

I am currently working on a fairly involved interface to administer data for a system that I built at work. In order to streamline the process, I am working on elements that allow users to select existing items for supporting data or create a new option inline. For some of the more involved elements, I am working out inline forms; for simpler items that can be captured as a single field of input, I wanted to use a combobox element. This is a web application and I am a big fan of jQuery, so I decided to look for a plugin that would give me the combobox functionality I was after.

What I found was a bit surprising. I found several pages of Google results that showed a fundamental lack of understanding around the term combobox.

Most of the information and plugins I found were basically replacements or enhancements for the HTML Select element. The select element gives you a dropdownlist of pre-set options to choose from. The plugins that I found were nice and offered some benefits over the standard select element, but they were not comboboxes.

The “combo” part of the name is short for combination. A combobox is the combination of a textbox and a dropdown. It should allow preset options while still allowing for a new value to be entered as plain text.

My guess is that if you are reading this, you knew this already, but maybe not. Maybe if, like me, you thought this was common knowledge, it will save you some of the surprise when you encounter it.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Andrew Back to Basics , ,

Change Object Owner in SQL Server

September 21st, 2008

When creating a new object in SQL Server while logged in using windows authentication, the object belongs to your username by default. I seem to forget this all the time and end up needing to change the owner of the new object to dbo. This is simple to do, yet I always end up having to search for the exact name of the stored procedure that does this. This post is for my future reference, hopefully it’ll help somebody else too (maybe even you).

To change an object’s owner all you need to do is run:

sp_changeobjectowner 'tablename', 'dbo'

Replace “tablename” with the name of the object you need to change and “dbo” can be changed to another owner if needed… I find that I am usually making the change to dbo.

Hope this helps somebody else.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Andrew SQL Server , ,

New Pics on Flickr

September 19th, 2008
Riverfest Fireworks

Riverfest '08 fireworks

I have uploaded a bunch of new photos to my flickr account. It was long overdue, so there are quite a few new photos now.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Andrew flickr ,

ASP.NET MVC and Unobtrusive Ajax with jQuery Part II

September 18th, 2008

In my last post, I introduced this series in which I add Ajax to an ASP.NET MVC application as a progressive enhancement, allowing the site to function without requiring JavaScript, but creating a better user experience for users with JavaScript enabled. In this post, I will discuss the feature I am working on and introduce the base controller and view code as well as introduce a minor change to the initial controller code to add support for Ajax calls/return data without breaking the standard post-based behavior.

The Target Functionality

The functionality that we will be looking at for the purpose of these posts will be a simple content page that allows comments. The comment form will exist on the content page and will call a controller that will then insert a record in the database. Since the comments live on the page with the associated content, the controller will redirect to the view that the form was submitted from (showing the content again, along with the comments). The page will be reloaded, just as you would expect from a typical form submission that redirects following the submission. Once that works, we can update the code to make the form submit via Ajax, at which point we will need to update the page through client script.

The Initial Code

The initial code is a simple controller action which makes a call to a business object that will handle inserting the comment into the database. I will be displaying a code comment as a placeholder for that code since it has very little relevance to the topic at hand.

[AcceptVerbs("POST")]
public ActionResult AddComment(string commentBody, int articleID)
{
//Logic and Database insert code...

//redirect to re-load the page
return RedirectToRoute("Default",
new { controller = "Article",
action = "Show",
id = articleID });
}

At this point, since the View for our content will re-query and display all of the associated comments all that this code needs to do is redirect the user back to the content page and the new comment will be loaded along with the rest of the comments. The above code accomplishes this redirect in a single line of code.

Updating The Controller Action

Now that we have the form in the view successfully submitting its content to the controller action through a post, we need to update the action code to distinguish between a standard post and an ajax-based post in order to return JSON when needed. One of the goals was to make any controller changes minimal. We also want to make sure that none of the business logic changes due to the addition of Ajax. So let’s take a look at the code for the first step:

[AcceptVerbs("POST")]
public ActionResult AddComment(string commentBody, int articleID, string mode)
{
   //Logic and Database insert code...

   //redirect to re-load the page
   return RedirectToRoute("Default",
      new { controller = "Article",
            action = "Show",
            id = articleID });
}

The only change we have made at this point is to add an additional string argument to the method’s signature. This “mode” argument isn’t part of the original form post, and that’s ok. Our form doesn’t need to change. The only time (at this point) the mode value will be passed is when we are making the call from JavaScript. Now we will add a simple check to see if that string has been passed. If it hasn’t been passed, then we know it was a standard post and we will perform the redirect, just like we have been doing:

[AcceptVerbs("POST")]
public ActionResult AddComment(string commentBody, int articleID, string mode)
{
   //Logic and Database insert code...

   if (!string.IsNullOrEmpty(mode) && mode == "ajax")
   {
      //handle json result for ajax call
   }
   else
   {
      //redirect to re-load the page
      return RedirectToRoute("Default",
         new { controller = "Article",
               action = "Show",
               id = articleID });
   }
}

Now all that’s left to do is return JSON formatted data if the mode has been passed. The final version of the controller action is listed below.

[AcceptVerbs("POST")]
public ActionResult AddComment(string commentBody, int articleID, string mode)
{
   //Logic and Database insert code...

   if (!string.IsNullOrEmpty(mode) && mode == "ajax")
   {
      //The comment object is returned after the data insert above
      return this.Json(comment);
   }
   else
   {
      //redirect to re-load the page
      return RedirectToRoute("Default",
         new { controller = "Article",
               action = "Show",
               id = articleID });
   }
}

This code includes a call to the Controller’s Json method (referenced as this.Json) which accepts your data object (in our case, a comment object that was returned from the omitted data insert code) and returns a JsonResult object that can be returned from the controller. The passed object is then made available to your JavaScript when it receives the Ajax result. We will take a closer look at the comment object in the next post, when we add the JavaScript that will trigger the JsonResult object being returned.

This controller action meets our goals of using the same logic regardless of the method that was used to post the form and I think the changes are fairly minimal (again, this is pretty subjective).

Coming Up

We still need to add the jQuery code required to make an Ajax call to the controller and ensure that there is a return value. After we have the code in place to make the call and run the controller code, there will be a couple more posts to explain how to handle the return data and add some other nice UX features for those with JavaScript enabled.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Andrew .NET, ASP.NET, Ajax, JavaScript, MVC, jQuery , , , , ,

ASP.NET MVC and Unobtrusive Ajax with jQuery Part I

September 15th, 2008

I have recently started developing a website using ASP.NET MVC (preview 5). One of the things I love about the MVC framework is the total control I have over my markup. I can keep the HTML clean, use ID values that make sense and won’t change each time the page is rendered and I can add all of my own client-side interactivity using jQuery (without the id mess that web controls create).

One of my goals with this new site is to create a functional site that works and renders in a usable manner even with CSS and JavaScript disabled. In order to do this, I have been creating all of the required interactions using standard get and post operations. The next logical step is to add Ajax functionality as a progressive enhancement using jQuery. Since ASP.NET MVC is still pre-beta, there isn’t a lot of documentation or published best practices with specifics about how to best handle this through the framework. I have read several posts from others with different solutions, they range anywhere from routing hacks (including ajax or html in the url) to seperate views (one standard view and an ajax enabled view). None of the solutions I have found have been what I wanted to do, so I set some goals for how I wanted it to work and through a process of trial and error, I have a solution. Through the next couple of posts, I will outline how I am handling this. I look forward to any feedback (good or bad) and if somebody has a better solution, please let me know.

The Goals

  1. Site should work in an acceptable manner without JavaScript enabled
  2. The same view should handle both Ajax enabled and standard post/get operations
  3. All controller code should be run in either scenario except for returning the ActionResult
  4. Changes to the controller action signature should be minimal and the same approach should work for any controller action (with minimal change)

Some of these goals are no-brainers, it helped to have all of the goals in place to keep myself from creating a massive amount of “Franken-code” in order to get the site working. I also realize that using the word “minimal” when talking about code changes is subjective, so if you don’t think what I have done is minimal, feel free to comment on the posts that contain the code and we can discuss it, please just share something more than “your solution sucks…” that won’t help anybody. And, if you have any other goals that you think I shoudl keep in mind, please let me know. I can’t promise that I’ll be able to attain more than I have already planned for in this series, but if something that I haven’t thought of seems important enough, I will do my best to try to meet the new criteria.

Upcoming Posts

Stay tuned. I have the code worked out for the most part, but it hasn’t been fully implemented, so I will be posting as I make more progress and I have tested enough to feel confident that I will have working code. I’m hoping to get the first post that has any real substance out before the end of the week.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Andrew .NET, ASP.NET, Ajax, JavaScript, MVC, jQuery , , , , ,

Alternating Item Styles In The ASP.NET ListView Control with jQuery

September 15th, 2008

In my last post I demonstrated how you could simply add alternating CSS styles to a ListView control without the need to duplicate your markup in an AlternateItemTemplate. This was accomplished through server-side code using the DataItemIndex to determine which style to apply. This time, we will look at how simple it is to apply the same effect using jQuery on the same simple markup that I used in the last post. I have removed the DataItemIndex related code and we are now left with this markup:

<asp:ListView ID="lvPeople" runat="server" ItemPlaceholderID="plcItem">
   <LayoutTemplate>
      <div id="people">
         <asp:PlaceHolder runat="server" ID="plcItem" />
      </div>
   </LayoutTemplate>
   <ItemTemplate>
      <div>
         First Name: <asp:Label runat="server" ID="lblFirstName" Text='<%# Eval("FirstName") %>' /><br />
         Last Name: <asp:Label runat="server" ID="lblLastName" Text='<%# Eval("LastName") %>' /><br />
         Age: <asp:Label runat="server" ID="lblAge" Text='<%# Eval("Age") %>' />
      </div>
   </ItemTemplate>
</asp:ListView>

With the markup in place, I have added a reference to the jQuery library in my page like so:

<script language="javascript" type="text/javascript" src="jquery-1.2.6.js"></script>

Now all that’s left is to add a little bit of jQuery code and we can apply our alternating css classes.

<script language="javascript" type="text/javascript">
   $(function() {
      $("div#people div")
         .filter(":even").addClass("even")
         .end().filter(":odd").addClass("odd");
   });
</script>

It’s that simple. The code listing above was broken out onto multiple lines, but could just as easily have been written in one single line, I prefer the format above for readability, but that’s just me.

The jQuery code selects all divs that are children of the wrapper div (identified with the “people” id attribute) and runs a filter that only returns the even items. It then adds a css class called “even” to those divs. The end() method then returns scope back to the first selection containing all of the child divs. The second filter runs just like the first, only this one returns the odd items and aplies the “odd” class to those divs.

If you haven’t used jQuery before, I suggest you check it out. It makes selecting items and then manipulating them simple and in a pretty intuitive way (IMHO). If you don’t think it looks easy, try writing code to do this without the aid of a JavaScript library such as jQuery, make it work across browsers and then decide if this way isn’t easier.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Andrew .NET, ASP.NET, JavaScript, jQuery , , ,

Alternating Item Styles In The ASP.NET ListView Control

September 15th, 2008

If you have used the asp.net listview control, you know that you place your output elements in between the ItemTemplate tags. You may or may not have noticed that there is also an AlternateItemTemplate tag that can be used to render every other item differently. This is great when you want to alter the layout of every other item, but if you just want to apply a different CSS class on alternate items, you will be duplicating a lot of markup for a fairly minor change. Well, I have good news, there is an easier way. All you need to do is look at the DataItemIndex for your data item, determine if it is even or odd and apply the appropriate css class. The code is pretty self-explanatory, so here it is:

<asp:ListView ID="lvPeople" runat="server" ItemPlaceholderID="plcItem">
   <LayoutTemplate>
      <div id="people">
         <asp:PlaceHolder runat="server" ID="plcItem" />
      </div>
   </LayoutTemplate>
   <ItemTemplate>
      <div class='<%# Container.DataItemIndex % 2 == 0 ? "even" : "odd" %>'>
         First Name: <asp:Label runat="server" ID="lblFirstName" Text='<%# Eval("FirstName") %>' /><br />
         Last Name: <asp:Label runat="server" ID="lblLastName" Text='<%# Eval("LastName") %>' /><br />
         Age: <asp:Label runat="server" ID="lblAge" Text='<%# Eval("Age") %>' />
      </div>
   </ItemTemplate>
</asp:ListView>

The key is this line of code:

<div class='<%# Container.DataItemIndex % 2 == 0 ? "even" : "odd" %>'>

This allows alternating styles without duplicating your markup, which makes changing the item layout in the future much easier. You could also accomplish this with some javascript (in a line or two using jQuery) but that is a topic for another post.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Andrew .NET, ASP.NET ,

Wordpress for iPhone

July 22nd, 2008

The wordpress app for the iPhone was just released. I’m using it to write this post. The app is pretty nice. I wouldn’t expect any code samples or wordy posts coming from my phone since my texting skills are pretty weak, but it’s a nice app for when blogging on the go is required. The built in access to categories, tags and the live preview are very impressive.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Andrew Tools, Writing , ,

UI-Patterns.com

July 22nd, 2008

I’ve been visiting the Yahoo! Design Patterns Library periodically for the past couple of years, but somehow I only now managed to stumble upon UI-Patterns.com. It’s always good to have another resource to help create better user experiences, so I’m glad I found it. The site is very well organized and cleanly designed, making it enjoyable to use (just as you would expect from a site that focuses on UI/UX). If you do any work that involves a UI, you should check out this site.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Andrew Tools, Usability , , , ,

The ASP.NET DropDownList Hates Me

July 22nd, 2008

It must, or I wouldn’t have spent nearly as much time over the last few days fighting with it as I have. He started it!

Ok, maybe it was slightly my fault that I’ve been having the issues I’ve been having. Maybe my expectations were just set too high. I figured the DropDownList could handle whatever I threw at it. I was wrong.

So I found myself in a position recently where I needed a DropDownList to allow users to select an item based on a search. So the workflow is a bit like this:

  • User enters a search term into a textfield
  • User clicks search
  • Resulting items are displayed in a DropDownList for selections
  • User selects appropriate item from DropDownList and moves on

Now, based on the search term, there is a good chance that multiple items in the list will have the same underlying value attached to them. That’s ok, it’s what is expected of the system. This allows the user to make their choice based on the display and still give the application the value that it needs to get the job done. This seems like something that should be reasonably easy to do, and at the beginning, it was.

The search returns its items and binds them to the DropDownList. No problem. The user can select an item in the list as part of the form completion process and submit the form. The value can be picked up on the server and the app can do what it needs with the data. Also, no problem.

At this point, there hasn’t been a problem. The problems arise when you go beyond simply binding a list of values and having that field as part of a larger form. Let’s look at each problem seperately.

The first problem arises when the form is bound to an exsiting record. When binding the form, the options that were available in the list for the initial selection will be populated again. This puts multiple items in the DropDownList and in this scenario, there are multiple entries with matching values (but different text). Now as part of the binding process, text fields are set, checkboxes are checked and an item (prefereably the correct one) needs to be pre-selected in the DropDownList based on our record. To account for this, the display value from the selected item is stored as well (strictly to put the selection back in this scenario). So we pull the display value since those are unique and use that to find our desired item. Set the returned item to selected and we’re set. But we’re not. Even thought we have picked the item based on a unique property and we know that in the code-behind, only one item was selected, the page will result in an http error letting you know that you cannot select more than one item in the DropDownList. Removing the other items from the list prevents this, but it is not ideal since the original options should be available during an edit operation.

The second problem occurs when you want to perform some operation based on the DropDownList changing. Typically, you would attach a SelectedIndexChanged event handler to the DropDownList and then set its AutoPostBack property to true. So, when I needed this functionality, I followed those steps and it worked. It worked until there were items with matching values in the list. Once that happened, changing the value would cause a postback, but would not trigger the SelectedIndexChanged event handler. I worked around this one with a Page Method and some client-side ASP.NET Ajax code. Again, not an ideal use for my time.

So why are these tings happening? Well, based on everything I have seen happen here, I have to say that the value of each item is important and probably should be unique. In my opinion, the event and method names lead you to believe that it is looking at the Index, or that you can select an item based on picking the right ListItem object. Apparently, at some point, the value needs to be used to complete the setting, change detecting, etc. so it should be treated as a unique key.

My situation is not the most common way to use a DropDownList, but I can’t imagine that I’m the first person that needed to do something like this. Oh well, I’ll come up with a better way to handle the UI in situations like this in the future.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Andrew .NET, ASP.NET