DennyDotNet

Awesome ASP.NET C# and other cool coding stuff

About the author

Denny Ferrassoli
Developer at Casting Networks. MCP / .NET
E-mail me Send mail
Add to Technorati Favorites

Recent posts

Recent comments

Authors

Categories

None


Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

UpdatePanels: When and Where

I've been using the ASP.NET AJAX Update Panels for quite some time now and have picked up a lot of tips on when and how to use them. Update Panels were intended to allow the developer to do Partial Page Updates. Usually what you see is Update Panels updating nearly the entire page which completely defeats the purpose of Update Panels!

Here are some good tips to take into account when developing with Update Panels:

#1. One thing I notice is that people want to stuff all their functionality into one page with multiple hidden/visible panels. Then utilize the functionality by showing/hiding the panels based on actions within the page. This can lead to very confusing code...

If you're changing from one action which does a lot of functionality with X to an action which does a lot of functionality with Y then separate the functionality and use a page postback to switch between those pages. Don't throw everything together into one update panel and separate it by hidden panels. You'll end up with a ton of code which is not resuable and difficult to understand. Separate your functionality just like you would separate your DAL, BL and Presentation.

Example for an Admin section:
  • User Management (insert, update, delete users)
  • Settings (change your web app's settings)
  • Media Management (insert, update, delete media)
  • etc...

#2. Separate your Update Panels. Instead of throwing everything into one update panel break it up! Plan what areas of your page will need to update and what will trigger them to update. This will save you an insane amount of bandwidth (and download time) and return much better performance.

Example:
Lets say you have 3 areas on your page that will allow a user to: select a category, select a video and then watch the video.

  • Part 1 displays a list of categories
  • Part 2 displays a list of videos within that category
  • Part 3 displays a video player

Lets think logically about the flow of execution with the 3 parts. First a user picks a category in Part 1. Then they select which video they want to watch in Part 2. And finally the video displays in Part 3 and begins playing.

So there are 2 steps involved to watch a video:

  1. Pick a category
  2. Pick a video


And 2 triggers:

  1. "Click" a category
  2. "Click" a video



(Each arrow represents a click)

So we've got the basic idea down now how do we determine WHERE we need update panels? We need to determine what parts change. The only parts that change are Part 2 which shows a list of videos within the selected category and Part 3 which plays the selected video. Part 1 will not change because nothing within that part changes. Part 1 is only used to select a category and the categories are loaded at Page_Load.

(Of course if you added paging or sorting to Part 1 you could then use an update panel but for this example Categories are static.)

So you have 2 parts that change meaning you only need 2 update panels, one for Part 2 and one for Part 3. Now how do we trigger these updates? Based on the flow we determined above we know what triggers are needed...

Triggers:

  • Part 2 needs to update when a category is selected from Part 1.
  • Part 3 should update when a video is selected from Part 2.

We also want to hide the video player when the user selects a new category because it wouldn't make sense to continue showing a video from the "Comedy" category after they selected the "Drama" category. So we'll need one more trigger:

  • Part 3 should update when a category has been selected since we don't want to display the old video when they select a new category.


(Each arrow represents where the item is triggered from [start of line inside part] and what part it affects [end of line])

And that's all we need to properly separate our update panels. The cool thing about upate panels is that your trigger control does not need to be within the same update panel. In other words, it can be located anywhere on your page outside the update panel. That's why we only need 2 update panels. The triggers in part 1 can be set programatically or through the update panel "triggers" GUI from the properties menu.

Quick Tip: If you want to know how to set a trigger programatically then read this post.

What's the benefit of separating the update panels? Alot of Bandwidth! Update panels respond with their entire rendered contents when doing an AJAX call. Update panels also attach any control viewstates to the response. If you were to place the entire content of the example above in one update panel you'll be uploading and downloading everything every time you do a callback. On the other hand if you separate your update panels, like the example above, you'll only download the contents of the update panel that has been triggered.

Quick Tip: If a control within an update panel does not need viewstate enabled then disable it! This is a good way to decrease the size of the response.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by SuperGhost on Thursday, August 30, 2007 9:19 AM
Permalink | Comments (1) | Post RSSRSS comment feed

JavaScript Model Objects (JMO) - An Idea

A rough prototype of what I like to call "JavaScript Model Objects" or JMO for short.While playing with ASP.NET AJAX I came across an idea of using AJAX, JSON, and JavaScript to bind data onto page elements. So today I decided to play around and try to create a "repeater" but on the client-side. This is the gist of the idea...

#1. Get the data which I want to bind using AJAX and JSON.

Example JSON data: 

var myTestObj =
{
            "rows":
                        [{"id":1, "title":"Test one", "imagesrc":"images/ajax.gif", "isTest":true},
                        {"id":2, "title":"Test two", "imagesrc":"images/playmini.gif", "isTest":true},
                        {"id":3, "title":"Test three", "imagesrc":"images/playmini.gif", "isTest":true}]
}

In this example the JSON data must have "rows" with an array of the row columns/values.

#2. Define the template that I want to bind to. This is defined directly on my HTML page.

Example:

<table>
            <tr id="JMO1">
                        <td style="border: solid 1px black">!id!</td>
                        <td style="border: solid 1px black">!title!</td>
                        <td style="border: solid 1px black"><img src="!imagesrc!" /></td>
                        <td style="border: solid 1px black">!isTest!</td>
            </tr>
</table>

As you can see I have a table with 4 columns. I want to bind to the TR object so I give my TR an id. The places where I want the data to appear are surrounded by exclamation points, like !<name>!. Also notice that I have given the TR tag an ID of "JMO1" which I will use to pass to my binding function. The TR tag is essentially my "Model Object."

#3. The functions to bind the data to my model object... Please note this is a very rough sketch of the functionality, and yes I am using jQuery:

function initJMO(modelObj, dataObj) {    
        var obj = $(modelObj);
        var data = eval(dataObj);
        var dataMembers = getDataMembers(obj)
                  
        if (dataMembers.length > 0) {
                    // Deep clone the model, save reference
                    //var clone = obj.clone(true);
                    var dataClone = obj[0].outerHTML;
                    
                    for (x = data.rows.length-1; x >= 0; x--) {
                          var thisRow = dataClone;
                                   
                          for (i = 0; i < dataMembers.length; i++) {
                                  var rg = new RegExp("!" + dataMembers[i] + "!"); rg.global = true;

                                  if (dataMembers[i] == "length") {
                                         ev = data.rows.length.toString();
                                  } else {
                                         ev = eval("data.rows[" + x + "]." + dataMembers[i]).toString();
                                  }
                                        
                                  thisRow = thisRow.replace(rg, ev);
                          }

                          obj.after(thisRow);
                    }
                            
                    // Remove model
                    obj.remove();
        }
}

function getDataMembers(obj) {
              var str = obj[0].outerHTML;

              if (str.length > 0) {
                          var rg = /!(\w+)!/g;
                          var match = str.match(rg);
                          var dMembers = [];
                          dMembers.push("length");

                          if (match != null) {
                                      for(i = 0; i < match.length; i++) {
                                            dMembers.push(match[i].replace(/!/g,""));
                                      }
                          }

                          return dMembers;
              } else {
                          return [];
              }
}

$(function() {
              initJMO("#JMO1", myTestObj);
} );

initJMO requires 2 params... 1 is the model object (our TR in this case). 2 is the data object (our un-eval'd JSON). 

initJMO clones the model object, finds all the data members (column names) we want to bind to and then goes through and replaces each !<name>! with the corresponding JSON column's data. It then appends the source of our cloned/replaced element after the model object, thus repeating the data with each row of our data object. Finally initJMO removes the model object from the page.

So what you get is your model object repeated with every row of your data object.

The cool thing about this is you can define ANY element as the model object!Now yes this still needs a lot of work and there are a few issues with it but I'd like to get some feedback. Good idea? Has this been done before?

A sample page can be viewed here: http://www.dennydotnet.com/Test/Default2.aspx

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by SuperGhost on Friday, August 10, 2007 4:48 PM
Permalink | Comments (19) | Post RSSRSS comment feed

ASP.NET AJAX createDelegate and the JavaScript "this"

If you're doing ASP.NET AJAX and you're creating a lot of JavaScript then you are hopefully aware of the Function.createDelegate method. If you're not using the createDelegate method then read on!

When you're building your classes in ASP.NET AJAX you'll have various function that interact with each other. Sometimes you may even have external methods that you're calling. So when you want to reference a javascript object you would probably pass the object through the parameters list. When it comes to doing a Web Service call you have a callback method for success and fail such as:


var el = this;
Client.GetSomeField(1, 5, onSuccess, onFail);

function onSuccess(r) {
 var el = this;
 alert(r);
}


Everything looks dandy. However when I use "this" inside any of the callback methods I won't get the object I am looking for. Lets say I wanted to pass "this" object to my onSuccess function. How could I do that? Well that's where the createDelegate comes in:


var el = this;
var newSuccess = Function.createDelegate(el, onSuccess);

Client.GetSomeField(1, 5, newSuccess, onFail);

function onSuccess(r) {
 // You now have access to the same object using "this"
 var hw = this.HelloWorld();
 alert(r + hw);
}


Wow well that was easy! The cool thing about this is that you can pass any object with the createDelegate method. So if I wanted to pass a string I could do:


var el = "Hey I came from down the way";
var newSuccess = Function.createDelegate(el, onSuccess);

Client.GetSomeField(1, 5, newSuccess, onFail);

function onSuccess(r) {
 var hw = this; // this = "Hey I came from down the way"
 alert(r + hw);
}


Tada! I just passed my string across.

Well now wait a second, I have another function that takes in a few extra params. It's not within a Web Service method, it's an external function. How do I use createDelegate with that?


var el = this;
var newSuccess = Function.createDelegate(el, onSuccess);

// Call the function
newSuccess(param1, param2, param3);

function onSuccess(p1, p2, p3) {
 // still the same object that we passed
 var hw = this.HelloWorld();
 hw += p1;
 hw += p2;
 hw += p3;
 alert(hw);
}


The createDelegate method takes two parameters. The first one is the object that will be referenced by "this" (inside the function). The second parameter is the function to be executed (where you'll use "this").

Another good trick is to use the createDelegate function with the $addHandler method:


$addHandler(btnSave, 'click', Function.createDelegate(someOtherObj, this.onSaveClicked));


So in conclusion, why use createDelegate? It wraps an existing function and returns a new function which can use the "this" keyword that points to an object of your desire. Why do I need this? In an event handler raised by a DOM element the "this" keyword will refer to the DOM element whereas you may want it to refer to a class or class object, or any other object for that matter.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by SuperGhost on Tuesday, July 24, 2007 8:57 AM
Permalink | Comments (0) | Post RSSRSS comment feed

New Dad, Job and Knowledge

Well it's been a long while since I've blogged and I'm finally getting around to it. There's been a lot of things going on lately! First and foremost I'm going to be a new Dad starting next year around February or March. I'm excited about the news and can't wait to find out if it's a boy or girl. Things will definitely start changing around the house!

Secondly, I started a new job! I'm really excited about working at this new place because they're doing some really cool AJAX stuff. It's a great opportunity for me because I'll get to work with some really bright people and work with the latest technologies too. I recently picked up a book titled: "Professional ASP.NET 2.0 AJAX" by Matt Gibbs and Dan Wahlin (Amazon) to get some further insight on the ASP.NET AJAX Framework. It's an excellent book and there's plenty of tips and knowledge in here even if you're experienced. For example, I finally found out what the benefit of using the ASP.NET AJAX registration methods (for namespaces, classes, etc...). It has to do with performance, amongst other things. I'll blog more about this later! On another note I introduced SubSonic to the team as well. I had some positive feedback and it looks like we could be implementing it across various projects in the future.

I've recently been working with the ASP.NET AJAX Serialization classes, in particular the JSON serializer. There didn't seem to be too many resources while Googling for examples so I poked around and created a few helper functions for myself such as serializing a DataTable or DataReader into a JSON array / object (Yes ASP.NET Futures supports this already). I'll blog about this in the future as well. Anyways, upon creating some helper functions I realized I had something interesting started. I began thinking about how I could bind my array of JSON objects to a pre-defined template, like a Repeater only on the client-side. It seems possible but I haven't researched this thoroughly to see what implications it could have. It may be a side project in the future.

Feedback:
What I'm interested in knowing is how other people have been using ASP.NET AJAX. Are you taking adavntage of Web Services, or are you using PageMethods? Are you relaying your data as XML or JSON? Why? How are you using the data passed to the client. For example are you using it to update one or two specific elements or are you bulking your objects together to complete multiple tasks?

I'm very interested in hearing your responses.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by SuperGhost on Monday, July 16, 2007 5:05 PM
Permalink | Comments (2) | Post RSSRSS comment feed

Some Interview Questions

Well I've been out on the chopping block lately getting some interviews. The first one sucked, needless to say I was not prepared. Anyways I came across a few interesting interview questions and thought I would share. They're mostly ASP.NET and not specific to any language except for question 1 which is for C#.

#1. Can you implement code in an abstract class?
I came from a VB.NET background and for some reason thought you couldn't (what the hell are interfaces then?? - D'oh!). Yes you can implement code in an abstract class! You can choose which properties and methods should be overridden by using the abstract keyword. The abstract keyword implicitly makes the method or property virtual whereas an interface is always virtual.

#2. Implement a function that will return a corresponding Fibonacci number: Fib(x)
Good old Fibonacci. Try creating a function that will add the sum of the previous 2 numbers. Example:

0 1 2 3 4 5 6  7...
------------------
0 1 1 2 3 5 8 13...

If we passed 6 into Fib(x) it should return 8 because it adds 3 and 5 (the two previous sums). This is a cool function because it can be implemented in about 2 lines of code (in a recursive function)! Try it yourself and then take a look at: http://en.csharp-online.net/Calculate_Fibonacci_number - It took me about 45 minutes to finally see the light, I was always slow at math.

#3. What is the order of Page_Load events if you have a page that uses a Master Page, the Content Page and a User Control? What if the User Control's PageOutput is set to cache the control?
I admit I goofed this one up. The events are as follows: Content Page, Master Page, User Control. And what about caching? The first time the page is loaded the control's Page_Load event will fire. It will not fire any further until it is removed from the cache. So while the User Control is cached the events are only Content Page and then Master Page. That will save you a lot of processing! (Makes sense doesn't it?)

#4. Create a regular expression to match the following: (xxx) xxx-xxxx
Ok, so unless you translate all your favorite books into hexadecimal and read them that way then you probably don't want to touch Regular Expressions. What in the world are all those slashes, squiggly's, dots, parenthesis and what not doing in there!! Well there's a good place to learn: www.regexlib.com and check out the Cheat Sheet. Anyways here's what I came up with (although at the interview I omitted the ^ and $):

^\(\d{3}\)\s\d{3}-\d{4}$

Yes that translates into a phone number :)

