← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 21519: tracker apps better meta-data loading time

 

------------------------------------------------------------
revno: 21519
committer: Abyot Asalefew Gizaw <abyota@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2015-12-23 09:56:16 +0100
message:
  tracker apps better meta-data loading time
removed:
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.map.contextmenu.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.map.textoverlay.js
added:
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.tracker.metadata.js
modified:
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/index.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/views/home.html


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache	2015-10-23 15:44:51 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache	2015-12-23 08:56:16 +0000
@@ -6,9 +6,6 @@
 
 CACHE:
 
-../dhis-web-commons/javascripts/dhis2/dhis2.map.contextmenu.js
-../dhis-web-commons/javascripts/dhis2/dhis2.map.textoverlay.js
-
 ../dhis-web-commons/javascripts/jQuery/jquery.min.js
 ../dhis-web-commons/javascripts/jQuery/ui/jquery-ui.min.js
 ../dhis-web-commons/javascripts/jQuery/jquery.plugin.min.js
@@ -58,7 +55,7 @@
 ../dhis-web-commons/javascripts/dhis2/dhis2.contextmenu.js
 ../dhis-web-commons/javascripts/dhis2/dhis2.appcache.js
 ../dhis-web-commons/ouwt/ouwt.js
-../main.js
+../dhis-web-commons/javascripts/dhis2/dhis2.tracker.metadata.js
 scripts/event-capture.js
 
 ../dhis-web-commons/javascripts/angular/plugins/angularLocalStorage.js
@@ -66,21 +63,22 @@
 ../dhis-web-commons/javascripts/angular/plugins/select.js
 ../dhis-web-commons/javascripts/dhis2/dhis2.angular.directives.js
 ../dhis-web-commons/javascripts/dhis2/dhis2.angular.map.directive.js
+../dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js
+../dhis-web-commons/javascripts/dhis2/dhis2.angular.filters.js
 ../dhis-web-commons/javascripts/dhis2/dhis2.angular.validations.js
-../dhis-web-commons/javascripts/dhis2/dhis2.angular.filters.js
-../dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js
 ../dhis-web-commons/javascripts/dhis2/dhis2.angular.controllers.js
 
 scripts/app.js
+scripts/directives.js
 scripts/services.js
-scripts/filters.js
-scripts/directives.js
 scripts/controllers.js        
 scripts/notes-controller.js
+scripts/filters.js
 
 ../dhis-web-commons/javascripts/dhis2/dhis2.translate.js
 ../dhis-web-commons/javascripts/dhis2/dhis2.menu.js
 ../dhis-web-commons/javascripts/dhis2/dhis2.menu.ui.js
+../main.js
 
 ../dhis-web-commons/font-awesome/css/font-awesome.min.css
 ../dhis-web-commons/css/light_blue/light_blue.css

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html	2015-10-23 15:42:36 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html	2015-12-23 08:56:16 +0000
@@ -56,6 +56,7 @@
         <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.contextmenu.js"></script>
         <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.appcache.js"></script>
         <script type="text/javascript" src="../dhis-web-commons/ouwt/ouwt.js"></script>
+        <script src="../dhis-web-commons/javascripts/dhis2/dhis2.tracker.metadata.js"></script>
         <script type="text/javascript" src="scripts/event-capture.js"></script>
         
         <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/angularLocalStorage.js"></script>

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js	2015-12-22 13:43:14 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js	2015-12-23 08:56:16 +0000
@@ -33,7 +33,7 @@
 dhis2.ec.store = new dhis2.storage.Store({
     name: 'dhis2ec',
     adapters: [dhis2.storage.IndexedDBAdapter, dhis2.storage.DomSessionStorageAdapter, dhis2.storage.InMemoryAdapter],
-    objectStores: ['programs', 'geoJsons', 'optionSets', 'events', 'programValidations', 'programRules', 'programRuleVariables', 'programIndicators', 'ouLevels', 'constants']
+    objectStores: ['programs', 'optionSets', 'events', 'programValidations', 'programRules', 'programRuleVariables', 'programIndicators', 'ouLevels', 'constants']
 });
 
 (function($) {
@@ -178,42 +178,25 @@
 
 function getUserRoles()
 {
-    var SessionStorageService = angular.element('body').injector().get('SessionStorageService');
-    
+    var SessionStorageService = angular.element('body').injector().get('SessionStorageService');    
     if( SessionStorageService.get('USER_ROLES') ){
        return; 
     }
     
     var def = $.Deferred();
-
-    $.ajax({
-        url: '../api/me.json?fields=id,name,userCredentials[userRoles[id,authorities]]',
-        type: 'GET'
-    }).done(function(response) {
-        SessionStorageService.set('USER_ROLES', response);
-        def.resolve();
-    }).fail(function(){
-        def.resolve();
-    });
-
-    return def.promise();
+    var promise = def.promise();
+    promise = promise.then( dhis2.tracker.getTrackerObject(null, 'USER_ROLES', '../api/me.json', 'fields=id,name,userCredentials[userRoles[id,authorities]]', 'sessionStorage', dhis2.ec.store) );
+    promise = promise.done(function(){});    
+    def.resolve();
 }
 
 function getCalendarSetting()
-{       
+{   
     var def = $.Deferred();
-
-    $.ajax({
-        url: '../api/systemSettings?key=keyCalendar&key=keyDateFormat',
-        type: 'GET'
-    }).done(function(response) {
-        localStorage['CALENDAR_SETTING'] = JSON.stringify(response);
-        def.resolve();
-    }).fail(function(){
-        def.resolve();
-    });
-
-    return def.promise();
+    var promise = def.promise();
+    promise = promise.then( dhis2.tracker.getTrackerObject(null, 'CALENDAR_SETTING', '../api/systemSettings', 'key=keyCalendar&key=keyDateFormat', 'localStorage', dhis2.ec.store) );
+    promise = promise.done(function(){});    
+    def.resolve();    
 }
 
 function getConstants()
@@ -222,7 +205,7 @@
         if(res.length > 0){
             return;
         }        
-        return getD2Objects('constants', 'constants', '../api/constants.json', 'paging=false&fields=id,name,name,value');        
+        return dhis2.tracker.getTrackerObjects('constants', 'constants', '../api/constants.json', 'paging=false&fields=id,name,displayName,value', 'idb', dhis2.ec.store);        
     });    
 }
 
@@ -232,25 +215,13 @@
         if(res.length > 0){
             return;
         }        
-        return getD2Objects('ouLevels', 'organisationUnitLevels', '../api/organisationUnitLevels.json', 'filter=level:gt:1&fields=id,name,level&paging=false');
-    });    
+        return dhis2.tracker.getTrackerObjects('ouLevels', 'organisationUnitLevels', '../api/organisationUnitLevels.json', 'filter=level:gt:1&fields=id,name,level&paging=false', 'idb', dhis2.ec.store);
+    }); 
 }
 
 function getMetaPrograms()
