Mobile Client How to write a Dynamic Menu

Last modified by Vincent Massol on 2024/11/19 16:12

 XWiki
 Implementation
 Completed
 

Description

Here are some notes about how to develop a screen for the Mobile Client v2. This code is a screen that can be added to the home screen for a wiki and allowing to access a list of projects stored in XWiki Classes. Such a module can be loaded dynamically by the XWiki Mobile application just after login in to the wiki.

The same code convention for writing a module that would be pre-loaded for all wikis also applies:

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

/*
 XWiki communication and pages display
 */

console.log("starting xproject execution");

// apps screen
var xproject1Screen = new XWikiScreen(
                                      {
                                      // this is the ID of the screen. It's important.
                                      name: "xprojects",
                                      // this is the title of the screen. It will be used in the title bar
                                      title: "Active Projects",
                                      // this is a the parent screen. This is important as only the parent screen 
                                      //will call addParentMenus to allow the screen to add it's menu
                                      parent: "xwikihome",
                                      // this is the initial panel content
                                      panelcontent: "<ul id='xwikiprojects'></ul>",
                                      // this is the backbone route that this screen will be called for
                                      route: "xprojects/:wikiName",
                                      // this function is called once and allows this screen to add global menus
                                      addMainMenus: function() {
                                      },
                                      // this function is called when the parent screen is displayed. 
                                      // It allows the child screens to add their menu items for instance
                                      addParentMenus: function() {
                                        console.log("Adding apps menu");
                                        var configName = xmobile.getCurrentConfig();
                                        // we verify here that the current wiki is actually the wiki for which we want the menu to appear
                                        if (xmobile.getCurrentService().url.indexOf("myurl.mydomain.com")!=-1) {
                                          // the href is important here as it will insure the click will activate the screen
                                          $("#xwikiactions").append("<li><a class='x-icon x-icon-list' href='#xprojects/" + configName + "'>Active Projects</a></li>");
                                        }
                                      },
                                      // this is the route callback. It's job is to set the current context of the request, 
                                      // currently in xmobile but this will change as it's not dynamic enough
                                      routeCallback: function(wiki) {
                                        console.log("In xprojects route callback");
  
                                        // make sur the config is set
                                        xmobile.setCurrentConfig(wiki);
                                        xmobile.setCurrentWiki("default");
                                        // important call showCallback here
                                        this.showCallback();
                                      },
                                      showCallback: function(cache) {
                                        // trying to force back menu to be called back. This should not be necessary in the future
                                        $.ui.setBackButtonText("Back");
                                        console.log("In xprojects show callback");
                                      // empty the panel
                                      $("#xwikiprojects").html("");
                                      // ask for the network data. Since the data is probably not yet there it will add the request to the queue
                                      // when the data is loaded our function will be called again automatically
                                      var data = this.getActiveProjects(xmobile.getCurrentWiki(), cache);
                                      if (data!=null) {
                                      // display the data
                                      var items = "";
                                      $.each(data.searchResults, function(key, val) {
                                             items += '<li>' + xmobile.getPageHTML(xmobile.getCurrentConfig(), val) + '</li>';
                                             });
                                      $("#xwikiprojects").html(items);
                                      }

                                        }
                                      }
                                      );



// adding network functions
xproject1Screen.addActiveProjectsRequest = function(wikiName, priority, cache) {
    if (cache==null)
        cache = true;
    
    var activeProjectsURL = this.getActiveProjectsURL(wikiName);
    console.log("requesting active project data");
    // the name of the request in the second parameter is very important here
    // it has to be 'xprojects' and be called the same way as the screen. This will insure proper callback when the data is ready.
    nq.addRequest(this, xmobile.getCurrentConfig() + "." + wikiName + ".xprojects", activeProjectsURL, priority, cache, null);
}


xproject1Screen.getActiveProjectsURL = function(wikiName) {
    var hql = ",BaseObject as obj, StringProperty as prop where doc.fullName=obj.name and obj.className='PMCode.XProjectClass' and obj.id=prop.id.id and prop.id.name='status' and doc.space='Projects' and prop.value='inProgress' order by doc.date desc";
    var activeProjectsURL = "query?type=hql&q=" + hql + "&media=json&number=20" + ((xmobile.getCurrentService().protocol>=3) ? "&orderField=date&order=desc&prettyNames=true" : "&orderfield=date&order=desc&prettynames=true");
    return xmobile.getCurrentService().getRestURL(wikiName, activeProjectsURL);
}

xproject1Screen.getActiveProjects = function(wikiName, cache) {
    // trying to get the data from the cache
    // if it's not there ask for it
    var result = nq.getResult(xmobile.getCurrentConfig() + "." + wikiName + ".xprojects");
    if (result==null || cache==false) {
        // we don't have a request we should add it in the queue
        // asking for the data
        this.addActiveProjectsRequest(wikiName, "high", cache);
        return result;
    } else if (result.status==4 || result.status==3) {
        return $.parseJSON(result.data);
    } else {
        return null;
    }
}


xmobile.addScreen(xproject1Screen);

 

Get Connected