Your First Magix Active Module

If you have experience with ASP.NET syntax, from e.g. Visual Studio, then the syntax for creating a Magix Module should be very familiar to you. In fact, a Magix Module is simply just a User Control, embedded into a DLL as a Resource, with a couple of additional features. If you run “magix.viewport.load-module” in the Active Event Executor with an “inspect” node, you will see something like the below …

inspect-load-module

The two most important parameters here are “container”  and “name”. Name is the fully qualified name of the C# class that implements your Active Module, and “container” is which Dynamic Panel your Module will be loaded into. If you open up “EventExecutor.cs” in the project “Magix.admin”, you’ll see how it calls the LoadModule method in its “magix.admin.open-event-viewer” event handler. The name is passes into the LoadModule method is “Magix.admin.ExecutorForm”.

Open up the “ExecutorForm.ascx.cs” file from the “Magix.admin” project. The only difference from this file, and a normal UserControl file, is that the class “ExecutorForm” is inheriting from the class “ActiveModule”, instead of UserControl. Besides from this, the “ExecutorForm.ascx” and “ExecutorForm.ascx.cs” are normal User Control files for markup and codebehind.

The “name” parameter we pass into our “magix.viewport.load-module” event, is the fully qualified name of this class, meaning its namespace plus class name, which combined becomes “Magix.admin.ExecutorForm”.

Ajax on Steroids!!

If you open op the “ExecutorForm.ascx” file, in the “Magix.admin” project, you will see conventional ASP.NET WebControls markup syntax. But instead of using “asp:” prefixing the controls, it’s using “mux:”. This ensures that you’re using the Magix UX Ajax Controls instead of the built in ASP.NET postback controls.

Magix UX works 100% perfectly together with conventional ASP.NET controls, but are “Ajax Alternatives”, which makes your website feel far more responsible, and facilitates for creating advanced Web Application functionality. They also have some more features, such as event handlers for MouseOver/Out etc, and also some more properties, but they can basically be used, 100% perfectly as counterparts to the ASP.NET WebControls hierarchy of controls.

Now, what we could have done, was to create a new “.ascx.cs” file and “.ascx” file, inheriting from Magix.Core.ActiveModule, brought in Magix.UX, created some ASP.NET markup, and we’d be done, however, there’s an even easier way to create our first form using Magix.

Dynamically Created Ajax User Controls!!

Run Magix and make sure you’ve got the below code pasted into it, such that your view resembles the screenshot below the code …

Method:magix.forms.create-form
container=>content2
form-id=>unique-identification-of-your-form
controls
  Button=>btn
    Text=>Hello World!
    OnClick
      magix.viewport.show-message
        message=>Howdy World!!!

inspect-create-form

When you run this, you should get a tiny button at the very bottom of your screen, looking somewhat like this once clicked …

inspect-create-form-2

What is really happening here, is that we’re internally loading a “Dynamic Form Creator”, which takes a node-set of Controls, which it will iterate upon, creating nested controls any ways we wish. This system is actually quite flexible, and you can easily create very advanced UI with it, such as for instance you can see in the screenshot below …

address-book

To create the “application” above, you can paste the following code into your “input” textbox …

Method:magix.execute
function
  event=>load-address
  code
    raise=>magix.data.load
      key=>adr
    for-each=>[/][raise][object]
      set=>[/][2][2][5][controls][[/][2][2][5][controls].Count].Value
      set=>[/][2][2][5][controls][item][CssClass].Value
        value=>span-6
      set=>[/][2][2][5][controls][item][Text].Value
        value=>[.][first].Value
      if=>[/][2][2][5][controls][item][Text].Value==
        set=>[/][2][2][5][controls][item][Text].Value
          value=> 
      set=>[/][2][2][5][controls][item].Name
        value=>Label
      set=>[/][2][2][5][controls][[/][2][2][5][controls].Count].Value
      set=>[/][2][2][5][controls][item][CssClass].Value
        value=>span-6
      set=>[/][2][2][5][controls][item][Text].Value
        value=>[.][last].Value
      if=>[/][2][2][5][controls][item][Text].Value==
        set=>[/][2][2][5][controls][item][Text].Value
          value=> 
      set=>[/][2][2][5][controls][item].Name
        value=>Label
      set=>[/][2][2][5][controls][[/][2][2][5][controls].Count].Value
      set=>[/][2][2][5][controls][item][CssClass].Value
        value=>span-6
      set=>[/][2][2][5][controls][item][Text].Value
        value=>[.][phone].Value
      if=>[/][2][2][5][controls][item][Text].Value==
        set=>[/][2][2][5][controls][item][Text].Value
          value=> 
      set=>[/][2][2][5][controls][item].Name
        value=>Label
      set=>[/][2][2][5][controls][[/][2][2][5][controls].Count].Value
      set=>[/][2][2][5][controls][item][CssClass].Value
        value=>span-6 last
      set=>[/][2][2][5][controls][item][Text].Value
        value=>[.][email].Value
      if=>[/][2][2][5][controls][item][Text].Value==
        set=>[/][2][2][5][controls][item][Text].Value
          value=> 
      set=>[/][2][2][5][controls][item].Name
        value=>Label
    raise=>magix.forms.create-form
      container=>content1
      form-id=>addressBook
      controls
        Panel
          CssClass=>prepend-top span-21 prepend-1 append-2 description
          controls
            Image
              ImageUrl=>media/images/magix-logo.png
              AlternateText=>Magix Illuminate Logo
              CssClass=>span-3 logo-medium
            Label
              CssClass=>prepend-top append-bottom span-17 last
              Text=>@"Welcome to the Magix Illuminate version of Address Book.