More to come... maybe...

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:
Posted by SuperGhost on Monday, June 18, 2007 3:33 PM
Permalink | Comments (2) | Post RSSRSS comment feed

I'm now an MCP!

Took my first Microsoft Certification today and passed with an 867 (yea I could have done better). But hey I'm happy, I can add this to my resume and I feel pretty good about it.

During my preparation I ran across a lot of blogs arguing over Certs vs. Experience. What I found is that even though I feel very confident with my skills I did pick up a few new things that I was not aware of prior to my certification path. A lot of those things were new to me because I have never been exposed to them at work. For the most part I could figure out nearly every question that was presented to me in the exam if I could just have a default Web application project open with Visual Studio. I had a completely different outlook on certs now than I did before. Here are a few certification vs experience questions I wanted to answer:

  1. Is getting a cert worth it? Why? Yes. I believe the process of studying for the exam and reading the literature related to passing the exam gives you well rounded knowledge of the subject area. You'll probably pick up on something you didn't know before.
  2. Would you hire someone with less experience and a cert or more experience and no cert? More experience and no cert. This is because although the cert is "proof" that you know your stuff a seasoned developer has been exposed to much more than just questions and answers. In the programming world we all know how brain-breakingly dynamic an environment can be.


So that's my take on the whole cert vs experience scene. Anyways! If you're interested in taking a cert here are some of my personal recommendations:

  1. Get an exam prep book. The exam prep books go over what you will be tested on, source code, samples and study questions. The book will tell you how Microsoft wants you to answer the questions.
  2. Take a skills assessment test on Microsoft Learning: http://www.microsoft.com/learning/assessment/default.mspx - This is a great way to prepare for an exam. The only issue I had with this is that it does not tell you which questions you had wrong. It only states what you should improve on. However it does give you many resources such as books and instructor-led training that will help you focus on the areas you need improvement.
  3. I stumbled on a great site that was loaded with practice questions: www.certyourself.com - Here you get to go over the answers to the questions and they give you explanations as to why the answers are right or wrong.
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:
Posted by SuperGhost on Monday, June 04, 2007 3:46 PM
Permalink | Comments (5) | Post RSSRSS comment feed

