May 06, 2008

 Using JQuery DatePicker in ASP.Net

I've had a number of uses for a more configurable date picker on my current application.  I needed something that looked good, and I one that I could set constraints for (Min and Max dates).  That last problem basically made the AJAX Toolkit CalendarExtender out of the running.

Luckily I found the JQuery DatePicker.  This used be a separate download, you can find the original here, but it is now part of JQuery.UI.

But first, there are a few tricks to using it (or any other JavaScript control for that matter).  First things first, this is not a separate server control that replaces the text box with a date friendly text box.  This is a javascript library that extends a standard text box and gives it date functionality.

So the first thing you have to do is put a text box on your form.

<asp:TextBox ID="DateTextBox" runat="server" />




Next on my list is to add the DatePicker JavaScript file, ui.datepicker.js.  I still use the Microsoft AJAX Library which has the nice ScriptManager control, so typically I use that control to add my JavaScript files to the page.





<link rel="stylesheet" href="~\Scripts\ui.datepicker.css" type="text/css" media="screen"  charset="utf-8" />


<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">


    <Scripts>


        <asp:ScriptReference Path="~/Scripts/jquery.js" />


        <asp:ScriptReference Path="~/Scripts/ui.datepicker.js"  />


    </Scripts>


</asp:ScriptManagerProxy>




Note: I also included a link to the CSS file used to "skin" the calendar control.



Now everything is in place, we still  have to tell the javascript which text box control (DateTextBox) to put a Calendar control on.  I typically make a quick little JavaScript function that I can call to hook them up.  It looks like this:





function LoadDateControls() {


    $('#<%= DateTextBox.ClientID %>').attachDatepicker(); 


}




This code block asks the ASP.Net page for the ClientId of the text box control (very handy when dealing with Master Pages or User Control), and then attaches the date picker to the text box.



OK, the final bit of hooking up we have to do is call this function once the page is loaded and ready.  If we are using the Microsoft AJAX Library then you can use the pageLoad method like this:





function pageLoad(sender, args) {


    LoadDateControls();


}




If you want to stick with "pure" JQuery then you can do this instead:





$(document).ready(function() {


   LoadDateControls();


 });




Either way works, it is up to you which you like better.



JQueryCalendarSo lets review where we are now.  We have added the JavaScript to our page, and pointed it at a text box to display a calendar.  If everything has gone according to plan, you should see something like what you see to the right when you click on the text box.



I like it.  And as far as I know all of the colors and fonts are configurable via css.



OK, that covers most of my requirements, but there was one other requirement that isn't here yet: Min and Max dates.



This one is a little harder.  First we have to know what Min and Max dates to use, and that will have to come from the code behind.  Assuming you know that, you can call this C# code:





protected string MinDate;


protected string MaxDate;


 


private void UpdateDateRangeContols(DateTime minDate, DateTime maxDate)


{


    MinDate = EncodeJsDate(minDate);


    MaxDate = EncodeJsDate(maxDate);


}


 


public string EncodeJsDate(DateTime date)


{


    return date.ToString("U") + " UTC";


}




Now I have a MinDate and MaxDate fields that I can access from my aspx page.  To do that I'm going to rewrite my LoadDateControls function to look like this:





function LoadDateControls() {


 <%


    Response.Write("$.datepicker.setDefaults({dateFormat:'m/d/yy', minDate: new Date('"+MinDate+"'), maxDate:new Date('"+MaxDate+"')});");


 %>


    $('#<%=DateTextBox.ClientID %>').attachDatepicker();


}




One side effect of that bit of code is that I also use it to specify the date format.



But wait, did I really just use a Response.Write in my ASP.Net file?  Isn't that old school and lame?  Old school: yes.  Lame: no (if used in moderation).  I'm note writing an entire web site using Response.Write, just setting some JavaScript.  Besides, if you want to be one of the cool kids and start using the MVC framework, you had better get used to Response.Write again.  You're going to need it.



In my code behind, I set my calendar controls to only allow date entries that go back 2 weeks.  Take a look at what we get.



JQueryCalendar2



Today's date is May 6 (highlighted in pink), so my date range is April 28 to May 11.  When you are on the month of May, the Next button is disabled.  And, if I hit the drop downs for Month I only see April and May, and for Year I only get 2008.  Same for April, I can't go to March.



OK, so what if all of this is too much for you.  This is too much code, to much work, all you want is darn server control to use.  You are in luck.  Head over to West Wind Technologies and pick up Rich Strahl's JQuery Calendar ASP.Net Control.  Also subscribe to his blog, he is usually worth the read.

 Using JQuery DatePicker in ASP.Net

