cdotyone / mochaui

development tree for MochaUI
http://mochaui.org/demo/
Other
290 stars 83 forks source link

Windows created from JSON (with newWindowsFromJSON() ) not playing nice with workspaces #62

Open moofoo opened 14 years ago

moofoo commented 14 years ago

Not too much to say that isn't in the Title: Windows created from a JSON Request (like with the 'Json Demo' link in the demo) aren't being saved to/loaded from the cookie correctly.

Well, it looks like they're set in the cookie correctly, so maybe it's just a loading-from-cookie problem.

I've poked around in the code, but it's somewhat above my level. Which is to say, I'm not able to identify what's peculiar to the JSON windows that's making them behave differently than, say, the parametrics window in the demo...

Following a hunch, I tried changing the newWindowsFromJSON function from this (original): newWindowsFromJSON: function(newWindows){ newWindows.each(function(options) { var temp = new Hash(options); temp.each( function(value, key, hash) { if ($type(value) != 'string') return; if (value.substring(0,8) == 'function'){ eval("options." + key + " = " + value); } });
new MUI.Window(options); }); }

to this: newWindowsFromJSON: function(newWindows){ newWindows.each(function(options) { var temp = new Hash(options); temp.each( function(value, key, hash) { if ($type(value) != 'string') return; if (value.substring(0,8) == 'function'){ eval("options." + key + " = " + value); } }); MUI[options.id+'Window'] = function(){
new MUI.Window(options); } MUI[options.id+'Window'](); }); }

but, that didn't seem to fix much of anything...

mui-org commented 13 years ago

Parametrics is hard coded to load. It appears workspaces is completely dead. I will add it to the list to get some attention. -Thanks

moofoo commented 13 years ago

I worked out a scheme for loading workspaces that may be worth considering for the library.

