65.9K
CodeProject is changing. Read more.
Home

Using AJAX and MDI on a web application

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.66/5 (11 votes)

Jan 30, 2007

3 min read

viewsIcon

95304

downloadIcon

1760

This article talks about two “technologies”, AJAX technology and a multi windows environment (MDI) inside an Internet application

Sample image

Introduction

This article talks about two "technologies", AJAX technology and a multi windows environment (MDI) inside an Internet application. The MDI-AJAX combination allows the creation of richer, user-friendly and faster Internet applications.

Standard Internet applications with a unique window implicate several complete page re-load on every http request, they are slower and less easy to use for common users. Common users are more accustomed to Window applications. With AJAX and MDI, it is easy to reproduce similar function like a Windows application.

Goal

This article is the result of a feasibility study, it explains a way to migrate a MDI Windows to a Web application. The biggest restriction is to avoiding any losses of user interface functionalities.

Used libraries

AJAX (Atlas)

For AJAX, I use a framework named "Atlas". This framework allows to create fast Internet applications using AJAX technology.

MDI

For the MDI environment, I use a JavaScript library called "Prototype Window Class v 0.95".

References

For more informations about used libraries refer to links at the end of the article.

Concept of sample

The main concepts aborted in this article are:

  • the use of an MDI environment within web pages
  • the use of AJAX
  • the possibilities of communication between windows

Sample scheme

Sample scheme

Scheme details

The part A is the principal page; it contains the references used in the sample.

Parts B and C are AJAXED windows.

The part D is a debug area which displays certain actions performed by the windows. And E the menu allowing is to display windows and other actions.

Elements A, B or C are able to communicate; B can call C to refresh a part of the contents. B contains a list of users; this page can do some actions like insertion, modification and deletion. When a user is added or deleted from the list, B ask C to refresh the DataList containing the number of users.

A can close B and C.

Another possibility is to show a modal window which locks access to all content.

Code

Now I am going to talk about the use of the "Prototype Window Class v 0.95" and how-to update a window from another on.

Use of "Prototype Window Class"

List of JavaScript libraries

<!-- Required Javascript's Files --> 
<script type="text/javascript" src="script/prototype.js"></script>
<script type="text/javascript" src="script/effects.js"></script>
<script type="text/javascript" src="script/debug.js"> </script>
<script type="text/javascript" src="script/window.js"> </script>

CSS style for windows

These style sheets contain information concerning the windows theme.

<link href="css/themes/default.css" rel="stylesheet" ... />
<link href="css/themes/spread.css" rel="stylesheet" ... />
<link href="css/themes/mac_os_x.css" rel="stylesheet" ... />
<link href="css/themes/alert.css" rel="stylesheet" ... />
<link href="css/themes/alert_lite.css" rel="stylesheet" ... />
<link href="css/themes/alphacube.css" rel="stylesheet" ... />
<link href="css/themes/darkX.css" rel="stylesheet" ... />
<link href="css/themes/nuncio.css" rel="stylesheet" ... />
<link href="css/themes/theme1.css" rel="stylesheet" ... />

Global variable used by the libraries

// Important variable, don't rename used by libs.

var contentWin = null;

Display a window

This function hold the standard windows creation

showWindow : function (oArg) {
        this.width = oArg.width || this.width;
        this.height = oArg.height || this.height;
        this.left = oArg.left || this.left;
        this.top = oArg.top || this.top;
        this.themeName = oArg.themeName || this.themeName;
        this.title = oArg.title || this.title;
        this.url = oArg.url || this.url;
        
this.winObj = new Window(this.winID, 
                         {
                          className: this.themeName, 
                          title:  this.title, 
                          top:this.top, 
                          left:this.left, 
                          width:this.width, 
                          height:this.height, 
                          closable: true, 
                          url: this.url, 
                          hideEffectOptions: {duration:1}, 
                          showEffectOptions: {duration:1}
                         });

// The window will be destroy by clicking on close button instead 

// of being hidden.

// If setDestroyOnClose() is omitted it's impossible to recreate 

// a window with the same ID

this.winObj.setDestroyOnClose();  
    
this.winObj.show();

Finding a window

Windows is the main object of "Prototype Window Class", in this method I set the window Id, and the method return the windows object.

findWindow : function (id) {
    return (Windows.getWindow(id));    
}

Tile all windows

In this method, I go through the list of opened windows by using Each and for every instance I change the position.

// Tile all Windows

function tileAllWindows(xRatio, yRation) {
    var x = xRatio;
    var y = yRation;

    Windows.windows.each( function(w) {
        if (w.getId != null) {
            w.setLocation(x,y);
            w.toFront();
            x += xRatio;
            y += yRation;
        }
    });
}

Events listening

// Set up a windows observer and trace into the textarea

var myObserver = {
  onStartMove: function(eventName, win) {
    traceInfo(eventName + " on " + win.getId())
  },
 ...
  onDestroy: function(eventName, win) {
    if (win == contentWin) {
    $('container').appendChild($('test_content'));
    contentWin = null;
    }

    traceInfo(eventName + " on " + win.getId())
  }
}

Windows.addObserver(myObserver);

Updating a part of a windows from another one

UserMan.aspx (window B)

<script language="JScript" type="text/jscript">
    // Execute updateInfo : Update user info window (User count)

    function form_OnPropertyChange() {
            window.parent.execScript("updateInfo()");

        return (true);
    }
</script>

In every change of the number of users, updateInfo() function is called.

// Update user count info on User Info Window

function updateInfo() {

    var v = new HWWeb("utils");

    var win = v.findWindow("winUserInfo");
    
    if (win != null) {
    
        var ww = win.content.contentWindow.window;
   
        win.content.contentWindow.window.execScript("updateNbUser()");
    }
          
}   

The updateInfo() function which is in the window A, calls the updateNbUser() function from on UserInfo.aspx (window C).

In the sample, a DataList displays the number of users, the control subscribe in a click event (using a trigger) of a refresh button.

function updateNbUser()
{
    fContent.UpdateButton.click();
}

<Triggers>
    <asp:AsyncPostBackTrigger ControlID="UpdateButton" EventName="Click"/>
</Triggers>

Be careful

Concerning the robustness of a such system, I don't have enough experience, but I believe that this solution works fine. It is necessary to have a good quality code with strong error management to prevent conflicts of numerous update or insert of data by the same user at the same time. For instance, if they have open two windows and that carrieas out two simultaneous update or insert, it is necessary to manage this case at the level of application to prevent some unexpected errors.

Conclusion

The use of AJAX and an MDI library may be interesting for Internet application. Some ERP are much more comfortable to use if they have a MDI environment. For instance it allows keeping permanently the result of a search, customer's list or other useful information.

Links