Click here to Skip to main content
15,886,919 members
Articles / Web Development / ASP.NET

ScriptArguments: An Easy Way to Programmatically Pass Arguments to Script from Codebehind

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
16 Jan 2012CPOL2 min read 20.8K   3  
Pass JavaScript arguments from codebehind to script the easy way!

During my on-going adventures AJAXifying a crusty old business app, I have been using a methodology by which most client events are setup in codebehind. The reason for this is I have easy access to my client ids, variables, and resources in codebehind. By constructing the script function calls at this stage, I can avoid messy and fragile in-line code. What I am endeavouring to do is remove all script from the markup itself. So instead of having MyPage.aspx with script mixed with markup, I have MyPage.js and all functions here. Separate js files avoid fragile in-line code which only fails at runtime, can’t be refactored, and doesn’t play as nice with the debugger. Besides, separation of markup and script is good!

The downside to setting up all this script in the codebehind is it didn’t take long for the number of arguments to grow and become unruly. My script function signature looked like this:

JavaScript
function fnAddressChange(ddId, labelId, checkId, sameAsId, 
    hidSelectId, hidSameAsId, onSelectEvent)

And in the codebehind, I had this:

C#
string selectArgs     = string.Format("'{0}', '{1}', '{2}', '{3}', '{4}', '{5}'", 
    _DropDownAddress.ClientID, _LabelAddress.ClientID, _RowSameAs.ChildClientID, 
    (SameAs && _SameAsAddress != null) ? _SameAsAddress.LabelControl.ClientID : 
    "-1", _HiddenSelectedID.ClientID, _HiddenSameAs.ClientID);

string selectScript   = string.Format("fnAddressSelect({0}); ", selectArgs);
string changeScript   = string.Format("fnAddressChange({0}, '{1}'); ", 
                selectArgs, OnClientSelect);

We can see selectArgs is getting out of control. Not only is it getting ridiculous to add more to it, the function signature in script is getting huge and the ordering is easier to mess up. So I came up with this solution:

C#
ScriptArguments args = new ScriptArguments ();
args.Add("ddId", _DropDownAddress.ClientID);
args.Add("labelId", _LabelAddress.ClientID);
args.Add("checkId", _RowSameAs.ChildClientID);
args.Add("sameAsId", (SameAs && _SameAsAddress != null) ? 
    _SameAsAddress.LabelControl.ClientID : "-1");
args.Add("hidSelectId", _HiddenSelectedID.ClientID);
args.Add("hidSameAsId", _HiddenSameAs.ClientID);

Not only is the codebehind cleaner but I don’t have to worry about string.Format or the order in which I add arguments in. The resulting script generated is:

C#
args.ToString()
"{ ddId : 'ctl00__ContentMain__ControlOrderSoldTo__AddressSoldTo__DropDownAddress', 
labelId : 'ctl00__ContentMain__ControlOrderSoldTo__AddressSoldTo__LabelAddress', 
checkId : 'ctl00__ContentMain__ControlOrderSoldTo__AddressSoldTo__RowSameAs_
FormField_CheckBox', sameAsId : '-1', hidSelectId : 'ctl00__ContentMain__
ControlOrderSoldTo__AddressSoldTo__HiddenSelectedID', hidSameAsId : 
'ctl00__ContentMain__ControlOrderSoldTo__AddressSoldTo__HiddenSameAs' }"

This is a JavaScript Object with a property per key set to the corresponding value. So in script, I only need to take in one argument, the argument object. I can then access every piece of information inserted into ScriptArguments via the correct key:

JavaScript
function fnAddressIsReadOnly(args) {
     alert(args.ddId);
     alert(args.labelId);
}

Will alert me with:

C#
"ctl00__ContentMain__ControlOrderSoldTo__AddressSoldTo__DropDownAddress" and 
"ctl00__ContentMain__ControlOrderSoldTo__AddressSoldTo__LabelAddress".

The great thing is how simple this was to implement:

C#
public class ScriptArguments : Dictionary<string, string>
{
    public override string ToString()
    {
        StringBuilder script = new StringBuilder("{ ");
        this.Keys.ToList().ForEach(key => script.AppendFormat("{0} : '{1}', ", 
        key, this[key]));
        script.Remove(script.Length - 2, 2);
        script.Append(" }");
        return script.ToString();
    }
}

This simple class solves a simple problem. I hope you find it useful.


License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Avaya Inc.
Ireland Ireland
Formerly a C++ client developer, nowadays I'm all about C# and ASP.NET. Over the years I have mastered some and played with many aspects of .NET.

Follow my blog as I catalogue the more arcane problems I encounter and their solutions at CodingLifestyle.com

Comments and Discussions

 
-- There are no messages in this forum --