Our Page Setup
Once you peer into our main .NET page, you'll immediately appreciate
the awesome power of .NET's code behind technology by noticing that there's
no visible client-side code! All you're seeing is a few standard server side
controls and our main custom Datagrid control tag. All of the main code responsible
for our application is hidden away in our code-behind code, implemented through
our @Page and @Register
directives.
Remember the old days of ASP? How many lines of code would your
page be typically filled with if doing the same thing? Lots and lots, right?
All jumbled together and messy. However in .NET, we instead have a total of
25 lines of code (which includes line breaks and stuff)! Now that's the amazing
thing about .NET!
Now when our example is ran, it'll utilize JavaScript to do all
sort of things, like focus the cursor in our main search box right on Page_Load.
We also have some JavaScript attached to our search button, our reset button
that clears our search criteria and our results, and finally a function that
will always reset focus back to our main textbox after each search.
This type of JavaScript of course may seem cut and dry; well
not quite. As we'll soon discover, that is simply is not quite the case, nor
so cut and dry as I'll explain. So before we get into actually creating our
control, we'll first examine some issues found with our textbox form field,
and its interaction with our custom Datagrid control within .NET.
We all know that the process of submitting text from a textbox
to a form is pretty straightforward. We type our text, then either hit return
or press the submit button; this is the typical scenario. However, here lies
the problem that I was just referring to, and really needs correcting. There
is an issue with .NET's Textbox server control,
that if the user decides to press the enter key from within the textbox containing
the same criteria, the form will not postback (as of v1.1 of the .NET Framework,
this does not seem to have been resolved)! Physically pressing the submit button
is the only way around this. Moreover, the Textbox's OnTextChanged
method or the AutoPostBack property can't help us either, unless again you modify
the text in some way. The result being we lose our initial Result No. X to X
stats; they simply reset to 0. Our previously fired event ceased to reinitialize!
At any rate, not be out done, with a little dash of JavaScript,
our issue quickly becomes a non-issue. Bear in mind the code below is formatted
to standard JS specifications. After my explanation of the code's function I'll
show you how it is implemented in our code-behind scheme.
So, our first step to resolving this is to add an attribute to our Textbox
control that'll trigger the JavaScript we need to call, once the user hits return.
We do this on Page_Load, like so:
srchTxt.Attributes.Add ("onkeydown", "getButton();");
Here we use our Control's Attribute.Add method that programmatically inserts
our JavaScript into the Textbox control's AttributeCollection object. After
this has taken place, the above issue if replicated won't occur. The client-side
JavaScript (compatible with both IE and Netscape) executes the getButton() function,
which simply grabs the users keystrokes, and handles the event. In turn, calling
the submitText() function once it detects the Enter Key was pressed, and clicks
our form's Submit button for us. Here is the JavaScript:
<script language="JavaScript">
var isIE;
if (navigator.appName == "Microsoft Internet Explorer"){isIE = true;}
function getButton()
{
//Capture Netscape events
if(!isIE) {
document.captureEvents (Event.KEYDOWN);
}
document.onkeydown = submitText
}
function submitText(evt){
var theButtonPressed;
if (isIE){
theButtonPressed = window.event.keyCode;
}else{
theButtonPressed = evt.which;
}
if (theButtonPressed == 13) {
if(isIE){
with(event){
cancelBubble = true;
returnValue = false;
}
}
document.getElementById ("Search").click();
}
}
</script>
Now getting back to our JavaScript code's location, it is all hidden away in
our datagrid.aspx.cs code-behind file. Implementing
this is done through another magnificent .NET method known as RegisterClientScriptBlock.
This method allows us to register client-side script blocks in our page from
behind the scenes.
The JavaScript above was discussed in clearer detail simply to show what is
being done. Adding this code to our code-behind file is done like so, similar
to the bare-bones example listed below:
StringBuilder jsScript = new StringBuilder();
string nl = Environment.NewLine;
jsScript.Append ("<script language=JavaScript>" + nl);
jsScript.Append ("function Hello() { " + nl);
jsScript.Append (" document.write ('Hello'); " + nl);
jsScript.Append ("}" + nl);
jsScript.Append ("</script>" + nl);
RegisterClientScriptBlock("clientScript", jsScript.ToString());
//Close our StringBuilder Object
jsScript = null;
Above we utilized the StringBuilder
class to concatenate and format our JavaScript code, and add a nl for our
line breaks, using the Environment Class's NewLine
member. We then call our RegisterClientScriptBlock method which will add our
code after our page's <form runat= server> element, and finally close our
StringBuilder object by setting it to null. Once you run the application and
view the page's source code, our client-block code will look exactly like the
standard JavaScript code we discussed.
Now returning back, one added note regarding the submitText() JavaScript function.
IE's event bubbling has to further be disabled,
alongside the value returned by our event, so it won't interfere with any other
elements higher up on the page, nor allow multiple actions to execute either.
Other server controls in our page are there to trigger events that'll interact
with our custom Datagrid control. We notice that both the search and reset button's
utilize the onClick method for their events, and needless to say, are completely
immune to the aforementioned JS behavior. Without complaint, they submit the
form and execute the Rebind_Grid method.
<asp:textbox id="srchTxt" runat="server" />
<asp:button text="Search" onClick="Rebind_Grid" runat="server" />
<asp:button text="Reset" onClick="Reset_Grid" runat="server" />
As an added note, our Rebind_Grid Method is also an important method in that it further demonstrates component-property assignment. This method is responsible for sending to our component our SQL query command and binding our datagrid by calling our custom control classes GetDataGrid() method. Finally, in our page we have our Stats Label server control that displays our Datagrid data/count statistics, and again all emanating from our complied control class. How all this occurs is going to be demonstrated later on.
<asp:label id="Stats" runat="server" />
But now that we've covered our initial .aspx page, and any known problems, we can now dig to our control's internal workings and everything pertaining to it.