-{
-    var def = $.Deferred();
-
-    $.ajax({
-        url: '../api/programs.json',
-        type: 'GET',
-        data:'filter=programType:eq:WITHOUT_REGISTRATION&paging=false&fields=id,version,categoryCombo[id,isDefault,categories[id]],programStages[id,version,programStageSections[id],programStageDataElements[dataElement[id,optionSet[id,version]]]]'
-    }).done( function(response) {        
-        def.resolve( response.programs ? response.programs: [] );
-    }).fail(function(){
-        def.resolve( null );
-    });
-    
-    return def.promise(); 
+{    
+    return dhis2.tracker.getTrackerObjects('programs', 'programs', '../api/programs.json', 'filter=programType:eq:WITHOUT_REGISTRATION&paging=false&fields=id,version,categoryCombo[id,isDefault,categories[id]],programStages[id,version,programStageSections[id],programStageDataElements[dataElement[id,optionSet[id,version]]]]', 'temp', dhis2.ec.store);    
 }
 
 function getPrograms( programs )
@@ -296,7 +267,7 @@
                 _ids = '[' + _ids + ']';
                 promise = promise.then( getAllPrograms( _ids ) );
             }            
-            mainDef.resolve( programs, _ids );
+            mainDef.resolve( programs, ids );
         } );
         def.resolve();
         
@@ -391,7 +362,7 @@
                 filter = filter + '&filter=id:in:' + _optionSetsInPromise + '&paging=false';
                 
                 var url = '../api/optionSets';
-                promise = promise.then( getD2Objects( 'optionSets', 'optionSets', url, filter ) );
+                promise = promise.then( dhis2.tracker.getTrackerObjects( 'optionSets', 'optionSets', url, filter, 'idb', dhis2.ec.store ) );
             }
             
             mainDef.resolve( programs );
