Readonly Input Controls with jQuery

Recently I had need for some visible input controls that were read only but where their values could still be posted with the form. Since I am working in an ASP.NET MVC project and not submitting this particular form asynchronously I wanted the model binding to bind the values of these fields. Typically there are two ways to accomplish having an input control that can not be edited.

The first of two ways is to use the disabled attribute. When disabled="disabled" an input element is visible but unable to be edited. Some browsers style these controls with a grey color to denote their inability to be edited, and some do not. Disabled controls do not post their values back when the form is submitted.

    //Apply the disabled attribute
    $('#myTextBox').attr("disabled", "disabled");

    //Remove the disabled attribute
    $('#myTextBox').removeAttr("disabled");

The second approach is to use the "readonly" attribute. I found that browsers do not style a read only control with the same grey color as some do with disabled, so I also applied a css class to the control. The value of a control with a "readonly" attribute set to true will still post values back.

    //Apply the readonly attribute and greyBackground css class
    $('#myTextBox').attr("readonly", true)
        .addClass("greyBackground");

    //Remove the readonly attribute and greyBackground css class
    $('#myTextBox').removeAttr("readonly")
        .removeClass("greyBackground");

DevConnections 2011 Summary

All in all the team did a great job putting together DevConnections. The location was nice (even though the Florida weather did not cooperate), the layout was good, the schedule wasn't too grueling and the people were enjoyable. My main complaint is that I had to search too hard to find coffee, but I guess that is minor when it comes down to it.

While all the sessions were informative and well presented (save a couple, *shudder*), my favorites were The Architect by Juval Lowy, MVC Best Practices and LINQ in Multi-tiered Apps both by Scott Allen. Both of them have a very fluid presentation style and articulate the topics well. If you have a chance to attend any session by either of them I would highly recommend it.

My Hiatus Is Over; New Job Summary

I still need to port my old posts to blogger, but going forward I will be posting here. I have started my new job and finally getting settled in. I accepted a position as an application developer for David Weekley Homes. What an amazing company. I have been here for 4 months now and every day something happens that reminds me that I made a great choice.

There are multiple apps to maintain here, and plenty on the horizon. The general purpose is to support and simplify the jobs of the team members in the field. Until you get into this domain you may not realize how many moving parts there are. Sales People, Warranty Reps, Builders, the list goes on and on. Not to mention the profit margin on a house can be greatly effected by so many factors; Waste, turn around speed from dirt to sale, market conditions, agility to provide what customers want in a timely fashion. It really does keep my brain churning night and day with all of the possible enhancements and additions to our suite.

As for the code, there are some pretty extensive opportunities to refactor the code base. Most of the .NET apps were written as 2.0 was new, many of the practices used are hold overs from 1.1 and it shows. That's not to say the developers are/were not talented, just that they were handcuffed by their own understanding at the time. Paradigms have shifted greatly in the .NETosphere since this code was written.

Hopefully I will be disciplined enough to post some nuggets every once in a while, if not then just as easily this serves as my very own FAQ blog.

Rendering a Partial View in a foreach loop

Sometimes we get requests for views that can make your code look like a big ball of crud. The ones where we get "I want to see ALL orders by every single user AND each order should have the details of what they ordered under it!!!! That would be awesome, everything in the whole database back in one page so I don't have to click ever!". Alright that's a bit of an exageration, but I did recently need to have a view that displayed a list of each order and then for each order a sublist of each of the order item details as well.

This is not a big deal, but it started to make my View difficult to read with all the foreach loops in it. So I decided to investigate using partials to break it up a bit. ASP.NET MVC's Html.RenderPartial helper has an overload that allows you to pass in the object model. This gives us freedom to do things such as:

Our main view which takes an IEnumerable of Order:

foreach (Order order in Model) {
Do what we want here...
}

A partial view called OrderItemList which takes an Order:

foreach (OrderItem item in Model.OrderItems) {
Html.Encode(item.Description)
}

Now, in our view we can replace "Do what we want here..." with:

Html.RenderPartial("OrderItemList", order);

The overload takes a second argument of the type of object model we need for the partial. This takes our main View from having multiple foreach loops to having one that then calls in the partials. It will also help us apply DRY principals as we can reuse the partial views over and over and take a more modular approach. If they come back and ask for multiple items again you can take partial view A and partial view B and pull them together to get the information you need.

ASP.NET MVC Drop Down List In View Model

While using custom view models I was looking to dynamically drive a drop down list of US States that my users could choose from.  I didn't want to pass a SelectList directly into the ViewData, but rather have it populate in the constructor of my view model and then pass that view model into the view for consumption.

Sidenote: I ran into a problem that I have not had time to fix yet.  I am using Castle for my IoC and want to pass in an IStateRepository to my view model, but kept receiving an error that the object does not have a constructor that takes zero arguments, so for now I have just newed up an instance of my StateRepository.

I have two properties in the EmployeeViewModel:

public string state { get; set; }
public SelectList states { get; set; }

My EmployeeViewModel takes an Employee object from my domain model:

public EmployeeViewModel(Employee employee)
{
state = employee.State;
statesDropDown = new SelectList(stateRepository.GetStates(), "StateName", "StateName", null);
}

And then to use the html helper provided with ASP.NET MVC:

<%= Html.DropDownList("State", Model.States) %>

The first value passed into the html helper should be the name of the property on your custom view model housing the current value that the employee has for state. This will allow for your drop down list to be pre-selected when the drop down list renders.

To use the selected value on your controller you can use it like any other form input:

public ActionResult EditEmployeeAddress(EmployeeViewModel model)
{
...

It's an easy way to keep my users from introducing spelling errors.