I've had a number of uses for a more configurable date picker on my current application.  I needed something that looked good, and I one that I could set constraints for (Min and Max dates).  That last problem basically made the AJAX Toolkit CalendarExtender out of the running.

Luckily I found the JQuery DatePicker.  This used be a separate download, you can find the original here, but it is now part of JQuery.UI.

But first, there are a few tricks to using it (or any other JavaScript control for that matter).  First things first, this is not a separate server control that replaces the text box with a date friendly text box.  This is a javascript library that extends a standard text box and gives it date functionality.

So the first thing you have to do is put a text box on your form.

<asp:TextBox ID="DateTextBox" runat="server" />




Next on my list is to add the DatePicker JavaScript file, ui.datepicker.js.  I still use the Microsoft AJAX Library which has the nice ScriptManager control, so typically I use that control to add my JavaScript files to the page.





<link rel="stylesheet" href="~\Scripts\ui.datepicker.css" type="text/css" media="screen"  charset="utf-8" />


<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">


    <Scripts>


        <asp:ScriptReference Path="~/Scripts/jquery.js" />


        <asp:ScriptReference Path="~/Scripts/ui.datepicker.js"  />


    </Scripts>


</asp:ScriptManagerProxy>




Note: I also included a link to the CSS file used to "skin" the calendar control.



Now everything is in place, we still  have to tell the javascript which text box control (DateTextBox) to put a Calendar control on.  I typically make a quick little JavaScript function that I can call to hook them up.  It looks like this:





function LoadDateControls() {


    $('#<%= DateTextBox.ClientID %>').attachDatepicker(); 


}




This code block asks the ASP.Net page for the ClientId of the text box control (very handy when dealing with Master Pages or User Control), and then attaches the date picker to the text box.



OK, the final bit of hooking up we have to do is call this function once the page is loaded and ready.  If we are using the Microsoft AJAX Library then you can use the pageLoad method like this:





function pageLoad(sender, args) {


    LoadDateControls();


}




If you want to stick with "pure" JQuery then you can do this instead:





$(document).ready(function() {


   LoadDateControls();


 });




Either way works, it is up to you which you like better.



JQueryCalendarSo lets review where we are now.  We have added the JavaScript to our page, and pointed it at a text box to display a calendar.  If everything has gone according to plan, you should see something like what you see to the right when you click on the text box.



I like it.  And as far as I know all of the colors and fonts are configurable via css.



OK, that covers most of my requirements, but there was one other requirement that isn't here yet: Min and Max dates.



This one is a little harder.  First we have to know what Min and Max dates to use, and that will have to come from the code behind.  Assuming you know that, you can call this C# code:





protected string MinDate;


protected string MaxDate;


 


private void UpdateDateRangeContols(DateTime minDate, DateTime maxDate)


{


    MinDate = EncodeJsDate(minDate);


    MaxDate = EncodeJsDate(maxDate);


}


 


public string EncodeJsDate(DateTime date)


{


    return date.ToString("U") + " UTC";


}




Now I have a MinDate and MaxDate fields that I can access from my aspx page.  To do that I'm going to rewrite my LoadDateControls function to look like this:





function LoadDateControls() {


 <%


    Response.Write("$.datepicker.setDefaults({dateFormat:'m/d/yy', minDate: new Date('"+MinDate+"'), maxDate:new Date('"+MaxDate+"')});");


 %>


    $('#<%=DateTextBox.ClientID %>').attachDatepicker();


}




One side effect of that bit of code is that I also use it to specify the date format.



But wait, did I really just use a Response.Write in my ASP.Net file?  Isn't that old school and lame?  Old school: yes.  Lame: no (if used in moderation).  I'm note writing an entire web site using Response.Write, just setting some JavaScript.  Besides, if you want to be one of the cool kids and start using the MVC framework, you had better get used to Response.Write again.  You're going to need it.



In my code behind, I set my calendar controls to only allow date entries that go back 2 weeks.  Take a look at what we get.



JQueryCalendar2 Today's date is May 6 (highlighted in pink), so my date range is April 28 to May 11.  When you are on the month of May, the Next button is disabled.  And, if I hit the drop downs for Month I only see April and May, and for Year I only get 2008.  Same for April, I can't go to March.