@@ -408,166 +379,42 @@
 function getMetaProgramValidations( programs, programIds )
 {
     programs.programIds = programIds;
-    return getD2MetaObjects(programs, 'programValidations', '../api/programValidations.json', 'paging=false&fields=id&filter=program.id:in:');
+    return dhis2.tracker.getTrackerMetaObjects(programs, 'programValidations', '../api/programValidations.json', 'paging=false&fields=id&filter=program.id:in:');
 }
 
 function getProgramValidations( programValidations )
 {  
-    return checkAndGetD2Objects( programValidations, 'programValidations', '../api/programValidations', 'fields=id,name,name,operator,rightSide[expression,description],leftSide[expression,description],program[id]');
+    return dhis2.tracker.checkAndGetTrackerObjects( programValidations, 'programValidations', '../api/programValidations', 'fields=id,name,name,operator,rightSide[expression,description],leftSide[expression,description],program[id]', dhis2.ec.store);
 }
 
 function getMetaProgramIndicators( programs )
 {   
-    return getD2MetaObjects(programs, 'programIndicators', '../api/programIndicators.json', 'paging=false&fields=id&filter=program.id:in:');
+    return dhis2.tracker.getTrackerMetaObjects(programs, 'programIndicators', '../api/programIndicators.json', 'paging=false&fields=id&filter=program.id:in:');
 }
 
 function getProgramIndicators( programIndicators )
 {
-    return checkAndGetD2Objects( programIndicators, 'programIndicators', '../api/programIndicators', 'fields=id,name,code,shortName,displayInForm,expression,displayDescription,rootDate,description,valueType,name,filter,program[id]');
+    return dhis2.tracker.checkAndGetTrackerObjects( programIndicators, 'programIndicators', '../api/programIndicators', 'fields=id,name,code,shortName,displayInForm,expression,displayDescription,rootDate,description,valueType,name,filter,program[id]', dhis2.ec.store);
 }
 
 function getMetaProgramRules( programs )
 {
-    return getD2MetaObjects(programs, 'programRules', '../api/programRules.json', 'paging=false&fields=id&filter=program.id:in:');
+    return dhis2.tracker.getTrackerMetaObjects(programs, 'programRules', '../api/programRules.json', 'paging=false&fields=id&filter=program.id:in:');
 }
 
 function getProgramRules( programRules )
 {
-    return checkAndGetD2Objects( programRules, 'programRules', '../api/programRules', 'fields=id,name,condition,description,program[id],programStage[id],priority,programRuleActions[id,content,location,data,programRuleActionType,programStageSection[id],dataElement[id],trackedEntityAttribute[id],programIndicator[id],programStage[id]]');
+    return dhis2.tracker.checkAndGetTrackerObjects( programRules, 'programRules', '../api/programRules', 'fields=id,name,condition,description,program[id],programStage[id],priority,programRuleActions[id,content,location,data,programRuleActionType,programStageSection[id],dataElement[id],trackedEntityAttribute[id],programIndicator[id],programStage[id]]', dhis2.ec.store);
 }
 
 function getMetaProgramRuleVariables( programs )
 {    
-    return getD2MetaObjects(programs, 'programRuleVariables', '../api/programRuleVariables.json', 'paging=false&fields=id&filter=program.id:in:');
+    return dhis2.tracker.getTrackerMetaObjects(programs, 'programRuleVariables', '../api/programRuleVariables.json', 'paging=false&fields=id&filter=program.id:in:');
 }
 
 function getProgramRuleVariables( programRuleVariables )
 {
-    return checkAndGetD2Objects( programRuleVariables, 'programRuleVariables', '../api/programRuleVariables', 'fields=id,name,name,programRuleVariableSourceType,program[id],programStage[id],dataElement[id]');
-}
-
-function getD2MetaObjects( programs, objNames, url, filter )
-{
-    if( !programs || !programs.programIds){
-        return;
-    }
-
-    filter = filter + programs.programIds;
-    var def = $.Deferred();
-    
-    $.ajax({
-        url: url,
-        type: 'GET',
-        data:filter
-    }).done( function(response) {        
-        def.resolve( {programs: programs, self: response[objNames], programIds: programs.programIds} );
-        
-    }).fail(function(){
-        def.resolve( null );
-    });
-    
-    return def.promise();    
-}
-
-function checkAndGetD2Objects( obj, store, url, filter )
-{   
-    if( !obj || !obj.programs || !obj.self || !obj.programIds){
-        return;
-    }
-    
-    var mainDef = $.Deferred();
-    var mainPromise = mainDef.promise();
-
-    var def = $.Deferred();
-    var promise = def.promise();
-
-    var builder = $.Deferred();
-    var build = builder.promise();
-
-    var ids = [];
-    _.each( _.values( obj.self ), function ( obj) {
-        build = build.then(function() {
-            var d = $.Deferred();
-            var p = d.promise();
-            dhis2.ec.store.get(store, obj.id).done(function(o) {
-                if(!o){                    
-                    ids.push( obj.id );
-                }
-                d.resolve();
-            });
-
-            return p;
-        });
-    });
-
-    build.done(function() {
-        def.resolve();
-        promise = promise.done( function () {
-            
-            if( ids && ids.length > 0 ){
-                var _ids = ids.toString();
-                _ids = '[' + _ids + ']';
-                filter = filter + '&filter=id:in:' + _ids + '&paging=false';
-                promise = promise.then( getD2Objects( store, store, url, filter ) );
-            }
-            
-            mainDef.resolve( obj.programs, obj.programIds );
-        } );
-    }).fail(function(){
-        mainDef.resolve( null );
-    });
-
-    builder.resolve();
-
-    return mainPromise;
-}
-
-function getD2Objects(store, objs, url, filter)
-{
-    var def = $.Deferred();
-
-    $.ajax({
-        url: url,
-        type: 'GET',
-        data: filter
-    }).done(function(response) {
-        if(response[objs]){
-            dhis2.ec.store.setAll( store, response[objs] );
-        }            
-        def.resolve();        
-    }).fail(function(){
-        def.resolve();
-    });
-
-    return def.promise();
-}
-
-
-function getD2Object( id, store, url, filter, storage )
-{
-    return function() {
-        if(id){
-            url = url + '/' + id + '.json';
-        }
-        return $.ajax( {
-            url: url,
-            type: 'GET',            
-            data: filter
-        }).done( function( response ){
-            if(storage === 'idb'){
-                if( response && response.id) {
-                    dhis2.ec.store.set( store, response );
-                }
-            }
-            if(storage === 'localStorage'){
-                localStorage[store] = JSON.stringify(response);
-            }            
-            if(storage === 'sessionStorage'){
-                var SessionStorageService = angular.element('body').injector().get('SessionStorageService');
-                SessionStorageService.set(store, response);
-            }            
-        });
-    };
+    return dhis2.tracker.checkAndGetTrackerObjects( programRuleVariables, 'programRuleVariables', '../api/programRuleVariables', 'fields=id,name,name,programRuleVariableSourceType,program[id],programStage[id],dataElement[id]', dhis2.ec.store);
 }
 
 function uploadLocalData()

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js	2015-12-22 13:18:43 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js	2015-12-23 08:56:16 +0000
@@ -10,7 +10,7 @@
     var store = new dhis2.storage.Store({
         name: 'dhis2ec',
         adapters: [dhis2.storage.IndexedDBAdapter, dhis2.storage.DomSessionStorageAdapter, dhis2.storage.InMemoryAdapter],
-        objectStores: ['programs', 'geoJsons', 'optionSets', 'events', 'programValidations', 'programRules', 'programRuleVariables', 'programIndicators', 'ouLevels', 'constants']
+        objectStores: ['programs', 'optionSets', 'events', 'programValidations', 'programRules', 'programRuleVariables', 'programIndicators', 'ouLevels', 'constants']
     });
     return{
         currentStore: store

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/index.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/index.html	2015-12-21 13:28:07 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/index.html	2015-12-23 08:56:16 +0000
@@ -63,6 +63,7 @@
         <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.contextmenu.js"></script>
         
         <script src="../dhis-web-commons/ouwt/ouwt.js"></script>
+        <script src="../dhis-web-commons/javascripts/dhis2/dhis2.tracker.metadata.js"></script>
         <script src="scripts/tracker-capture.js"></script>
 
         <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/select.js"></script>

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js	2015-12-07 13:13:01 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js	2015-12-23 08:56:16 +0000
@@ -26,7 +26,7 @@
 dhis2.tc.store = new dhis2.storage.Store({
     name: 'dhis2tc',
     adapters: [dhis2.storage.IndexedDBAdapter, dhis2.storage.DomSessionStorageAdapter, dhis2.storage.InMemoryAdapter],
-    objectStores: ['programs', 'programStages', 'trackedEntities', 'attributes', 'attributeGroups','relationshipTypes', 'optionSets', 'programValidations', 'programIndicators', 'ouLevels', 'programRuleVariables', 'programRules','constants']      
+    objectStores: ['programs', 'programStages', 'trackedEntities', 'attributes', 'relationshipTypes', 'optionSets', 'programValidations', 'programIndicators', 'ouLevels', 'programRuleVariables', 'programRules','constants']      
 });
 
 (function($) {
@@ -133,22 +133,20 @@
     promise = promise.then( getRelationships );       
     promise = promise.then( getTrackedEntities );
     promise = promise.then( getMetaPrograms );     
-    promise = promise.then( getPrograms );     
-    promise = promise.then( getProgramStages );    
+    promise = promise.then( getPrograms );
     promise = promise.then( getOptionSetsForDataElements );
     promise = promise.then( getMetaTrackeEntityAttributes );
     promise = promise.then( getTrackedEntityAttributes );
     promise = promise.then( getOptionSetsForAttributes );
+    promise = promise.then( getMetaProgramValidations );
+    promise = promise.then( getProgramValidations );
     promise = promise.then( getMetaProgramRuleVariables );
     promise = promise.then( getProgramRuleVariables );
     promise = promise.then( getMetaProgramRules );
-    promise = promise.then( getProgramRules );
-    promise = promise.then( getMetaProgramValidations );
-    promise = promise.then( getProgramValidations );   
+    promise = promise.then( getProgramRules );       
     promise = promise.then( getMetaProgramIndicators );
     promise = promise.then( getProgramIndicators );
     promise = promise.then( getOrgUnitLevels );
-    promise = promise.then( getTrackedEntityAttributeGroups );
     promise.done(function() {        
         //Enable ou selection after meta-data has downloaded
         $( "#orgUnitTree" ).removeClass( "disable-clicks" );
@@ -170,7 +168,7 @@
     
     var def = $.Deferred();
     var promise = def.promise();
-    promise = promise.then( getD2Object(null, 'USER_ROLES', '../api/me.json', 'fields=id,name,userCredentials[userRoles[id,authorities]]', 'sessionStorage') );
+    promise = promise.then( dhis2.tracker.getTrackerObject(null, 'USER_ROLES', '../api/me.json', 'fields=id,name,userCredentials[userRoles[id,authorities]]', 'sessionStorage', dhis2.tc.store) );
     promise = promise.done(function(){});    
     def.resolve();
 }
@@ -179,7 +177,7 @@
 {   
     var def = $.Deferred();
     var promise = def.promise();
-    promise = promise.then( getD2Object(null, 'CALENDAR_SETTING', '../api/systemSettings', 'key=keyCalendar&key=keyDateFormat', 'localStorage') );
+    promise = promise.then( dhis2.tracker.getTrackerObject(null, 'CALENDAR_SETTING', '../api/systemSettings', 'key=keyCalendar&key=keyDateFormat', 'localStorage', dhis2.tc.store) );
     promise = promise.done(function(){});    
     def.resolve();    
 }
@@ -190,17 +188,27 @@
         if(res.length > 0){
             return;
         }        
-        return getD2Objects('constants', 'constants', '../api/constants.json', 'paging=false&fields=id,name,displayName,value', 'idb');        
+        return dhis2.tracker.getTrackerObjects('constants', 'constants', '../api/constants.json', 'paging=false&fields=id,name,displayName,value', 'idb', dhis2.tc.store);        
     });    
 }
 
+function getOrgUnitLevels()
+{
+    dhis2.tc.store.getKeys( 'ouLevels').done(function(res){        
+        if(res.length > 0){
+            return;
+        }        
+        return dhis2.tracker.getTrackerObjects('ouLevels', 'organisationUnitLevels', '../api/organisationUnitLevels.json', 'filter=level:gt:1&fields=id,name,level&paging=false', 'idb', dhis2.tc.store);
+    }); 
+}
+
 function getRelationships()
 {    
     dhis2.tc.store.getKeys( 'relationshipTypes').done(function(res){        
         if(res.length > 0){
             return;
         }
-        return getD2Objects('relationshipTypes', 'relationshipTypes', '../api/relationshipTypes.json', 'paging=false&fields=id,name,aIsToB,bIsToA,displayName', 'idb');
+        return dhis2.tracker.getTrackerObjects('relationshipTypes', 'relationshipTypes', '../api/relationshipTypes.json', 'paging=false&fields=id,name,aIsToB,bIsToA,displayName', 'idb', dhis2.tc.store);
     });    
 }
 
@@ -210,13 +218,13 @@
         if(res.length > 0){
             return;
         }        
-        return getD2Objects('trackedEntities', 'trackedEntities', '../api/trackedEntities.json', 'paging=false&fields=id,name', 'idb');
+        return dhis2.tracker.getTrackerObjects('trackedEntities', 'trackedEntities', '../api/trackedEntities.json', 'paging=false&fields=id,name', 'idb', dhis2.tc.store);
     });    
 }
 
 function getMetaPrograms()
