In my crusade against in-line code, I am endeavoring to clean up the script hell in my current project. My JavaScript is littered with these types of statements:
Part of the cleanup is to minimize script on the page and instead use a separate .js file. This encourages me to write static
functions which take in IDs and resources as parameters, allows for easier script debugging, and removes all in-line code making maintenance or future refactoring easier.
While moving code to a proper .js file is nice, there are times we might miss the in-line goodness. Never fear, we can build a JavaScript object containing properties for anything we might need with ease. This equates to passing a name/value pair collection to JavaScript from code-behind. Take a look at this example:
ScriptOptions options = new ScriptOptions();
options.Add("ok", GetResourceString("btnOK"));
options.Add("oksave", GetResourceString("btnOkSave"));
options.Add("cancel", GetResourceString("btnCancel"));
options.Add("viewTitle", GetResourceString("lblAddressEditorView"));
options.Add("editTitle", GetResourceString("lblAddressEditorEdit"));
options.Add("createTitle", GetResourceString("lblAddressEditorCreate"));
options.RegisterOptionsScript(this, "_OptionsAddressEditorResources");
Here we’re using the ScriptOptions
class to create an object called _OptionsAddressEditorResources
we can access in our script. Now let’s see these options in use:
function fnAddressEditDialog(address, args) {
var buttonList = {};
buttonList[_OptionsAddressEditorResources.ok] =
function() { return fnAddressEditOnOk(jQuery(this), args); };
buttonList[_OptionsAddressEditorResources.oksave] =
function() { return fnAddressEditOnOkSave(jQuery(this), args); };
buttonList[_OptionsAddressEditorResources.cancel] =
function() { jQuery(this).dialog("close"); };
jQuery("#addressEditorDialog").dialog({
title: _OptionsAddressEditorResources.editTitle,
modal: true,
width: 535,
resizable: false,
buttons: buttonList
});
}
Above, we see the jQuery dialog using the resources contained within the _OptionsAddressEditorResources
object.
This seems simple but pretty powerful. Below is the ScriptOptions
class which simply extends a Dictionary
and writes out the script creating a named global
object. Good luck cleaning up your script hell. Hopefully, this will help.
public class ScriptOptions : Dictionary<string, string>
{
public void AddControlId(WebControl control)
{
this.Add(control.ID, control.ClientID);
}
public void RegisterOptionsScript(Page page, string optionsName)
{
if (!page.ClientScript.IsStartupScriptRegistered(page.GetType(), optionsName))
{
StringBuilder script = new StringBuilder(
string.Format("var {0} = new Object();", optionsName));
this.Keys.ToList().ForEach(key => script.Append(
string.Format("{0}.{1}='{2}';", optionsName, key, this[key])));
page.ClientScript.RegisterStartupScript(page.GetType(),
optionsName, script.ToString(), true);
}
}
}