Tuesday, December 25, 2012

Replace window.showModalDialog with window.open

showModalDialog method supports most of the modern browsers. But in some browsers such as safari browser in iPad does not support showModalDialog method simply because they don’t have a concept of popup windows. So if a system needs to support to view in iPads showModalDialog method needs to be replaced with another method. The closest method is the window.open method, but this method has major limitations comparing to window.showModalDialog method.

The major difference between these two methods is showModalDialog halts the executions of the JavaScript until the dialog box is closed and can get a return value from the opened dialog box when its closing. In contrast window.open just opens a window asynchronously (User can access both the parent window and the opened window). And the JavaScript execution will continue immediately. 

To replace showModalDialog with window.open there is no easy way to do this. But with some limitations window.showModalDialog method can be replaced with window.open method.

To implement the functionality of getting return value from the dialog box normal JavaScript execution has to be divided into two deferent phases.

Phase 1 – JavaScript execution until the dialog box is open.
Phase 2 –JavaScript execution after the return value is been returned from the dialog box. 
Let’s take a simple JavaScript function as follows.

function openNewWindow() {
            var ModalWidth = "100px";
            var ModalHeight = "500px";
            var retValue = window.showModalDialog(urlPath, arrArguments, "dialogWidth:" + ModalWidt +";dialogHeight:" + ModalHeight + ";center:yes;help:no;resizable:no;status:no;scroll:no");

      if (retValue != null || retValue != "") {
             alert(retValue);
        }
        else {
             alert('No value returned');
        }
}

In the above example first of all we need to divide it to two main functions.

Phase 1
Let’s take a simple JavaScript function as follows.

function openNewWindow() {
            var ModalWidth = "100px";
            var ModalHeight = "500px";
            var retValue = window.showModalDialog(urlPath, arrArguments, "dialogWidth:" + ModalWidt +";dialogHeight:" + ModalHeight + ";center:yes;help:no;resizable:no;status:no;scroll:no");
}

Phase 2
function callback(retValue){
    if (retValue != null || retValue != "") {
             alert(retValue);
        }
        else {
             alert('No value returned');
        }
}

The callback function is the function which is going to call when the child window is getting closed. So the child window calls a function in parent window when the window is getting closed.  We can use Jquary unload method to bind a window unload event. So the unload event calls a callback function when the window is getting closed. But there is a limitation here, this window unload event will fires when the full post back occur in the child window. To avoid this, update panels have to be used to implement partial post backs.  The bottom line is, the window unload event should trigger only when the window is actually closing.  Following code lines shows how we can implement the window unload event.

var childWindow = window.open(urlPath,"","toolbar=no, directories=no, location=no, status=yes, menubar=no, resizable=yes, scrollbars=no, width="+Width+", height="+Height);
   
    $(childWindow).unload(function(){
            //We use isOpened propoerty to see whether the "unload" event is being called for the second time.
            //On the first time, isOpened is not defined, so we don't call the callback on that occassion.
            //In the second time, isOpened is defined, so can call the callback function.
            if (childWindow.isOpened == null) {
                childWindow.isOpened = 1;
            }
            else {
                if(callback){
                    callback(childWindow.returnValue);
                }
            }
      });
In this example a parameter called isOpened is used to avoid triggering unload event when the page loads. Here callback is the function which needs to call when the window getting closed and which is in the parent window.

Let’s consider the phase 1 again. In here we need to call the window.open, and also we need to preserve the normal execution of the code as previously in the browsers which showModalDialog supports.


function openNewWindow() {
            var ModalWidth = "100px";
            var ModalHeight = "500px";
            var retValue = openDialogBox(width,hight,callback);
           
            //To preserve the normal JavaScript execution
            if(window. showModalDialog){
                callback(retValue);
          }
 }

function callback(retValue){
    if (retValue != null || retValue != "") {
             alert(retValue);
        }
        else {
             alert('No value returned');
        }
}

We will implement a generic method to open the new window.

function openDialogBox(width,hight,callback){

     if(window. showModalDialog){
          retValue = window.showModalDialog(urlPath, arrArguments, "dialogWidth:" + width +";dialogHeight:" + hight+ ";center:yes;help:no;resizable:no;status:no;scroll:no");
     }
     else{
        windowUnloadEvent(width,height, callback);
    }
}


