DCSIMG
March 2009 - Posts - Pini Dayan

Pini Dayan

The best thing about a boolean is even if you are wrong, you are only off by a bit.

March 2009 - Posts

ASP.NET 4.0 solution for the ClientID problem

Hi all, Ever needed a solution for the ugly naming of your server side controls?

Ever wanted to be able to control the id's ASP.NET automatically generates for you? Ever viewed the source of you aspx page and saw control with id like this: "ctl00_MB_btnExit" ?  This is the post for you!

The solution is very simple and all you have to do is simply wait! (For the next release of ASP.NET and VS.NET 2010)

As a brief introduction lets explain what is the problem in the first place:

Whenever we place a control (A server control actually) in our page and this server control implements the Interface INamingContrainer all the controls ID's within this control will have a special effect on their ID's. Their ID's will be build from the INamingContrainer control itself + the original ID of the control in side. This happens for ensuring each control on the Page will have a unique ID (For ASP.NET to work properly). If this INamingContrainer control himself is in another INamingContrainer control the ID will be the concatenation of this hierarchy. So we will get an ID in the form of: FirstContainer_SecondContainer_OurControlID. Now imagine a web application that works with master pages and GridView controls, we will get a very ugly and KB consumer in our client side HTML. (By the way , To easily understand what it does think of it as a Control namespace.)

The problem gets even worse if you are not specifying an ID for this INamingContrainer control. In this case the runtime will automatically assign a container ID for you (Like ctrl100 etc).

Why do we even care you ask? well for many reasons, one of them is when we have a low bandwidth we don't want a performance problem because of these ID's for example.

