Mobile Client How to write a Dynamic Menu
Last modified by Vincent Massol on 2024/11/19 16:12
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);
Ludovic Dubost