How to use the CacheItemRemovedCallBack

.NET provides a callback method when a cached item is being removed from memory. Knowing when your cached item is removed is a good way to help manage caching performance. Below we'll take a look at how to implement the callback function that notifies us when a cached object is removed. We'll then display which cached object was removed along with the reason.

First add a label: lblInfo and a button: btnRemove to your web form.

Now move to the code-behind. First import the System.Web.Caching namespace.

In your Page_Load add the following:

    Protected Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If Not IsPostBack Then
            Dim evtRemove As CacheItemRemovedCallback
            evtRemove = New CacheItemRemovedCallback(AddressOf RemoveCallback)

            ' Add our new cached object, notice the onRemove callback
            Cache.Add("CacheMe", _
                "1 + 2 = 3", _
                Nothing, _
                Caching.Cache.NoAbsoluteExpiration, _
                System.TimeSpan.FromSeconds(5), _
                Caching.CacheItemPriority.Default, _
                evtRemove)
        End If
    End Sub

What we do there is create the CacheItemRemovedCallback which points to our RemoveCallBack method (yet to be created) which will handle an event when the cached item is removed. We then add our cache object as normal but we pass our CacheItemRemovedCallback object. We set the expiration for 5 seconds for the sake of testing, assuming you'll be playing around with the code.

