← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 18207: tracker-capture: changes to dashboard layout are now pesisted per user per program

 

------------------------------------------------------------
revno: 18207
committer: Abyot Asalefew Gizaw <abyota@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2015-02-09 18:04:31 +0100
message:
  tracker-capture: changes to dashboard layout are now pesisted per user per program
modified:
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard-controller.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/enrollment/enrollment-controller.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/profile/profile-controller.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js


--
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-tracker-capture/components/dashboard/dashboard-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard-controller.js	2015-02-06 20:22:45 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard-controller.js	2015-02-09 17:04:31 +0000
@@ -3,53 +3,91 @@
         function($rootScope,
                 $scope,
                 $location,
+                $route,
                 $modal,
                 $timeout,
+                $filter,
+                orderByFilter,
                 storage,
                 TEIService, 
                 TEService,
                 OptionSetService,
                 EnrollmentService,
                 ProgramFactory,
+                DashboardLayoutService,
                 CurrentSelection) {
-    //dashboard items   
-    $rootScope.dashboardWidgets = [];
-    $rootScope.dashboardStatus = [];
-    $scope.widgetsChanged = [];
-    
-    $rootScope.enrollmentWidget = {title: 'enrollment', view: "components/enrollment/enrollment.html", show: true, expand: true, parent: 'biggerWidget', order: 0};
-    $rootScope.dataentryWidget = {title: 'dataentry', view: "components/dataentry/dataentry.html", show: true, expand: true, parent: 'biggerWidget', order: 1};
-    $rootScope.reportWidget = {title: 'report', view: "components/report/tei-report.html", show: true, expand: true, parent: 'biggerWidget', order: 2};
-    $rootScope.selectedWidget = {title: 'current_selections', view: "components/selected/selected.html", show: false, expand: true, parent: 'smallerWidget', order: 0};
-    $rootScope.profileWidget = {title: 'profile', view: "components/profile/profile.html", show: true, expand: true, parent: 'smallerWidget', order: 1};
-    $rootScope.relationshipWidget = {title: 'relationships', view: "components/relationship/relationship.html", show: true, expand: true, parent: 'smallerWidget', order: 2};
-    $rootScope.notesWidget = {title: 'notes', view: "components/notes/notes.html", show: true, expand: true, parent: 'smallerWidget', order: 3};  
-    
-    $scope.dashboardStatus['enrollment'] = {title: 'enrollment', view: "components/enrollment/enrollment.html", show: true, expand: true, parent: 'biggerWidget', order: 0};
-    $scope.dashboardStatus['dataentry'] = {title: 'dataentry', view: "components/dataentry/dataentry.html", show: true, expand: true, parent: 'biggerWidget', order: 1};
-    $scope.dashboardStatus['report'] = {title: 'report', view: "components/report/tei-report.html", show: true, expand: true, parent: 'biggerWidget', order: 2};
-    $scope.dashboardStatus['current_selections'] = {title: 'current_selections', view: "components/selected/selected.html", show: false, expand: true, parent: 'smallerWidget', order: 0};
-    $scope.dashboardStatus['profile'] = {title: 'profile', view: "components/profile/profile.html", show: true, expand: true, parent: 'smallerWidget', order: 1};
-    $scope.dashboardStatus['relationships'] = {title: 'relationships', view: "components/relationship/relationship.html", show: true, expand: true, parent: 'smallerWidget', order: 2};
-    $scope.dashboardStatus['notes'] = {title: 'notes', view: "components/notes/notes.html", show: true, expand: true, parent: 'smallerWidget', order: 3};  
-    
-    $scope.dashboardWidgetsOrder = {biggerWidgets: ['enrollment', 'dataentry', 'report'], smallerWidgets: ['current_selections', 'profile', 'relationships', 'notes']};
-    
-    $rootScope.dashboardWidgets.push($rootScope.enrollmentWidget);
-    $rootScope.dashboardWidgets.push($rootScope.dataentryWidget);
-    $rootScope.dashboardWidgets.push($rootScope.reportWidget);
-    $rootScope.dashboardWidgets.push($rootScope.selectedWidget);
-    $rootScope.dashboardWidgets.push($rootScope.profileWidget);
-    $rootScope.dashboardWidgets.push($rootScope.relationshipWidget);
-    $rootScope.dashboardWidgets.push($rootScope.notesWidget);
-    
     //selections
     $scope.selectedTeiId = ($location.search()).tei; 
     $scope.selectedProgramId = ($location.search()).program; 
     $scope.selectedOrgUnit = storage.get('SELECTED_OU');
-
     $scope.selectedProgram;    
-    $scope.selectedTei;    
+    $scope.selectedTei;   
+    
+    //dashboard items   
+    var getDashboardLayout = function(){        
+        $rootScope.dashboardWidgets = [];    
+        $scope.widgetsChanged = [];
+        $scope.dashboardStatus = [];
+        $scope.dashboardWidgetsOrder = {biggerWidgets: [], smallerWidgets: []};
+        $scope.orderChanged = false;
+        
+        DashboardLayoutService.get().then(function(response){
+            $scope.dashboardLayouts = response;
+            
+            var selectedLayout = $scope.dashboardLayouts ['DEFAULT'];            
+            if($scope.selectedProgram && $scope.selectedProgram.id){
+                selectedLayout = $scope.dashboardLayouts [$scope.selectedProgram.id] ? $scope.dashboardLayouts [$scope.selectedProgram.id] : selectedLayout;
+            }
+
+            for(var widget in selectedLayout.widgets){
+                switch(selectedLayout.widgets[widget].title){
+                    case 'enrollment':
+                        $rootScope.enrollmentWidget = selectedLayout.widgets[widget];
+                        $rootScope.dashboardWidgets.push($rootScope.enrollmentWidget);
+                        $scope.dashboardStatus[widget] = selectedLayout.widgets[widget];
+                        break;
+                    case 'dataentry':
+                        $rootScope.dataentryWidget = selectedLayout.widgets[widget];
+                        $rootScope.dashboardWidgets.push($rootScope.dataentryWidget);
+                        $scope.dashboardStatus[widget] = selectedLayout.widgets[widget];
+                        break;
+                    case 'report':
+                        $rootScope.reportWidget = selectedLayout.widgets[widget];
+                        $rootScope.dashboardWidgets.push($rootScope.reportWidget);
+                        $scope.dashboardStatus[widget] = selectedLayout.widgets[widget];
+                        break;
+                    case 'current_selections':
+                        $rootScope.selectedWidget = selectedLayout.widgets[widget];
+                        $rootScope.dashboardWidgets.push($rootScope.selectedWidget);
+                        $scope.dashboardStatus[widget] = selectedLayout.widgets[widget];
+                        break;
+                    case 'profile':
+                        $rootScope.profileWidget = selectedLayout.widgets[widget];
+                        $rootScope.dashboardWidgets.push($rootScope.profileWidget);
+                        $scope.dashboardStatus[widget] = selectedLayout.widgets[widget];
+                        break;
+                    case 'relationships':
+                        $rootScope.relationshipWidget = selectedLayout.widgets[widget];
+                        $rootScope.dashboardWidgets.push($rootScope.relationshipWidget);
+                        $scope.dashboardStatus[widget] = selectedLayout.widgets[widget];
+                        break;    
+                    case 'notes':
+                        $rootScope.notesWidget = selectedLayout.widgets[widget];
+                        $rootScope.dashboardWidgets.push($rootScope.notesWidget);
+                        $scope.dashboardStatus[widget] = selectedLayout.widgets[widget];
+                        break;    
+                }
+            }
+
+            angular.forEach(orderByFilter($filter('filter')($scope.dashboardWidgets, {parent: "biggerWidget"}), 'order'), function(w){
+                $scope.dashboardWidgetsOrder.biggerWidgets.push(w.title);
+            });
+
+            angular.forEach(orderByFilter($filter('filter')($scope.dashboardWidgets, {parent: "smallerWidget"}), 'order'), function(w){
+                $scope.dashboardWidgetsOrder.smallerWidgets.push(w.title);
+            });
+        });        
+    };
     
     if($scope.selectedTeiId){
         
@@ -90,7 +128,9 @@
                                 if($scope.selectedProgramId && program.id === $scope.selectedProgramId || selectedEnrollment && selectedEnrollment.program === program.id){
                                     $scope.selectedProgram = program;
                                 }
-                            }); 
+                            });
+                            
+                            getDashboardLayout();                            
 
                             //broadcast selected items for dashboard controllers
                             CurrentSelection.set({tei: $scope.selectedTei, te: $scope.trackedEntity, prs: $scope.programs, pr: $scope.selectedProgram, enrollments: response.enrollments, selectedEnrollment: selectedEnrollment, optionSets: $scope.optionSets});