So how will ASP.NET 4.0 solves the problem: They added to each control (actually to every control's parent, The System.Web.UI.Control) a nice property by the name : "ClientIdMode". This property will have 4 options:

1. Legacy.

2. Static.

3. Predictable.

4. Inherit.

The Legacy option is very simple. It means that the same "algorithm" for creating the ID's is just like the previous framework versions, for example:

<asp:TextBox ID="txtName" runat="server" ClientIDMode="Legacy" /> 

will be rendered to:

<input id="ctl00_someMasterPage_ctl00_txtName" name="ctl00$someMasterPage$ctl00$txtName" />

The Static option means: You want it, you got it!!!! It will render the exact ID as you wrote it. No container ID will be appended to the ID.This means that a programmer must be very careful with this option.

The Inherit option is the default option for all controls. This means that when rendering the controls ID it will look it up in his parent.

The Predictable option is used to be able to predict the ID when writing our code. (Since this is the problem in the first place). It will be used mostly when using DataBound control such as GridView.When using this option we will use another property by the name:"ClientIDRowSuffix"

 

Setting up the ClientIdMode:

Instead of having to specify this new property on each and every control we can specify it in several places:

1. In out Page directive such as:

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" ClientIdMode="Some Option" %>

2. Do it for all our pages using the web.config file:

<system.web>
  <pages clientIdMode="Predictable"></pages>
</system.web>

Nice right?

Enjoy

Showing Ajax toolkit ModalPopUp using client controls

Since I am so fond of the Microsoft Ajax toolkit (And Microsoft Ajax Framework as well) I tried today to use the ModalPopUp control. Since I need in this current project to use client side controls to activate this control and showing the modal window, I needed to find a solution. The problem in the first place was that the ModalPopUp wants it's TargetControlID property to be a valid server controls (such as asp:button). So in order to trick the ModalPopUp control here is a simple work around:

 

<form id="form1" runat="server">
    <div>
    <asp:ScriptManager runat=server ID="sm">       
    </asp:ScriptManager>
    
    <input type=button value="Confirm" onclick="OpenModalWin();" />
    <asp:Button ID="dummyButton" runat="server"  Width="0" Height="0"
     Visible="true" />
    <br />
    
    text text text texttext texttext texttext text<br />
    text text text texttext texttext texttext text<br />
    text text text texttext texttext texttext text<br />
    text text text texttext texttext texttext text<br />
    text text text texttext texttext texttext text<br />
    text text text texttext texttext texttext text<br />
    text text text texttext texttext texttext text<br />
    text text text texttext texttext texttext text<br />
    text text text text 
    </div>
    
    <ajaxToolkit:ModalPopupExtender ID="MPE" runat="server"  
             TargetControlID="dummyButton" PopupControlID="divYesNO"
             BackgroundCssClass="BG" OkControlID="btnClose" 
             OnOkScript="OnOK()"></ajaxToolkit:ModalPopupExtender>

Notice that the server side button("dummyButton") is set to be not visible using the Width and Hieght properties.

When the user wished to show the modal window he can do it using simple javascript to activate the click event of this dummy button, like this:

function OpenModalWin()
{
     document.getElementById("<%= dummyButton.ClientID %>").click();
}

Another way and much more elegant way to do it is to use the ModalPopupExtender property by the name "BehaviorID". You can set this property to some name and then use it to open and show the modal window:

<ajaxToolkit:ModalPopupExtender ID="MPE" runat="server" 
           BehaviorID="ModalPopupExtenderBehviour" OnOkScript="YesFunction();"
           OnCancelScript="NOFunction();" OkControlID="btnYes" 
           CancelControlID="btnNO"  TargetControlID="dummyButton"
           PopupControlID="divYesNO"  BackgroundCssClass="BG" >
</ajaxToolkit:ModalPopupExtender>   

and then to open the modal window:

$find('ModalPopupExtenderBehviour').show();         
Enjoy

Convert objects to JSON in C# using JavaScriptSerializer

Want to convert a C# object into it's JSON equivalent? Here is a simple object from the System.Web.Script namespace that does exactly that:

System.Web.Script.Serialization.JavaScriptSerializer . It is stored in the System.Web.Extentions DLL (.Net Framework 3.5 only)

Using this object we serialize and deserialize  objects in C#. Here is a quick sample:

A simple Employee object:

public class Employee
{
    public string Name { get; set; }
    public string Age { get; set; }
    public string ID { get; set; }   
}
 

Adding some instances of them to a List:

Employee oEmployee1 = 
       new Employee{Name="Pini",ID="111", Age="30"};

Employee oEmployee2 = 
      new Employee { Name = "Yaniv", ID = "Cohen", Age = "31" };
Employee oEmployee3 = 
        new Employee { Name = "Yoni", ID = "Biton", Age = "20" };

List<Employee> oList = new List<Employee>() 
{ oEmployee1, oEmployee2, oEmployee3 };
 

Serializing then:

System.Web.Script.Serialization.JavaScriptSerializer oSerializer = 
         new System.Web.Script.Serialization.JavaScriptSerializer();
string sJSON = oSerializer.Serialize(oList);

And here is the output:

[{"Name":"Pini","Age":"30","ID":"111"},
{"Name":"Yaniv","Age":"31","ID":"Cohen"},
{"Name":"Yoni","Age":"20","ID":"Biton"}]
 
Enjoy. 

JavaScript - How to get focused control

Today I had to solve a very ugly JavaScript bug.

I was building this advance AutoCompleteTextBox control (Don't ask why. I know there are many of them ready out there including the ASP.NET Ajax toolkit) and i had a problem of focusing. Every time the div containing the results of the key that was typed the focus went somewhere else and when users clicked the up and down arrow it scrolled the entire page, which was not the behavior I was looking for.

Anyway, During my request for the focused control I found an interesting property that the "document" object has that is unique to IE. It is called document.ActiveElement. This property will return a reference to the focused control. As it turns out when the page is loaded this property is set to the body element and it then sets when the mouse is clicked (after mouse down). Now, it the mouse target is a "focusable" element like the input types then the document.ActiveElement property will be set to this target. otherwise it will set to it's parent.

One can change this property only if he call some other control's "focus()" function.

 

For more information: http://msdn.microsoft.com/en-us/library/ms533065(VS.85).aspx

Enjoy