Next create the RemoveCallback method:

    Protected Sub RemoveCallback(ByVal key As String, ByVal value As Object, ByVal reason As System.Web.Caching.CacheItemRemovedReason)
        Dim nfo as String = "Cache item: [" & key & "] <br />value: [" & value.ToString() & "] <br />was [" & reason.ToString() & "]"
        lblInfo.Text = nfo.ToString()
    End Sub

The RemoveCallback returns a key (the name of the cached object), a value (the value of the cached object), and a reason (DependencyChanged, Expired, Removed, UnderUsed). Then we create a string to show what and why the cached object was removed by using the above values respectively.

Finally add the button that removes the cached object:

    Protected Sub btnRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRemove.Click
        ' Remove the cached item
        Cache.Remove("CacheMe")
    End Sub

The button's execution causes the cached item to be removed which in turn fires our callback function that we created above (RemoveCallback).

That's all there is to it. Now compile and run your app and play with the button. Also try letting the cache expire and refresh the page to see the different reasons for removing the cached object.

Update (5/29/2007 9:45AM): Some great advice from McGurk from the comments section of this post. I'm going to post the comments here because it's important to remember.

Whenever talking about cache and the CacheItemRemovedCallback it is always wise to remind people that you should NEVER re-add the item removed in this callback. Doing so can cause your application to bring down the worker process. Often this is because the item is being removed due to memory pressure, and re-adding the item will result in the cache immediately removing the item, which will result in the callback being called again. You can see the nasty loop you can get into.

