← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 17209: tracker capture - dynamic update of event status color; use of option name in display and code in...

 

------------------------------------------------------------
revno: 17209
committer: Abyot Asalefew Gizaw <abyota@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2014-10-22 13:46:33 +0200
message:
  tracker capture - dynamic update of event status color; use of option name in display and code in saving and also conversion vice-versa
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/dataentry/dataentry-controller.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/default-form.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/enrollment/enrollment.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/notes/notes-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/components/profile/profile.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/registration/registration-controller.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/tei-report-controller.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/en.json
  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
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/views/dialog.html
  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-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	2014-10-09 15:37:26 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard-controller.js	2014-10-22 11:46:33 +0000
@@ -8,6 +8,7 @@
                 storage,
                 TEIService, 
                 TEService,
+                OptionSetFactory,
                 ProgramFactory,
                 CurrentSelection,
                 TranslationService) {
@@ -66,9 +67,22 @@
                         }
                     });
                     
-                    //broadcast selected items for dashboard controllers
-                    CurrentSelection.set({tei: $scope.selectedTei, te: $scope.trackedEntity, pr: $scope.selectedProgram, enrollment: null});
-                    $scope.broadCastSelections();                                    
+                    $scope.optionSets = {optionSets: [], optionNamesByCode: new Object(), optionCodesByName: new Object()};                    
+                    OptionSetFactory.getAll().then(function(optionSets){
+                        angular.forEach(optionSets, function(optionSet){
+                            angular.forEach(optionSet.options, function(option){
+                                if(option.name && option.code){
+                                    $scope.optionSets.optionNamesByCode[ '"' + option.code + '"'] = option.name;
+                                    $scope.optionSets.optionCodesByName[ '"' + option.name + '"'] = option.code;
+                                }                       
+                            });
+                            $scope.optionSets.optionSets[optionSet.id] = optionSet;
+                        });
+                        
+                        //broadcast selected items for dashboard controllers
+                        CurrentSelection.set({tei: $scope.selectedTei, te: $scope.trackedEntity, pr: $scope.selectedProgram, enrollment: null, optionSets: $scope.optionSets});
+                        $scope.broadCastSelections();  
+                    });
                 });
             });            
         });      
@@ -92,7 +106,9 @@
         var selections = CurrentSelection.get();
         $scope.selectedTei = selections.tei;
         $scope.trackedEntity = selections.te;
-        CurrentSelection.set({tei: $scope.selectedTei, te: $scope.trackedEntity, pr: $scope.selectedProgram, enrollment: null});
+        $scope.optionSets = selections.optionSets;
+        
+        CurrentSelection.set({tei: $scope.selectedTei, te: $scope.trackedEntity, pr: $scope.selectedProgram, enrollment: null, optionSets: $scope.optionSets});
         $timeout(function() { 
             $rootScope.$broadcast('selectedItems', {programExists: $scope.programs.length > 0});            
         }, 100); 

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js	2014-10-20 16:24:09 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js	2014-10-22 11:46:33 +0000
@@ -1,5 +1,6 @@
 trackerCapture.controller('DataEntryController',
-        function($scope, 
+        function($scope,
+                $timeout,
                 DateUtils,
                 EventUtils,
                 orderByFilter,
@@ -57,6 +58,7 @@
         $scope.selectedEntity = selections.tei;      
         $scope.selectedProgram = selections.pr;        
         $scope.selectedEnrollment = selections.enrollment;   
+        $scope.optionSets = selections.optionSets;
         $scope.selectedProgramWithStage = [];
         
         if($scope.selectedOrgUnit && 
@@ -106,7 +108,7 @@
                             }                       
 
                             dhis2Event.statusColor = EventUtils.getEventStatusColor(dhis2Event);  
-                            dhis2Event = EventUtils.setEventOrgUnitName(dhis2Event);
+                            //dhis2Event = EventUtils.setEventOrgUnitName(dhis2Event);
                         } 
                     }                    
                 });
@@ -258,7 +260,7 @@
 
             if($scope.currentEvent && $scope.currentEvent.event === event.event){
                 //clicked on the same stage, do toggling
-                $scope.currentEvent = {};
+                $scope.currentEvent = null;
                 $scope.currentElement = {id: '', saved: false};
                 $scope.showDataEntryDiv = !$scope.showDataEntryDiv;      
             }
