# Wednesday, 20 October 2010

We had a situation with one of our applications were the team felt it was easier to use straight html to do some work in a form.  All went pretty well until we created a checkbox input array:

<input type="checkbox" name="CheckboxArray" />
<input type="checkbox" name="CheckboxArray" />
<input type="checkbox" name="CheckboxArray" />
<input type="checkbox" name="CheckboxArray" />

and we retrieved them via the Request.Form(“CheckboxArray”).

image

We discovered when we tried to retrieve the array only the checked items were being returned and their position in the array is lost. 

image

Which ones are on? We can’t assume it’s the first and second one.

Solution:

Give the checkboxes a value that uniquely identifies it.

<input type="checkbox" name="CheckboxArray" value="1" />
<input type="checkbox" name="CheckboxArray" value="2" />
<input type="checkbox" name="CheckboxArray" value="3" />
<input type="checkbox" name="CheckboxArray" value="4" />

Now when you retrieve the array it returns the values of the checkboxes that are checked.

image

What if you want to return all the checkboxes whether they are on or off?  A little more work is needed in this case.  We’ll add a hidden field array for each of our checkboxes and will have these fields keep the status of our checkboxes.

<input type="checkbox" name="CheckboxArray2" /><input type="hidden" name="CheckboxFix" value="false" />
<input type="checkbox" name="CheckboxArray2" /><input type="hidden" name="CheckboxFix" value="false" />
<input type="checkbox" name="CheckboxArray2" /><input type="hidden" name="CheckboxFix" value="false" />
<input type="checkbox" name="CheckboxArray2" /><input type="hidden" name="CheckboxFix" value="false"/>

We’ll use jQuery to help with keeping the status.

<script type="text/javascript">
    $(document).ready(function () {
      $("[name=CheckboxArray2]").click(function () {
        $(this).next("[name=CheckboxFix]").val($(this).attr("checked"));
    });
}); 
</script>

Now in the code behind we’ll use the CheckboxFix instead of using the CheckboxArray2 in the Request.Forms call.

image

In our case we went with this second option because we were using jQuery on the client to enable the user to add, delete and reorder the rows of information.  Using the latter technique allowed us to easily work with the submitted data in a similar manner with the rest of the items in each row.

Happy Coding!

Posted 10.20.2010  #    Comments [0]  | 
# Wednesday, 29 September 2010

Our team is working on a UI facelift for an intranet application that helps drive our internal yearly budgetary process.  During the beginning stages of the development of this effort we hired a new webmaster and we invited him to the effort to help give our UI a nice finish with all the CSS goodness and jQuery goodies.

During this process our webmaster began using some CSS3 magic to make things look nice.  As most good webmasters and designers firefox was used as the start of the design.  For our intranet however, IE is king and we have a mix of IE7 - 8 and they don’t support many CSS3 features.  Our webmaster turned to CSS3Pie.  I had no idea about this little gem and he had just recently come across it.  Download it, write your CSS3 and apply PIE and magically Internet Explorer renders CSS3.

As an example of what it can do, what if you wanted to apply a nice rounded edge to an element.  Fire up VS 2010 and start a new web forms project.  Let’s round the edges of the bottom of the border in the default page.

image

Let’s edit the page element in the site.css to get this going.

.page
{
    width: 960px;
    background-color: #fff;
    margin: 20px auto 0px auto;
    border: 1px solid #496077;
    border-radius: 0px 0px 10px 10px;
    -moz-border-radius: 0px 0px 10px 10px;
    -webkit-border-radius:  0px 0px 10px 10px;
}

We’ve added three items. The W3C standard for adding a rounded border is border-radius but for backwards compatibility we add the –moz-border-radius for older versions of Firefox and –webkit-border-radius for older versions of Chrome.

Now fire these up in Firefox and Chrome and you will have your rounded corner.  If you are using IE however, no luck.

Firefox sample:

image

Now to make this magic happen in IE we sprinkle in just a dash of CSS3Pie.  After downloading CSS3 Pie add the .htc file to your project and then add the below line to your page element in the site.css file:

.page
{
    width: 960px;
    background-color: #fff;
    margin: 20px auto 0px auto;
    border: 1px solid #496077;
    border-radius: 0px 0px 10px 10px;
    -moz-border-radius: 0px 0px 10px 10px;
    -webkit-border-radius:  0px 0px 10px 10px;
    behavior: url('./Scripts/PIE.htc');
}

Fire up IE again and CSS3 rounded corners appear thanks to CSS3Pie.

image 

Happy Coding

Posted 09.29.2010  #    Comments [0]  | 
# Tuesday, 03 August 2010

I replaced all my buttons in my web application with the jQuery buttons widget to get a quick and easy look and feel going that was better than the drab stock buttons. It worked great and was simple.

Unfortunately, the login button was not changing until after I logged in successfully (hint!!!!).  I ended up spending far too long trying to figure out why it wasn’t working, even setting up a brand new project to “repeat” my results. I ended the day no better on what was occurring. duh

 

As a new day began I realized I had never even tried my app in Fiddler to see if it could give me a clue.  Besides taking a few minutes to remember why my localhost wasn’t being inspected, (Did I remember to add a . after the localhost? Of course not.) fiddler showed me the error of my ways quickly.

I had forgotten to allow my scripts folder access.  Duh!

 

 

fiddler

looser

Unfortunately, I imagine this situation is familiar to many developers. Spending way too long on a problem that once the answer appears we know we should have solved it a lot sooner. Here’s your slice of humble pie. Enjoy!

Moral of the story?  Lean on your tools and stepping away from the problem (or sleeping on it in this case) will almost always get you to the end faster.

 

 

 

Happy Coding!

Posted 08.03.2010  #    Comments [0]  | 
# Monday, 02 August 2010

Over the past week our team has been crunching out an asp.net webforms app to help manage our flood response situation that has been a very unfortunate side effect of the fire here in Coconino County.  We have been going pretty fast, releasing one to two updates a day in order to get functionality out quickly to those who need it.

Today, we had a breather and I decided to go back and spruce up our work.  One item on my plate was to help the users more easily enter dates.  The main entry form has over 10 date fields.  A little excessive but it’s what they need.  I could just use the AJAX calendar extender but that would mean quite a bit of clicking and properties to set manually.

I had a hunch that the jQuery way may have an easier solution.  Using Selectors, the solution ended up being one line of code.

<script type="text/javascript">
    $(function() {
        $("input[name*='dte']").datepicker();
    });
</script>

How awesome is that. All of our date inputs have a prefix of 'dte' allowing a simple selector over all inputs with 'dte' in the name attribute.  Normally, one would give all date inputs a class that can be use instead but they all already had this in common.

With the same idea in mind, I decided to change all of our buttons to use the jQuery button widget to get a nice and quick improvement on the look and feel.

<script type="text/javascript">
    $(function() {
        $(":submit, :button").button();
    });
</script>

In our case, we defined buttons two different ways in our code.  Again, with selectors we can handle this with one line of code.

Downloading and using jQuery UI couldn’t be simpler.  I customized the download (you don’t have to) to only use the date picker and button widgets and added the customized jQuery to a script tag.  jQuery UI depends on jQuery but instead of using the version downloaded I used the google CDN to help speed things up a bit.  Last, I added the theme for the controls to the app and referenced the stylesheet.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="scripts/jquery-ui-1.8.2.custom.min.js"></script>
<link href="~/stylesheets/jqueryUIcss/ui-lightness/jquery-ui-1.8.2.custom.css" rel="Stylesheet" type="text/css" /> 

The ability to do this so easily and quickly with jQuery is a big WIN.  I wonder if this is easily replicated with MS AJAX?  My hunch is it’s probably doable but can’t possibly be easier and I imagine it’s not nearly as easy.  I could be wrong though…

Happy Coding!

Posted 08.02.2010  #    Comments [0]  | 
# Friday, 08 January 2010

In a couple of earlier posts I used jQuery to add a character counter to the ASP.Net AJAX HTML Editor.  I was contacted by a reader stating that when they modified the editor’s toolbar items the character counter stopped working.  After a small bit of troubleshooting I noticed the toolbar items drive the number of IFrames created.