For critical items set your priority on the item to an appropriate level. Use a pattern where you attempt to retrieve an item from the cache, and if it is not present retrieve it from storage (file, database, etc.), re-insert it in the cache and then return it to callers.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:
Posted by SuperGhost on Tuesday, May 22, 2007 4:00 PM
Permalink | Comments (5) | Post RSSRSS comment feed

Install: Windows Vista Business

Just got back from a short, but very much needed, vacation. I went fishing at a nearby lake and it was sooo relaxing! This was the first actual vacation I have ever taken from work. I didn't catch any fish this time so the score is Fish: 1, Denny: 0. We'll see how it goes next time around ;)

I received my free copy of Windows Vista Business last week (powertogether.com ~ no more freebies available sorry). Although I had no intentions of installing it yet I ended up trying to upgrade my BIOS and destroyed my XP boot configuration. Destroying the boot config gave me an excuse to do a fresh install of Vista. I had some second thoughts about getting Visual Studio, SQL Server, IIS and my other apps to run on Vista but figured it would pan out.

After a quick installation (I was surprised) Vista was installed and on my first boot I had a blank screen. After a few reboots I realized I was running a dual screen setup and that the Vista startup screen was actually showing on my second monitor, which at the time was off (silly me). So after feeling dumb I completed the setup and it booted right up. The nVidia FX5500 graphics card held out for the Vista Aero interface though I will definitely be upgrading to an 8800. I had no problems installing Visual Studio 2005 or IIS though I did run across a few snags with SQL Server 2005.