@@ -332,26 +334,28 @@
     
     $scope.saveDatavalue = function(prStDe){
         
-        $scope.currentElement = {};
-        
         //check for input validity
         $scope.dataEntryOuterForm.submitted = true;        
         if( $scope.dataEntryOuterForm.$invalid ){
+            $scope.currentElement = {id: prStDe.dataElement.id, saved: false};
             return false;
         }
          
         //input is valid
-        $scope.updateSuccess = false;      
-        
-        if(!angular.isUndefined($scope.currentEvent[prStDe.dataElement.id])){
+        $scope.updateSuccess = false;
+        var value = $scope.currentEvent[prStDe.dataElement.id];        
+        if(!angular.isUndefined(value)){
+            if(prStDe.dataElement.type === 'date'){                    
+                value = DateUtils.formatFromUserToApi(value);
+            }
+            if(prStDe.dataElement.type === 'string'){                    
+                if(prStDe.dataElement.optionSet && $scope.optionCodesByName[  '"' + value + '"']){                        
+                    value = $scope.optionCodesByName[  '"' + value + '"'];                                                      
+                }                    
+            }
 
-            if($scope.currentEventOriginal[prStDe.dataElement.id] !== $scope.currentEvent[prStDe.dataElement.id]){
+            if($scope.currentEventOriginal[prStDe.dataElement.id] !== value){
                 
-                //get current element
-                $scope.currentElement = {id: prStDe.dataElement.id, saved: false};
-
-                //currentEvent.providedElsewhere[prStDe.dataElement.id];
-                var value = $scope.currentEvent[prStDe.dataElement.id];
                 var ev = {  event: $scope.currentEvent.event,
                             orgUnit: $scope.currentEvent.orgUnit,
                             program: $scope.currentEvent.program,
@@ -367,10 +371,10 @@
                                         ]
                          };
                 DHIS2EventFactory.updateForSingleValue(ev).then(function(response){
-                    $scope.currentElement.saved = true;
+                    $scope.currentElement = {id: prStDe.dataElement.id, saved: true};
                 });
             }
-        }        
+        }
     };
     
     $scope.saveDatavalueLocation = function(prStDe){
@@ -404,7 +408,7 @@
     $scope.saveEventDate = function(){
         
         $scope.eventDateSaved = false;
-        if($scope.currentEvent.eventDate == ''){            
+        if($scope.currentEvent.eventDate === ''){            
             $scope.invalidDate = true;
             return false;
         }
@@ -420,7 +424,7 @@
         var e = {event: $scope.currentEvent.event,
              enrollment: $scope.currentEvent.enrollment,
              dueDate: DateUtils.formatFromUserToApi($scope.currentEvent.dueDate),
-             status: $scope.currentEvent.status == 'SCHEDULE' ? 'ACTIVE' : $scope.currentEvent.status,
+             status: $scope.currentEvent.status === 'SCHEDULE' ? 'ACTIVE' : $scope.currentEvent.status,
              program: $scope.currentEvent.program,
              programStage: $scope.currentEvent.programStage,
              orgUnit: $scope.currentEvent.orgUnit,
@@ -432,23 +436,14 @@
             $scope.currentEvent.sortingDate = $scope.currentEvent.eventDate;
             $scope.invalidDate = false;
             $scope.eventDateSaved = true;
-
-            var statusColor = EventUtils.getEventStatusColor($scope.currentEvent);  
-            var continueLoop = true;
-            for(var i=0; i< $scope.dhis2Events.length && continueLoop; i++){
-                if($scope.dhis2Events[i].event === $scope.currentEvent.event ){
-                    $scope.dhis2Events[i].statusColor = statusColor;
-                    $scope.dhis2Events[i].status = e.status;
-                    continueLoop = false;
-                }
-            }
+            $scope.currentEvent.statusColor = EventUtils.getEventStatusColor($scope.currentEvent);
         });
     };
     
     $scope.saveDueDate = function(){
         $scope.dueDateSaved = false;
 
-        if($scope.currentEvent.dueDate == ''){
+        if($scope.currentEvent.dueDate === ''){
             $scope.invalidDate = true;
             return false;
         }
@@ -474,22 +469,15 @@
         DHIS2EventFactory.update(e).then(function(data){            
             $scope.invalidDate = false;
             $scope.dueDateSaved = true;
-            $scope.currentEvent.sortingDate = $scope.currentEvent.dueDate;                
-            var statusColor = EventUtils.getEventStatusColor($scope.currentEvent);  
-            var continueLoop = true;
-            for(var i=0; i< $scope.dhis2Events.length && continueLoop; i++){
-                if($scope.dhis2Events[i].event === $scope.currentEvent.event ){
-                    $scope.dhis2Events[i].statusColor = statusColor;
-                    continueLoop = false;
-                }
-            }
+            $scope.currentEvent.sortingDate = $scope.currentEvent.dueDate;
+            $scope.currentEvent.statusColor = EventUtils.getEventStatusColor($scope.currentEvent);            
             $scope.schedulingEnabled = !$scope.schedulingEnabled;
         });
                       
     };
     
     $scope.addNote = function(){
-        if(!angular.isUndefined($scope.note) && $scope.note != ""){
+        if(!angular.isUndefined($scope.note) && $scope.note !== ""){
             var newNote = {value: $scope.note};
 
             if(angular.isUndefined( $scope.currentEvent.notes) ){
@@ -669,4 +657,20 @@
     $scope.toggleLegend = function(){
         $scope.showEventColors = !$scope.showEventColors;
     };
+    
+    $scope.getEventStyle = function(ev, dummy){
+        var style = EventUtils.getEventStatusColor(ev);
+        
+        if(dummy){
+            if($scope.currentDummyEvent && $scope.currentDummyEvent.programStage === ev.programStage){
+                style = style + ' ' + 'current-stage';
+            }
+        }
+        else{
+            if($scope.currentEvent && $scope.currentEvent.event === ev.event){
+                style = style + ' ' + 'current-stage';
+            }
+        }        
+        return style;
+    };
 });
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html	2014-10-20 16:24:09 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html	2014-10-22 11:46:33 +0000
@@ -32,10 +32,8 @@
                 <tbody>
                     <tr>
                         <td class="inline-block" ng-repeat="dhis2Event in dhis2Events | orderBy:'sortingDate':reverse">
-                            <span class="block align-center">{{dhis2Event.eventOrgUnitName}}</span>                                              
-                            <span class="stage-container"                                                     
-                                  ng-class="{'current-stage': currentEvent && currentEvent.event == dhis2Event.event, '{{dhis2Event.statusColor}}': true}"                                                      
-                                  ng-click="showDataEntry(dhis2Event)">
+                            <!--<span class="block align-center">{{dhis2Event.eventOrgUnitName}}</span> -->
+                            <span class="stage-container" ng-class='getEventStyle(dhis2Event, false)' ng-click="showDataEntry(dhis2Event)">
                                 {{dhis2Event.name}}<br/>
                                 {{dhis2Event.sortingDate}}         
                             </span>
@@ -53,17 +51,15 @@
                 <tbody>
                     <tr>
                         <td class="inline-block" ng-repeat="dummyEvent in dummyEvents| orderBy:'sortingDate':reverse">
-                            <span class="block align-center">{{dhis2Event.eventOrgUnitName}}</span>                                              
-                            <span class="stage-container"                                                     
-                                  ng-class="{'current-stage': currentDummyEvent && currentDummyEvent.programStage == dummyEvent.programStage, '{{dummyEvent.statusColor}}': true}"                                                      
-                                  ng-click="showDummyEventCreation(dummyEvent)">
+                            <!--<span class="block align-center">{{dhis2Event.eventOrgUnitName}}</span>-->                                              
+                            <span class="stage-container" ng-class='getEventStyle(dummyEvent, true)' ng-click="showDummyEventCreation(dummyEvent)">
                                 {{dummyEvent.name}}<br/>
                                 {{dummyEvent.dueDate}}         
                             </span>
                             <i class="fa fa-arrow-right" ng-if="$index < dummyEvents.length - 1"></i>
-                        </td>                        
-                    </tr>                        
-                </tbody>                
+                        </td>
+                    </tr>
+                </tbody>
             </table>
             <form name="eventCreationForm" novalidate ng-show="currentDummyEvent">
                 <div class="row">

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/default-form.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/default-form.html	2014-10-13 15:05:01 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/default-form.html	2014-10-22 11:46:33 +0000
@@ -31,17 +31,19 @@
                         </div>                        
                         <div ng-switch-when="string">                            
                             <div ng-if="prStDe.dataElement.optionSet">
-                                <div ng-if="!selectedProgram.dataEntryMethod || prStDe.dataElement.optionSet.options.length >= 7">
+                                <div ng-if="!selectedProgram.dataEntryMethod || optionSets.optionSets[prStDe.dataElement.optionSet.id].options.length >= 7">
                                     <input type="text"
                                         ng-class='getInputNotifcationClass(prStDe.dataElement.id,false)'
                                         ng-model="currentEvent[prStDe.dataElement.id]" 
                                         ng-required={{prStDe.compulsory}} 
-                                        typeahead="option.code as option.name for option in prStDe.dataElement.optionSet.options | filter:$viewValue | limitTo:20" 
-                                        typeahead-open-on-focus    
+                                        typeahead="option.name as option.name for option in optionSets.optionSets[prStDe.dataElement.optionSet.id].options | filter:$viewValue | limitTo:20" 
+                                        typeahead-open-on-focus 
+                                        typeahead-editable="false"
                                         ng-blur="saveDatavalue(prStDe)" 
                                         name="foo"/>
+                                    <span ng-show="dataEntryOuterForm.submitted && dataEntryInnerForm.foo.$invalid || !currentEvent[prStDe.dataElement.id] && currentElement.id === prStDe.dataElement.id" class="error">{{'invalid'| translate}}</span>
                                 </div>
-                                <div ng-if="selectedProgram.dataEntryMethod && prStDe.dataElement.optionSet.options.length < 7">
+                                <div ng-if="selectedProgram.dataEntryMethod && optionSets.optionSets[prStDe.dataElement.optionSet.id].options.length < 7">
                                     <label>                                        
                                         <input type="radio"
                                             ng-class='getInputNotifcationClass(prStDe.dataElement.id,true)'
@@ -51,7 +53,7 @@
                                             ng-change="saveDatavalue(prStDe)" 
                                             value=""> {{'no_value' | translate}}<br>                                       
                                     </label><br>
-                                    <span ng-repeat="option in  prStDe.dataElement.optionSet.options">
+                                    <span ng-repeat="option in optionSets.optionSets[prStDe.dataElement.optionSet.id].options">
                                         <label>
                                             <input type="radio"
                                                 ng-class='getInputNotifcationClass(prStDe.dataElement.id,true)'
@@ -59,7 +61,7 @@
                                                 ng-required={{prStDe.compulsory}} 
                                                 ng-model="currentEvent[prStDe.dataElement.id]"
                                                 ng-change="saveDatavalue(prStDe)" 
-                                                value={{option.code}}> {{option.name}}
+                                                value={{option.name}}> {{option.name}}
                                         </label><br>
                                     </span>
                                 </div>                                    
@@ -72,7 +74,6 @@
                                     ng-blur="saveDatavalue(prStDe)" 
                                     name="foo"/>
                             </div>
-                           
                         </div>
                         <div ng-switch-when="bool">
                             <select ng-class='getInputNotifcationClass(prStDe.dataElement.id,false)'
@@ -89,7 +90,8 @@
                         <div ng-switch-when="date">
                             <input type="text" 
                                    placeholder="{{dhis2CalendarFormat.keyDateFormat}}" 
-                                   d2-date 
+                                   d2-date
+                                   max-date="prStDe.allowFutureDate ? '' : 0"
                                    ng-class='getInputNotifcationClass(prStDe.dataElement.id,false)'
                                    ng-model="currentEvent[prStDe.dataElement.id]"
                                    ng-required={{prStDe.compulsory}}  
@@ -105,7 +107,8 @@
                                    name="foo"/>
                         </div>
                     </div>
-                </ng-form>                            
+                </ng-form>
+                <span ng-show="dataEntryOuterForm.submitted && dataEntryInnerForm.foo.$invalid" class="error">{{'required'| translate}}</span>
             </td>
             <td class="col-md-2" ng-if="allowProvidedElsewhereExists">                
                 <div class="align-center" ng-show="prStDe.allowProvidedElsewhere">

=== 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	2014-10-13 14:47:39 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/enrollment/enrollment-controller.js	2014-10-22 11:46:33 +0000
@@ -33,6 +33,7 @@
         $scope.selectedTei = angular.copy(selections.tei); 
         $scope.selectedEntity = selections.te;
         $scope.selectedProgram = selections.pr;
+        $scope.optionSets = selections.optionSets;
         $scope.programExists = args.programExists;
         
         $scope.selectedOrgUnit = storage.get('SELECTED_OU');
@@ -150,17 +151,45 @@
         //existing attributes
         angular.forEach($scope.selectedTei.attributes, function(attribute){
             if(!angular.isUndefined(attribute.value)){
+                if(attribute.type === 'date'){
+                    attribute.value = DateUtils.formatFromUserToApi(attribute.value);
+                }
+                if(attribute.type === 'optionSet' && $scope.optionSets.optionCodesByName[  '"' + attribute.value + '"']){   
+                    attribute.value = $scope.optionSets.optionCodesByName[  '"' + attribute.value + '"'];
+                }
                 tei.attributes.push({attribute: attribute.attribute, value: attribute.value});
             } 
         });
         
         //get enrollment attributes and their values - new attributes because of enrollment
         angular.forEach($scope.attributesForEnrollment, function(attribute){
-            if(!angular.isUndefined(attribute.value)){
-                tei.attributes.push({attribute: attribute.id, value: attribute.value});
-            } 
+            
+            if(attribute.valueType === 'trueOnly'){ 
+                if(!attribute.value){
+                    tei.attributes.push({attribute: attribute.id, value: ''});
+                    $scope.formEmpty = false;                    
+                }
+                else{
+                    tei.attributes.push({attribute: attribute.id, value: 'true'});
+                    $scope.formEmpty = false;
+                }
+            }            
+            else{
+                var val = attribute.value;
+                if(!angular.isUndefined(val) && val !== ''){
+                    if(attribute.valueType === 'date'){
+                        val = DateUtils.formatFromUserToApi(val);
+                    }
+                    if(attribute.valueType === 'optionSet' && $scope.optionSets.optionCodesByName[  '"' + val + '"']){   
+                        val = $scope.optionSets.optionCodesByName[  '"' + val + '"'];
+                    }                    
+                    $scope.formEmpty = false;
+                    tei.attributes.push({attribute: attribute.id, value: val});
+                }                
+            }
         });
         
+        console.log('Finally:  ', tei);
         var enrollment = {trackedEntityInstance: tei.trackedEntityInstance,
                             program: $scope.selectedProgram.id,
                             status: 'ACTIVE',
@@ -171,14 +200,13 @@
         TEIService.update(tei).then(function(updateResponse){
             
             if(updateResponse.status === 'SUCCESS'){
-                
                 //registration is successful, continue for enrollment               
-                EnrollmentService.enroll(enrollment).then(function(enrollmentResponse){
+                EnrollmentService.enroll(enrollment).then(function(enrollmentResponse){                    
                     if(enrollmentResponse.status !== 'SUCCESS'){
                         //enrollment has failed
                         var dialogOptions = {
                                 headerText: 'enrollment_error',
-                                bodyText: enrollmentResponse.description
+                                bodyText: enrollmentResponse
                             };
                         DialogService.showDialog({}, dialogOptions);
                         return;
@@ -186,16 +214,27 @@
                     
                     //update tei attributes without refetching from the server
                     angular.forEach($scope.attributesForEnrollment, function(attribute){
-                        if(!angular.isUndefined(attribute.value)){
-                             if(attribute.type === 'number' && !isNaN(parseInt(attribute.value))){
-                                 attribute.value = parseInt(attribute.value);
-                             }
-                            $scope.selectedTei.attributes.push({attribute: attribute.id, value: attribute.value, type: attribute.valueType, displayName: attribute.name});                            
-                        }
+                        $scope.selectedTei.attributes.push({attribute: attribute.id, value: attribute.value, type: attribute.valueType, displayName: attribute.name});
+                        /*var val = attribute.value;
+                        if(!angular.isUndefined(val)){
+                            if(attribute.valueType === 'number' && !isNaN(parseInt(val))){
+                                val = parseInt(val);
+                            }
+                            if(attribute.valueType === 'date'){
+                                val = DateUtils.formatFromApiToUser(val);
+                            }
+                            if(attribute.valueType === 'optionSet' && $scope.optionSets.optionNamesByCode[  '"' + attribute.value + '"']){   
+                                attribute.value = $scope.optionSets.optionNamesByCode[  '"' + attribute.value + '"'];
+                            } 
+                            
+                            $scope.selectedTei.attributes.push({attribute: attribute.id, value: attribute.value, type: attribute.valueType, displayName: attribute.name});
+                        }*/
                     });
                     
                     enrollment.enrollment = enrollmentResponse.reference;
-                    $scope.selectedEnrollment = enrollment;                    
+                    $scope.selectedEnrollment = enrollment;
+                    $scope.selectedEnrollment.dateOfEnrollment = DateUtils.formatFromApiToUser(enrollment.dateOfEnrollment);
+                    $scope.selectedEnrollment.dateOfIncident = DateUtils.formatFromApiToUser(enrollment.dateOfIncident);
                     $scope.autoGenerateEvents();                    
                     $scope.broadCastSelections('dashboardWidgets'); 
                     
@@ -211,13 +250,13 @@
                     };
                 DialogService.showDialog({}, dialogOptions);
                 return;
-            }            
+            }
         });
     };
     
     $scope.broadCastSelections = function(listeners){
-        CurrentSelection.set({tei: $scope.selectedTei, te: $scope.selectedEntity, pr: $scope.selectedProgram, enrollment: $scope.selectedEnrollment});
-        $timeout(function() { 
+        CurrentSelection.set({tei: $scope.selectedTei, te: $scope.selectedEntity, pr: $scope.selectedProgram, enrollment: $scope.selectedEnrollment, optionSets: $scope.optionSets});
+        $timeout(function(){
             $rootScope.$broadcast(listeners, {});
         }, 100);
     };
@@ -243,8 +282,7 @@
             bodyText: 'are_you_sure_to_terminate_enrollment'
         };
 
-        ModalService.showModal({}, modalOptions).then(function(result){
-            
+        ModalService.showModal({}, modalOptions).then(function(result){            
             EnrollmentService.cancel($scope.selectedEnrollment).then(function(data){                
                 $scope.selectedEnrollment.status = 'CANCELLED';
                 $scope.loadEnrollmentDetails();                
@@ -261,8 +299,7 @@
             bodyText: 'are_you_sure_to_complete_enrollment'
         };
 
-        ModalService.showModal({}, modalOptions).then(function(result){
-            
+        ModalService.showModal({}, modalOptions).then(function(result){            
             EnrollmentService.complete($scope.selectedEnrollment).then(function(data){                
                 $scope.selectedEnrollment.status = 'COMPLETED';
                 $scope.loadEnrollmentDetails();                

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/enrollment/enrollment.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/enrollment/enrollment.html	2014-10-13 15:05:01 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/enrollment/enrollment.html	2014-10-22 11:46:33 +0000
@@ -1,6 +1,5 @@
 <div class="panel panel-info" ng-controller="EnrollmentController">
     <div class="panel-heading handle bold">                                            
-        <!--<span ng-class="{'text-primary': !showEnrollmentHistoryDiv}">{{enrollmentWidget.title| translate}}</span>-->
         {{enrollmentWidget.title| translate}}
         <span class="nav-pills" ng-show="selectedProgram && !selectedEnrollment">
             | <a href ng-click="showNewEnrollment()" title="{{'new'| translate}}"><span class="bold">{{'new'| translate}}</span></a>
@@ -117,32 +116,37 @@
                             <ng-form name="innerForm">
                                 <div ng-switch="attribute.valueType">
                                     <div ng-switch-when="date">
-                                        <input type="text" placeholder="{{dhis2CalendarFormat.keyDateFormat}}" class="form-control" name="foo" d2-date ng-model="attribute.value" ng-required="attribute.mandatory"/>
-                                        <span ng-show="outerForm.submitted && innerForm.foo.$invalid" style="color:red;font-size:12px">{{'required'| translate}}</span>
+                                        <input type="text" 
+                                               placeholder="{{dhis2CalendarFormat.keyDateFormat}}" 
+                                               class="form-control" 
+                                               name="foo" 
+                                               max-date="attribute.allowFutureDate ? '' : 0"
+                                               d2-date 
+                                               ng-model="attribute.value" 
+                                               ng-required="attribute.mandatory"/>                                        
                                     </div>
                                     <div ng-switch-when="trueOnly">
-                                        <input type="checkbox" class="form-control" name="foo" ng-model="attribute.value" ng-required="attribute.mandatory"/>
-                                        <span ng-show="outerForm.submitted && innerForm.foo.$invalid" style="color:red;font-size:12px">{{'required'| translate}}</span>
+                                        <input type="checkbox" class="form-control" name="foo" ng-model="attribute.value" ng-required="attribute.mandatory"/>                                        
                                     </div>
                                     <div ng-switch-when="bool">
                                         <select ng-model="attribute.value" name="foo" class="form-control" ng-required="attribute.mandatory">
                                             <option value="">{{'please_select'| translate}}</option>                        
                                             <option value="false">{{'no'| translate}}</option>
                                             <option value="true">{{'yes'| translate}}</option>
-                                        </select>
-                                        <span ng-show="outerForm.submitted && innerForm.foo.$invalid" style="color:red;font-size:12px">{{'required'| translate}}</span>
+                                        </select>                                        
                                     </div>
                                     <div ng-switch-when="optionSet">
-                                        <div ng-if="!selectedProgram.dataEntryMethod || attribute.optionSet.options.length >= 7">
+                                        <div ng-if="!selectedProgram.dataEntryMethod || optionSets.optionSets[attribute.optionSet.id].options.length >= 7">
                                             <input type="text" 
                                                name="foo"
                                                class="form-control"
                                                ng-model="attribute.value"                                                 
-                                               typeahead="option.code as option.name for option in attribute.optionSet.options | filter:$viewValue | limitTo:20" 
+                                               typeahead="option.name as option.name for option in optionSets.optionSets[attribute.optionSet.id].options | filter:$viewValue | limitTo:20" 
                                                typeahead-open-on-focus
+                                               typeahead-editable="false"
                                                ng-required="attribute.mandatory"/>
                                         </div>
-                                        <div ng-if="selectedProgram.dataEntryMethod && attribute.optionSet.options.length < 7">
+                                        <div ng-if="selectedProgram.dataEntryMethod && optionSets.optionSets[attribute.optionSet.id].options.length < 7">
                                             <label>                                        
                                                 <input type="radio"
                                                     name={{attribute.id}}
@@ -150,28 +154,34 @@
                                                     ng-model="attribute.value"
                                                     value=""> {{'no_value' | translate}}<br>                                       
                                             </label><br>
-                                            <span ng-repeat="option in  attribute.optionSet.options">
+                                            <span ng-repeat="option in optionSets.optionSets[attribute.optionSet.id].options">
                                                 <label>
                                                     <input type="radio"
                                                         name={{attribute.id}}
                                                         ng-required="attribute.mandatory"
                                                         ng-model="attribute.value" 
-                                                        value={{option.code}}> {{option.name}}
+                                                        value={{option.name}}> {{option.name}}
                                                 </label><br>
                                             </span>                                            
                                         </div>
-                                        <span ng-show="outerForm.submitted && innerForm.foo.$invalid" style="color:red;font-size:12px">{{'required'| translate}}</span>
                                     </div>
                                     <div ng-switch-when="number">
-                                        <input type="number" class="form-control" name="foo" ng-model="attribute.value" ng-required="attribute.mandatory"/>
-                                        <span ng-show="outerForm.submitted && innerForm.foo.$invalid" style="color:red;font-size:12px">{{'required'| translate}}</span>
+                                        <input type="number" 
+                                               class="form-control" 
+                                               name="foo" 
+                                               ng-model="attribute.value" 
+                                               ng-required="attribute.mandatory"/>                                        
                                     </div>
                                     <div ng-switch-default>
-                                        <input type="text" class="form-control" name="foo" ng-model="attribute.value" ng-required="attribute.mandatory"/>
-                                        <span ng-show="outerForm.submitted && innerForm.foo.$invalid" style="color:red;font-size:12px">{{'required'| translate}}</span>
+                                        <input type="text" 
+                                               class="form-control" 
+                                               name="foo" 
+                                               ng-model="attribute.value" 
+                                               ng-required="attribute.mandatory"/>                                        
                                     </div>
                                 </div>
                             </ng-form>
+                            <span ng-show="outerForm.submitted && innerForm.foo.$invalid" style="color:red;font-size:12px">{{'required'| translate}}</span>
                         </td>
                     </tr>                        
                 </table>

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/notes/notes-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/notes/notes-controller.js	2014-10-13 14:47:39 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/notes/notes-controller.js	2014-10-22 11:46:33 +0000
@@ -26,6 +26,7 @@
         var selections = CurrentSelection.get();                    
         $scope.selectedTei = angular.copy(selections.tei);
         $scope.selectedProgram = selections.pr;
+        $scope.optionSets = selections.optionSets;
         
         var selections = CurrentSelection.get();
         if(selections.enrollment){
@@ -43,7 +44,7 @@
         if($scope.selectedProgram && $scope.selectedTei){
             //check if the selected TEI has any of the contact attributes
             //that can be used for communication
-            TEIService.processAttributes($scope.selectedTei, $scope.selectedProgram, $scope.selectedEnrollment).then(function(tei){
+            TEIService.processAttributes($scope.selectedTei, $scope.selectedProgram, $scope.selectedEnrollment, $scope.optionSets).then(function(tei){
                 $scope.selectedTei = tei; 
                 var continueLoop = true;
                 for(var i=0; i<$scope.selectedTei.attributes.length && continueLoop; i++){

=== 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	2014-10-09 15:37:26 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/profile/profile-controller.js	2014-10-22 11:46:33 +0000
@@ -2,6 +2,7 @@
         function($rootScope,
                 $scope,     
                 CurrentSelection,
+                DateUtils,
                 TEIService,
                 DialogService,
                 AttributesFactory,
@@ -23,13 +24,15 @@
     $scope.$on('dashboardWidgets', function(event, args) { 
         var selections = CurrentSelection.get();
         $scope.selectedTei = angular.copy(selections.tei);
+
         $scope.trackedEntity = selections.te;
         $scope.selectedProgram = selections.pr;   
-        $scope.selectedEnrollment = selections.enrollment;  
-        
+        $scope.selectedEnrollment = selections.enrollment;
+        $scope.optionSets = selections.optionSets;
+
         //display only those attributes that belong to the selected program
         //if no program, display attributesInNoProgram
-        TEIService.processAttributes($scope.selectedTei, $scope.selectedProgram, $scope.selectedEnrollment).then(function(tei){
+        TEIService.processAttributes($scope.selectedTei, $scope.selectedProgram, $scope.selectedEnrollment, $scope.optionSets).then(function(tei){
             $scope.selectedTei = tei;
         });
     });
@@ -40,23 +43,53 @@
         $rootScope.profileWidget.expand = true;
     };
     
-    $scope.save = function(){
+    $scope.save = function(){        
         
         //check for form validity
         $scope.outerForm.submitted = true;        
         if( $scope.outerForm.$invalid ){
             return false;
         }
-        
+
+        //form is valid, continue the update process        
+        //get tei attributes and their values
+        //but there could be a case where attributes are non-mandatory and
+        //form comes empty, in this case enforce at least one value
+        $scope.formEmpty = true;
         var tei = angular.copy($scope.selectedTei);
         tei.attributes = [];
-        //prepare to update the tei on the server side 
         angular.forEach($scope.selectedTei.attributes, function(attribute){
-            if(!angular.isUndefined(attribute.value)){
-                tei.attributes.push({attribute: attribute.attribute, value: attribute.value});
-            } 
+            if(attribute.type === 'trueOnly'){ 
+                if(!attribute.value){
+                    tei.attributes.push({attribute: attribute.attribute, value: ''});
+                    $scope.formEmpty = false;                    
+                }
+                else{
+                    tei.attributes.push({attribute: attribute.attribute, value: 'true'});
+                    $scope.formEmpty = false;
+                }
+            }            
+            else{
+                var val = attribute.value;
+                if(!angular.isUndefined(val) && val !== ''){
+                    if(attribute.type === 'date'){   
+                        val = DateUtils.formatFromUserToApi(val);
+                    }
+                    if(attribute.type === 'optionSet' && $scope.optionSets.optionCodesByName[  '"' + val + '"']){   
+                        val = $scope.optionSets.optionCodesByName[  '"' + val + '"'];
+                    }                    
+                    $scope.formEmpty = false;
+                }
+                tei.attributes.push({attribute: attribute.attribute, value: val});
+            }           
+             
         });
         
+        if($scope.formEmpty){
+            //form is empty            
+            return false;
+        }
+
         TEIService.update(tei).then(function(updateResponse){
             
             if(updateResponse.status !== 'SUCCESS'){//update has failed
@@ -69,9 +102,9 @@
             }
             
             $scope.editProfile = !$scope.editProfile;
-            CurrentSelection.set({tei: $scope.selectedTei, te: $scope.trackedEntity, pr: $scope.selectedProgram, enrollment: $scope.selectedEnrollment});   
+            CurrentSelection.set({tei: $scope.selectedTei, te: $scope.trackedEntity, pr: $scope.selectedProgram, enrollment: $scope.selectedEnrollment, optionSets: $scope.optionSets});   
             $scope.outerForm.submitted = false; 
-        });       
+        });
     };
     
     $scope.cancel = function(){

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/profile/profile.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/profile/profile.html	2014-10-13 15:05:01 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/profile/profile.html	2014-10-22 11:46:33 +0000
@@ -24,47 +24,73 @@
                     </td>
                     <td>
                         <ng-form name="innerForm">
-                            <div ng-switch="attribute.type">
-                                <div ng-switch-when="date">
-                                    <input type="text" placeholder="{{dhis2CalendarFormat.keyDateFormat}}" name="foo" class="form-control" d2-date ng-model="attribute.value"  value="attribute.value | date:'yyyy-MM-dd" ng-disabled="!editProfile" ng-required="attribute.mandatory"/>
-                                    <span ng-show="outerForm.submitted && innerForm.foo.$invalid" class="error">{{'required'| translate}} - {{attribute.type}}</span>
-                                </div>
-                                <div ng-switch-when="trueOnly">
-                                    <input type="checkbox" name="foo" class="form-control" ng-model="attribute.value" ng-disabled="!editProfile" ng-required="attribute.mandatory"/>
-                                    <span ng-show="outerForm.submitted && innerForm.foo.$invalid" class="error">{{'required'| translate}} - {{attribute.type}}</span>
-                                </div>
-                                <div ng-switch-when="bool">
-                                    <select name="foo" ng-model="attribute.value" class="form-control" ng-disabled="!editProfile" ng-required="attribute.mandatory">
+                            <span ng-switch="attribute.type">
+                                <span ng-switch-when="date">
+                                    <input type="text" 
+                                           placeholder="{{dhis2CalendarFormat.keyDateFormat}}" 
+                                           name="foo" 
+                                           class="form-control" 
+                                           d2-date
+                                           max-date="attribute.allowFutureDate ? '' : 0"
+                                           ng-model="attribute.value"
+                                           ng-disabled="!editProfile" 
+                                           ng-required="attribute.mandatory"/>
+                                </span>
+                                <span ng-switch-when="trueOnly">
+                                    <input type="checkbox" 
+                                           name="foo" 
+                                           class="form-control" 
+                                           ng-model="attribute.value" 
+                                           ng-disabled="!editProfile" 
+                                           ng-required="attribute.mandatory"/>
+                                </span>
+                                <span ng-switch-when="bool">
+                                    <select name="foo" 
+                                            ng-model="attribute.value" 
+                                            class="form-control" 
+                                            ng-disabled="!editProfile" 
+                                            ng-required="attribute.mandatory">
                                         <option value="">{{'please_select'| translate}}</option>                        
                                         <option value="false">{{'no'| translate}}</option>
                                         <option value="true">{{'yes'| translate}}</option>
                                     </select>
-                                    <span ng-show="outerForm.submitted && innerForm.foo.$invalid" class="error">{{'required'| translate}} - {{attribute.type}}</span>
-                                </div>
-                                <div ng-switch-when="optionSet">
+                                </span>
+                                <span ng-switch-when="optionSet">
                                     <input type="text"
                                            name="foo"
                                            class="form-control"
                                            ng-model="attribute.value"                                                 
-                                           typeahead="option.code as option.name for option in attributes[attribute.attribute].optionSet.options | filter:$viewValue | limitTo:20" 
-                                           typeahead-open-on-focus 
+                                           typeahead="option.name as option.name for option in optionSets.optionSets[attributes[attribute.attribute].optionSet.id].options | filter:$viewValue | limitTo:20" 
+                                           typeahead-open-on-focus                                           
                                            ng-disabled="!editProfile" ng-required="attribute.mandatory"/>
-                                    <span ng-show="outerForm.submitted && innerForm.foo.$invalid" class="error">{{'required'| translate}} - {{attribute.type}}</span>
-                                </div>
-                                <div ng-switch-when="number">
-                                    <input type="number" name="foo" class="form-control" ng-model="attribute.value" ng-disabled="!editProfile" ng-required="attribute.mandatory"/>
-                                    <span ng-show="outerForm.submitted && innerForm.foo.$invalid" class="error">{{'required'| translate}} - {{attribute.type}}</span>
-                                </div>
-                                <div ng-switch-when="email">
-                                    <input type="email" name="foo" class="form-control" ng-model="attribute.value" ng-disabled="!editProfile" ng-required="attribute.mandatory"/>
-                                    <span ng-show="outerForm.submitted && innerForm.foo.$invalid" class="error">{{'required'| translate}}</span>
-                                </div>
-                                <div ng-switch-default>
-                                    <input type="text" name="foo" class="form-control" ng-model="attribute.value" ng-disabled="!editProfile" ng-required="attribute.mandatory"/>
-                                    <span ng-show="outerForm.submitted && innerForm.foo.$invalid" class="error">{{'required'| translate}} - {{attribute.type}}</span>
-                                </div>
-                            </div>
+                                </span>
+                                <span ng-switch-when="number">
+                                    <input type="number" 
+                                           name="foo" 
+                                           class="form-control" 
+                                           ng-model="attribute.value" 
+                                           ng-disabled="!editProfile" 
+                                           ng-required="attribute.mandatory"/>
+                                </span>
+                                <span ng-switch-when="email">
+                                    <input type="email" 
+                                           name="foo" 
+                                           class="form-control" 
+                                           ng-model="attribute.value" 
+                                           ng-disabled="!editProfile" 
+                                           ng-required="attribute.mandatory"/>
+                                </span>
+                                <span ng-switch-default>
+                                    <input type="text" 
+                                           name="foo" 
+                                           class="form-control" 
+                                           ng-model="attribute.value" 
+                                           ng-disabled="!editProfile" 
+                                           ng-required="attribute.mandatory"/>                                    
+                                </span>
+                            </span>
                         </ng-form>
+                        <span ng-show="outerForm.submitted && innerForm.foo.$invalid" class="error">{{'required'| translate}}</span>
                     </td>
                 </tr>           
             </table>

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/registration/registration-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/registration/registration-controller.js	2014-10-13 14:47:39 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/registration/registration-controller.js	2014-10-22 11:46:33 +0000
@@ -114,7 +114,6 @@
                                 dateOfEnrollment: DateUtils.formatFromUserToApi($scope.enrollment.dateOfEnrollment),
                                 dateOfIncident: $scope.enrollment.dateOfIncident == '' ? DateUtils.formatFromUserToApi($scope.enrollment.dateOfEnrollment) : DateUtils.formatFromUserToApi($scope.enrollment.dateOfIncident)
                             };                           
-                    console.log('enrollment details:  ', enrollment);
                     EnrollmentService.enroll(enrollment).then(function(data){
                         if(data.status !== 'SUCCESS'){
                             //enrollment has failed
@@ -197,13 +196,9 @@
                             dueDate: DateUtils.formatFromUserToApi(EventUtils.getEventDueDate(null,stage, enrollment)),
                             status: 'SCHEDULE'
                         };
-                    console.log('enrollment details:  ', enrollment);     
-                    console.log('the event due date is:  ', EventUtils.getEventDueDate(null,stage, enrollment));    
                     dhis2Events.events.push(newEvent);    
                 }
             });
-
-            console.log('the events are:  ', dhis2Events);
             if(dhis2Events.events.length > 0){
                 DHIS2EventFactory.create(dhis2Events).then(function(data){
 

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/tei-report-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/tei-report-controller.js	2014-10-13 14:47:39 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/tei-report-controller.js	2014-10-22 11:46:33 +0000
@@ -35,7 +35,8 @@
         $scope.selectedTei = selections.tei;  
         $scope.selectedEntity = selections.te;
         $scope.selectedProgram = selections.pr;        
-        $scope.selectedEnrollment = selections.enrollment; 
+        $scope.selectedEnrollment = selections.enrollment;
+        $scope.optionSets = selections.optionSets;
     
         if($scope.selectedTei && $scope.selectedOrgUnit){            
             $scope.getEvents();
@@ -108,7 +109,7 @@
 
         //process tei attributes, this is to have consistent display so that the tei 
         //contains program attributes whether it has value or not
-        TEIService.processAttributes($scope.selectedTei, $scope.selectedProgram, null).then(function(tei){
+        TEIService.processAttributes($scope.selectedTei, $scope.selectedProgram, null, $scope.optionSets).then(function(tei){
             $scope.tei = tei;  
         });
         

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/en.json'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/en.json	2014-10-20 16:24:09 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/en.json	2014-10-22 11:46:33 +0000
@@ -27,6 +27,7 @@
     "list_all_entities": "List all entities",
     "list_all": "List all",
     "list": "List",
+    "invalid": "Invalid",
     "required": "Required",
     "number_required": "Number required",
     "date_required": "Date required (yyyy-mm-dd)",

=== 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	2014-10-20 16:24:09 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js	2014-10-22 11:46:33 +0000
@@ -7,7 +7,7 @@
 
 .factory('StorageService', function(){
     var store = new dhis2.storage.Store({
-        name: "dhis2tc",
+        name: "dhis2",
         adapters: [dhis2.storage.IndexedDBAdapter, dhis2.storage.DomSessionStorageAdapter, dhis2.storage.InMemoryAdapter],
         objectStores: ['trackerCapturePrograms', 'programStages', 'trackedEntities', 'trackedEntityForms', 'attributes','optionSets']
     });
@@ -16,6 +16,39 @@
     };
 })
 
+/* Factory to fetch optioSets */
+.factory('OptionSetFactory', function($q, $rootScope, StorageService) { 
+    return {
+        getAll: function(){
+            
+            var def = $q.defer();
+            
+            StorageService.currentStore.open().done(function(){
+                StorageService.currentStore.getAll('optionSets').done(function(optionSets){
+                    $rootScope.$apply(function(){
+                        def.resolve(optionSets);
+                    });                    
+                });
+            });            
+            
+            return def.promise;            
+        },
+        get: function(uid){
+            
+            var def = $q.defer();
+            
+            StorageService.currentStore.open().done(function(){
+                StorageService.currentStore.get('optionSets', uid).done(function(optionSet){                    
+                    $rootScope.$apply(function(){
+                        def.resolve(optionSet);
+                    });
+                });
+            });                        
+            return def.promise;            
+        }
+    };
+})
+
 /* factory for loading logged in user profiles from DHIS2 */
 .factory('CurrentUserProfile', function($http) { 
            
@@ -107,13 +140,6 @@
             var def = $q.defer();
             StorageService.currentStore.open().done(function(){
                 StorageService.currentStore.get('programStages', uid).done(function(pst){                    
-                    angular.forEach(pst.programStageDataElements, function(pstDe){   
-                        if(pstDe.dataElement.optionSet){
-                            StorageService.currentStore.get('optionSets', pstDe.dataElement.optionSet.id).done(function(optionSet){
-                                pstDe.dataElement.optionSet = optionSet;                                
-                            });
-                        }
-                    });
                     $rootScope.$apply(function(){
                         def.resolve(pst);
                     });
@@ -132,17 +158,10 @@
             StorageService.currentStore.open().done(function(){
                 StorageService.currentStore.getAll('programStages').done(function(stages){   
                     angular.forEach(stages, function(stage){
-                        if(stageIds.indexOf(stage.id) !== -1){
-                            angular.forEach(stage.programStageDataElements, function(pstDe){   
-                                if(pstDe.dataElement.optionSet){
-                                    StorageService.currentStore.get('optionSets', pstDe.dataElement.optionSet.id).done(function(optionSet){
-                                        pstDe.dataElement.optionSet = optionSet;                                
-                                    });                            
-                                }                            
-                            });
+                        if(stageIds.indexOf(stage.id) !== -1){                            
                             programStages.push(stage);                               
                         }                        
-                    });                    
+                    });
                     $rootScope.$apply(function(){
                         def.resolve(programStages);
                     });
@@ -392,27 +411,27 @@
             });
             return promise;
         },
-        processAttributes: function(selectedTei, selectedProgram, selectedEnrollment){
+        processAttributes: function(selectedTei, selectedProgram, selectedEnrollment, optionSets){
             var def = $q.defer();            
             if(selectedTei.attributes){
                 if(selectedProgram && selectedEnrollment){
                     //show attribute for selected program and enrollment
-                    AttributesFactory.getByProgram(selectedProgram).then(function(atts){    
-                        selectedTei.attributes = AttributesFactory.showRequiredAttributes(atts,selectedTei.attributes, true);
+                    AttributesFactory.getByProgram(selectedProgram).then(function(atts){
+                        selectedTei.attributes = AttributesFactory.showRequiredAttributes(atts,selectedTei.attributes, true, optionSets);
                         def.resolve(selectedTei);
                     }); 
                 }
                 if(selectedProgram && !selectedEnrollment){
                     //show attributes for selected program            
                     AttributesFactory.getByProgram(selectedProgram).then(function(atts){    
-                        selectedTei.attributes = AttributesFactory.showRequiredAttributes(atts,selectedTei.attributes, false);
+                        selectedTei.attributes = AttributesFactory.showRequiredAttributes(atts,selectedTei.attributes, false, optionSets);
                         def.resolve(selectedTei);
                     }); 
                 }
                 if(!selectedProgram && !selectedEnrollment){
                     //show attributes in no program            
                     AttributesFactory.getWithoutProgram().then(function(atts){                
-                        selectedTei.attributes = AttributesFactory.showRequiredAttributes(atts,selectedTei.attributes, false);     
+                        selectedTei.attributes = AttributesFactory.showRequiredAttributes(atts,selectedTei.attributes, false, optionSets);     
                         def.resolve(selectedTei);
                     });
                 }
@@ -423,7 +442,7 @@
 })
 
 /* Factory for getting tracked entity attributes */
-.factory('AttributesFactory', function($q, $rootScope, StorageService, orderByFilter) {      
+.factory('AttributesFactory', function($q, $rootScope, StorageService, orderByFilter, DateUtils) {      
 
     return {
         getAll: function(){
@@ -431,17 +450,10 @@
             var def = $q.defer();
             
             StorageService.currentStore.open().done(function(){
-                StorageService.currentStore.getAll('attributes').done(function(attributes){
-                    angular.forEach(attributes, function(att){
-                        if(att.optionSet){
-                            StorageService.currentStore.get('optionSets', att.optionSet.id).done(function(optionSet){
-                                att.optionSet = optionSet;
-                            });
-                        }
-                        $rootScope.$apply(function(){
-                            def.resolve(attributes);
-                        });
-                    });                    
+                StorageService.currentStore.getAll('attributes').done(function(attributes){                    
+                    $rootScope.$apply(function(){
+                        def.resolve(attributes);
+                    });
                 });
             });            
             return def.promise;            
@@ -505,14 +517,21 @@
             });            
             return def.promise();            
         },
-        showRequiredAttributes: function(requiredAttributes, teiAttributes, fromEnrollment){        
-
+        showRequiredAttributes: function(requiredAttributes, teiAttributes, fromEnrollment, optionSets){        
             //first reset teiAttributes
             for(var j=0; j<teiAttributes.length; j++){
                 teiAttributes[j].show = false;
-                if(teiAttributes[j].type === 'number' && !isNaN(parseInt(teiAttributes[j].value))){
-                    teiAttributes[j].value = parseInt(teiAttributes[j].value);
-                }
+                if(teiAttributes[j].value){                    
+                    if(teiAttributes[j].type === 'number' && !isNaN(parseInt(teiAttributes[j].value))){
+                        teiAttributes[j].value = parseInt(teiAttributes[j].value);                        
+                    }
+                    /*if(teiAttributes[j].type === 'date'){
+                        teiAttributes[j].value = DateUtils.formatFromApiToUser(teiAttributes[j].value);                        
+                    }*/
+                    if(teiAttributes[j].type === 'optionSet' && optionSets.optionNamesByCode[ '"' + teiAttributes[j].value + '"']){
+                        teiAttributes[j].value = optionSets.optionNamesByCode[ '"' + teiAttributes[j].value + '"'];
+                    }
+                }               
             }
 
             //identify which ones to show
@@ -524,17 +543,17 @@
                         teiAttributes[j].show = true;
                         teiAttributes[j].order = i;
                         teiAttributes[j].mandatory = requiredAttributes[i].mandatory ? requiredAttributes[i].mandatory : false;
+                        teiAttributes[j].allowFutureDate = requiredAttributes[i].allowFutureDate ? requiredAttributes[i].allowFutureDate : false;
                     }
                 }
 
                 if(!processed && fromEnrollment){//attribute was empty, so a chance to put some value
-                    teiAttributes.push({show: true, order: i, mandatory: requiredAttributes[i].mandatory ? requiredAttributes[i].mandatory : false, attribute: requiredAttributes[i].id, displayName: requiredAttributes[i].name, type: requiredAttributes[i].valueType, value: ''});
+                    teiAttributes.push({show: true, order: i, allowFutureDate: requiredAttributes[i].allowFutureDate ? requiredAttributes[i].allowFutureDate : false, mandatory: requiredAttributes[i].mandatory ? requiredAttributes[i].mandatory : false, attribute: requiredAttributes[i].id, displayName: requiredAttributes[i].name, type: requiredAttributes[i].valueType, value: ''});
                 }                   
             }
 
             teiAttributes = orderByFilter(teiAttributes, '-order');
             teiAttributes.reverse();
-
             return teiAttributes;
         }
     };
@@ -1309,9 +1328,14 @@
                 }               
             }            
         },
-        getEventDueDate: function(events, programStage, enrollment){
-            var referenceDate = enrollment.dateOfIncident ? enrollment.dateOfIncident : enrollment.dateOfEnrollment;
-            var offset = programStage.minDaysFromStart;
+        getEventDueDate: function(events, programStage, enrollment){            
+            var referenceDate = enrollment.dateOfIncident ? enrollment.dateOfIncident : enrollment.dateOfEnrollment,
+                offset = programStage.minDaysFromStart,
+                calendarSetting = CalendarService.getSetting();
+        
+            if(programStage.generatedByEnrollmentDate){
+                referenceDate = enrollment.dateOfEnrollment;
+            }
             
             if(programStage.repeatable){
                 var eventsPerStage = [];
@@ -1326,8 +1350,8 @@
                     referenceDate = eventsPerStage[0].eventDate;
                     offset = programStage.standardInterval;
                 }                
-            }
-            var calendarSetting = CalendarService.getSetting();
+            }            
+            
             var dueDate = moment(referenceDate, calendarSetting.momentFormat).add('d', offset)._d;
             dueDate = $filter('date')(dueDate, calendarSetting.keyDateFormat); 
             return dueDate;
@@ -1383,8 +1407,7 @@
 })
 
 /* service for getting calendar setting */
-.service('CalendarService', function(storage, $rootScope){    
-
+.service('CalendarService', function(storage, $rootScope){
     return {
         getSetting: function() {
             
@@ -1405,5 +1428,5 @@
             $rootScope.dhis2CalendarFormat = dhis2CalendarFormat;
             return dhis2CalendarFormat;
         }
-    };            
+    };
 });
\ No newline at end of file

=== 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	2014-10-13 14:47:39 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js	2014-10-22 11:46:33 +0000
@@ -6,7 +6,7 @@
 // Instance of the StorageManager
 dhis2.tc.storageManager = new StorageManager();
 
-var TC_STORE_NAME = "dhis2tc";
+var TC_STORE_NAME = "dhis2";
 var i18n_no_orgunits = 'No organisation unit attached to current user, no data entry possible';
 var i18n_offline_notification = 'You are offline, data will be stored locally';
 var i18n_online_notification = 'You are online';
@@ -397,7 +397,7 @@
         return $.ajax( {
             url: '../api/programs.json',
             type: 'GET',
-            data: 'paging=false&filter=id:eq:' + id +'&fields=id,name,version,dataEntryMethod,relationshipText,relationshipFromA,dateOfEnrollmentDescription,dateOfIncidentDescription,displayIncidentDate,ignoreOverdueEvents,realionshipText,relationshipFromA,selectEnrollmentDatesInFuture,selectIncidentDatesInFuture,onlyEnrollOnce,externalAccess,displayOnAllOrgunit,registration,trackedEntity[id,name,description],userRoles[id,name],organisationUnits[id,name],programStages[id,name,version,minDaysFromStart,standardInterval,reportDateDescription,repeatable,autoGenerateEvent],programTrackedEntityAttributes[displayInList,mandatory,trackedEntityAttribute[id]]'
+            data: 'paging=false&filter=id:eq:' + id +'&fields=id,name,version,dataEntryMethod,relationshipText,relationshipFromA,dateOfEnrollmentDescription,dateOfIncidentDescription,displayIncidentDate,ignoreOverdueEvents,realionshipText,relationshipFromA,selectEnrollmentDatesInFuture,selectIncidentDatesInFuture,onlyEnrollOnce,externalAccess,displayOnAllOrgunit,registration,trackedEntity[id,name,description],userRoles[id,name],organisationUnits[id,name],programStages[id,name,version,minDaysFromStart,standardInterval,generatedByEnrollmentDate,reportDateDescription,repeatable,autoGenerateEvent],programTrackedEntityAttributes[displayInList,mandatory,allowFutureDate,trackedEntityAttribute[id]]'
         }).done( function( response ){
             
             _.each( _.values( response.programs ), function ( program ) { 
@@ -474,7 +474,7 @@
         return $.ajax( {
             url: '../api/programStages.json',
             type: 'GET',
-            data: 'filter=id:eq:' + id +'&fields=id,name,version,dataEntryForm,captureCoordinates,blockEntryForm,autoGenerateEvent,reportDateDescription,minDaysFromStart,standardInterval,repeatable,programStageDataElements[displayInReports,allowProvidedElsewhere,allowDateInFuture,compulsory,dataElement[id,name,formName,type,optionSet[id]]]'
+            data: 'filter=id:eq:' + id +'&fields=id,name,version,dataEntryForm,captureCoordinates,blockEntryForm,autoGenerateEvent,reportDateDescription,minDaysFromStart,standardInterval,repeatable,programStageDataElements[displayInReports,allowProvidedElsewhere,allowFutureDate,compulsory,dataElement[id,name,formName,type,optionSet[id]]]'
         }).done( function( response ){            
             _.each( _.values( response.programStages ), function( programStage ) {
                 dhis2.tc.store.set( 'programStages', programStage );

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/views/dialog.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/views/dialog.html	2014-03-17 15:59:31 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/views/dialog.html	2014-10-22 11:46:33 +0000
@@ -6,5 +6,5 @@
 </div>
 
 <div class="modal-footer">
-    <button class="big-button grey" data-ng-click="dialogOptions.ok();">{{dialogOptions.closeButtonText| translate}}</button>
+    <button class="btn btn-default" data-ng-click="dialogOptions.ok();">{{dialogOptions.closeButtonText| translate}}</button>
 </div>
\ 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	2014-10-13 16:02:01 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/views/home.html	2014-10-22 11:46:33 +0000
@@ -17,237 +17,242 @@
     <img id="ouwt_loader" src="../images/ajax-loader-bar.gif"/>
 </div>
 
-<div class="page" id="mainPage" ng-show="selectedOrgUnit">
-
-    <!-- top bar begins -->
-    <div class="row top-bar">        
-        <div class="col-sm-12">            
-            <span ng-if='searchState'>
-                {{selectedProgram.trackedEntity.name}} {{'search'| translate}}
-            </span>
-            <span ng-if='showRegistrationDiv'>
-                {{selectedProgram.trackedEntity.name}} {{'register'| translate}}
-            </span>        
-            <span ng-if='showReportDiv'>
-                {{selectedProgram.name}} {{'report'| translate}}
-            </span>
-            <div class="pull-right not-printable">
-                <div class="btn-group" dropdown is-open="status.isopen">
-                    <button type="button" class="btn btn-default dropdown-toggle" ng-disabled="trackedEntityList.rows.length <= 0">
-                        <i class="fa fa-cog" title="{{'settings'| translate}}"></i>
-                    </button>
-                    <ul class="dropdown-menu pull-right" role="menu">
-                        <li ng-show="trackedEntityList.rows.length > 0"><a href ng-click="showHideColumns()">{{'show_hide_columns'| translate}}</a></li>
+<div class="page" id="mainPage">
+    
+    <img src="../images/ajax-loader-bar.gif" alt="{{'in_progress'| translate}}" ng-if="!selectedOrgUnit"/>
+
+    <div ng-show="selectedOrgUnit">
+        <!-- top bar begins -->
+        <div class="row top-bar">        
+            <div class="col-sm-12">            
+                <span ng-if='searchState'>
+                    {{selectedProgram.trackedEntity.name}} {{'search'| translate}}
+                </span>
+                <span ng-if='showRegistrationDiv'>
+                    {{selectedProgram.trackedEntity.name}} {{'register'| translate}}
+                </span>        
+                <span ng-if='showReportDiv'>
+                    {{selectedProgram.name}} {{'report'| translate}}
+                </span>
+                <div class="pull-right not-printable">
+                    <div class="btn-group" dropdown is-open="status.isopen">
+                        <button type="button" class="btn btn-default dropdown-toggle" ng-disabled="trackedEntityList.rows.length <= 0">
+                            <i class="fa fa-cog" title="{{'settings'| translate}}"></i>
+                        </button>
+                        <ul class="dropdown-menu pull-right" role="menu">
+                            <li ng-show="trackedEntityList.rows.length > 0"><a href ng-click="showHideColumns()">{{'show_hide_columns'| translate}}</a></li>
+                        </ul>
+                    </div>
+                </div>            
+            </div>        
+        </div>
+        <!-- top bar ends -->
+
+        <!--- selected org unit begins -->
+        <input type="text" selected-org-unit ng-model="selectedOrgUnit.name" ng-hide=true>
+        <!--- selected org unit ends  -->
+
+        <!--- search, registration and reporting menu begins -->
+        <div class="row vertical-spacing not-for-screen">
+            <div class="col-md-4">
+                <h4>{{'org_unit' | translate}}</h4>
+            </div>
+            <div class="col-md-4">
+                <input type="text" class="form-control" ng-disabled='true' value="{{selectedOrgUnit.name}}">
+            </div>
+        </div>
+        <div class="row"> 
+            <div id="selectDropDownParent" class="input-group col-md-4">            
+                <button type="button" class="select-dropdown-button form-control" ng-show="programs.length > 0">{{selectedProgram ? selectedProgram.name : 'please_select_a_program'| translate}}</button>
+                <button type="button" class="select-dropdown-button form-control" ng-show="programs.length < 1" ng-disabled="true">{{programs.length > 0 ? 'please_select_a_program' : 'no_program_exists' | translate}}</button>
+                <div class="input-group-btn">
+                    <button class="btn btn-default select-dropdown-caret" type="button" title="{{'list_programs'| translate}}" data-toggle="dropdown" ng-disabled="programs.length < 1"><i class="fa fa-caret-down"></i></button>
+                    <ul id="selectDropDown" class="dropdown-menu dropdown-menu-right">
+                        <li>
+                            <a href ng-click="getProgramAttributes(null)">{{'please_select_a_program' | translate}}</a>
+                        </li>
+                        <li ng-repeat="program in programs| orderBy: 'name'">
+                            <a href ng-click="getProgramAttributes(program)">{{program.name}}</a>
+                        </li>
                     </ul>
-                </div>
-            </div>            
-        </div>        
-    </div>
-    <!-- top bar ends -->
-
-    <!--- selected org unit begins -->
-    <input type="text" selected-org-unit ng-model="selectedOrgUnit.name" ng-hide=true>
-    <!--- selected org unit ends  -->
-
-    <!--- search, registration and reporting menu begins -->
-    <div class="row vertical-spacing not-for-screen">
-        <div class="col-md-4">
-            <h4>{{'org_unit' | translate}}</h4>
-        </div>
-        <div class="col-md-4">
-            <input type="text" class="form-control" ng-disabled='true' value="{{selectedOrgUnit.name}}">
-        </div>
-    </div>
-    <div class="row"> 
-        <div id="selectDropDownParent" class="input-group col-md-4">            
-            <button type="button" class="select-dropdown-button form-control" ng-show="programs.length > 0">{{selectedProgram ? selectedProgram.name : 'please_select_a_program'| translate}}</button>
-            <button type="button" class="select-dropdown-button form-control" ng-show="programs.length < 1" ng-disabled="true">{{programs.length > 0 ? 'please_select_a_program' : 'no_program_exists' | translate}}</button>
-            <div class="input-group-btn">
-                <button class="btn btn-default select-dropdown-caret" type="button" title="{{'list_programs'| translate}}" data-toggle="dropdown" ng-disabled="programs.length < 1"><i class="fa fa-caret-down"></i></button>
-                <ul id="selectDropDown" class="dropdown-menu dropdown-menu-right">
-                    <li>
-                        <a href ng-click="getProgramAttributes(null)">{{'please_select_a_program' | translate}}</a>
-                    </li>
-                    <li ng-repeat="program in programs| orderBy: 'name'">
-                        <a href ng-click="getProgramAttributes(program)">{{program.name}}</a>
-                    </li>
-                </ul>
-            </div>                
-        </div>
-        <div id="searchDropDownParent" class="input-group col-md-4 not-printable">
-            <input type="text" placeholder="{{'type_here_for_simple_search'| translate}}" ng-model="searchText" class="form-control expanded" d2-enter="search(searchMode.freeText)" ng-class="{true: 'invalid-input'} [!searchText && emptySearchText]" ng-focus="showHideSearch()" ng-disabled="showRegistrationDiv || showReportDiv">
-            <div class="input-group-btn">
-                <button class="btn btn-default search-dropdown-button trim" type="button" title="{{'advanced_search'| translate}}" data-toggle="dropdown" ng-click="showHideSearch()" ng-disabled="showRegistrationDiv || showReportDiv"><i class="fa fa-caret-down"></i></button>
-                <button class="btn btn-primary trim" type="button" title="{{'search'| translate}}" ng-disabled="showRegistrationDiv || showReportDiv" ng-click="search(searchMode.freeText)"><i class="fa fa-search"></i></button>
-                <div id="searchDropDown" class="dropdown-menu dropdown-menu-right">
-                    <form ng-submit="search(searchMode.attributeBased)">
-                        <div class="search-container-main">
-                            <div class="search-container">    
-                                <table data-stop-propagation="true" class="table-borderless table-striped">
-                                    <tr>
-                                        <td>{{'org_unit'| translate}}</td>
-                                        <td>                    
-                                            <label><input type="radio" ng-model="selectedOuMode.name" name="selected" value="SELECTED"> {{'SELECTED'| translate}}</label><br/>
-                                            <label><input type="radio" ng-model="selectedOuMode.name" name="children" value="CHILDREN"> {{'CHILDREN'| translate}}</label><br/>
-                                            <label><input type="radio" ng-model="selectedOuMode.name" name="descendants" value="DESCENDANTS"> {{'DESCENDANTS'| translate}}</label><br/>
-                                            <label><input type="radio" ng-model="selectedOuMode.name" name="accessible" value="ACCESSIBLE"> {{'ACCESSIBLE'| translate}}</label>
-                                        </td>
-                                    </tr>
-                                    <tr ng-if="selectedProgram">
-                                        <td>{{'enrollment_date'| translate}}</td>
-                                        <td>
-                                            <div class="dataelement-filter">
-                                                <div class="filter-operator">
-                                                    <select ng-model="enrollment.operator" class="form-control-select2" ng-options="operator | translate for operator in defaultOperators">
-                                                    </select>
-                                                </div>
-                                                <div class="filter-value" ng-show="enrollment.operator === defaultOperators[0]">
-                                                    <input type="text" placeholder="{{'exact_date'| translate}}" class="form-control-select2" d2-date ng-model="enrollment.programExactDate"/>
-                                                </div>
-                                                <div class="filter-value" ng-show="enrollment.operator === defaultOperators[1]">
-                                                    <div class="container-1-2">
-                                                        <input type="text" placeholder="{{'start_date'| translate}}" class="form-control-select2" d2-date ng-model="enrollment.programStartDate"/>
-                                                    </div>
-                                                    <div class="container-1-2">
-                                                        <input type="text" placeholder="{{'end_date'| translate}}" class="form-control-select2" d2-date ng-model="enrollment.programEndDate"/>                
-                                                    </div>
-                                                </div>                    
-                                            </div>                
-                                        </td>
-                                    </tr>
-                                    <tr ng-repeat="attribute in attributesLighter">
-                                        <td>
-                                            {{attribute.name}}
-                                        </td>
-                                        <td>
-                                            <div ng-switch="attribute.type">
-                                                <div ng-switch-when="number">
-                                                    <div class="dataelement-filter">                                                
-                                                        <div class="filter-operator">
-                                                            <select ng-model="attribute.operator" class="form-control-select2" ng-options="operator | translate for operator in defaultOperators">
-                                                            </select>
-                                                        </div>
-                                                        <div class="filter-value" ng-show="attribute.operator === defaultOperators[0]">
-                                                            <input type="number" placeholder="{{'exact_value'| translate}}" class="form-control-select2" ng-model="attribute.exactValue"/>
-                                                        </div>
-                                                        <div class="filter-value" ng-show="attribute.operator === defaultOperators[1]">
-                                                            <div class="container-1-2">
-                                                                <input type="number" placeholder="{{'from'| translate}}" class="form-control-select2" ng-model="attribute.startValue"/>
-                                                            </div>
-                                                            <div class="container-1-2">
-                                                                <input type="number" placeholder="{{'to'| translate}}" class="form-control-select2" ng-model="attribute.endValue"/>                
-                                                            </div>
-                                                        </div>                            
+                </div>                
+            </div>
+            <div id="searchDropDownParent" class="input-group col-md-4 not-printable">
+                <input type="text" placeholder="{{'type_here_for_simple_search'| translate}}" ng-model="searchText" class="form-control expanded" d2-enter="search(searchMode.freeText)" ng-class="{true: 'invalid-input'} [!searchText && emptySearchText]" ng-focus="showHideSearch()" ng-disabled="showRegistrationDiv || showReportDiv">
+                <div class="input-group-btn">
+                    <button class="btn btn-default search-dropdown-button trim" type="button" title="{{'advanced_search'| translate}}" data-toggle="dropdown" ng-click="showHideSearch()" ng-disabled="showRegistrationDiv || showReportDiv"><i class="fa fa-caret-down"></i></button>
+                    <button class="btn btn-primary trim" type="button" title="{{'search'| translate}}" ng-disabled="showRegistrationDiv || showReportDiv" ng-click="search(searchMode.freeText)"><i class="fa fa-search"></i></button>
+                    <div id="searchDropDown" class="dropdown-menu dropdown-menu-right">
+                        <form ng-submit="search(searchMode.attributeBased)">
+                            <div class="search-container-main">
+                                <div class="search-container">    
+                                    <table data-stop-propagation="true" class="table-borderless table-striped">
+                                        <tr>
+                                            <td>{{'org_unit'| translate}}</td>
+                                            <td>                    
+                                                <label><input type="radio" ng-model="selectedOuMode.name" name="selected" value="SELECTED"> {{'SELECTED'| translate}}</label><br/>
+                                                <label><input type="radio" ng-model="selectedOuMode.name" name="children" value="CHILDREN"> {{'CHILDREN'| translate}}</label><br/>
+                                                <label><input type="radio" ng-model="selectedOuMode.name" name="descendants" value="DESCENDANTS"> {{'DESCENDANTS'| translate}}</label><br/>
+                                                <label><input type="radio" ng-model="selectedOuMode.name" name="accessible" value="ACCESSIBLE"> {{'ACCESSIBLE'| translate}}</label>
+                                            </td>
+                                        </tr>
+                                        <tr ng-if="selectedProgram">
+                                            <td>{{'enrollment_date'| translate}}</td>
+                                            <td>
+                                                <div class="dataelement-filter">
+                                                    <div class="filter-operator">
+                                                        <select ng-model="enrollment.operator" class="form-control-select2" ng-options="operator | translate for operator in defaultOperators">
+                                                        </select>
+                                                    </div>
+                                                    <div class="filter-value" ng-show="enrollment.operator === defaultOperators[0]">
+                                                        <input type="text" placeholder="{{'exact_date'| translate}}" class="form-control-select2" d2-date ng-model="enrollment.programExactDate"/>
+                                                    </div>
+                                                    <div class="filter-value" ng-show="enrollment.operator === defaultOperators[1]">
+                                                        <div class="container-1-2">
+                                                            <input type="text" placeholder="{{'start_date'| translate}}" class="form-control-select2" d2-date ng-model="enrollment.programStartDate"/>
+                                                        </div>
+                                                        <div class="container-1-2">
+                                                            <input type="text" placeholder="{{'end_date'| translate}}" class="form-control-select2" d2-date ng-model="enrollment.programEndDate"/>                
+                                                        </div>
+                                                    </div>                    
+                                                </div>                
+                                            </td>
+                                        </tr>
+                                        <tr ng-repeat="attribute in attributesLighter">
+                                            <td>
+                                                {{attribute.name}}
+                                            </td>
+                                            <td>
+                                                <div ng-switch="attribute.type">
+                                                    <div ng-switch-when="number">
+                                                        <div class="dataelement-filter">                                                
+                                                            <div class="filter-operator">
+                                                                <select ng-model="attribute.operator" class="form-control-select2" ng-options="operator | translate for operator in defaultOperators">
+                                                                </select>
+                                                            </div>
+                                                            <div class="filter-value" ng-show="attribute.operator === defaultOperators[0]">
+                                                                <input type="number" placeholder="{{'exact_value'| translate}}" class="form-control-select2" ng-model="attribute.exactValue"/>
+                                                            </div>
+                                                            <div class="filter-value" ng-show="attribute.operator === defaultOperators[1]">
+                                                                <div class="container-1-2">
+                                                                    <input type="number" placeholder="{{'from'| translate}}" class="form-control-select2" ng-model="attribute.startValue"/>
+                                                                </div>
+                                                                <div class="container-1-2">
+                                                                    <input type="number" placeholder="{{'to'| translate}}" class="form-control-select2" ng-model="attribute.endValue"/>                
+                                                                </div>
+                                                            </div>                            
+                                                        </div>                        
+                                                    </div>
+                                                    <div ng-switch-when="date">
+                                                        <div class="dataelement-filter">
+                                                            <div class="filter-operator">
+                                                                <select ng-model="attribute.operator" class="form-control-select2" ng-options="operator | translate for operator in defaultOperators">
+                                                                </select>
+                                                            </div>
+                                                            <div class="filter-value" ng-show="attribute.operator === defaultOperators[0]">
+                                                                <input type="text" placeholder="{{'exact_date'| translate}}" class="form-control-select2" d2-date ng-model="attribute.exactValue"/>
+                                                            </div>
+                                                            <div class="filter-value" ng-show="attribute.operator === defaultOperators[1]">
+                                                                <div class="container-1-2">
+                                                                    <input type="text" placeholder="{{'start_date'| translate}}" class="form-control-select2" d2-date ng-model="attribute.startValue"/>
+                                                                </div>
+                                                                <div class="container-1-2">
+                                                                    <input type="text" placeholder="{{'end_date'| translate}}" class="form-control-select2" d2-date ng-model="attribute.endValue"/>                
+                                                                </div>
+                                                            </div>                            
+                                                        </div> 
                                                     </div>                        
-                                                </div>
-                                                <div ng-switch-when="date">
-                                                    <div class="dataelement-filter">
-                                                        <div class="filter-operator">
-                                                            <select ng-model="attribute.operator" class="form-control-select2" ng-options="operator | translate for operator in defaultOperators">
-                                                            </select>
-                                                        </div>
-                                                        <div class="filter-value" ng-show="attribute.operator === defaultOperators[0]">
-                                                            <input type="text" placeholder="{{'exact_date'| translate}}" class="form-control-select2" d2-date ng-model="attribute.exactValue"/>
-                                                        </div>
-                                                        <div class="filter-value" ng-show="attribute.operator === defaultOperators[1]">
-                                                            <div class="container-1-2">
-                                                                <input type="text" placeholder="{{'start_date'| translate}}" class="form-control-select2" d2-date ng-model="attribute.startValue"/>
-                                                            </div>
-                                                            <div class="container-1-2">
-                                                                <input type="text" placeholder="{{'end_date'| translate}}" class="form-control-select2" d2-date ng-model="attribute.endValue"/>                
-                                                            </div>
-                                                        </div>                            
+                                                    <div ng-switch-when="optionSet">
+                                                        <select multiple ui-select2  ng-model="attribute.value" data-placeholder="{{'please_select'| translate}}" style="width:100%;">
+                                                            <option ng-repeat="option in attributes[attribute.id].optionSet.options | filter:$viewValue | limitTo:100" value="{{option.code}}">{{option.name}}</option>
+                                                        </select>
+                                                    </div>
+                                                    <div ng-switch-when="bool">
+                                                        <select ui-select2 multiple ng-model="attribute.value" data-placeholder="{{'please_select'| translate}}" style="width:100%;">
+                                                            <option ng-repeat="option in boolOperators" value="{{option}}">{{option| translate}}</option>
+                                                        </select>
                                                     </div> 
-                                                </div>                        
-                                                <div ng-switch-when="optionSet">
-                                                    <select multiple ui-select2  ng-model="attribute.value" data-placeholder="{{'please_select'| translate}}" style="width:100%;">
-                                                        <option ng-repeat="option in attributes[attribute.id].optionSet.options | filter:$viewValue | limitTo:100" value="{{option.code}}">{{option.name}}</option>
-                                                    </select>
-                                                </div>
-                                                <div ng-switch-when="bool">
-                                                    <select ui-select2 multiple ng-model="attribute.value" data-placeholder="{{'please_select'| translate}}" style="width:100%;">
-                                                        <option ng-repeat="option in boolOperators" value="{{option}}">{{option| translate}}</option>
-                                                    </select>
-                                                </div> 
-                                                <div ng-switch-default>
-                                                    <input type="text" class="form-control-select2" ng-model="attribute.value" /> 
-                                                </div>
-                                            </div>
-                                        </td>
-                                    </tr>         
-                                </table>
-                            </div>
-
-                            <div class="horizonal-spacing">
-                                <button type="submit"
-                                        class="btn btn-primary"
-                                        ng-click="search(searchMode.attributeBased)">
-                                    {{'search'| translate}}
-                                </button>
-                                <button type="button" 
-                                        class="btn btn-success small-horizonal-spacing" 
-                                        ng-click="search(searchMode.listAll)">
-                                    {{'list_all'| translate}}
-                                </button>        
-                            </div>
-                        </div>
-                    </form>
-                </div>
-            </div>                
-        </div>        
-        <div class="col-md-4 trim not-printable">            
-            <button type="button" 
-                    class="btn btn-success"
-                    ng-disabled="showRegistrationDiv || showReportDiv"
-                    ng-click="search(searchMode.listAll)">
-                {{'list_all'| translate}}
-            </button>
-            <button type="button" 
-                    class="btn btn-primary"
-                    ng-disabled="showReportDiv"
-                    ng-click="showRegistration()">                    
-                {{'register'| translate}}
-            </button>
-            <button type="button" 
-                    class="btn btn-info"
-                    ng-if="teiCount > 0"
-                    onclick="javascript:window.print()">                    
-                {{'print'| translate}}
-            </button>
-        </div>
-    </div>
-    <!--- search, registration and reporting menu ends -->
-
-    <!--- Error display for search begins -->
-    <div class="row" ng-if="emptySearchAttribute || !searchText && emptySearchText">
-        <div class="col-md-8 vertical-spacing">
-            <div class="alert alert-warning">{{'search_input_required'| translate}}</div>         
-        </div>
-    </div>
-    <!--- Error display for search ends -->
-
-    <!--registration form begins -->
-    <div class="row" ng-if="showRegistrationDiv">
-        <div class="col-md-8">
-            <div ng-include="'components/registration/registration.html'"></div>             
-        </div>
-    </div>
-    <!-- registration form ends -->
+                                                    <div ng-switch-default>
+                                                        <input type="text" class="form-control-select2" ng-model="attribute.value" /> 
+                                                    </div>
+                                                </div>
+                                            </td>
+                                        </tr>         
+                                    </table>
+                                </div>
+
+                                <div class="horizonal-spacing">
+                                    <button type="submit"
+                                            class="btn btn-primary"
+                                            ng-click="search(searchMode.attributeBased)">
+                                        {{'search'| translate}}
+                                    </button>
+                                    <button type="button" 
+                                            class="btn btn-success small-horizonal-spacing" 
+                                            ng-click="search(searchMode.listAll)">
+                                        {{'list_all'| translate}}
+                                    </button>        
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                </div>                
+            </div>        
+            <div class="col-md-4 trim not-printable">            
+                <button type="button" 
+                        class="btn btn-success"
+                        ng-disabled="showRegistrationDiv || showReportDiv"
+                        ng-click="search(searchMode.listAll)">
+                    {{'list_all'| translate}}
+                </button>
+                <button type="button" 
+                        class="btn btn-primary"
+                        ng-disabled="showReportDiv"
+                        ng-click="showRegistration()">                    
+                    {{'register'| translate}}
+                </button>
+                <button type="button" 
+                        class="btn btn-info"
+                        ng-if="teiCount > 0"
+                        onclick="javascript:window.print()">                    
+                    {{'print'| translate}}
+                </button>
+            </div>
+        </div>
+        <!--- search, registration and reporting menu ends -->
+
+        <!--- Error display for search begins -->
+        <div class="row" ng-if="emptySearchAttribute || !searchText && emptySearchText">
+            <div class="col-md-8 vertical-spacing">
+                <div class="alert alert-warning">{{'search_input_required'| translate}}</div>         
+            </div>
+        </div>
+        <!--- Error display for search ends -->
+
+        <!--registration form begins -->
+        <div class="row" ng-if="showRegistrationDiv">
+            <div class="col-md-8">
+                <div ng-include="'components/registration/registration.html'"></div>             
+            </div>
+        </div>
+        <!-- registration form ends -->
+
+        <!--report div begins -->
+        <div class="row" ng-if="showReportDiv">
+            <div class="col-md-8">
+                <div ng-include="'components/report/report.html'"></div>             
+            </div>
+        </div>
+        <!-- report div ends -->
+
+        <!-- entity grid begins -->
+        <img src="../images/ajax-loader-bar.gif" alt="{{'in_progress' | translate}}" ng-if="!teiFetched && searchText && !emptySearchTex"/>
+        <div class="row" ng-if="showTrackedEntityDiv">
+            <div class="col-md-12" ng-include="'views/tei.html'"></div>  
+        </div>
+        <!-- entity grid ends -->
+    </div>
     
-    <!--report div begins -->
-    <div class="row" ng-if="showReportDiv">
-        <div class="col-md-8">
-            <div ng-include="'components/report/report.html'"></div>             
-        </div>
-    </div>
-    <!-- report div ends -->
-
-    <!-- entity grid begins -->
-    <img src="../images/ajax-loader-bar.gif" alt="{{'in_progress' | translate}}" ng-if="!teiFetched && searchText && !emptySearchTex"/>
-    <div class="row" ng-if="showTrackedEntityDiv">
-        <div class="col-md-12" ng-include="'views/tei.html'"></div>  
-    </div>
-    <!-- entity grid ends -->
 </div>