Address Book is one of the main examples from Qt. The application
basically shows how you can store, update and retreieve objects,
some basic forms manipulation, dynamic creation of nodes according
to contents in stored objects, and some other things."
        Label
          CssClass=>description span-6 top-1
          Text=>First Name
        Label
          CssClass=>description span-6 top-1
          Text=>Last name
        Label
          CssClass=>description span-6 top-1
          Text=>Phone no
        Label
          CssClass=>description span-6 last top-1
          Text=>Email
        Panel=>rep
          CssClass=>description span-24 last height-10 top-1
        Panel=>new
          CssClass=>span-20 left-1 prepend-1 append-1 top-1 last
          controls
            Label
              Text=>First Name
              CssClass=>span-5
            Label
              Text=>Last Name
              CssClass=>span-5
            Label
              Text=>Phone
              CssClass=>span-5
            Label
              Text=>Email
              CssClass=>span-5 last
            TextBox=>first
              PlaceHolder=>First Name ...
              CssClass=>span-5
            TextBox=>last
              PlaceHolder=>Last Name ...
              CssClass=>span-5
            TextBox=>phone
              PlaceHolder=>Phone ...
              CssClass=>span-5
            TextBox=>email
              PlaceHolder=>Email ...
              CssClass=>span-5 last
            Button=>save
              CssClass=>span-3 height-2 top-1 right
              Text=>Save
              OnClick
                raise=>magix.data.load
                  key=>adr
                raise=>magix.forms.get-value
                  id=>first
                  form-id=>addressBook
                set=>[.ip][..][0][object][[.ip][..][0][object].Count][first].Value
                  value=>[.ip][..][1][value].Value
                raise=>magix.forms.get-value
                  id=>last
                  form-id=>addressBook
                set=>[.ip][..][0][object][item][last].Value
                  value=>[.ip][..][3][value].Value
                raise=>magix.forms.get-value
                  id=>phone
                  form-id=>addressBook
                set=>[.ip][..][0][object][item][phone].Value
                  value=>[.ip][..][5][value].Value
                raise=>magix.forms.get-value
                  id=>email
                  form-id=>addressBook
                set=>[.ip][..][0][object][item][email].Value
                  value=>[.ip][..][7][value].Value
                set=>[.ip][..][0][object][item].Name
                  value=>Item
                set=>[.ip][..][11][object]
                  value=>[.ip][..][0][object]
                raise=>magix.data.save
                  key=>adr
                  object
                raise=>load-address
raise=>load-address

The above code will create a new “function” for you, which will use the “magix.forms.create-form” active event, to dynamically create the entire form as you see it in the screenshot. Basically a port of Address Book, almost, from Qt, 100% dynamically tied together, with dynamic declarative syntax, over the web. Notice how the above code will replace the Active Event Executor, since it uses the “content1″ container, which is the container the Active Event Executor also happens to be within. Which will remove the Active Event Executor in favor of your newly dynamically created form.

I want to create with CODE!!

If you want to create a new Magix Module from scratch, using C#, you can just copy and paste the existing “ExecutorForm.ascx” and “ExecutorForm.ascx.cs” files, rename them to something intelligent, change their class names, include them in a project which links in Magix.Core, System.Web and Magix.UX, make sure the “Xxx.ascx” file was marked as a “EmbeddedResource” in its properties as “Build action”, toss that DLL into the bin folder of an existing Web Site, either as a reference to your web-project, or some other ways, and VOILA! You’d have a new Active Module, created from scratch, in C# code …

Please remember to change the name of the class and the namespace though. Then you can load the module like this in your input nodes for your Active Event Executor.

Method:magix.viewport.load-module
name=>MyModuleFullNameSpace.MyModuleClassName
container=>content2

Or in C# code like this…

	LoadModule (
		"MyModuleFullNameSpace.MyModuleClassName", 
		"content2");

The beauty of the above architecture, from a modular design perspective, is that it’s 100% interchangeable with any future similar types of modules you’d imagine yourself implementing, as long as they take the same Data parameters, and have the same names. This means that your Modules, meaning the visible parts of your application, is 100% de-coupled from your logical parts, which are implemented in Active Controllers.

This creates a flexibility and agility in your project, that will probably feel much greater than, what you’ve been able to achieve previously in your projects …

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s