I believe SQL Server 2005 kept killing my BOOTMGR and Vista would then need to be repaired from the CD after a reboot. I had to download the SQL Server 2005 service pack 2 (don't use the Windows Update method!). After trying a few Windows Updates on SQL Server 2005 I decided to manually download SP2 and install it which worked perfectly. I had to create a new instance because apparently the default instance was already used (not sure why).

Either way everything works great now and I run Visual Studio 2005 in Administrator mode for debugging purposes. Also VS2005 seems to have some graphics glitches after debugging though this may just be my video card. You have to install IIS7 from Windows Features but IIS7 rocks! I noticed a lot of my apps installed much quicker in Vista than in XP. It may be better support for my dual core or perhaps XP was just bloated. The Vista SideBar comes in very handy and there are quite a few gadgets available for it.

Overall I like Vista a lot more than I originally thought I would.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags: ,
Posted by SuperGhost on Tuesday, May 08, 2007 4:00 PM
Permalink | Comments (4) | Post RSSRSS comment feed

Interview Questions: What Should I Expect?

I'm expecting an interview within the next few weeks for a position as a C# ASP.NET Developer (Mid-Level). At my current position I do a lot of VB.NET development; however I work with C# extensively at home on personal projects. I feel very confident about my presentation but in preparation would like to get some feedback on what to expect or what to focus on prior to an interview (C# specific). For example what kind of C# specific questions have you run into? What were you being tested for as far as your C# skills? Each company is different, of course, but I would like to hear about some of the experiences you have had.

I have read through Buu Nguyen's recent Interview Questions and this was a great starting point.

I look forward to your comments.

Update (4/30/2007 8:15am): Found a few more resources. This is a really good one http://www.devbistro.com/tech-interview-questions/.NET.jsp and also http://www.techinterviews.com/?cat=9

 

kick it on DotNetKicks.com

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:
Posted by SuperGhost on Sunday, April 29, 2007 4:00 PM
Permalink | Comments (3) | Post RSSRSS comment feed

JavaScript and Server Controls

I've been finding quite a few people on the Client-Side forums on ASP.NET asking about how to bridge the gap between JavaScript and ASP.NET. The questions are usually related to getting data, or a variable, from JavaScript to ASP.NET and vice versa. So today I am going to show how to accomplish both tasks, along with some time saving tips. Ok, you know how I roll, let's get started.

Objective #1: Read and Set data to a TextBox Server Control from a JavaScript var

The only two things we'll need here is a TextBox Server Control and an Input button.

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<input id="Button1" type="submit" value="JavaScript" onclick="return myScript();"/>

Notice the onclick event of the input button. It's pointing to the myScript() JavaScript function that we have yet to create. Let's do it now.

function myScript()
{
  // Reference to our TextBox1 Server Control
  var txtBox = document.getElementById("<%=TextBox1.ClientID%>");

  // Set
  txtBox.value ="You ran myScript()";

  // Read
  var read = txtBox.value;

  return false;
}

Pay very close attention to the "var txtBox" line. Look at the ID of the element. Now before we go on let me explain why I used <%=TextBox1.ClientID%> instead of the ID TextBox1. For .NET to keep track of all its server controls it generates IDs for each server control based on its heirarchy in the page. If you're looking at this page generated with a MasterPage you would get a different ID for the TextBox. Move the control into a Wizard and you'll get another ID.

Example: The same TextBox control inside a Wizard control looks like

<input name="Wizard1$TextBox1" type="text" id="Wizard1_TextBox1"/>

Notice the ID is now Wizard1_TextBox1. The JavaScript code would throw an error if it were looking for the ID TextBox1 because the .NET engine has rendered the control with a different ID. That's where ClientID comes in. ClientID contains the rendered ID of the server control. So no matter where you move TextBox1 on the page using TextBox1.ClientID will point to the correct element in HTML, and this is precisely what our JavaScript needs. This also saves you a lot of time should you ever want to move your controls around.

Side Note: The ClientID property should be used on Server Controls that implement the INamingContainer. This is to keep all control IDs unique (more here: http://msdn2.microsoft.com/en-us/library/3hc29e2a.aspx).

Continuing on now... Our txtBox variable now points to our TextBox1 server control. We can then set or read the value of the textbox using the next lines of code.

// Set
txtBox.value = "You ran myScript()";

// Read
var read = txtBox.value;

Finally we return false instructing the onclick event to stop any further processing. This stops the button from doing a postback. On the other hand you could return true. In this case the JavaScript code will run and then the form will postback.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by SuperGhost on Tuesday, April 24, 2007 4:00 PM
Permalink | Comments (2) | Post RSSRSS comment feed