-{
-    return getD2Objects('programs', 'programs', '../api/programs.json', 'filter=programType:eq:WITH_REGISTRATION&paging=false&fields=id,version,programTrackedEntityAttributes[trackedEntityAttribute[id,optionSet[id,version]]],programStages[id,name,version,minDaysFromStart,standardInterval,periodType,generatedByEnrollmentDate,excecutionDateLabel,repeatable,autoGenerateEvent,openAfterEnrollment,reportDateToUse,programStageDataElements[dataElement[optionSet[id,version]]]]', 'temp');
+{    
+    return dhis2.tracker.getTrackerObjects('programs', 'programs', '../api/programs.json', 'filter=programType:eq:WITH_REGISTRATION&paging=false&fields=id,version,programTrackedEntityAttributes[trackedEntityAttribute[id,optionSet[id,version]]],programStages[id,version,programStageDataElements[dataElement[optionSet[id,version]]]]', 'temp', dhis2.tc.store);
 }
 
 function getPrograms( programs )
@@ -234,13 +242,14 @@
     var builder = $.Deferred();
     var build = builder.promise();
 
+    var ids = [];
     _.each( _.values( programs ), function ( program ) {
         build = build.then(function() {
             var d = $.Deferred();
             var p = d.promise();
             dhis2.tc.store.get('programs', program.id).done(function(obj) {
                 if(!obj || obj.version !== program.version) {
-                    promise = promise.then( getProgram( program.id ) );
+                    ids.push( program.id );
                 }
 
                 d.resolve();
@@ -254,10 +263,17 @@
         def.resolve();
 
         promise = promise.done( function () {
-            mainDef.resolve( programs );
+            var _ids = null;
+            if( ids && ids.length > 0 ){
+                _ids = ids.toString();
+                _ids = '[' + _ids + ']';
+                promise = promise.then( getAllPrograms( _ids ) );
+            } 
+            
+            mainDef.resolve( programs, ids );
         } );
     }).fail(function(){
-        mainDef.resolve( null );
+        mainDef.resolve( null, null );
     });
 
     builder.resolve();
@@ -265,89 +281,43 @@
     return mainPromise;
 }
 
-function getProgram( id )
-{
+function getAllPrograms( ids )
+{    
     return function() {
         return $.ajax( {
-            url: '../api/programs/' + id + '.json',
+            url: '../api/programs.json',
             type: 'GET',
-            data: 'fields=id,name,type,version,displayFrontPageList,dataEntryMethod,enrollmentDateLabel,incidentDateLabel,displayIncidentDate,ignoreOverdueEvents,selectEnrollmentDatesInFuture,selectIncidentDatesInFuture,onlyEnrollOnce,externalAccess,displayOnAllOrgunit,registration,relationshipText,relationshipFromA,relatedProgram[id,name],relationshipType[id,name],trackedEntity[id,name,description],userRoles[id,name],organisationUnits[id,name],userRoles[id,name],programStages[id,name,version,minDaysFromStart,standardInterval,periodType,generatedByEnrollmentDate,excecutionDateLabel,repeatable,autoGenerateEvent,openAfterEnrollment,reportDateToUse],programTrackedEntityAttributes[displayInList,mandatory,allowFutureDate,trackedEntityAttribute[id,unique]]'
-        }).done( function( program ){            
-            var ou = {};
-            if(program.organisationUnits){
-                _.each(_.values( program.organisationUnits), function(o){
-                    ou[o.id] = o.name;
-                });
-            }
-            program.organisationUnits = ou;
-
-            var ur = {};
-            if(program.userRoles){
-                _.each(_.values( program.userRoles), function(u){
-                    ur[u.id] = u.name;
-                });
-            }
-            program.userRoles = ur;            
-            dhis2.tc.store.set( 'programs', program );  
+            data: 'fields=id,name,type,version,displayFrontPageList,dataEntryMethod,enrollmentDateLabel,incidentDateLabel,displayIncidentDate,ignoreOverdueEvents,selectEnrollmentDatesInFuture,selectIncidentDatesInFuture,onlyEnrollOnce,externalAccess,displayOnAllOrgunit,registration,relationshipText,relationshipFromA,relatedProgram[id,name],relationshipType[id,name],trackedEntity[id,name,description],userRoles[id,name],organisationUnits[id,name],userRoles[id,name],programStages[id,name,sortOrder,version,dataEntryForm[id,name,style,htmlCode,format],captureCoordinates,blockEntryForm,autoGenerateEvent,allowGenerateNextVisit,generatedByEnrollmentDate,remindCompleted,hideDueDate,excecutionDateLabel,minDaysFromStart,repeatable,openAfterEnrollment,standardInterval,periodType,reportDateToUse,programStageSections[id,name,programStageDataElements[dataElement[id]]],programStageDataElements[displayInReports,allowProvidedElsewhere,allowFutureDate,compulsory,dataElement[id,code,name,description,formName,valueType,optionSetValue,optionSet[id]]]],programTrackedEntityAttributes[displayInList,mandatory,allowFutureDate,trackedEntityAttribute[id,unique]]&paging=false&filter=id:in:' + ids
+        }).done( function( response ){
+            
+            if(response.programs){
+                _.each(_.values( response.programs), function(program){
+                    var ou = {};
+                    _.each(_.values( program.organisationUnits), function(o){
+                        ou[o.id] = o.name;
+                    });
+                    program.organisationUnits = ou;
+
+                    var ur = {};
+                    _.each(_.values( program.userRoles), function(u){
+                        ur[u.id] = u.name;
+                    });
+                    program.userRoles = ur;
+
+                    dhis2.tc.store.set( 'programs', program );                    
+                    dhis2.tc.store.setAll( 'programStages', program.programStages );
+                });
+            }
         });
     };
 }
 
-function getProgramStages( programs )
-{
-    if( !programs ){
-        return;
-    }
-    
-    var mainDef = $.Deferred();
-    var mainPromise = mainDef.promise();
-
-    var def = $.Deferred();
-    var promise = def.promise();
-
-    var builder = $.Deferred();
-    var build = builder.promise();
-
-    _.each( _.values( programs ), function ( program ) {
-        
-        if(program.programStages){
-            _.each(_.values(program.programStages), function(programStage){
-                build = build.then(function() {
-                    var d = $.Deferred();
-                    var p = d.promise();
-                    dhis2.tc.store.get('programStages', programStage.id).done(function(obj) {
-                        if(!obj || obj.version !== programStage.version) {
-                            promise = promise.then( getD2Object( programStage.id, 'programStages', '../api/programStages', 'fields=id,name,sortOrder,version,dataEntryForm[id,name,style,htmlCode,format],captureCoordinates,blockEntryForm,autoGenerateEvent,allowGenerateNextVisit,generatedByEnrollmentDate,remindCompleted,hideDueDate,excecutionDateLabel,minDaysFromStart,repeatable,openAfterEnrollment,standardInterval,periodType,reportDateToUse,programStageSections[id,name,programStageDataElements[dataElement[id]]],programStageDataElements[displayInReports,allowProvidedElsewhere,allowFutureDate,compulsory,dataElement[id,code,name,description,formName,valueType,optionSetValue,optionSet[id]]]', 'idb' ) );
-                        }
-                        d.resolve();
-                    });
-                    return p;
-                });            
-            });
-        }                             
-    });
-
-    build.done(function() {
-        def.resolve();
-
-        promise = promise.done( function () {
-            mainDef.resolve( programs );
-        } );
-    }).fail(function(){
-        mainDef.resolve( null );
-    });
-
-    builder.resolve();
-
-    return mainPromise;    
-}
-
-function getOptionSetsForDataElements( programs )
-{
-    if( !programs ){
-        return;
-    }
-    
+function getOptionSetsForDataElements( programs, programIds )
+{
+    if( !programs ){
+        return;
+    }
+
     var mainDef = $.Deferred();
     var mainPromise = mainDef.promise();
 
@@ -370,9 +340,7 @@
                                 var p = d.promise();
                                 dhis2.tc.store.get('optionSets', prStDe.dataElement.optionSet.id).done(function(obj) {                                    
                                     if( (!obj || obj.version !== prStDe.dataElement.optionSet.version) && optionSetsInPromise.indexOf(prStDe.dataElement.optionSet.id) === -1) {                                
-                                        optionSetsInPromise.push( prStDe.dataElement.optionSet.id );
-                                        promise = promise.then( getD2Object( prStDe.dataElement.optionSet.id, 'optionSets', '../api/optionSets', 'fields=id,name,version,options[id,name,code]', 'idb' ) );
-                                    }
+                                        optionSetsInPromise.push( prStDe.dataElement.optionSet.id );                                    }
                                     d.resolve();
                                 });
 
@@ -387,9 +355,8 @@
 
     build.done(function() {
         def.resolve();
-
         promise = promise.done( function () {
-            mainDef.resolve( programs );
+            mainDef.resolve( programs, programIds );
         } );
     }).fail(function(){
         mainDef.resolve( null );
@@ -400,7 +367,7 @@
     return mainPromise;    
 }
 
-function getMetaTrackeEntityAttributes( programs ){
+function getMetaTrackeEntityAttributes( programs, programIds ){
     
     var def = $.Deferred();
     
@@ -424,7 +391,7 @@
             }
         });
         
-        def.resolve( {trackedEntityAttributes: trackedEntityAttributes, programs: programs} );
+        def.resolve( {trackedEntityAttributes: trackedEntityAttributes, programs: programs, programIds: programIds} );
         
     }).fail(function(){
         def.resolve( null );
@@ -455,7 +422,6 @@
             dhis2.tc.store.get('attributes', teAttribute.id).done(function(obj) {
                 if((!obj || obj.version !== teAttribute.version) && attributesInPromise.indexOf(teAttribute.id) === -1) {
                     attributesInPromise.push( teAttribute.id );
-                    promise = promise.then( getD2Object( teAttribute.id, 'attributes', '../api/trackedEntityAttributes', 'fields=id,name,code,version,description,valueType,optionSetValue,confidential,inherit,sortOrderInVisitSchedule,sortOrderInListNoProgram,displayOnVisitSchedule,displayInListNoProgram,unique,programScope,orgunitScope,confidential,optionSet[id,version],trackedEntity[id,name]', 'idb' ) );
                 }
                 d.resolve();
             });
@@ -467,7 +433,18 @@
         def.resolve();
 
         promise = promise.done( function () {
-            mainDef.resolve( {trackedEntityAttributes: data.trackedEntityAttributes, programs: data.programs} );
+            if( attributesInPromise && attributesInPromise.length > 0 ){
+                var _attributesInPromise = attributesInPromise.toString();
+                _attributesInPromise = '[' + _attributesInPromise + ']';
+                
+                var filter = 'fields=id,name,code,version,description,valueType,optionSetValue,confidential,inherit,sortOrderInVisitSchedule,sortOrderInListNoProgram,displayOnVisitSchedule,displayInListNoProgram,unique,programScope,orgunitScope,confidential,optionSet[id,version],trackedEntity[id,name]';
+                filter = filter + '&filter=id:in:' + _attributesInPromise + '&paging=false';
+                
+                var url = '../api/trackedEntityAttributes';
+                promise = promise.then( dhis2.tracker.getTrackerObjects( 'attributes', 'trackedEntityAttributes', url, filter, 'idb', dhis2.tc.store ) );
+            }            
+            
+            mainDef.resolve( {trackedEntityAttributes: data.trackedEntityAttributes, programs: data.programs, programIds: data.programIds} );
         } );
     }).fail(function(){
         mainDef.resolve( null );
@@ -501,7 +478,6 @@
                 dhis2.tc.store.get('optionSets', teAttribute.optionSet.id).done(function(obj) {                            
                     if((!obj || obj.version !== teAttribute.optionSet.version) && optionSetsInPromise.indexOf(teAttribute.optionSet.id) === -1) {                                
                         optionSetsInPromise.push(teAttribute.optionSet.id);
-                        promise = promise.then( getD2Object( teAttribute.optionSet.id, 'optionSets', '../api/optionSets', 'fields=id,name,version,options[id,name,code]', 'idb' ) );
                     }
                     d.resolve();
                 });
@@ -515,10 +491,22 @@
         def.resolve();
 
         promise = promise.done( function () {
-            mainDef.resolve( data.programs );
+            
+            if( optionSetsInPromise && optionSetsInPromise.length > 0 ){
+                var _optionSetsInPromise = optionSetsInPromise.toString();
+                _optionSetsInPromise = '[' + _optionSetsInPromise + ']';
+                
+                var filter = 'fields=id,name,version,options[id,name,code]';                
+                filter = filter + '&filter=id:in:' + _optionSetsInPromise + '&paging=false';
+                
+                var url = '../api/optionSets';
+                promise = promise.then( dhis2.tracker.getTrackerObjects( 'optionSets', 'optionSets', url, filter, 'idb', dhis2.tc.store ) );
+            }
+            
+            mainDef.resolve( data.programs, data.programIds );
         } );
     }).fail(function(){
-        mainDef.resolve( null );
+        mainDef.resolve( null, null);
     });
 
     builder.resolve();
@@ -526,210 +514,43 @@
     return mainPromise;    
 }
 
-function getOrgUnitLevels()
-{
-    dhis2.tc.store.getKeys( 'ouLevels').done(function(res){        
-        if(res.length > 0){
-            return;
-        }        
-        return getD2Objects('ouLevels', 'organisationUnitLevels', '../api/organisationUnitLevels.json', 'filter=level:gt:1&fields=id,name,level&paging=false', 'idb');        
-    }); 
-}
-
-function getTrackedEntityAttributeGroups()
-{
-    dhis2.tc.store.getKeys( 'attributeGroups').done(function(res){        
-        if(res.length > 0){
-            return;
-        }        
-        return getD2Objects('attributeGroups', 'trackedEntityAttributeGroups', '../api/trackedEntityAttributeGroups.json', 'fields=id,name,trackedEntityAttributes[id]&paging=false', 'idb');        
-    }); 
-}
-
-function getMetaProgramValidations( programs )
-{    
-    return getD2MetaObject(programs, 'programValidations', '../api/programValidations.json', 'paging=false&fields=id,program[id]');
+function getMetaProgramValidations( programs, programIds )
+{
+    programs.programIds = programIds;
+    return dhis2.tracker.getTrackerMetaObjects(programs, 'programValidations', '../api/programValidations.json', 'paging=false&fields=id&filter=program.id:in:');
 }
 
 function getProgramValidations( programValidations )
 {
-    return checkAndGetD2Objects( programValidations, 'programValidations', '../api/programValidations', 'fields=id,name,displayName,operator,rightSide[expression,description],leftSide[expression,description],program[id]');
+    return dhis2.tracker.checkAndGetTrackerObjects( programValidations, 'programValidations', '../api/programValidations', 'fields=id,name,displayName,operator,rightSide[expression,description],leftSide[expression,description],program[id]', dhis2.tc.store);
 }
 
 function getMetaProgramIndicators( programs )
 {    
-    return getD2MetaObject(programs, 'programIndicators', '../api/programIndicators.json', 'paging=false&fields=id,program[id]');
+    return dhis2.tracker.getTrackerMetaObjects(programs, 'programIndicators', '../api/programIndicators.json', 'paging=false&fields=id&filter=program.id:in:');
 }
 
 function getProgramIndicators( programIndicators )
 {
-    return checkAndGetD2Objects( programIndicators, 'programIndicators', '../api/programIndicators', 'fields=id,name,code,shortName,displayInForm,expression,displayDescription,rootDate,description,valueType,DisplayName,filter,program[id]');
+    return dhis2.tracker.checkAndGetTrackerObjects( programIndicators, 'programIndicators', '../api/programIndicators', 'fields=id,name,code,shortName,displayInForm,expression,displayDescription,rootDate,description,valueType,DisplayName,filter,program[id]', dhis2.tc.store);
 }
 
 function getMetaProgramRules( programs )
 {    
-    return getD2MetaObject(programs, 'programRules', '../api/programRules.json', 'paging=false&fields=id,program[id]');
+    return dhis2.tracker.getTrackerMetaObjects(programs, 'programRules', '../api/programRules.json', 'paging=false&fields=id&filter=program.id:in:');
 }
 
 function getProgramRules( programRules )
 {
-    return checkAndGetD2Objects( programRules, 'programRules', '../api/programRules', 'fields=id,name,condition,description,program[id],programStage[id],priority,programRuleActions[id,content,location,data,programRuleActionType,programStageSection[id],dataElement[id],trackedEntityAttribute[id],programIndicator[id],programStage[id]]');
+    return dhis2.tracker.checkAndGetTrackerObjects( programRules, 'programRules', '../api/programRules', 'fields=id,name,condition,description,program[id],programStage[id],priority,programRuleActions[id,content,location,data,programRuleActionType,programStageSection[id],dataElement[id],trackedEntityAttribute[id],programIndicator[id],programStage[id]]', dhis2.tc.store);
 }
 
 function getMetaProgramRuleVariables( programs )
 {    
-    return getD2MetaObject(programs, 'programRuleVariables', '../api/programRuleVariables.json', 'paging=false&fields=id,program[id]');
+    return dhis2.tracker.getTrackerMetaObjects(programs, 'programRuleVariables', '../api/programRuleVariables.json', 'paging=false&fields=id&filter=program.id:in:');
 }
 
 function getProgramRuleVariables( programRuleVariables )
 {
-    return checkAndGetD2Objects( programRuleVariables, 'programRuleVariables', '../api/programRuleVariables', 'fields=id,name,displayName,programRuleVariableSourceType,program[id],programStage[id],dataElement[id],trackedEntityAttribute[id]');
-}
-
-function getD2MetaObject( programs, objNames, url, filter )
-{
-    if( !programs ){
-        return;
-    }
-    
-    var def = $.Deferred();
-    
-    var programIds = [];
-    _.each( _.values( programs ), function ( program ) { 
-        if( program.id ) {
-            programIds.push( program.id );
-        }
-    });
-    
-    $.ajax({
-        url: url,
-        type: 'GET',
-        data:filter
-    }).done( function(response) {          
-        var objs = [];
-        _.each( _.values( response[objNames]), function ( o ) { 
-            if( o &&
-                o.id &&
-                o.program &&
-                o.program.id &&
-                programIds.indexOf( o.program.id ) !== -1) {
-            
-                objs.push( o );
-            }  
-            
-        });
-        
-        def.resolve( {programs: programs, self: objs} );
-        
-    }).fail(function(){
-        def.resolve( null );
-    });
-    
-    return def.promise();    
-}
-
-function checkAndGetD2Objects( obj, store, url, filter )
-{
-    if( !obj || !obj.programs || !obj.self ){
-        return;
-    }
-    
-    var mainDef = $.Deferred();
-    var mainPromise = mainDef.promise();
-
-    var def = $.Deferred();
-    var promise = def.promise();
-
-    var builder = $.Deferred();
-    var build = builder.promise();
-
-    _.each( _.values( obj.self ), function ( obj) {
-        build = build.then(function() {
-            var d = $.Deferred();
-            var p = d.promise();
-            dhis2.tc.store.get(store, obj.id).done(function(o) {
-                if(!o) {
-                    promise = promise.then( getD2Object( obj.id, store, url, filter, 'idb' ) );
-                }
-                d.resolve();
-            });
-
-            return p;
-        });
-    });
-
-    build.done(function() {
-        def.resolve();
-        promise = promise.done( function () {
-            mainDef.resolve( obj.programs );
-        } );
-    }).fail(function(){
-        mainDef.resolve( null );
-    });
-
-    builder.resolve();
-
-    return mainPromise;
-}
-
-function getD2Objects(store, objs, url, filter, storage)
-{
-    var def = $.Deferred();
-
-    $.ajax({
-        url: url,
-        type: 'GET',
-        data: filter
-    }).done(function(response) {
-        if(response[objs]){            
-            if(storage === 'idb'){
-                dhis2.tc.store.setAll( store, response[objs] );
-            }
-            if(storage === 'localStorage'){                
-                localStorage[store] = JSON.stringify(response[objs]);
-            }            
-            if(storage === 'sessionStorage'){
-                var SessionStorageService = angular.element('body').injector().get('SessionStorageService');
-                SessionStorageService.set(store, response[objs]);
-            }
-        }
-        
-        if(storage === 'temp'){
-            def.resolve(response[objs] ? response[objs] : []);
-        }
-        else{
-            def.resolve();
-        }    
-    }).fail(function(){
-        def.resolve();
-    });
-
-    return def.promise();
-}
-
-function getD2Object( id, store, url, filter, storage )
-{
-    return function() {
-        if(id){
-            url = url + '/' + id + '.json';
-        }
-        return $.ajax( {
-            url: url,
-            type: 'GET',            
-            data: filter
-        }).done( function( response ){
-            if(storage === 'idb'){
-                if( response && response.id) {
-                    dhis2.tc.store.set( store, response );
-                }
-            }
-            if(storage === 'localStorage'){
-                localStorage[store] = JSON.stringify(response);
-            }            
-            if(storage === 'sessionStorage'){
-                var SessionStorageService = angular.element('body').injector().get('SessionStorageService');
-                SessionStorageService.set(store, response);
-            }            
-        });
-    };
+    return dhis2.tracker.checkAndGetTrackerObjects( programRuleVariables, 'programRuleVariables', '../api/programRuleVariables', 'fields=id,name,displayName,programRuleVariableSourceType,program[id],programStage[id],dataElement[id],trackedEntityAttribute[id]', dhis2.tc.store);
 }
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/views/home.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/views/home.html	2015-12-16 09:17:18 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/views/home.html	2015-12-23 08:56:16 +0000
@@ -131,9 +131,7 @@
         <!--- Error display for search ends -->
 
         <!--registration form begins -->
-        <div class="row" ng-if="showRegistrationDiv">            
-            <div class="col-sm-8 bordered-div " ng-include="'components/registration/registration.html'"></div>
-        </div>
+        <div class="col-sm-8 bordered-div" ng-if="showRegistrationDiv" ng-include="'components/registration/registration.html'"></div>
         <!-- registration form ends -->        
 
         <!-- entity grid begins -->

=== removed file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.map.contextmenu.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.map.contextmenu.js	2015-03-05 15:48:50 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.map.contextmenu.js	1970-01-01 00:00:00 +0000
@@ -1,138 +0,0 @@
-/*
-	MapContextMenu v1.0
-	
-	A context menu for Google Maps API v3
-	http://code.martinpearman.co.uk/googlemapsapi/contextmenu/
-	
-	Copyright Martin Pearman
-	Last updated 21st November 2011
-	
-	developer@xxxxxxxxxxxxxxxxxxx
-	
-	This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
-
-	This program 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 General Public License for more details.
-
-	You should have received a copy of the GNU General Public License along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-function MapContextMenu(map, options){
-	options=options || {};
-	
-	this.setMap(map);
-	
-	this.classNames_=options.classNames || {};
-	this.map_=map;
-	this.mapDiv_=map.getDiv();
-	this.menuItems_=options.menuItems || [];
-	this.pixelOffset=options.pixelOffset || new google.maps.Point(10, -5);
-}
-
-MapContextMenu.prototype=new google.maps.OverlayView();
-
-MapContextMenu.prototype.draw=function(){
-	if(this.isVisible_){
-		var mapSize=new google.maps.Size(this.mapDiv_.offsetWidth, this.mapDiv_.offsetHeight);
-		var menuSize=new google.maps.Size(this.menu_.offsetWidth, this.menu_.offsetHeight);
-		var mousePosition=this.getProjection().fromLatLngToDivPixel(this.position_);
-		
-		var left=mousePosition.x;
-		var top=mousePosition.y;
-		
-		if(mousePosition.x>mapSize.width-menuSize.width-this.pixelOffset.x){
-			left=left-menuSize.width-this.pixelOffset.x;
-		} else {
-			left+=this.pixelOffset.x;
-		}
-		
-		if(mousePosition.y>mapSize.height-menuSize.height-this.pixelOffset.y){
-			top=top-menuSize.height-this.pixelOffset.y;
-		} else {
-			top+=this.pixelOffset.y;
-		}
-		
-		this.menu_.style.left=left+'px';
-		this.menu_.style.top=top+'px';
-	}
-};
-
-MapContextMenu.prototype.getVisible=function(){
-	return this.isVisible_;
-};
-
-MapContextMenu.prototype.hide=function(){
-	if(this.isVisible_){
-		this.menu_.style.display='none';
-		this.isVisible_=false;
-	}
-};
-
-MapContextMenu.prototype.onAdd=function(){
-	function createMenuItem(values){        
-		var menuItem=document.createElement('div');
-		menuItem.innerHTML=values.label;
-		if(values.className){
-			menuItem.className=values.className;
-		}
-		if(values.id){
-			menuItem.id=values.id;
-		}
-		menuItem.style.cssText='white-space:nowrap; font-size: 12pt;';
-		menuItem.onclick=function(){
-			google.maps.event.trigger($this, 'menu_item_selected', $this.event_, $this.position_, values.eventName);
-		};
-		return menuItem;
-	}
-	function createMenuSeparator(){
-		var menuSeparator=document.createElement('div');
-		if($this.classNames_.menuSeparator){
-			menuSeparator.className=$this.classNames_.menuSeparator;
-		}
-		return menuSeparator;
-	}
-	var $this=this;	//	used for closures
-	
-	var menu=document.createElement('div');
-	if(this.classNames_.menu){
-		menu.className=this.classNames_.menu;
-	}
-	menu.style.cssText='display:none; position:absolute';
-	
-	for(var i=0, j=this.menuItems_.length; i<j; i++){
-		if(this.menuItems_[i].label && this.menuItems_[i].eventName){
-			menu.appendChild(createMenuItem(this.menuItems_[i]));
-		} else {
-			menu.appendChild(createMenuSeparator());
-		}
-	}
-	
-	delete this.classNames_;
-	delete this.menuItems_;
-	
-	this.isVisible_=false;
-	this.menu_=menu;
-	this.position_=new google.maps.LatLng(0, 0);
-	
-	google.maps.event.addListener(this.map_, 'click', function(mouseEvent){
-		$this.hide();
-	});
-	
-	this.getPanes().floatPane.appendChild(menu);
-};
-
-MapContextMenu.prototype.onRemove=function(){
-	this.menu_.parentNode.removeChild(this.menu_);
-	delete this.mapDiv_;
-	delete this.menu_;
-	delete this.position_;
-};
-
-MapContextMenu.prototype.show=function(e){
-	if(!this.isVisible_){
-		this.menu_.style.display='block';
-		this.isVisible_=true;
-	}
-	this.position_=e.latLng;
-    this.event_=e;
-	this.draw();
-};
\ No newline at end of file

=== removed file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.map.textoverlay.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.map.textoverlay.js	2015-03-04 11:34:55 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.map.textoverlay.js	1970-01-01 00:00:00 +0000
@@ -1,103 +0,0 @@
-// https://developers.google.com/maps/documentation/javascript/customoverlays
-/** @constructor */
-function Dhis2TextOverlay(pos, txt, cls, map) {
-
-    // Initialize properties.
-    this.pos = pos;
-    this.txt_ = txt;
-    this.cls_ = cls;
-    this.map_ = map;
-
-    // Div to contain text
-    this.div_ = null;
-
-    // Explicitly call setMap() on this overlay
-    this.setMap(map);
-}
-
-Dhis2TextOverlay.prototype = new google.maps.OverlayView();
-
-
-/**
- * onAdd is called when the map's panes are ready and the overlay has been
- * added to the map.
- */
-Dhis2TextOverlay.prototype.onAdd = function () {
-
-    // Create the DIV and set some basic attributes.
-    var div = document.createElement('DIV');
-    div.className = this.cls_;
-    div.innerHTML = this.txt_;
-
-    // Set the overlay's div_ property to this DIV
-    this.div_ = div;
-    var overlayProjection = this.getProjection();
-    var position = overlayProjection.fromLatLngToDivPixel(this.pos);
-    div.style.left = position.x + 'px';
-    div.style.top = position.y + 'px';
-    
-    // Add the element to the "overlayLayer" pane.
-    var panes = this.getPanes();
-    panes.floatPane.appendChild(div);
-};
-
-Dhis2TextOverlay.prototype.draw = function () {
-
-    // We use the south-west and north-east
-    // coordinates of the overlay to peg it to the correct position and size.
-    // To do this, we need to retrieve the projection from the overlay.
-    var overlayProjection = this.getProjection();
-
-    // Retrieve the southwest and northeast coordinates of this overlay
-    // in latlngs and convert them to pixels coordinates.
-    // We'll use these coordinates to resize the DIV.
-    var position = overlayProjection.fromLatLngToDivPixel(this.pos);
-
-    // Resize the div to fit the indicated dimensions.
-    var div = this.div_;
-    div.style.left = position.x + 'px';
-    div.style.top = position.y + 'px';
-};
-
-// The onRemove() method will be called automatically from the API if
-// we ever set the overlay's map property to 'null'
-Dhis2TextOverlay.prototype.onRemove = function () {
-    this.div_.parentNode.removeChild(this.div_);
-    this.div_ = null;
-};
-
-// Set the visibility to 'hidden' or 'visible'.
-Dhis2TextOverlay.prototype.hide = function () {
-    if (this.div_) {
-        this.div_.style.visibility = "hidden";
-    }
-};
-
-Dhis2TextOverlay.prototype.show = function () {
-    if (this.div_) {
-        this.div_.style.visibility = "visible";
-    }
-};
-
-Dhis2TextOverlay.prototype.toggle = function () {
-    if (this.div_) {
-        if (this.div_.style.visibility === "hidden") {
-            this.show();
-        }
-        else {
-            this.hide();
-        }
-    }
-};
-
-// Detach the map from the DOM via toggleDOM().
-// Note that if we later reattach the map, it will be visible again,
-// because the containing <div> is recreated in the overlay's onAdd() method.
-Dhis2TextOverlay.prototype.toggleDOM = function () {
-    if (this.getMap()) {
-        this.setMap(null);
-    }
-    else {
-        this.setMap(this.map_);
-    }
-};

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.tracker.metadata.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.tracker.metadata.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.tracker.metadata.js	2015-12-23 08:56:16 +0000
@@ -0,0 +1,170 @@
+"use strict";
+
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+dhis2.util.namespace('dhis2.tracker');
+
+dhis2.tracker.getTrackerMetaObjects = function( programs, objNames, url, filter )
+{
+    if( !programs || !programs.programIds || programs.programIds.length === 0 ){
+        return;
+    }       
+
+    filter = filter + '[' + programs.programIds.toString() + ']';
+    
+    var def = $.Deferred();
+    
+    $.ajax({
+        url: url,
+        type: 'GET',
+        data:filter
+    }).done( function(response) {
+        
+        def.resolve( {programs: programs, self: response[objNames], programIds: programs.programIds} );
+        
+    }).fail(function(){
+        def.resolve( null );
+    });
+    
+    return def.promise();    
+};
+
+dhis2.tracker.checkAndGetTrackerObjects  = function( obj, store, url, filter, db )
+{
+    if( !obj || !obj.programs || !obj.programIds || !obj.self || !db ){
+        return;
+    }
+    
+    var mainDef = $.Deferred();
+    var mainPromise = mainDef.promise();
+
+    var def = $.Deferred();
+    var promise = def.promise();
+
+    var builder = $.Deferred();
+    var build = builder.promise();
+
+    var ids = [];
+    _.each( _.values( obj.self ), function ( obj) {
+        build = build.then(function() {
+            var d = $.Deferred();
+            var p = d.promise();
+            db.get(store, obj.id).done(function(o) {
+                if(!o) {                    
+                    ids.push( obj.id );
+                }
+                d.resolve();
+            });
+
+            return p;
+        });
+    });
+
+    build.done(function() {
+        def.resolve();
+        promise = promise.done( function () {
+            
+            if( ids && ids.length > 0 ){
+                var _ids = ids.toString();
+                _ids = '[' + _ids + ']';
+                filter = filter + '&filter=id:in:' + _ids + '&paging=false';
+                promise = promise.then( dhis2.tracker.getTrackerObjects( store, store, url, filter, 'idb', db ) );
+            }
+            
+            mainDef.resolve( obj.programs, obj.programIds );
+        } );
+    }).fail(function(){
+        mainDef.resolve( null );
+    });
+
+    builder.resolve();
+
+    return mainPromise;
+};
+
+dhis2.tracker.getTrackerObjects = function( store, objs, url, filter, storage, db )
+{
+    var def = $.Deferred();
+
+    $.ajax({
+        url: url,
+        type: 'GET',
+        data: filter
+    }).done(function(response) {
+        if(response[objs]){
+            if(storage === 'idb'){
+                db.setAll( store, response[objs] );
+            }
+            if(storage === 'localStorage'){                
+                localStorage[store] = JSON.stringify(response[objs]);
+            }            
+            if(storage === 'sessionStorage'){
+                var SessionStorageService = angular.element('body').injector().get('SessionStorageService');
+                SessionStorageService.set(store, response[objs]);
+            }
+        }
+        
+        if(storage === 'temp'){
+            def.resolve(response[objs] ? response[objs] : []);
+        }
+        else{
+            def.resolve();
+        }    
+    }).fail(function(){
+        def.resolve();
+    });
+
+    return def.promise();
+};
+
+dhis2.tracker.getTrackerObject = function( id, store, url, filter, storage, db )
+{
+    return function() {
+        if(id){
+            url = url + '/' + id + '.json';
+        }
+        return $.ajax( {
+            url: url,
+            type: 'GET',            
+            data: filter
+        }).done( function( response ){
+            if(storage === 'idb'){
+                if( response && response.id) {
+                    db.set( store, response );
+                }
+            }
+            if(storage === 'localStorage'){
+                localStorage[store] = JSON.stringify(response);
+            }            
+            if(storage === 'sessionStorage'){
+                var SessionStorageService = angular.element('body').injector().get('SessionStorageService');
+                SessionStorageService.set(store, response);
+            }            
+        });
+    };
+};
\ No newline at end of file