Anyone who develops on the web these days develops with JavaScript.  As applications become richer in capability, they need to rely on the functionality JavaScript has to offer, or seek another solution like Silverlight or WPF.  As ASP.NET web forms or MVC applications grow in size, functionality gets separated into separate classes, pages (views), user controls (partial views), etc.  When it comes to JavaScript, scripts can get separated between script in a page, script in a user control, script emitted from code or embedded JavaScript files, or even dynamically loaded JavaScript.

It’s easy to write JavaScript, but it can be hard to write it in a way that can be easily maintained inside an ASP.NET page that has 10-20 user controls.  One user control may use JQuery to find a control in another user control, and that user control talks to another user control.  It all works because at the time of coding everything was setup with a specific hierarchy.  But as soon as the user adds functionality or changes their mind on certain functionality, the structure changes, leaving the developer taking over the work with an array errors and a whole lot of mess.

Here are some tips to make these interactions across user controls more managable.  First, it may be best to control these interactions through a plugin.  For instance, we can start with a component in the page:

if (typeof(window[“$p”]) === “undefined”) {
window[“$p”] = (function() {
var ctls = {};

return {
addControl: function(name, ctl) {
ctls[name] = ctl;
}
};
})();
};

Within the user control, the user control can interface with the page by adding itself to the list of child controls of the page.

window[“$uc1”] = (function() {
return {
init: function() {
if (typeof($p) !== “undefined”)
$p.addControl(“search”, this);
},

//set of functions to manage features of the user control
};
})();

The samples above would need to be tweaked some but this is a rough implementation.  Anyway, since we have an established hierarchy, the page can drive features within its user controls, or the user control can communicate certain actions and events by referencing the page through $p variable.

Loading Panels

For instance, with a loading panel that appears over the page, the page class can define methods to show and hide the loading panel, as in the following (assuming the display div is styled via CSS).

window[“$p”] = (function() {
return {
.
.

showPanel: function() {
$(“#display”).show();
},

hidePanel: function() {
$(“#display”).hide();
}
})();

Events

Sometimes an event in the user control, the page needs to know about the event.  We can use the ASP.NET AJAX events framework via Sys.EventHandlerList component to register and fire events.  We can add events and methods to the user control as in:

window[“$uc1”] = (function() {
var evt = new Sys.EventHandlerList();
return {
.
.

add_itemSelected: function(h) {
evt.addHandler(“itemSelected”, h);
},

remove_itemSelected: function(h) {
evt.removeHandler(“itemSelected”, h);
},

_onitemSelected: function(e) {
var h = evt.getHandler(“itemSelected”);
if (h) h(this, e);
},

init: function() {
//Add control event handler
//in event handler, fire _onitemSelected
}

//set of functions to manage features of the user control
};
})();

The page can attach an event handler and receive the bubbled notification.  Or, a callback or observer pattern could be used here too.