The fix is small but requires some sleuthing that we can do with firebug to identify the correct IFrame we should be targeting.  With firebug console and our browser open to the url for our application we can type in $('#Editor1').contents().find('iframe').eq(0).  This grabs the first IFrame.  Be sure to change "Editor1" to the name of your control.

FirebugShot1

If we hover over the item in the brackets it will highlight the IFrame selected.  If the text area for the control isn’t highlighted then change the index value and try again until the text area is highlighted.

FirebugShot2

To be sure we have the right IFrame, click on the item in the brackets and it shows the HTML.  Look for the text you typed in to be sure.

FirebugShot3

Now that we’ve identified the correct index for the IFrame based on a customized editor we’ll need to change the GetEditor Function with this correct value.

function GetEditor() {
    return editor = $(Editor1).contents().find('iframe').eq(0);
}

You should be ready to go now! But wait! There’s more…

I was dissatisfied with having to hunt for the correct index value and thankfully there is a better way.  I noticed while trying this out on several scenarios that the IFrame we want is given the same ID.  At first, I didn’t think this would work since the ID is assigned by ASP.Net but it seems in this case we can trust it (could be my famous last words).  The IFrame is always given an ID of ControlName_ctl02_ctl00 or in this case Editor1_ctl02_ctl00.

Armed with this we can change the code to:

function GetEditor() {
    return editor = $(Editor1 + '_ctl02_ctl00')
}

That's a little better. We don't have to hunt for the correct index value for the IFrame used for the text.

Please download the code and give it a spin! AjaxHtmlEditorV3.zip (1.01 MB)

Happy Coding!

Read the earlier posts.

Posted 01.08.2010  #    Comments [2]  | 
# Friday, 11 December 2009

In an earlier post I added character counting functionality to the ASP.Net AJAX HTML Editor with jQuery.  Soon after posting the entry I noticed that cutting and pasting text into the editor via the context menu did not change the character count immediately.  I enhanced the jQuery code in my last post to do this.

var Editor1 = '#Editor1';
var Editor1CountLimit = 50
var Editor1InfoArea = '#Info';

$(document).ready(function() {
    TrackCharacterCount(Editor1, Editor1CountLimit, Editor1InfoArea);
});

function TrackCharacterCount(ctl, limit, info) {
    var editor = GetEditor();
    $(editor).load(function() {

    var body = $(this).contents().find('body');
    var txt = $(body).text();
    $(info).html(txt.length); //set initial value 

    $(body).bind('cut paste', function(e) {
            setTimeout(function() {
                var txt = $(body).text();
                UpdateTextCounter(txt,limit,info);
            }, 150)
        });
        
        $(this).contents().keyup(function() {
            var txt = $(this).contents().find('body').text();
            UpdateTextCounter(txt,limit,info);
        });
    });
}

function UpdateTextCounter(txt,limit,counter) {
    if (txt.length > limit)
        $(counter).html(txt.length).css("color", "red");
    else
        $(counter).html(txt.length).css("color", "");
} 

I added the bind code on line 17 to handle the cut and paste functionality.  I went through a couple iterations of the cut & paste functionality to count the characters correctly.  I was running into an issue where the textbox value was not being updated immediately with what was pasted.  Then I stumbled upon a nice stackoverflow answer that used a timeout to wait for the textbox to be updated.  This little jewel allowed me to simplify the code to what it is now.

I refactored the code to decrease duplication of code by creating the UpdateTextCounter function. 

I also noticed a subtle difference between IE7 and IE8 that stopped the counter from working and have corrected that in this version with a browser check.

function GetEditor() {
    if ($.browser.msie == 'true' && $.browser.version == '7.0')
        return editor = $(Editor1).contents().find('iframe').eq(1);
    else
        return editor = $(Editor1).contents().find('iframe').eq(2);
}

I verified the code runs on IE7, IE8, FF 3.5.5 & Chrome 3.0.

Enjoy!

AjaxHtmlEditorV2.zip (1.28 MB)

Read the first post.

Read the next post where I fix a bug when using a customized toolbox with the editor and find a better way to locate the IFrame that our text editor is in.

Posted 12.11.2009  #    Comments [0]  | 
# Wednesday, 25 November 2009