OK, so what if all of this is too much for you.  This is too much code, to much work, all you want is darn server control to use.  You are in luck.  Head over to West Wind Technologies and pick up Rich Strahl's JQuery Calendar ASP.Net Control.  Also subscribe to his blog, he is usually worth the read.

 April 30, 2008

 New Date and Time types in SQL Server 2008

I've been going through some of the new language features in SQL Server 2008.   The easiest to find are the new HierarchyID, sparse data columns, and brand spanking new date and time types.

I'm just going to (briefly) discuss the date and time types.

Start with new Date and Time types.  Not DateTime, or SmallDateTime (does anyone even use this type?).  No, separate Date and Time types.  I have no doubt these will make my life easier for a number of sql functions. 

You don't have to stretch your imagination far to find a use for the Date.  The Date type can take any date between year 1 and year 9999.  The DateTime can only go back as far as 1753.  Plus it only takes up 3 bytes (I'm not one to worry about things like that very often, but with large databases these things do come into play).

The Time type (no date allowed) is accurate up to 100 nanoseconds.  I say up to because it can be configured to be less accurate -- and take up less space (anywhere from 3 to 5 bytes).

Next comes the interesting one: DateTime2.  If you were wondering why we need a new DateTime type, there are two reasons.  DateTime is not SQL standard compliant, and DateTime is not completely compatible with the .Net DateTime type.  SQL compliance isn't a big concern for me, but better .Net compatibility is good.

So for details.  DateTime2 is basically a combination of the new Date and Time types.  The time portion is configurable again, and there are a lot of string formats that the DateTime2 will accept.  More interesting, the current guidance out of Microsoft for .Net developers is to stop using the DateTime type in favor of DateTime2.  This is mainly for the .Net compatibility. 

So why didn't they just make DateTime compatible with .Net.  Well, in databases, things just don't work that way.

Impact: But I still have a few questions about these types that are not answered as of yet.  In .Net we don't have dedicated Date and Time types, just a DateTime.  I can deal with the Date...but the Time will be interesting.   It will be interesting to see how LINQ to SQL, NHibernate, and SubSonic all handle these changes.

More info can be found on Ravi s. Maniam's blog.

 March 30, 2008

 What is Elegant Code to me?

This question keeps popping up around here ("around here" being the loose conglomeration that makes up the Elegant Code group).  It isn't easy to describe.  And really, the notion of what constitutes elegance in code changes over time.  There is no static "this is good code" test, and I doubt there ever will be.  Plus, what makes good code in one language, may not apply to the next.

So let me state for the record: today's elegant code is tomorrow's drivel.  Don't feel bad, many writers have the same problems.  What was super amazing back in the day is now rubbish or near unreadable.  I am thinking of the Victorian writing that Hemingway usurped, and now Hemingway himself is almost unreadable (to me anyway).  Tastes change with the times.  That is a simple fact.

