Wiki source code of Mobile Client How to write a Dynamic Menu
Last modified by Vincent Massol on 2024/11/19 16:12
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | 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. | ||
| 2 | |||
| 3 | The same code convention for writing a module that would be pre-loaded for all wikis also applies: | ||
| 4 | |||
| 5 | {{code}} | ||
| 6 | /* | ||
| 7 | * See the NOTICE file distributed with this work for additional | ||
| 8 | * information regarding copyright ownership. | ||
| 9 | * | ||
| 10 | * This is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU Lesser General Public License as | ||
| 12 | * published by the Free Software Foundation; either version 2.1 of | ||
| 13 | * the License, or (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This software is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * Lesser General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU Lesser General Public | ||
| 21 | * License along with this software; if not, write to the Free | ||
| 22 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| 23 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | XWiki communication and pages display | ||
| 28 | */ | ||
| 29 | |||
| 30 | console.log("starting xproject execution"); | ||
| 31 | |||
| 32 | // apps screen | ||
| 33 | var xproject1Screen = new XWikiScreen( | ||
| 34 | { | ||
| 35 | // this is the ID of the screen. It's important. | ||
| 36 | name: "xprojects", | ||
| 37 | // this is the title of the screen. It will be used in the title bar | ||
| 38 | title: "Active Projects", | ||
| 39 | // this is a the parent screen. This is important as only the parent screen | ||
| 40 | //will call addParentMenus to allow the screen to add it's menu | ||
| 41 | parent: "xwikihome", | ||
| 42 | // this is the initial panel content | ||
| 43 | panelcontent: "<ul id='xwikiprojects'></ul>", | ||
| 44 | // this is the backbone route that this screen will be called for | ||
| 45 | route: "xprojects/:wikiName", | ||
| 46 | // this function is called once and allows this screen to add global menus | ||
| 47 | addMainMenus: function() { | ||
| 48 | }, | ||
| 49 | // this function is called when the parent screen is displayed. | ||
| 50 | // It allows the child screens to add their menu items for instance | ||
| 51 | addParentMenus: function() { | ||
| 52 | console.log("Adding apps menu"); | ||
| 53 | var configName = xmobile.getCurrentConfig(); | ||
| 54 | // we verify here that the current wiki is actually the wiki for which we want the menu to appear | ||
| 55 | if (xmobile.getCurrentService().url.indexOf("myurl.mydomain.com")!=-1) { | ||
| 56 | // the href is important here as it will insure the click will activate the screen | ||
| 57 | $("#xwikiactions").append("<li><a class='x-icon x-icon-list' href='#xprojects/" + configName + "'>Active Projects</a></li>"); | ||
| 58 | } | ||
| 59 | }, | ||
| 60 | // this is the route callback. It's job is to set the current context of the request, | ||
| 61 | // currently in xmobile but this will change as it's not dynamic enough | ||
| 62 | routeCallback: function(wiki) { | ||
| 63 | console.log("In xprojects route callback"); | ||
| 64 | |||
| 65 | // make sur the config is set | ||
| 66 | xmobile.setCurrentConfig(wiki); | ||
| 67 | xmobile.setCurrentWiki("default"); | ||
| 68 | // important call showCallback here | ||
| 69 | this.showCallback(); | ||
| 70 | }, | ||
| 71 | showCallback: function(cache) { | ||
| 72 | // trying to force back menu to be called back. This should not be necessary in the future | ||
| 73 | $.ui.setBackButtonText("Back"); | ||
| 74 | console.log("In xprojects show callback"); | ||
| 75 | // empty the panel | ||
| 76 | $("#xwikiprojects").html(""); | ||
| 77 | // ask for the network data. Since the data is probably not yet there it will add the request to the queue | ||
| 78 | // when the data is loaded our function will be called again automatically | ||
| 79 | var data = this.getActiveProjects(xmobile.getCurrentWiki(), cache); | ||
| 80 | if (data!=null) { | ||
| 81 | // display the data | ||
| 82 | var items = ""; | ||
| 83 | $.each(data.searchResults, function(key, val) { | ||
| 84 | items += '<li>' + xmobile.getPageHTML(xmobile.getCurrentConfig(), val) + '</li>'; | ||
| 85 | }); | ||
| 86 | $("#xwikiprojects").html(items); | ||
| 87 | } | ||
| 88 | |||
| 89 | } | ||
| 90 | } | ||
| 91 | ); | ||
| 92 | |||
| 93 | |||
| 94 | |||
| 95 | // adding network functions | ||
| 96 | xproject1Screen.addActiveProjectsRequest = function(wikiName, priority, cache) { | ||
| 97 | if (cache==null) | ||
| 98 | cache = true; | ||
| 99 | |||
| 100 | var activeProjectsURL = this.getActiveProjectsURL(wikiName); | ||
| 101 | console.log("requesting active project data"); | ||
| 102 | // the name of the request in the second parameter is very important here | ||
| 103 | // it has to be 'xprojects' and be called the same way as the screen. This will insure proper callback when the data is ready. | ||
| 104 | nq.addRequest(this, xmobile.getCurrentConfig() + "." + wikiName + ".xprojects", activeProjectsURL, priority, cache, null); | ||
| 105 | } | ||
| 106 | |||
| 107 | |||
| 108 | xproject1Screen.getActiveProjectsURL = function(wikiName) { | ||
| 109 | 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"; | ||
| 110 | 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"); | ||
| 111 | return xmobile.getCurrentService().getRestURL(wikiName, activeProjectsURL); | ||
| 112 | } | ||
| 113 | |||
| 114 | xproject1Screen.getActiveProjects = function(wikiName, cache) { | ||
| 115 | // trying to get the data from the cache | ||
| 116 | // if it's not there ask for it | ||
| 117 | var result = nq.getResult(xmobile.getCurrentConfig() + "." + wikiName + ".xprojects"); | ||
| 118 | if (result==null || cache==false) { | ||
| 119 | // we don't have a request we should add it in the queue | ||
| 120 | // asking for the data | ||
| 121 | this.addActiveProjectsRequest(wikiName, "high", cache); | ||
| 122 | return result; | ||
| 123 | } else if (result.status==4 || result.status==3) { | ||
| 124 | return $.parseJSON(result.data); | ||
| 125 | } else { | ||
| 126 | return null; | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | |||
| 131 | xmobile.addScreen(xproject1Screen); | ||
| 132 | {{/code}} |