I have been developing with ASP.Net since it debuted.  Before that I was doing windows form development with VB and classic ASP web development.  The advent of ASP.Net was phenomenal for me and my team.  The web forms model allowed our team to continue using the Windows event driven model over the web and allowed us to take our web development to a new level than classic ASP.  We quickly dispatched of our windows development in favor of the simple deploy / update model and gladly left the dreaded PC install / update nightmare.

Fast forward many years and ASP.Net matured quite a bit, Windows Forms had click once and all sorts of other goodies in the framework.  Now MVC.  My experience with MVC up until this point had only been my reading in the Gang of Four book and the occasional blog entry.  While all this was going on I had (and still am) been on a mission to improve my programming skills.  The majority of this was and has been reading, reading, and more reading.  I started trying out test driven development with a side project of mine.  The project was web forms based.  I was greatly encouraged with TDD but had read all the difficulties with TDD and web forms.  I had just begun this side project and decided why not make the switch to MVC?  So I did.

Along the way, I have had a lot of  "aha" moments.  Here’s some of them:

Web forms code behind faked me out. I thought I had good separation of concerns. Or I really abused the code behind file but I thought I was doing right.

For quite a while I knew large code behind files were not healthy.  I had been working as best as possible to decrease the code in them.  However, with my MVC journey I think I have come to see just how unhealthy large code behind files are and just because the code was not in the same file as my html did not mean I had a strong separation.  MVC by it’s nature encourages good separation and all the books and blog entries I have read show this by default.  In the web forms world I had to seek this out (not so much today but definitely in the early days and habits can be hard to change).

I’m having data source withdrawals and View State withdrawals.

I’m nearly over it now but this was a big hurdle for me.  It’s amazing how reliant I became on this but it shouldn’t be too much of a surprise since this is the magic of Web Forms. 

I'm loving having control back of the HTML and the HTML is actually readable now.

This is definitely has been a pleasant return to HTML for me.  With web forms I went on autopilot for much of the HTML / JavaScript that my apps produced.  I just lived with it even when I saw disgusting and bloated source.  Many took great pains to make web forms bend to their HTML will and I certainly understand why.  For me though, this is one of the reasons I like web forms so it didn’t bother me much.

So why would I want the control back.  Simple, because I can easily have it back now and the trade off to me doesn’t really feel like a trade off.  MVC is far more bare bones by design but I still don’t feel like I am back at the classic ASP spaghetti code.  It’s this bare bones nature that I am really digging.  I have a lot more control over everything and even though I may not want to control a lot I know I have the option to.  I do miss at times the "drag and drop a control unto the canvas and go" mentality but with jQuery and HTML helpers I am missing it less and less as I become more proficient.

Hello, JavaScript. It's been a while since we last worked together.

With web forms, I enjoyed the luxury of not having to really getting down and dirty with JavaScript.  I used everything at my disposal to use a control and/or post backs to handle what was needed and only used JavaScript when I needed to.  Mind you, I realized this came with a price of some nice user interactions but I was willing to pay that price.  JavaScript and the DOM specifically were always giving me fits. 

Unfortunately, this experience in the long ago past blinded me to the wonderful things going on with JavaScript over the years.  With JavaScript libraries like jQuery the capabilities that once required a JavaScript and DOM wizard are now at your fingertips.  I have fallen for JavaScript and am ashamed I had closed my mind off to it for so long. 

MVC by it’s nature encourages JavaScript for rich UI interaction much like controls did for Web Forms but so much more.

Testing? Ya, I did that. It's F5 right?

MVC was not my start on considering better ways to test but everything I read and worked with on MVC had testing involved all the way.  Every book I have read, every beginning MVC blog entry has testing intertwined.  My first attempts at unit testing was with a web forms project and I was absolutely convinced it would make me a better developer, faster developer and create more maintainable code.  However, with web forms, testing for me and many I suspect was changing some code and hitting F5 to run the application and manually test.  With a little unit testing / TDD under my belt I have come to see how much more efficient it is to "F5 testing". 

MVC permeates with the idea of unit testing and that’s by design.  I have much to learn on my testing journey but it has already paid dividends for me that has me convinced it’s an important tool in my toolset.