function windowUnloadEvent(width,height, callback){
    var childWindow = window.open(urlPath,"","toolbar=no, directories=no, location=no, status=yes, menubar=no, resizable=yes, scrollbars=no, width="+Width+", height="+Height);
   
        $(childWindow).unload(function(){
            //We use isOpened propoerty to see whether the "unload" event is being called for the second time.
            //On the first time, isOpened is not defined, so we don't call the callback on that occassion.
            //In the second time, isOpened is defined, so can call the callback function.
            if (childWindow.isOpened == null) {
                childWindow.isOpened = 1;
            }
            else {
                if(callback){
                    callback(childWindow.returnValue);
                }
            }
        });
}

By using above method we can simply replace the showModalDialog with window.open, but sometimes there should be a server side event also trigger after the client side event. To achieve this we need to do the post back by force and to trigger the appropriate server side event we need a sender element. So we need to pass the sender also.

  function openNewWindow(sender) {
            var ModalWidth = "100px";
            var ModalHeight = "500px";
            var retValue = openDialogBox(width,hight,callback,sender);
           
            //To preserve the normal JavaScript execution
            if(window. showModalDialog){
      return  callback(retValue);
            }
 }

function callback(retValue,sender){
    if (retValue != null || retValue != "") {
                 alert(retValue);

// sender null implies normal JavaScript execution
              if(sender == null){
        retuen true;
}
setTimeout(function () { __doPostBack(getElementDynamicName(sender), ''); }, 500); // forcely doing the post back

        }
        else {
             alert('No value returned');
        }
}

function openDialogBox(width,hight,callback,sender){

     if(window. showModalDialog){
    retValue = window.showModalDialog(urlPath, arrArguments, "dialogWidth:" + width +";dialogHeight:" + hight+ ";center:yes;help:no;resizable:no;status:no;scroll:no");
     }
     else{
       windowUnloadEvent(width,height, callback,sender);
    }
}


function windowUnloadEvent(width,height, callback,sender){
    var childWindow = window.open(urlPath,"","toolbar=no, directories=no, location=no, status=yes, menubar=no, resizable=yes, scrollbars=no, width="+Width+", height="+Height);
   
        $(childWindow).unload(function(){
            //We use isOpened propoerty to see whether the "unload" event is being called for the second time.
            //On the first time, isOpened is not defined, so we don't call the callback on that occassion.
            //In the second time, isOpened is defined, so can call the callback function.
            if (childWindow.isOpened == null) {
                childWindow.isOpened = 1;
            }
            else {
                if(callback){
                    callback(childWindow.returnValue,sender);
                }
            }
        });
}
The reason for using the setTimeout function, sometimes the form element is not initialized properly at the time the callback function calls(this step only need in low processing power devices only such as iPads). 

Tuesday, June 19, 2012

Remove Commas from WebNumericEdit


When using Infragistics WebNumericEdit, unnecessary commas have to be removed to use this control as a general numeric control. This format is inherited from NumberFormatInfo class, in order to modify this behavior new instance on this class has to be created and set the NumberGroupSeparator property. WebNumericEdit control has the propery called Culture, so a new CultureInfo object can be assign with the required  NumberGroupSeparator. Following code snippet can be use to achieve required behavior.

//C#
using System.Globalization;

// In the page load event
CultureInfo culInfo=new CultureInfo("en-US");  //instance of CultureInfo class

NumberFormatInfo numFromatInfo = new NumberFormatInfo();  // instance of NumberFormatInfo class
numFromatInfo.NumberGroupSeparator= string.Empty;  //set NumberGroupSeparator any string you want

culInfo.NumberFormat=numFromatInfo;

this.WebNumericEdit1.Culture = culInfo; //WebNumericEdit1 is the control to be applied with the new number format

 
This code has to be in the page load event and has to be called in the post backs also .

Wednesday, June 13, 2012

Creating a Multi-Text DropDownList from general ASP.NET DropDownList