@@ -104,7 +144,7 @@
     
     //listen for any change to program selection
     //it is possible that such could happen during enrollment.
-    $scope.$on('mainDashboard', function(event, args) { 
+    $scope.$on('mainDashboard', function(event, args) {
         var selections = CurrentSelection.get();
         $scope.selectedProgram = null;
         angular.forEach($scope.programs, function(pr){
@@ -112,7 +152,6 @@
                 $scope.selectedProgram = pr;
             }
         });
-        $scope.broadCastSelections(); 
     }); 
     
     //watch for widget sorting    
@@ -141,13 +180,18 @@
         }
     });
     
+    $scope.applySelectedProgram = function(){
+        getDashboardLayout();
+        $scope.broadCastSelections(); 
+    };
+    
     $scope.broadCastSelections = function(){
         
         var selections = CurrentSelection.get();
         $scope.selectedTei = selections.tei;
         $scope.trackedEntity = selections.te;
         $scope.optionSets = selections.optionSets;
-      
+        
         CurrentSelection.set({tei: $scope.selectedTei, te: $scope.trackedEntity, prs: $scope.programs, pr: $scope.selectedProgram, enrollments: selections.enrollments, selectedEnrollment: null, optionSets: $scope.optionSets});
         $timeout(function() { 
             $rootScope.$broadcast('selectedItems', {programExists: $scope.programs.length > 0});            
@@ -185,14 +229,40 @@
         }
     };
     
-    $scope.saveDashboardLayout = function(){
-        if($scope.widgetsChanged.length > 0){
-            console.log('dashboardWidgets:  ', $rootScope.dashboardWidgets);
-        }
-        
-        if($scope.orderChanged){
-            console.log('order:  ', $scope.widgetsOrder);
-        }
+    $scope.saveDashboardLayout = function(){        
+        var widgets = [];
+        angular.forEach($rootScope.dashboardWidgets, function(widget){
+            var w = angular.copy(widget);            
+            if($scope.orderChanged){
+                if($scope.widgetsOrder.biggerWidgets.indexOf(w.title) !== -1){
+                    w.parent = 'biggerWidget';
+                    w.order = $scope.widgetsOrder.biggerWidgets.indexOf(w.title);
+                }
+                
+                if($scope.widgetsOrder.smallerWidgets.indexOf(w.title) !== -1){
+                    w.parent = 'smallerWidget';
+                    w.order = $scope.widgetsOrder.smallerWidgets.indexOf(w.title);
+                }
+            }            
+            widgets.push(w);
+        });
+        
+        //$scope.dashboardLayouts 
+            
+        if($scope.selectedProgram && $scope.selectedProgram.id){
+            $scope.dashboardLayouts[$scope.selectedProgram.id] = {widgets: widgets, program: $scope.selectedProgram.id};
+        }
+        
+        DashboardLayoutService.saveLayout($scope.dashboardLayouts).then(function(){            
+            if($scope.selectedProgramId && $scope.selectedProgram && $scope.selectedProgramId === $scope.selectedProgram.id ||
+                    !$scope.selectedProgramId && !$scope.selectedProgram){
+                $route.reload();
+            }
+            else{
+                $location.path('/dashboard').search({tei: $scope.selectedTeiId,                                            
+                                            program: $scope.selectedProgram ? $scope.selectedProgram.id: null});
+            }            
+        });
     };
     
     $scope.showHideWidgets = function(){

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard.html	2015-02-06 20:22:45 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard.html	2015-02-09 17:04:31 +0000
@@ -1,53 +1,3 @@
-<!--<div class="container-1-1">    
-    <div class="col-sm-12 vertical-spacing  not-printable">
-
-        <button type="button" class="btn btn-default" ng-click="back()">{{'back'| translate}}</button>
-
-        <select ng-model="selectedProgram"
-                class="form-control-program"
-                ng-options="program as program.name for program in programs | orderBy: 'name'" 
-                ng-disabled="programs.length < 1"
-                ng-change="broadCastSelections()">
-            <option value="">{{programs.length > 0 ? 'please_select_a_program' : 'no_program_exists' | translate}}</option>
-        </select>
-
-        <div class="pull-right">
-            <span ng-if="widgetsChanged.length > 0">
-                <span class="trimmed-alert alert-danger">{{'dashboard_layout_not_saved'| translate}}</span><button type="button" class="btn btn-primary small-horizonal-spacing" ng-click="saveDashboardLayout()">{{'save'| translate}}</button>
-            </span>
-            <div class="btn-group" dropdown is-open="status.isopen">
-                <button type="button" class="btn btn-default dropdown-toggle">
-                    <i class="fa fa-cog" title="{{'settings'| translate}}"></i>
-                </button>
-                <ul class="dropdown-menu pull-right" role="menu">
-                    <li><a href ng-click="showHideWidgets()">{{'show_hide_widgets'| translate}}</a></li>
-                </ul>
-            </div>
-        </div>
-    </div>
-
-    <div class='separator'></div>
-
-    <div class="col-sm-12">
-        <div class="row">            
-            <div class="col-sm-6 col-md-8">
-                <div d2-sortable class="row connectedSortable empty-dashboard-container">
-                    <div class="col-sm-12" ng-repeat="biggerWidget in biggerDashboardWidgets">
-                        <div ng-show="biggerWidget.show" ng-include="biggerWidget.view" ng-class="{true: 'not-printable'} [biggerWidget.title != 'report']"></div>
-                    </div>                                       
-                </div>                
-            </div>            
-            <div class="col-sm-6 col-md-4">
-                <div d2-sortable class="row connectedSortable empty-dashboard-container">                   
-                    <div class="col-sm-12" ng-repeat="smallerWidget in smallerDashboardWidgets">                        
-                        <div ng-show="smallerWidget.show" ng-include="smallerWidget.view" ng-class="{true: 'not-printable'} [smallerWidget.title != 'report']"></div>
-                    </div>                   
-                </div>
-            </div>
-        </div>
-    </div>    
-</div>-->
-
 <div class="container-1-1">    
     <div class="col-sm-12 vertical-spacing  not-printable">
 
@@ -57,12 +7,12 @@
                 class="form-control-program"
                 ng-options="program as program.name for program in programs | orderBy: 'name'" 
                 ng-disabled="programs.length < 1"
-                ng-change="broadCastSelections()">
+                ng-change="applySelectedProgram()">
             <option value="">{{programs.length > 0 ? 'please_select_a_program' : 'no_program_exists' | translate}}</option>
         </select>
 
         <div class="pull-right">
-            <span ng-if="widgetsChanged.length > 0 || orderChanged">
+            <span ng-if="selectedProgram && (widgetsChanged.length > 0 || orderChanged)">
                 <span class="trimmed-alert alert-danger">{{'dashboard_layout_not_saved'| translate}}</span><button type="button" class="btn btn-primary small-horizonal-spacing" ng-click="saveDashboardLayout()">{{'save'| translate}}</button>
             </span>            
             <div class="btn-group" dropdown is-open="status.isopen">

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/enrollment/enrollment-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/enrollment/enrollment-controller.js	2015-02-06 20:22:45 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/enrollment/enrollment-controller.js	2015-02-09 17:04:31 +0000
@@ -17,14 +17,16 @@
                 DialogService) {
     
     $scope.today = DateUtils.getToday();
-    $scope.selectedOrgUnit = storage.get('SELECTED_OU');
-    
-    $scope.attributes = [];
-    $scope.attributesById = [];
+    $scope.selectedOrgUnit = storage.get('SELECTED_OU');    
+      
     AttributesFactory.getAll().then(function(atts){
+        $scope.attributes = [];  
+        $scope.attributesById = [];
         angular.forEach(atts, function(att){
             $scope.attributesById[att.id] = att;
         });
+        
+        CurrentSelection.setAttributesById($scope.attributesById);
     });
     
     //listen for the selected items
@@ -233,7 +235,8 @@
         }, 200);
     };    
     
