Script controls

A script control is a regular Web Forms control that derives Calipso's Comkarl.Web.UI.Controls.ScriptControl base class.

Script controls are able of render HTML markup from the server side like any other server control. Usually that means a script control can append other server controls, either other script controls or Web Forms regular controls. For example, this would be done overriding CreateChildControls() method.

In the other hand, script controls, like regular ones, can render raw HTML markup by overriding RenderControl(HtmlTextWriter) method. In addition, Calipso introduces other RenderControl method overload that allows script controls to write HTML markup using an XML writer, which is far better, because it ensures that output will be a well-formed document. This is acquired by overriding RenderControl(XmlWriter) overload. Recommended way of rendering raw HTML is using a RenderControl(XmlWriter) override, rather than standard one.

But what makes Calipso unique is that script controls can have a client-side counterpart that is executed in the client Web browser and it is coded using standard JavaScript.

Client-side JavaScript script control is just a JavaScript class that derives other JavaScript class calledComkarl.Web.UI.Controls.Control. Calipso makes an intensive use of jOOPL object-oriented JavaScript library in order to leverage object-oriented programming in Web browsers.

Implementation details on server-side ScriptControls.

  • Script controls are classes that must derive Comkarl.Web.UI.Controls.ScriptControl in the server code (that is, .NET assembly containing the control written in C#, VB.NET or other CLS-compliant languages).
  • Server ScriptControl-derived controls must override two properties in order to work with client-side JavaScript infrastructure:
    • CommonID. It is an arbitrary identifier that will be required to identify client-side JavaScript part of the control in the client infrastructure.
    • ControlElementCssClass. It is a CSS class name that will be added to the HTML element representing the control in the client-side. For example, if the script control renders <span>Hello world!</span>, the <span /> HTML element is the control. Either server-side or client-side part is responsible of assigning this CSS class name to the container.

Creating script controls that renders HTML from the server-side with a client-side JavaScript part

An script control can render HTML as pure server control like any other regular Web Forms control. For example, imagine a control that renders a Hello world text inside a <span>...</span> HTML element:
public class HelloWorldAndAlert : Comkarl.Web.UI.Controls.ScriptControl
{
          public override string CommonID { get { return "HelloWorldAndAlert"; } }
          public override string ControlElementCssClass { get { return "helloworld-and-alert"; } }

          protected override void CreateChildControls()
          {
                      HtmlGenericControl text = new HtmlGenericControl("span");
                      text.Attributes["class"] = ControlElementCssClass;
                      text.Controls.Add(new Literal { Text = "Hello world!" });
                      Controls.Add(text);
          }
}

Above code should render <span class="helloworld-control">Hello world!</span>.

Once this is rendered in the Web browser, clicking on such <span> element could open an alert saying "I did it!". This would be done by coding a JavaScript class.

This JavaScript class should be coded in a separate JavaScript file. This can be an embedded file, a physical file or it can be hosted in a remote site. In this case, it is going to be embedded into HelloWorldControl server control's assembly. For example, in the root namespace, and in this example the root namespace could be assembly's name itself: MyControls. JavaScript file will be called ScriptControl.js.

JavaScript file will look like this:
$namespace.register("Comkarl.Calipso.Controls");

Comkarl.Calipso.Controls.HelloWorldAndAlert = $class.declare(
       function () { },
       {
           // This control does not render HTML in client-side code
           Render: function () {
           },

           Initialize: function () {
               // Using jQuery events...
               $(this.get_Element()).on("click", function (e) {
                   alert("I did it!");
               });
           }
       },
       Comkarl.Web.UI.Controls.Control
);

Comkarl.Web.PageContext.get_Manager().RegisterControl("HelloWorldAndAlert", Comkarl.Calipso.Controls.HelloWorldAndAlert);

After embedding it into project's assembly, next step is registering an include and a reference to the include of HelloWorldControl server control. In this example, this is done by overriding OnLoad(System.EventArgs)** ScriptControl's method:
protected override void OnLoad(EventArgs e)
{
            base.OnLoad(e);

            JavaScriptManager.RegisterInclude
            (
                "Controls//HelloWorldAndAlert",
                "Comkarl.Calipso.Web.SampleClient.Controls.HelloWorldAndAlert.ScriptControl.js, Comkarl.Calipso.Web.SampleClient", 
                ResourceKind.Resource
            );

            JavaScriptManager.RegisterReference("Controls//HelloWorldAndAlert");
}


Creating script controls that renders HTML from the client-side using pure JavaScript and jQuery

In some kind of solutions, there is no need of rendering HTML from the server side, because maybe SEO is not important in the whole Web application. Or solution requires some dynamic widgets.

If this is the case, creating controls that do render nothing in the server-side is as easy as just register the required include and register of client-side JavaScript file and output HTML in the Render method.

Server control doing just the same thing like one rendering HTML in the server-side (see how was that) would look like the next code sample:
public class HelloWorldAndAlert : Comkarl.Web.UI.Controls.ScriptControl
{
          public override string CommonID { get { return "HelloWorldAndAlert"; } }
          public override string ControlElementCssClass { get { return "helloworld-and-alert"; } }

          protected override void OnLoad(EventArgs e)
          {
                      base.OnLoad(e);

                      JavaScriptManager.RegisterInclude
                      (
                               "Controls//HelloWorldAndAlert",
                               "Comkarl.Calipso.Web.SampleClient.Controls.HelloWorldAndAlert.ScriptControl.js, Comkarl.Calipso.Web.SampleClient", 
                                ResourceKind.Resource
                      );

                      JavaScriptManager.RegisterReference("Controls//HelloWorldAndAlert");
          }
}


And this time client-side JavaScript class will render the HTML Hello world! using jQuery:

JavaScript file will look like this:
$namespace.register("Comkarl.Calipso.Controls");

Comkarl.Calipso.Controls.HelloWorldAndAlert = $class.declare(
       function () 
       { 
                  this.$_.text = null;
       },
       {
           // This control does not render HTML in client-side code
           Render: function () {
                   this.$_.text = $("<span />").addClass(this.get_ElementCssClass());
                   this.$_.text.append("Hello world");
                   $(this.get_ParentElementSelector()).append(this.$_.text);
           },

           Initialize: function () {
               // Using jQuery events...
               this.$_.text.on("click", function (e) {
                   alert("I did it!");
               });
           }
       },
       Comkarl.Web.UI.Controls.Control
);

Comkarl.Web.PageContext.get_Manager().RegisterControl("HelloWorldAndAlert", Comkarl.Calipso.Controls.HelloWorldAndAlert);

Last edited Nov 1, 2012 at 10:06 PM by MFidemraizer, version 31

Comments

No comments yet.