Wednesday, February 3, 2010

Using Original HTML IDs of Controls in JavaScript

One of the first problems I found went I started using JavaScript code within ASP .Net pages was that the controls from ASP.Net where at many times not directly accessible by JavaScript.

The IDs used for the controls within the ASP.Net page cannot be reliably used in JavaScript to reference that control. The reason is simple. To avoid conflicts in naming, ASP.Net automatically converts the IDs to unique IDs in HTML. These IDs generated for HTML are usually much bigger that the actual Control’s ID. This generated ID is called CllientID.

Almost all ASP.Net controls have a ClientID property. So, to get the ClientID in server code one could use:

string clientId = myControl.ClientID;

Where myControl is an ASP.Net Control.

Now the tricky part is to access this ClientID property from within JavaScript. One easy way I found to do this was to pass the ClientID of required controls at page start up. To do so, we should use ClientScript.RegisterClientScriptBlock. A sample usage:

ClientScript.RegisterClientScriptBlock(this.GetType(), "StartupScript", String.Format(@"
     var txtControlClientID = '{0}';
",
     txtControl.ClientID)
, true);

Now, in JavaScript, we access the control as:

var txtControl = $get(txtControlClientID);

Friday, March 6, 2009

Web Profile in Visual Studio Web Projects

Recently I had a need to implement Memberships, Roles, and Profiles on my web project. After going to several websites and blogs, I was finally able to setup the Membership and Roles without much problem. Then came along the Profiles. I found the post “Profiles in ASP.NET” by Scott on how to setup Profiles. It looked quiet easy. Just a few lines in the web.config and I should be ready to go. So, I went along and set-it-up. According to the article, a class called Profile should be automatically generated. After dozens of searched in Google, I finally found out what the problem was.

It appears that automatic profile creation only works for ASP.NET web sites (not web projects). Now, mine was a web project. I searched several websites but couldn’t find a way to implement profiles in a web projects.

Then at last, I came across Web Profile Builder. A detailed usage instruction is available at Joe Wrobel’s blog. This profile builder is compatible with both Visual Studio 2005 & Visual Studio 2008.

Technorati Tags: ,,

del.icio.us Tags: ,,

Thursday, March 5, 2009

Using Function.createCallback with Function.createDelegate

In my earlier posts, I had described the functionalities of both Function.createCallback and Function.createDelegate. Basically, Function.createCallback can be used to pass extra data to the callback method (in the form of context) and Function.createDelegate creates wrapper function which in-turn calls the callback method as a part of the object instance passed to the createDelegate function.

But, what can we do, if we need both the functionalities? Well, basic logics says simply join both the functions. So, an affecting callback would be:

var callback = Function.createDelegate(this, Function.createCallback(this.callbackMethod, { id: id }));

$addHandler($get(‘TestElement’), ‘click’, callback);


Function.createCallback

In my earlier post, I had given some details about the Function.createDelegate function. Actually there exists another function Function.createCallback with similar functionality. It doesn’t actually maintain the instance of the object. The only similarity is that it creates a wrapper function around the callback method provided.

The format of the function is:

Function.createCallback(callbackMethod, context)

So, what is the purpose of this function?  Let me demonstrate this with a simple example. Let us assume that we have a table with id “TestTable”. Clicking each row should bring up an alert box showing the row number clicked. The callback method used should be the same for all the rows.

Let us try:

var table = $get(‘TestTable’);
var rows = table.getElementsByTagName(‘tr’);

for(var i = 0; i < rows.length; i++) {
    $addHandler(rows[i], ‘click’, callbackMethod);
}

Now the problem. From within the callback method, how can we know which row was clicked. We need to show the row number clicked. This is where Function.createCallback kicks in. The context parameter given to this function would be passed on to the callback function when it is called by the $addHandler method. We could re-write the loop as:

for(var i = 0; i < rows.length; i++) {
    var callback = Function.createCallback(callbackMethod, { num:i });
    $addHandler(rows[i], ‘click’, callback);
}

Now the callback function can be implemented as:

function callbackMethod(e, context) {
    alert(‘Row Clicked: ‘ + (context[‘num’] + 1));
}

This should display the row number clicked.

Technorati Tags: ,

del.icio.us Tags: ,

The web server process that was being debugged has been terminated by Internet Information Services (IIS)

By default, debugging a website or web project within Visual Studio bring up the built-in server of Visual Studio. But, we do have a problem to change the server to an IIS instance. I recently switched to debugging on IIS on my Windows 2008 Server Machine. Debugging works fine. The only problem is that if your code hit some breakpoint and if you leave the program in ‘break’ mode for more than 90 seconds, Visual Studio shows the following message:

image

After a bit tweaking around in the new IIS interface, I got the solution:

  1. image Open Internet Information Services (IIS) Manager.
  2. From the server tree (the item with the name as the server name), choose Application Pools.
  3. Choose the Application Pool corresponding to your testing IIS website (usually it has the same name as your IIS website)
  4. Right-click and choose Advanced Settings.
  5. From the Process Model node, change the Ping Maximum Response Time (seconds) to a comfortably higher value (I have set the value to 900 seconds which is 15 minutes).

Alternatively, you can also set the Ping Enabled property to False.

Apparently what happens is that the server keeps pinging the worker process and waits for a response. When in debugging mode, the worker process is affectively suspended, which results in the ping not being responded.

Technorati Tags: ,

del.icio.us Tags: ,

Wednesday, March 4, 2009

Function.createDelegate

In order to manipulate callback event of DOM objects, Asp.Net Ajax comes with a handy set of functions. One of such handy method is the $addHandler method. Usage is straight forward. The syntax is:

$addHandler(domObject, eventName, callbackFunction);

Everything works perfectly. The only problem is when you use the function with the callback method as a method within an object, 

For example, we have a class:

var TestClass = function() {
   this.testVar = “Test Variable”;
}

TestClass.prototype = {
   testFunction: function() {
      alert(this.testVar);
   }
}

Now, if we have a DOM element with ID ‘TestElement’, we could register the click event of the element using:

$addHandler($get(‘TestElement’), ‘click’, this.testFunction);

When clicked, the element will show a dialog box ‘Undefined’. This is because, when an element is ‘clicked’, within the callback method, this refers to the instance of the event object. Since the event object instance does not have a variable called testVar, we get an ‘undefined’ prompt.

To overcome this limitation, we have the Function.createDelegate method. The format of this method is:

Function.createDeleagte(instance, event, callbackMethod);

This essential creates a wrapper function around the callback-method. When the wrapper function is called by the event handler, it delegates the call to the callbackMethod in the proper manner so that the this keyword will refer to object instance, which was provided as the first parameter to the createDelegate method. An example usage would be:

var del = Function.createDelegate(this, this.testFunction);
$addHandler($get(‘TestElement’), ‘click’, del);

Technorati Tags: ,

del.icio.us Tags: ,

Sunday, March 1, 2009

Changing Namespace of Typed Data Set

Last day, I spent half my day searching for a way to change the Namespace of a generated typed dataset class. Although there was no strict requirement for the same, still it would be nice to have a clean namespace for the generated classes. After searching a lot, I came up with various solutions. But none of them seemed to solve my problem. After a lot of pondering with the various properties of the file, I came up with the very simple solution.

imageSimply right-click the DataSet file and choose Property (or press F4) and from the Properties box, type the namespace in the "Custom Tool Namespace" field.

Thats it. Such a simple solution. Anyway, I dont believe many people need to change the namespace of the typed dataset, as it automatically generates namespace based on the folder structure.

Technorati Tags: ,

del.icio.us Tags: ,