So what can you do about this?  As I say that old writing sucks to read (read Washington Irvine lately?), great works of literature still abound (for instance, Hemingway is still a great writer -- even if I prefer Tolkien) .  So take some notes from them, and from other crafts in looking for the answer.  If you want a cliff notes version of what this is going to tell you, it is this: you must always push yourself to get better.

  1. Find a good teacher.  Nothing is better than sitting at the feet of a master who can nudge you along in the right direction.  While early mistakes can often be corrected easily with a little bit of guidance, after they have had some time to fester all bets are off.  I believe a fare number of "Anit-patterns" were created by self taught developers (find SQL Ejaculation on Elegant Code). 
  2. Read.   Good writer are first good readers.  Start with Code Complete, move into a good Patterns book, get MSDN Magazine, find some bloggers your like, but keep moving.  You will NEVER be done reading.  I imagine that even Martin Fowler has a "to read" booklist a mile long.
  3. Read code.   There are a plethora of open source project just waiting to be read -- do so.  This is the single best way to expand your coding repertoire, find things your language can do that you didn't even know about..   Scott Hanselman has recently popularized this idea, and I thank him for it.
  4. Practice.  This means writing small applications at home.  You get an idea that you want to try out -- do it.  I don't mean you have to write finished applications, just have some exploring time.  I remember talking with an 80 year old master woodworker (he lives down the street from me), who was telling me how many time he would practice making dovetail joints before he felt competent.  It was years worth.
  5. Pay Attention.  Being good at anything really amounts to that.  And don't just pay attention when reading, writing, or talking about code.  Inspiration come from everywhere, any good artist will tell you that.  Pay attention when you cook, when you work on the car, when you are wood working, playing an instrument, whatever it is that you do.  This will help you in the end, event if it is just learning the amount of dedication it really takes to become good at something.
  6. Beware of preferences.  Any time I hear someone start a statement with "I prefer code to ..." you know things are going downhill.  If you find someone who cares more about how your code is formatted then how it is written you have found yourself in a mess.  More importantly, beware of them in yourself.   Having code style standard is important, but it isn't worth loosing sleep over.  This also pertains to inheritance, patterns, use of particular classes (e.g. always using the generic list class in C# when a Dictionary would be better). 
  7. No Sacred Cows. Believe no single source of information.  This means not thinking that Microsoft, Sun, IBM, Richard Stallman, or anyone else will have all of the correct answers.  Apply the scientific method and do some research, experiment, and question the authority.   There should be no sacred cows in programming.
  8. Talk with others.  Join a user group, show up every now and then, heckle the presenter, and -maybe- speak.  You want a broad range of people who you can talk to and bounce ideas off of.  This will help you from becoming that crazy guy in the corner who vehemently states that all your code should be in one file.  Having a mentor (mentioned earlier) is great, but having people around to push you from multiple directions is also good.
  9. Learn languages.  This gets back to the "read code" idea. Make that multiple types of languages as well.  If you know C# or Java and SQL, learn Python or Ruby, get really good at JavaScript.  If you want something really out there, learn MDX.  This is also a repertoire thing.  Seeing how other languages work will make you rethink your ideas about what your current code, in whatever languages you are working in, should look like.
  10. Keep Thinking!!!  That is possibly the most important point.  Keep thinking.  Don't just evaluate something once and never return, go back and reevaluate. Did the technique work?  How could it have been better?   The idea is continual improvement.
  11. Switch jobs every now and then.  When I announced I was leaving my first programming job out of college, the VP of R&D had me sit down with him and talk.  He wasn't trying to keep me (he knew I was moving to be closer to family), he wanted to give me some advice.  He told me to change jobs every three years.  After you have been with a place for three years you have probably learned everything you are going to learn and it time to move on.  This doesn't mean changing companies either.  I've been with the same company now for four years, but I've had three different jobs.  If you have been writing commercial applications, become a consultant - or vise-versa, become a test engineer, expand your boundaries.  Again, this is about pushing yourself to be better.
  12. Have a Hobby. But don't ask about me, I have too many.   Creating software is about creating things.  So I suggest picking a hobby that involves creating something.  Popular hobbies amongst programmers I know include: cooking, music, woodworking, beer making, and BBQ (which is different than cooking).  But don't discount sports (golf is always popular), computer games, and board games.  Anything that promotes the development of skill levels can't be a bad thing.

And I'm stopping there.  This is my beginner's guide to how to become the writer elegant code.  If you have others you think I missed, add them too the comments.

 March 25, 2008

 ReSharper Value Proposition

I'm still one of those freaks that insists on having ReSharper around to code with.  When I go to a client, I ask (politely) that they get it for all of their developers.  When I talk at a user group I tell the attendees (not so politely) to get it.

But the one question comes up all the time: is it really worth it.  Then someone else will state how they don't even use the features that are built into Visual Studio as is.

You need ReSharper.  (note: if you are a CodeRush/Refactor user...carry on, it is also a fine tool)

Anyway, JetBrains just published a comparison matrix between ReSharper and naked Visual Studio.  For me, the value is in these areas: Navigation, Coding Assistance, and Unit Testing.  Everything aside from those is just gravy.  (personal TODO: record a coding session using Camtasia)

Check it out.

For myself though, that isn't the comparison I want to see.  I want to see a comparison between ReSharper and CodeRush (I'd do it, but I don't have the time).  This is a comparison where I expect no clear winner, but I know these tools differ quite a bit.

 March 24, 2008

 Boise is #2

I have been living in Boise, Idaho for the past 9 years now, and it has rarely failed to live up to my expectations (especially as a programmer).  Now Forbes seems to agree with me, recently ranking Boise as the #2 best place for Business and Careers.

http://www.forbes.com/lists/2008/1/bestplaces08_Best-Places-For-Business-And-Careers_Rank.html

In past poles, and in other magazines, Boise has also been ranked the best place for bicycles, and in the top 10 Tech cities.

Personally, I like the fact that Boise doesn't feel like a city (it does to the rest of my family, but my home town is only 2000 people).  I don't like cities, I don't like the "downtown" or "urban" lifestyle/feel.  I like to see nature and mountains, not buildings.  Having zoo and lots of parks is really nice though (we have an aquarium coming as well).  So, lucky for us, Boise can accommodate both types -- but New York/LA/San Francisco/Seattle it aint.