The first issue I ran into was the size limitations of cookies. To overcome this, I used the PersistJS (http://pablotron.org/?cid=1557) library to put the window options in local storage instead of cookies. I also added in the option to save/load workspaces via an ajax call instead of local storage. (in my implementation this involves a PHP script which queries a MySQL database table).

There was some difficulty figuring out a way of storing/retrieving/running custom window event functions. I worked out a solution to this that evals javascript code loaded from .js files for each window, which takes the form:

new Object({
    onContentLoaded:function(){ 
    //onContentLoaded event code
    }
});

This code is eval-ed, combined with the options object loaded from the workspace storage, and then the combination object is used to open the new window. However, the related code for this is thoroughly app-specific and, to be honest, kind of ham-fisted/ugly, so I haven't included below. Unfortunately, this means that the Workspaces code below doesn't handle custom window events correctly.

In any event, here's code for Workspaces using the PersistJS library/Ajax calls. I'm fairly confident that it can be copy-pasted into the existing demo code and will work, with some possible minor tweaking.

First, in the index.html file in the demo directory, put this code at the bottom of the file. (This is going here just so the modified workspace code works with the demo, without needing to modify anything else besides the Workspace.js file. Also, don't forget to include the PersistJS file before mocha.js/mocha-init.js)

<script type="text/javascript">

/***********************
    Create the PersistJS storeage object.
***********************/

var store;
window.addEvent('domready', function(){
     store = new Persist.Store('Workspace');
});

/***********************
Additional options for workspaces.
In my implementation I just add these to the MUI options, but 
they should probably be put somewhere else.

If your implementation involves a login process,
and you want each user to have a unique workspace,
you would set the workspaceUser option to some
unique value per user (you would also probably be
setting "ajax" for workspaceMethod and using 
workspaceUser   as a key value for a database table, 
but not necessarily - maybe you're running an
intranet site with public terminals, or something)
***********************/

MUI.options.set("workspaceMethod", "local"); // or "ajax"
MUI.options.set("workspaceAjaxLoadUrl", "");
MUI.options.set("workspaceAjaxSaveUrl", "");    
MUI.options.set("workspaceTable","Workspace");
MUI.options.set("workspaceKeyColumn", "user");
MUI.options.set("workspaceJSONColumn", "workspace");
MUI.options.set("workspaceUser", "internet_user");

</script>

Then, in demo\plugins\mochaui\Layout\Workspace.js, replace the MUI.extend({ block of code with this: MUI.extend({ / This is a shortcut function for showing notifications /
showNote:function(text){

                        new MUI.Window({
                        loadMethod: 'html',
                        type: 'notification',
                        addClass: 'notification',
                        content: text,
                        closeAfter: '1400',
                        advancedClose:true,
                        width: 200,
                        height: 40,
                        y: 53,
                        padding:  { top: 10, right: 12, bottom: 10, left: 12 },
                        shadowBlur: 5,
                        bodyBgColor: [255, 255, 255],
                        blurOtherWindows: false

                    });
        },  

        windowUnload: function(){
            if ($$('.mocha').length == 0 && this.myChain){
                this.myChain.callChain();
            }       
        },      

        saveWorkspace: function(){
            var windowHash = new Hash();            

            MUI.Windows.instances.each(function(instance)
            {

                var instance_options = instance.options;

                instance_options.y = instance.windowEl.getCoordinates().top.toInt();
                instance_options.x = instance.windowEl.getCoordinates().left.toInt();
                instance_options.width = instance.windowEl.getCoordinates().width.toInt();
                instance_options.height = instance.windowEl.getCoordinates().height.toInt();        

                windowHash.set(instance_options.id, instance_options);      

            }.bind(this));  

            var table = MUI.options.workspaceTable;
            var key_column = MUI.options.workspaceKeyColumn;
            var json_column = MUI.options.workspaceJSONColumn;
            var user = MUI.options.workspaceUser;

            if(MUI.options.workspaceMethod == "local")
            {
                var local_storage_string = json_column+"_"+key_column+"_"+user;     
                store.set(local_storage_string, JSON.encode(windowHash.getClean()));    
                MUI.showNote("Worskpace Saved");

            }else if(MUI.options.workspaceMethod == "ajax")
            {
                var post_data = new Object({'table':table, 'key_column':key_column, 'json_column':json_column, 'key_value': user, 'workspace':JSON.encode(windowHash.getClean())});         
                new Request({
                  url: MUI.options.workspaceAjaxSaveUrl,
                  data: post_data,
                  onSuccess: function(){
                      MUI.showNote("Worskpace Saved");
                  }
                  }).send();
            }

        },

    workspaceChain: function(stored_workspace_json){

    /***********************
    The following is just code from the original loadWorkspace function
    that I've put in a separate function for space/cleanliness reasons.
    ***********************/    

            var workspaceWindows = new Object();
            workspaceWindows = JSON.decode(stored_workspace_json);

                    if ($$('.mocha').length != 0)
                    {
                        this.loadingWorkspace = true;
                        this.myChain = new Chain();
                        this.myChain.chain(
                            function()
                            {
                                $$('.mocha').each(function(el) {
                                    MUI.closeWindow(el);
                                }.bind(this));

                            }.bind(this),

                            function()
                            {
                                this.loadWorkspace2(workspaceWindows);

                            }.bind(this));

                        this.myChain.callChain();
                    }
                    else 
                    {
                        this.loadWorkspace2(workspaceWindows);
                    }       
        },      

        loadWorkspace2: function(workspaceWindows){         

            $each(workspaceWindows, function(item, index)
            {
                    var toggleAdvanced = false;
                    new MUI.Window(item);
                    var instance = $(item.id).retrieve('instance');             

                    if(MUI.options.advancedEffects)
                    {
                         toggleAdvanced = true;
                         MUI.toggleAdvancedEffects();
                    }

                    MUI.resizeWindow(instance.windowEl, {top: item.y, left: item.x, height: item.height, width: item.width});

                    if(toggleAdvanced) MUI.toggleAdvancedEffects();

            }.bind(this));

          this.loadingWorkspace = false;
        },

        loadWorkspace: function(){

            var table = MUI.options.workspaceTable;
            var key_column = MUI.options.workspaceKeyColumn;
            var json_column = MUI.options.workspaceJSONColumn;
            var user = MUI.options.workspaceUser;

            if(MUI.options.workspaceMethod == "local")
            {
                var local_storage_string = json_column+"_"+key_column+"_"+user;     
                store.get(local_storage_string, function(ok, json)
                {               
                      if (!ok)
                      {
                          MUI.showNote("You do not have a saved workspace");                
                          return;

                      }else
                      {                 
                          this.workspaceChain(json);                                  
                      }

                }.bind(this));  

            }else if(MUI.options.workspaceMethod == 'ajax')
            {

                var post_data = new Object({'table':table, 'key_column':key_column, 'json_column':json_column, 'key_value': user});             
                new Request({               
                    url: MUI.options.workspaceAjaxLoadUrl,          
                    data: post_data,
                    onSuccess: function(json)
                    {

    /***********************        
    This conditional is not very robust and could use some improvement 
    ***********************/                                            

                          if(json.length < 1)
                          {
                             MUI.showNote("You do not have a saved workspace");             
                             return;                              

                          }else
                          {
                             this.workspaceChain(json); 

                          }
                    }
                }).send();
            }

        }              

    });

....now some caveats:

For example, MUI.htmlWindow = function(options_obj){ if(typeof options_obj == 'undefined' || options_obj == null || $type(options_obj) != 'object') { new MUI.Window({ id: 'htmlpage', content: 'Hello World', width: 340, height: 150 }); }else { new MUI.Window(options_obj);
} }

mui-org commented 13 years ago

I will take a look at this when I revisit desktop code. Thanks for the code.