Friday, May 22, 2009

Limit the characters in a multi row textbox

The maxlength property to limit the number of characters does not work on a multi row text box. We have to rely on custom JavaScript to limit the MaxLength functionality. Here is a snippet that does that.

function ValidateCharCount(txtBox, maxLength,controlName) {
var input;
var length;

input = txtBox.value;
length = input.length;

var allowedLength = new Number(maxLength);
if (length > allowedLength) {
txtBox.value = txtBox.value.substring(0, allowedLength);
alert(" Only " + maxLength + " characters are allowed in the field " + controlName);

The function above takes three parameters. The first parameter is reference to the textbox control,second parameter is the max length of characters, third one is the textbox field description.
The function kicks in once the texbox loses focus, alerts the user if the character count exceeded the allowed length and then truncates the characters to the allowed length.


<input type="text" rows="5" id="Description" onfocusout="ValidateCharCount(this,100,'Description')" />

Digg It! Add to Stumble This

IF by Rudyard Kipling

I came across this beautiful poem by Rudyard Kipling which totally blew my mind away. The poem is simple to read and sums up the way one has carry himself in just a few stanzas.
Here it is in its entirety.


If you can keep your head when all about you
Are losing theirs and blaming it on you,
If you can trust yourself when all men doubt you
But make allowance for their doubting too,
If you can wait and not be tired by waiting,
Or being lied about, don't deal in lies,
Or being hated, don't give way to hating,
And yet don't look too good, nor talk too wise:

If you can dream--and not make dreams your master,
If you can think--and not make thoughts your aim;
If you can meet with Triumph and Disaster
And treat those two impostors just the same;
If you can bear to hear the truth you've spoken
Twisted by knaves to make a trap for fools,
Or watch the things you gave your life to, broken,
And stoop and build 'em up with worn-out tools:

If you can make one heap of all your winnings
And risk it all on one turn of pitch-and-toss,
And lose, and start again at your beginnings
And never breath a word about your loss;
If you can force your heart and nerve and sinew
To serve your turn long after they are gone,
And so hold on when there is nothing in you
Except the Will which says to them: "Hold on!"

If you can talk with crowds and keep your virtue,
Or walk with kings--nor lose the common touch,
If neither foes nor loving friends can hurt you;
If all men count with you, but none too much,
If you can fill the unforgiving minute
With sixty seconds' worth of distance run,
Yours is the Earth and everything that's in it,
And--which is more--you'll be a Man, my son!

--Rudyard Kipling

Digg It! Add to Stumble This

Monday, May 11, 2009

Debug classic ASP in Visual Studio 2008 with SP1

At work we still have some classic ASP applications. Visual Studio 2008 did not support classic ASP debugging until SP1. Once you installed VS 2008 SP1, follow these steps to debug classic ASP.
1) Enable ASP server side script debugging in IIS
a. To do this, launch IIS, right click on the virtual directory of your application, and click on properties from the context menu. Select the virtual directory tab from the properties windows. Click on the Configuration button in the application settings section.

b. In the application configuration window, select the debugging tab and make sure that enable ASP server-side script debugging is checked

2) From your visual studio 2008, launch the classic ASP application by pressing F5. Wait for the asp page to show up in the browser
3) Once the application is launched, go to Debug --> Attach to Process to launch the Attach to process window. In that window, click on the Show Processes for all users checkbox to show all processes.

4) In the list of available processes, select the process dllhost.exe with user name COMPUTERName\IWAM_COMPUTERNAME and click Attach.
5) Set a break point in classic ASP code you want to browse, the execution should stop at the break point

Digg It! Add to Stumble This

Saturday, May 09, 2009

Adding custom client side validation to controls inside GridView

Some times we find it necessary to provide custom validation to controls inside a GridView.
Recently I had to have a DropDownList for selecting a country inside a gridview, the country dropdownlist contains several items including an item with the text "Other". When "Other" is selected, a textbox should show up where in the user can provide the rationale for selecting "Other". Also, I had to make sure that the textbox is not left blank when "Other" is selected.

To Recap
Make sure that a value is selected from the country dropdownlist.
When "Other" is selected for country, show a textbox to show enter what the "Other" country is
Make sure that a value is entered in the textbox when "Other" is selected

First the GridView, for simplicity I'm just showing the country dropdownlist and the TextBox. Both those controls are included in a templatefield in the GridView
Leaving out the databinding details.

I also add an eventhandler for OnRowDataBound event.

<asp:GridView ID="grdSales" runat="server" OnRowDataBound="grdSales_RowDataBound"
<asp:TemplateField HeaderText="Country">
<asp:RequiredFieldValidator runat="server" ID="reqValCountry" ControlToValidate="ddlCountry"
Display="Dynamic" ErrorMessage="Country is required<br>" ValidationGroup="Country"></asp:RequiredFieldValidator>
<asp:DropDownList ID="ddlCountry" runat="server">
<asp:ListItem Value=""> --Select Country--</asp:ListItem>
<asp:ListItem Value="1">USA</asp:ListItem>
<asp:ListItem Value="2">Canada</asp:ListItem>
<asp:ListItem Value="3">Mexico</asp:ListItem>
<asp:ListItem Value="4">Other</asp:ListItem>
<asp:Panel ID="pnlOther" Style="display: none" runat="server">
Other:&nbsp;<asp:TextBox runat="server" ID="txtOther"></asp:TextBox>
<asp:CustomValidator ID="custValCountry" runat="server" ValidationGroup="Country"
ControlToValidate="ddlCountry" ClientValidationFunction="ValidateCountry"
ErrorMessage="Other is required"></asp:CustomValidator>