I do worry though, that Boise will get too big for me.  At some point I'll have to leave to get the smell out of my clothes. But even then, I don't see myself leaving Idaho any time soon.

 March 22, 2008

 Reflector Screen cast

OK, here it is: my first screen cast.  It is a short video on how to use Reflector.  Let the heckling begin!

Anyway, if you are a .Net developer and don't already have Reflector, get it immediately.  The only thing it will cost you is a one-time download.

Also, like I said, this is my first screen cast -- don't be kind.  I want to know how to improve.  I'll take any criticism aside from "you suck" and "change the sound of your voice". 

Things I learned doing this: getting an opening statement ready and a small script together is key.  If you've ever seen one of my presentations you know I rarely script anything, preferring to just wing it.  Also, my microphone picks up EVERYTHING!  The background voice are my kids.  I need to learn how to use Audacity and filter that out...or buy a better microphone.

http://video.google.com/videoplay?docid=-6159938059372574667
Download it

 March 19, 2008

 Hacking around IE6

OK, one think I hate is having specific code just to satisfy the gripes of one particular browser.  Right now that browser is IE 6.  Specifically, IE 6's (lack) of CSS support.

I was trying to have a transparent div that would cover the screen whenever an AJAX transaction was taking too long.  No problem, this little css class does the trick to my div:

.BackgroundCover {
    background-color:gray;
    opacity:0.8;
    filter: alpha(opacity=80);
    position: fixed;
    top:0px;
    left:0px;
    width:100%;
    height:100%;
    z-index:10000;
}

 

Visual Studio (2005 and 2008) complains about the opacity and filter tags, but oh well, it works -- except on IE 6. 

On IE 6, any div with this class will display correctly horizontally, but not vertically.  So I get a semi-transparent bar stretch left to right across the screen, but not filling the screen.

My solution, on IE 6 is to give up and not display that div.  Seems harsh, but that is what it has come to.  I know there is a JavaScript answer, I could probably wip something up with JQuery (that is what the Ajax Toolkit ModalDialogExtender does) but that is more trouble than this feature is worth.

So how to get rid of it without affecting the other browser (that support that bit of CSS correctly)?   Conditional Comments (and yes, I feel dirty for some reason).

Here is my new html:

<!--[if !IE 6]>
<div id="BackgroundDiv" runat="server" class="BackgroundCover" >
</div>
<![endif]-->
<div class="PleaseWaitPanel" >
Processing...
<asp:Image ID="PleaseWaitImage" runat="server" ImageUrl="~/Images/Progress5.Gif" AlternateText="Processing request" />
</div>



The [if !IE 6] detects if the current browser is NOT IE 6, and displays the html inside of it.  Simple as that. I don't like it, but it does work, and it isn't overly messy.

 Inline search for IE 7 (FireFox like search)

One feature that I love of FireFox is how FireFox handles searching the current page for text.  It opens a small toolbar at the bottom of the browser with a text box.  Then you type in what you want to find and hit Enter or F3.  At no point are you hampered from interacting with the page, and it will even highlight all instances of the text if you want.

IE, on the other hand, displays a dialog that keeps you from being able to interact with the page, it will only find one instance of the text at a time, and if you close the find dialog you have to start over from the beginning.

I finally found an IE add-in that fixes that: InlineSearch by IEforge.  It correctly recreates the functionality of FireFox and overrides the standard IE search dialog.

Simply beautiful.

 February 19, 2008

 My PodCast on Elegant Code

Some things are just weird, like listening to your recorded voice.  But that happens, you need to redo your answering machine message -- no problem, 5 minutes and your are done.

You can listen to it yourself: http://elegantcode.com/2008/02/18/elegant-code-cast-episode-3-is-online/

I just listened to my own voice for an hour.  It is one thing to be thinking "That is what I sound like" when it is only 5 minutes of pain.  Pain of realizing that everyone else has a very different impression of what you sound like.  But an hour of that beaten into your head, that is just cruel.

Then you start going through all of your old joke and impressions, wondering if they still work with your ACTUAL voice.  Do I sound that dumb?  Well granted, I'm not that smart, so who is to say on that one.

Anyway, we cover a lot of topics in a small timeframe.  The idea is to give enough exposer to a topic that a listener can look it up later.  And heck, that is what programming is all about these days anyway.