-    var getProcessedForm = function(){
+    var getProcessedForm = function(){        
+        $scope.attributesById = CurrentSelection.getAttributesById();
         var tei = angular.copy(selections.tei);
         tei.attributes = [];
         var formEmpty = true;
@@ -249,7 +252,7 @@
     
     var processSelectedTei = function(){
         $scope.selectedTei = null;
-        $scope.selectedTei = angular.copy(selections.tei); 
+        $scope.selectedTei = angular.copy(selections.tei);
         angular.forEach($scope.selectedTei.attributes, function(att){
             $scope.selectedTei[att.attribute] = att.value;
         });

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/profile/profile-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/profile/profile-controller.js	2015-02-04 12:53:26 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/profile/profile-controller.js	2015-02-09 17:04:31 +0000
@@ -40,12 +40,13 @@
         angular.forEach($scope.selectedTei.attributes, function(att){
             $scope.selectedTei[att.attribute] = att.value;
         });
+        
         delete $scope.selectedTei.attributes;
         
-        if($scope.selectedProgram && $scope.selectedProgram.id){            
-            AttributesFactory.getByProgram($scope.selectedProgram).then(function(atts){
-                $scope.attributes = atts;
-
+        AttributesFactory.getByProgram($scope.selectedProgram).then(function(atts){
+            $scope.attributes = atts;
+            
+            if($scope.selectedProgram && $scope.selectedProgram.id){
                 $scope.selectedProgram.hasCustomForm = false;               
                 TEFormService.getByProgram($scope.selectedProgram, atts).then(function(teForm){                    
                     if(angular.isObject(teForm)){                        
@@ -55,13 +56,8 @@
                         $scope.customForm = CustomFormService.getForTrackedEntity($scope.trackedEntityForm, $scope.widget);
                     }                    
                 });
-            });                
-        }
-        else{            
-            AttributesFactory.getWithoutProgram().then(function(atts){
-                $scope.attributes = atts;
-            });
-        }
+            }            
+        });
     });
     
     //listen for enrollment editing

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js	2015-02-06 20:22:45 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js	2015-02-09 17:04:31 +0000
@@ -48,6 +48,40 @@
     };
 })
 
