Question
· Apr 14, 2016

Bootstrap - load body content dynamically with fixed menu

Hello, one of our application partner, is considering modernizing their old CSP laboratory portal by using Zen Mojo with Bootstrap. They have a lot of experience with COS, CSP and some ZEN. They are new to REST/JSON and have some limited knowledge of javascript - perhaps not enough to the extent used by client framework. 

They are trying to create their portal main page with header and footer fixed where at the header level is going to have a menu or navbar and at the footer level they would like to have some options (buttons, search options, text, messages, etc) dynamically loaded during run time. 

At the body level they would like to load the layout page accorging to the menu header option once selected. They would like not to repeat the header and footer code on all the template classes. They are really interested in to know wether is it possible or not  to have the header/footer as components?

Thanks.

Discussion (6)0
Log in or sign up to continue

Hi,

you need to re-render all components of header and footer on each layout-change. But there is a way to initialize the header and footer once and outside of the zen-pane.

In your zenPage create a ClientMethod that pushes html-code outside of the panes:

ClientMethod InitHeader(force) [ language = javascript ]
{
     if (force || !zenPage._zHeaderInit) {
        var head_html = [];
        var footer_html = [];
        head_html.push('<div id="header">');
        head_html.push('...things...')
        head_html.push('</div>');
        footer_html.push('<div id="header">...things...</div>')
        $('#zen1').html(head_html.join('') + $('#zen1').html() + footer_html.join(''));
        //init client-code here like onclick
        $('#header').find('a').each(function() {
            $(this).on('click',function() {
                //I clicked a emnu-item
            })
        });
        zenPage._zHeaderInit = true;
    }
}

In $executeCodeAfterChildren in getLayout() you can execute zenPage.InitHeader()

I thought about stash the header and footer and inject this code on the layouts when needed . Also they would likje to control the active option, for instance, or have a history bar right bellow the menu. 

I am really interested in advice to them the best approach and I am worried about do not make simple things became a monster in order to get difficult for maintanance, etc.

Jochen's approach is one way of dealing with this scenario. Another approach is to always inject the header and footer layout and drive the content with a data binding. This way you can always include your generic header/footer layout objects in all of your pages. This approach also allows you to implement your header and footer logic in a central method, so you don't duplicate code.

If you want more sophisticated control, you can easily build your own plugin and implement your own header/footer components with specialized logic and behavior.

Hi Steffan,

I though about have those header and footer layouts stashed and or loaded dinamically so that it can be  injected the other pages/layouts when needed. 

Could you please provide me more details about how to have this menu logic in a central method, as you mentioned? I have adviced them to use Multiple Templates (Dynamic Dispatch) in order to have the code more organized and easy to maintain. 

 

Thanks.

Hi Fabio,

 

in template dispatch mode you can have a super layout class where you can have a collection of clientmethods implemented in every layout extending from it. Our menu is initialized by every layout each time it loads. You can define a method that initialize the menuitems as active for example or load dynamic data.

I'm sure that there is a better way of handling menus with onepage-concepts. Menus in general are difficult in client oriented template systems.

We implemented a way to display two layouts in a single pane; a detail part in a modal for example. I think this technique can be used to display a dynamic-menu. Just create a menu-layout that just provide the layout by criteria-parameters. In your superclass add a method that calls this layout and injects it into a div provided by every layout. Example:

Content-Layout:

var that = this;

return {...,children:[{type:'$div',id:'menu'}], $executeCodeAfterChildren: function() {  that.initMenu({"parm":"value"}) }}

Super-Layout:

ClientMethod initMenu(view, criteria) [ language = "javascript] 

{

    var layout =  zenPage.getContent("layout","Menu",criteria)

     view = view || zen('mainView');
     var menucontainer view.getComponentById("menu"); *****

    //Empty all children-elements first before refresh and add the layout

    menucontainer.$children = menucontainer.children = layout.children;

    //rerenders menu

    menucontainer.$refresh();

}

***** I added following code in createLayoutObjects before return in bootstrap-plugin to get layout-elements by id instead of index:

 

var mainView instance.$documentView; //zen('mainView');
if (typeof mainView._IDIndex === "undefined") {
mainView._IDIndex [];
}
if (instance && instance.id) {
mainView._IDIndex[instance.id]=instance;
}
if (!mainView.getComponentById) {
mainView.getComponentById function(id) {
return this._IDIndex[id] || null;
}
}

 

While I'm not experienced with CSP/ZEN, I thought I'd make a suggestion from an outsider's perspective. As we all know, server-side does the work and client-side does the tidying up. So, let's keep things simple. I see your current situation is as follows.
 
Back-End Issue
You need to know a CSP/Zen Mojo approach to including code.
 
Front-End Issue
You are unsure how to create a fixed header with a navbar; and sticky footer in Bootstrap.
 
Back-End Solution
 
In PHP, this is usually obtained with includes. However, CSP does this in a similar fashion through the include directive (#INCLUDE), which you can find more info here: http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=.... Also, any client-side changes you'd want to be done with JS so that unnecessary load isn't placed on the server.
 
Front-End Solution
The front-end should be simple. There's lots of articles on how to use Bootstrap to achieve this. Here's on example: http://getbootstrap.com/examples/sticky-footer-navbar. Be sure you are using a CDN to maximize the load time for the client.