To meet the first requirement add a required field validator to ddlCountry drowdownlist.
For the second requirement, I need to add an onchange Event to the dropdownlist. In the event handler, I want to inspect the value selected and show the panel that contains the text box.
For the third requirement, I added a custom validator which calls a javascript function ValidateCountry.

Inside the grdCountry_RowDataBound event handler, pass the appropriate ids of the controls to the javascript functions.

protected void grdSales_RowDataBound(object sender, GridViewRowEventArgs e)
if (e.Row.RowType != DataControlRowType.DataRow) return;

DropDownList ddl = e.Row.FindControl("ddlCountry") as DropDownList;
Panel pnl = e.Row.FindControl("pnlOther") as Panel;
TextBox txt = e.Row.FindControl("txtOther") as TextBox;
CustomValidator val = e.Row.FindControl("custValCountry") as CustomValidator;

if (ddl == null || pnl == null || txt == null || val == null) return;

//Add an onchange event to the ddlCountry drop down list which is in each data row of the grid view
//The javascript function will take as parameters Ids of the drop down list and the div that should be shows/hid

string jsToggle = "TogleCountry('" + ddl.ClientID + "','" + pnl.ClientID + "')";
ddl.Attributes.Add("onchange", jsToggle);

//The custom validation control will validate the drop down list. If option Other is selcted, it checks
//if the txtOther has some text
//Here we are adding ids of the ddlCountry and txtOther as client attributes of the validation control
//These attributes can be accessed from the client side function to help in doing the custom validation
val.Attributes.Add("ddl", ddl.ClientID);
val.Attributes.Add("txt", txt.ClientID);

Finally the javascript functions
I'm using AJAX client side library here. If you are not using AJAX just replace $get with document.getElementById

function TogleCountry(ddl, div) {
var selectedIndex = $get(ddl).selectedIndex;
$get(div).style.display = 'none';
if (selectedIndex == 5)
$get(div).style.display = 'block';

function ValidateCountry(sender, args) {
var ddl = sender.attributes["ddl"].value; //These attributes are added to the validator in the rowdatabound event of the GridView
var txt = sender.attributes["txt"].value;

var selectedIndex = $get(ddl).selectedIndex;
var txtOther = $get(txt).value;

if (selectedIndex == 4 && txtOther.length < isvalid =" false;" isvalid =" true;">

Digg It! Add to Stumble This

Find the cause of poor performance in Sql Server

I found the following two part article by Gail Shaw on Simple-Talk really helpful in trouble shooting poorly performing queries in Sql Server.
The articles talks about spotting poorly performing queries with the help of the Profiler, understand Sql Server Query plans and fine tune the peformance using proper indexes.

Part 1:
Part 2:

Digg It! Add to Stumble This

Validating checkbox list in using JQuery does not provide in built support to validate a checkbox list. We have to rely on custom javascript to verify if at least one checkbox in the list is checked.

Since we cannot add a validator to the checkbox list, I usually put a dummy textbox on the form and add a custom validator to that textbox.

<asp:CheckBoxList ID="cblLostDescription" runat="server" RepeatDirection="Horizontal" TabIndex="14">
<asp:ListItem Value="L">Lost/Stolen</asp:ListItem>
<asp:ListItem Value="D">Destroyed</asp:ListItem>
<asp:ListItem Value="M">Damaged</asp:ListItem>
<asp:ListItem Value="O">Other</asp:ListItem>
<asp:CustomValidator ID="custValDescrption" runat="server" ErrorMessage="Property Description is required"
Display="Dynamic" ControlToValidate="txtPropertyDummy"
ClientValidationFunction="ValidatePropertyDescription" ValidateEmptyText="true"></asp:CustomValidator>
<asp:TextBox runat="server" ID="txtPropertyDummy" Width="1px" Style="display: none"></asp:TextBox>

Following is the client side validation function that we added to the custom validator. If we take a look at the rendered html, all The checkboxes in our list do not have the same id or name attribute.But all the ids start with the id we gave to the checkbox list. We can use JQeury to select the group of checkboxes whose ids start with a given text , then loop through the set and verify if at least one checkbox is checked. Make sure you have a reference to the JQuery script file on your page.

//Using JQuery, select all the checkboxes whose id begins with the
// checkbox list server control's ID.
function ValidatePropertyDescription(sender, args) {
var chkGroup = $("input[id^=<%=cblLostDescription.ClientID%>]");
//Loop through the set returned by JQuery
for (i = 0; i < chkGroup.length; i++) {
if (chkGroup[i].checked) {
args.IsValid = true;
args.IsValid = false;

Digg It! Add to Stumble This