+/* Service to fetch/store dasboard widgets */
+.service('DashboardLayoutService', function($http) {
+    
+    var w = {};
+    w.enrollmentWidget = {title: 'enrollment', view: "components/enrollment/enrollment.html", show: true, expand: true, parent: 'biggerWidget', order: 0};
+    w.dataentryWidget = {title: 'dataentry', view: "components/dataentry/dataentry.html", show: true, expand: true, parent: 'biggerWidget', order: 1};
+    w.reportWidget = {title: 'report', view: "components/report/tei-report.html", show: true, expand: true, parent: 'biggerWidget', order: 2};
+    w.selectedWidget = {title: 'current_selections', view: "components/selected/selected.html", show: false, expand: true, parent: 'smallerWidget', order: 0};
+    w.profileWidget = {title: 'profile', view: "components/profile/profile.html", show: true, expand: true, parent: 'smallerWidget', order: 1};
+    w.relationshipWidget = {title: 'relationships', view: "components/relationship/relationship.html", show: true, expand: true, parent: 'smallerWidget', order: 2};
+    w.notesWidget = {title: 'notes', view: "components/notes/notes.html", show: true, expand: true, parent: 'smallerWidget', order: 3};            
+    var defaultLayout = new Object();
+    defaultLayout['DEFAULT'] = {widgets: w, program: 'DEFAULT'};
+    
+    return {
+        saveLayout: function(dashboardLayout){
+            var layout = JSON.stringify(dashboardLayout);
+            var promise = $http.post( '../api/userSettings/dhis2-tracker-dashboard?value=' + layout, '', {headers: {'Content-Type': 'text/plain;charset=utf-8'}}).then(function(response){
+                return response.data;
+            });
+            return promise;            
+        },
+        get: function(){            
+            var promise = $http.get(  '../api/userSettings/dhis2-tracker-dashboard' ).then(function(response){                
+                return response.data === "" ? defaultLayout: response.data;
+            }, function(){
+                console.log('has failed....');
+                return defaultLayout;
+            });
+            return promise;
+        }
+    };
+})
+
 /* Factory to fetch optionSets */
 .factory('OptionSetService', function($q, $rootScope, TCStorageService) { 
     return {
@@ -684,25 +718,36 @@
             return def.promise;            
         }, 
         getByProgram: function(program){
-            
-            var attributes = [];
-            var programAttributes = [];
-
             var def = $q.defer();
-            this.getAll().then(function(atts){
-                angular.forEach(atts, function(attribute){
-                    attributes[attribute.id] = attribute;
-                });
+            this.getAll().then(function(atts){                
+                
+                if(program && program.id){
+                    var attributes = [];
+                    var programAttributes = [];
+                    angular.forEach(atts, function(attribute){
+                        attributes[attribute.id] = attribute;
+                    });
 
-                angular.forEach(program.programTrackedEntityAttributes, function(pAttribute){
-                    var att = attributes[pAttribute.trackedEntityAttribute.id];
-                    att.mandatory = pAttribute.mandatory;
-                    if(pAttribute.displayInList){
-                        att.displayInListNoProgram = true;
-                    }                    
-                    programAttributes.push(att);                
-                });
-                def.resolve(programAttributes);
+                    angular.forEach(program.programTrackedEntityAttributes, function(pAttribute){
+                        var att = attributes[pAttribute.trackedEntityAttribute.id];
+                        att.mandatory = pAttribute.mandatory;
+                        if(pAttribute.displayInList){
+                            att.displayInListNoProgram = true;
+                        }                    
+                        programAttributes.push(att);                
+                    });
+                    
+                    def.resolve(programAttributes);
+                }                
+                else{
+                    var attributes = [];
+                    angular.forEach(atts, function(attribute){
+                        if (attribute.displayInListNoProgram) {
+                            attributes.push(attribute);
+                        }
+                    });     
+                    def.resolve(attributes);
+                }                
             });
             return def.promise;    
         },
@@ -1018,6 +1063,7 @@
     this.currentSelection = '';
     this.relationshipInfo = '';
     this.optionSets = null;
+    this.attributesById = null;
     
     this.set = function(currentSelection){  
         this.currentSelection = currentSelection;        
@@ -1039,6 +1085,13 @@
     this.getOptionSets = function(){
         return this.optionSets;
     };    
+    
+    this.setAttributesById = function(attributesById){
+        this.attributesById = attributesById;
+    };
+    this.getAttributesById = function(){
+        return this.attributesById;
+    };  
 })
 
 .service('TEIGridService', function(OrgUnitService, OptionSetService, DateUtils, $translate, AttributesFactory){

=== 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-01-29 17:13:36 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js	2015-02-09 17:04:31 +0000
@@ -168,7 +168,7 @@
     promise = promise.then( getMetaProgramValidations );
     promise = promise.then( getProgramValidations );
     promise = promise.then( getMetaTrackedEntityForms );
-    promise = promise.then( getTrackedEntityForms );        
+    promise = promise.then( getTrackedEntityForms );
     promise.done(function() {
         
         //Enable ou selection after meta-data has downloaded
@@ -831,4 +831,4 @@
             });
         });
     };
-}
+}
\ No newline at end of file