In some projects there may be a requirement to bind multiple data fields with some pattern as the datatextfield such as "Name - Address". To achieve this requirement new column can be added to the datatable before bind data to the dropdownlist. Following C# code can be use to achieve this requirement.

DataColumn newColumn = new DataColumn("AddedColumn"); // Create a new data column
newColumn.Expression = "Name + ' - ' + Address"; //Name and Address are columns in datatable
dtData.Columns.Add(newColumn); //dtData is the datatable

ddDropDownList.DataTextField = "AddedColumn";

ddDropDownList.DataSource = dtData;
ddDropDownList.DataBind();

Like this any formatted string can be created using data table columns and bind to the DropDownList as the DataTextField. 


showModalDialog not returning value after a postback in Chrome

There is a bug in the Chrome browser engine, which is showModalDialog fails to return window.returnValue after childpage do any postback. This issue has been there for long time and status of the this issue is still available. More information on this issue can be found here.

For a solution for this issue update panels can be used to avoid unnecessary postbacks but this solution is not extendable for all the scenarios. The best solution posted in the stackoverflow can be found here.  What has done in this solution is, it uses the window.operner return value to get the return value in the Chrome. After postbacks also window.opener property in the modal dialog points to the caller window, so the result can be directly set to the returnValue property of the caller window(parent window).

Monday, May 7, 2012

Disable auto run in Windows XP Home Edition

Have you every try to disable autorun in Windows XP Home edition, If you use a common way using Gpedit.msc you will end up like this.

Have you ever seen this message and stuck with this. Windows home edition does not contain this option, So Gpedit.msc cant be used for disabling auto run in XP Home Edition. You have to do it in the registry editor. 

Back to hardware mode... :)

Here are the steps you have to follow.... (Note: please backup the registry before you proceed)
  1. type regedit and go to - HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer   

                                     
  2. Locate the DWORD value with the name "NoDriveTypeAutoRun", if this value is not there you have to create a new one with the exact same name. To do that right click on the pane -> new -> DWORD value.
  3. Change the value data to - 0x000000b1 (177)
                         

Tuesday, May 1, 2012

Collation conflict in T-SQL

Have you ever encounter a problem when working in T-SQL like, "Cannot resolve the collation conflict between "XX_90_CI_AI" and "SQL_Latin1_General_CP1_CI_AS" in the UNION operation." The reason for this error message is collation conflict has been occurred while SQL server trying to compare two columns or expressions which have different collations. This error cause most of the time when compare columns with a temporary table column, because other table columns are in the database default collation settings and temporary tables may not in the default collation. 

As I experienced to overcome this problem we can simply apply collation setting for the tempary table column with default collation settings as follows

Colname COLLATE DATABASE_DEFAULT from #temp

 

Tuesday, March 27, 2012

Operation is not valid due to the current state of the object.

Some times when using .NET web applications you have came a cross yellow pages with the stack trace some thing like bellow. 

System.InvalidOperationExceptionOperation is not valid due to the current state of the object.
System.InvalidOperationException: Operation is not valid due to the current state of the object.
at System.Web.HttpRequest.FillInFormCollection()
at System.Web.HttpRequest.get_Form()

Reason for this exception is a recent update which has been done to the .NET framework.  In the Microsoft security update MS11-100, they limit the maximum number of form keys to 1000 in a HTTP request. Because of this update ASP.NET applications rejects the requests which have more than 1000 of form keys. So the error message will be displayed in the browser, with HTTP 500 status code.

This change was made to address mainly the Denial of Service vulnerability. 

This new limit can be override on a per application basic by putting a new "appSettings" in an ASP.NET application’s configuration file. 

Thursday, March 22, 2012

Remove New Line charactors from data in SQL

Some times we need to avoid newline characters and other characters such as tab from the data we retrieve from the SQL server. There is a easy way to do this, we just need to replace those characters with a space or what ever we need as follows.

declare @newLine char(2)
set @newLine = char(13) + char(10)

which is in SQL :
char(9) -  Tab
char(10) - Line feed
char(13)  - Carriage return

then we can directly replace these characters when ever we need.

e.g :-
select
replace(theDataBaseField,@newLine,' ' ) 
from.....

as above we can get data without any newline characters.