I am working in harmony with the HTTP protocol now.

I mentioned one of the reasons I liked web forms is that it allowed me a very easy transition from windows forms development.  As much as I would like to say I understood how the web really worked underneath the hood I know now that I didn’t.  Yes, I knew it was stateless and all that jazz but with web forms I was abstracted away from the way the web worked. 

When I started learning MVC it became painfully obvious how much I had forgotten and/or didn’t really understand about how the web works.  I am still tripping over this while I continue my MVC journey but I am happy to say that the knowledge gained in understanding more deeply how the HTTP protocol really works is making me a better web developer.  “Working in harmony” is a paraphrased quote from "Pro ASP.NET MVC Framework" by Steven Sanderson.

I am enjoying my MVC journey and look forward to becoming extremely proficient with it.  I will also admit that much of my 'aha' moments are not because of Web Forms, rather they were mainly a result of my own lack of exploration into what was possible and what was out there.  I was too busy keeping my head down and firing out widgets instead of really trying to hone my craft at all times while spitting out widgets. :-) This has changed for me now.  I have an extremely strong desire to be a real craftsman and not just someone who can bang on a keyboard.

Web Forms is a great tool and I imagine I will continue to have it as a tool in my toolset for a long time to come along with MVC.

Posted 11.25.2009  #    Comments [0]  | 
# Saturday, 14 November 2009

Recently, one of our ASP.Net WebForm app’s had a new requirement for formatted text entry. No problem, the HTML Editor control from the AJAX control toolkit would fit the bill nicely.

In this new version, we were asked to show the count of characters used as a user types and enforce a maximum character count allowed.  Unfortunately, the HTML Editor doesn't have anything built in to give this information and it's a conglomerate of many controls such as iframes and hidden text area's that make this a slightly less than trivial task (at least it felt that way initially).

After some thought on this and seeing a lot of great stuff from jQuery I figured it was up to the task. It didn't disappoint.  Here's what I came up with.

var Editor1 = '#Editor1';
var Editor1CountLimit = 50
var Editor1InfoArea = '#Info';

$(document).ready(function() {
  TrackCharacterCount(Editor1, Editor1CountLimit, Editor1InfoArea);
});

function TrackCharacterCount(ctl, limit, info) {
  var editor = $(ctl)contents().find('iframe').eq(1);
  $(editor).load(function() {
      var txt = $(this).contents().find('body').text();
      $(info).html(txt.length); //set initial value 
    $(this).contents().keyup(function() {
      var txt = $(this).contents().find('body').text();
      
      if (txt.length > limit)
        $(info).html(txt.length).css("color", "red");
      else
        $(info).html(txt.length).css("color", "");
     });  
   });
}

My HTML looks like this:

Info

When the document is ready we call the TrackCharacterCount function that takes the ID of the HTML Editor control, then the character limit, and last the element you want to have the character count displayed in.   Be sure to replace these parameters with your values.  

The second iframe contains the contents of the text typed.  The iframe contains a document and the text we are after is in the body tag.  I did some jQuery spelunking in firebug’s console to figure this out.  I added a little touch to have the div element turn red if the user goes over the limit passed into the function. 

In order to enforce the maximum length allowed, I set a custom validator to call the below function.

function ValidateEditor1Length(source, args) {
  var editor = $(Editor1).contents().find('iframe').eq(1);
  var txt = editor.contents().find('body').text();
  var isValid = txt.length > 0 && txt.length <= Editor1CountLimit;
    args.IsValid = isValid;
}

Some jQuery goodness I found along the way.  My first attempt at counting the characters retrieved the entire HTML (used .html()) and then removed the HTML with a regular expression.  It was a little later that I found .text() which simply returns all of the text without markup.  Thank you jQuery!!!!

Here’s a shot of what it looks like before they go over the limit:

HTMLEditor1

And after the go over the limit…

HTMLEditor2

Now, I’m not a jQuery wizard.  In fact, this is my first jQuery foray and I am extremely impressed with jQuery so far.

AjaxHtmlEditor.zip (1.28 MB)

Read my second post where I add functionality to capture the context menu’s cut and paste.

Posted 11.14.2009  #    Comments [0]  |