← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 15861: tracker capture - tei searching with multiple filters

 

------------------------------------------------------------
revno: 15861
committer: Abyot Asalefew Gizaw abyota@xxxxxxxxx
branch nick: dhis2
timestamp: Thu 2014-06-26 15:35:30 +0200
message:
  tracker capture - tei searching with multiple filters
modified:
  dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js
  dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html
  dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/i18n/en.json
  dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/scripts/controllers.js
  dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/scripts/services.js
  dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/styles/style.css
  dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/views/home.html
  dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/views/search.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-tracker-capture/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js'
--- dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js	2014-06-20 15:17:00 +0000
+++ dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js	2014-06-26 13:35:30 +0000
@@ -176,12 +176,14 @@
             if($scope.currentEvent && $scope.currentEvent.event === event.event){
                 //clicked on the same stage, do toggling
                 $scope.currentEvent = null;
+                $scope.currentElement = {id: '', saved: false};
                 $scope.showDataEntryDiv = !$scope.showDataEntryDiv;                
             }
             else{
-                $scope.currentEvent = event;
+                $scope.currentElement = {};
+                $scope.currentEvent = event;                
                 $scope.showDataEntryDiv = !$scope.showDataEntryDiv;
-                $scope.getDataEntryForm();
+                $scope.getDataEntryForm();                
             }               
         }
     }; 
@@ -213,35 +215,48 @@
             });
 
             $scope.currentEvent.dataValues = [];
+            $scope.currentEventOriginal = angular.copy($scope.currentEvent);
         }); 
     };
     
     $scope.saveDatavalue = function(prStDe){
         
-        $scope.updateSuccess = false;
-        
+        //check for input validity
+        $scope.dataEntryOuterForm.submitted = true;        
+        if( $scope.dataEntryOuterForm.$invalid ){
+            return false;
+        }
+         
+        //input is valid
+        $scope.updateSuccess = false;      
+   
         if(!angular.isUndefined($scope.currentEvent[prStDe.dataElement.id])){
-            
-            //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,
-                        programStage: $scope.currentEvent.programStage,
-                        status: $scope.currentEvent.status,
-                        trackedEntityInstance: $scope.currentEvent.trackedEntityInstance,
-                        dataValues: [
-                                        {
-                                            dataElement: prStDe.dataElement.id, 
-                                            value: value, 
-                                            providedElseWhere: $scope.currentEvent.providedElsewhere[prStDe.dataElement.id] ? $scope.currentEvent.providedElsewhere[prStDe.dataElement.id] : false
-                                        }
-                                    ]
-                     };
-            DHIS2EventFactory.updateForSingleValue(ev).then(function(response){
-                $scope.updateSuccess = true;
-            });
-            
+
+            if($scope.currentEventOriginal[prStDe.dataElement.id] != $scope.currentEvent[prStDe.dataElement.id]){
+                
+                //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,
+                            programStage: $scope.currentEvent.programStage,
+                            status: $scope.currentEvent.status,
+                            trackedEntityInstance: $scope.currentEvent.trackedEntityInstance,
+                            dataValues: [
+                                            {
+                                                dataElement: prStDe.dataElement.id, 
+                                                value: value, 
+                                                providedElseWhere: $scope.currentEvent.providedElsewhere[prStDe.dataElement.id] ? $scope.currentEvent.providedElsewhere[prStDe.dataElement.id] : false
+                                            }
+                                        ]
+                         };
+                DHIS2EventFactory.updateForSingleValue(ev).then(function(response){
+                    $scope.currentElement.saved = true;
+                });
+            }
         }        
     };
     
@@ -270,8 +285,7 @@
                      };
             DHIS2EventFactory.updateForSingleValue(ev).then(function(response){
                 $scope.updateSuccess = true;
-            });
-            
+            });            
         }        
     };
     
@@ -290,4 +304,16 @@
         }
         return dummyEvent;
     };
+    
+    $scope.getClass = function(id){
+        if($scope.currentElement){
+            if($scope.currentElement.saved && ($scope.currentElement.id === id)){
+                return 'form-control input-success';
+            }            
+            if(!$scope.currentElement.saved && ($scope.currentElement.id === id)){
+                return 'form-control input-error';
+            }            
+        }        
+        return 'form-control';      
+    };
 });
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html'
--- dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html	2014-06-25 14:08:18 +0000
+++ dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html	2014-06-26 13:35:30 +0000
@@ -72,80 +72,84 @@
                 </form>                
             </div>
         </div>        
-        <div ng-show="currentEvent">
-            <hr>
-            <table class="table-borderless table-striped">
-                <thead>
-                    <tr class="col-md-12">
-                        <th class="col-md-5">
-                            {{'data_element'| translate}}
-                        </th>
-                        <th class="col-md-5 align-center">
-                            {{'value'| translate}}
-                        </th>
-                        <th class="col-md-2 align-center" ng-if="allowProvidedElsewhereExists">
-                            {{'provided_elsewhere'| translate}}
-                        </th>
+        <div>            
+            <form name="dataEntryOuterForm" novalidate>
+                <hr>
+                <table class="table-borderless table-striped" ng-if='currentEvent'>
+                    <thead>
+                        <tr class="col-md-12">
+                            <th class="col-md-5">
+                                {{'data_element'| translate}}
+                            </th>
+                            <th class="col-md-5 align-center">
+                                {{'value'| translate}}
+                            </th>
+                            <th class="col-md-2 align-center" ng-if="allowProvidedElsewhereExists">
+                                {{'provided_elsewhere'| translate}}
+                            </th>
+                        </tr>
+                    </thead>
+                    <tr class="col-md-12" ng-repeat="prStDe in currentStage.programStageDataElements">
+                        <td class="col-md-5">
+                            {{prStDe.dataElement.name}} - {{prStDe.dataElement.type}}
+                        </td>
+                        <td class="col-md-5">
+                            <ng-form name="dataEntryInnerForm">
+                                <div ng-switch="prStDe.dataElement.type">
+                                    <div ng-switch-when="int">
+                                        <input type="number"
+                                               ng-class='getClass(prStDe.dataElement.id)'
+                                               ng-model="currentEvent[prStDe.dataElement.id]" 
+                                               ng-required={{prStDe.compulsory}}
+                                               ng-blur="saveDatavalue(prStDe)" 
+                                               name="foo"/>
+                                        <span ng-show="dataEntryOuterForm.submitted && dataEntryInnerForm.foo.$invalid" style="color:red;font-size:12px">{{'number_required' | translate}}</span>
+                                    </div>
+                                    <div ng-switch-when="string">                                        
+                                        <input type="text"
+                                               ng-class='getClass(prStDe.dataElement.id)'
+                                               ng-model="currentEvent[prStDe.dataElement.id]" 
+                                               ng-required={{prStDe.compulsory}} 
+                                               typeahead="option for option in prStDe.dataElement.optionSet.options | filter:$viewValue | limitTo:20" 
+                                               typeahead-open-on-focus    
+                                               ng-blur="saveDatavalue(prStDe)" 
+                                               name="foo"/>
+                                    </div>
+                                    <div ng-switch-when="bool">
+                                        <select ng-class='getClass(prStDe.dataElement.id)'
+                                                ng-model="currentEvent[prStDe.dataElement.id]" 
+                                                ng-required={{prStDe.compulsory}} 
+                                                ng-change="saveDatavalue(prStDe)" 
+                                                name="foo">
+                                            <option value="">{{'please_select'| translate}}</option>                        
+                                            <option value="0">{{'no'| translate}}</option>
+                                            <option value="1">{{'yes'| translate}}</option>
+                                        </select>
+
+                                    </div>
+                                    <div ng-switch-when="date">
+                                        <input type="text" 
+                                               placeholder="yyyy-mm-dd" 
+                                               ng-date 
+                                               ng-class='getClass(prStDe.dataElement.id)'
+                                               ng-model="saveDatavalue(prStDe)" 
+                                               ng-required={{prStDe.compulsory}}  
+                                               blur-or-change="saveDatavalue(dhis2Event, eventGridColumn.id)"
+                                               name="foo"/>
+                                    </div>
+                                </div>
+                            </ng-form>                            
+                        </td>
+                        <td class="col-md-2" ng-if="allowProvidedElsewhereExists">                    
+                            <div class="align-center" ng-show="prStDe.allowProvidedElsewhere">
+                                <input type="checkbox" 
+                                       ng-model="currentEvent.providedElsewhere[prStDe.dataElement.id]"
+                                       ng-change="saveDatavalueLocation(prStDe)"/>
+                            </div>
+                        </td>
                     </tr>
-                </thead>
-                <tr class="col-md-12" ng-repeat="prStDe in currentStage.programStageDataElements">
-                    <td class="col-md-5">
-                        {{prStDe.dataElement.name}}
-                    </td>
-                    <td class="col-md-5">
-                        <div ng-switch="prStDe.dataElement.type">
-                            <div ng-switch-when="int">
-                                <input type="number"
-                                       class="form-control"
-                                       ng-model="currentEvent[prStDe.dataElement.id]" 
-                                       ng-required={{prStDe.compulsory}}
-                                       ng-blur="saveDatavalue(prStDe)" 
-                                       name="foo"/>
-                            </div>
-                            <div ng-switch-when="string">                                        
-                                <input type="text"
-                                       class="form-control"
-                                       ng-model="currentEvent[prStDe.dataElement.id]" 
-                                       ng-required={{prStDe.compulsory}} 
-                                       typeahead="option for option in prStDe.dataElement.optionSet.options | filter:$viewValue | limitTo:20" 
-                                       typeahead-open-on-focus    
-                                       ng-blur="saveDatavalue(prStDe)" 
-                                       name="foo"/>
-                            </div>
-                            <div ng-switch-when="bool">
-                                <select class="form-control"
-                                        ng-model="currentEvent[prStDe.dataElement.id]" 
-                                        ng-required={{prStDe.compulsory}} 
-                                        ng-change="saveDatavalue(prStDe)" 
-                                        name="foo">
-                                    <option value="">{{'please_select'| translate}}</option>                        
-                                    <option value="0">{{'no'| translate}}</option>
-                                    <option value="1">{{'yes'| translate}}</option>
-                                </select>
-
-                            </div>
-                            <div ng-switch-when="date">
-                                <input type="text" 
-                                       placeholder="yyyy-mm-dd" 
-                                       ng-date 
-                                       class="form-control"
-                                       ng-model="saveDatavalue(prStDe)" 
-                                       ng-required={{prStDe.compulsory}}  
-                                       blur-or-change="saveDatavalue(dhis2Event, eventGridColumn.id)"
-                                       name="foo"/>
-                            </div>
-                        </div>
-                    </td>
-                    <td class="col-md-2" ng-if="allowProvidedElsewhereExists">                    
-                        <div class="align-center" ng-show="prStDe.allowProvidedElsewhere">
-                            <input type="checkbox" 
-                                   ng-model="currentEvent.providedElsewhere[prStDe.dataElement.id]"
-                                   ng-change="saveDatavalueLocation(prStDe)"/>
-                        </div>
-                    </td>
-                </tr>
-            </table>
-            <hr>
+                </table>
+            </form>
         </div>
         <div ng-show="!selectedEnrollment">
             <div class="alert alert-warning">{{'not_yet_enrolled'| translate}}</div> 

=== modified file 'dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/i18n/en.json'
--- dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/i18n/en.json	2014-06-25 14:08:18 +0000
+++ dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/i18n/en.json	2014-06-26 13:35:30 +0000
@@ -14,6 +14,7 @@
     "list_all": "List all",
     "list": "List",
     "required": "Required",
+    "number_required": "Number required",
     "search": "Search",
     "advanced_search": "Advanced search",
     "search_for": "Search for",
@@ -39,6 +40,8 @@
     "remove": "Remove",
     "entity": "Entity",
     "add_new": "Add new",
+    "add_filter": "Add filter",
+    "remove_filter": "Remove filter",
     "new_event": "New event",
     "create_new_event": "Create new event",
     "create_new_event_repeatable": "Create new event from a repeatable stage",
@@ -52,6 +55,7 @@
     "back": "Back",
     "profile": "Profile",
     "enrollment": "Enrollment",
+    "enrollment_date": "Enrollment date",
     "notes": "Notes",
     "relationship": "Relationship",
     "dataentry": "Data Entry",
@@ -77,8 +81,16 @@
     "scheduling": "Scheduling",
     "reschedule": "Reschedule",
     "enroll": "Enroll",
-    "like": "LIKE",
-    "not_like": "NOT LIKE",
+    "from": "From",
+    "to": "To",
+    "EQ": "Equals",
+    "GT": "Greater than",
+    "GE": "Greater equal", 
+    "LT": "Less than", 
+    "LE": "Less equal", 
+    "NE": "Not equal",
+    "like": "Like",
+    "not_like": "Not like",
     "boolean": "Boolean",
     "yes": "Yes",
     "no": "No",

=== modified file 'dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/scripts/controllers.js'
--- dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/scripts/controllers.js	2014-06-19 15:27:17 +0000
+++ dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/scripts/controllers.js	2014-06-26 13:35:30 +0000
@@ -39,7 +39,10 @@
     $scope.searchText = null;
     $scope.emptySearchText = false;
     $scope.searchFilterExists = false;   
-    
+    $scope.numberOperands = ['EQ', 'GT','GE', 'LT', 'LE', 'NE' ];
+    $scope.boolOperands = ['yes', 'no'];
+    $scope.enrollment = {programStartDate: '', programEndDate: ''};
+   
     $scope.searchMode = { 
                             listAll: 'LIST_ALL', 
                             freeText: 'FREE_TEXT', 
@@ -68,6 +71,7 @@
                 setTimeout(function () {
                     $scope.$apply(function () {
                         $scope.attributes = atts;   
+                        $scope.attributes = $scope.generateAttributeFilters($scope.attributes);
                         $scope.gridColumns = $scope.generateGridColumns($scope.attributes);
                         $scope.search($scope.searchMode.listAll);
                     });
@@ -99,6 +103,7 @@
                         setTimeout(function () {
                             $scope.$apply(function () {
                                 $scope.attributes = atts;    
+                                $scope.attributes = $scope.generateAttributeFilters($scope.attributes);
                                 $scope.gridColumns = $scope.generateGridColumns($scope.attributes);
                             });
                         }, 100);
@@ -117,6 +122,7 @@
                 setTimeout(function () {
                     $scope.$apply(function () {
                         $scope.attributes = atts; 
+                        $scope.attributes = $scope.generateAttributeFilters($scope.attributes);
                         $scope.gridColumns = $scope.generateGridColumns($scope.attributes);
                     });
                 }, 100);
@@ -126,7 +132,8 @@
             AttributesFactory.getWithoutProgram().then(function(atts){
                 setTimeout(function () {
                     $scope.$apply(function () {
-                        $scope.attributes = atts;    
+                        $scope.attributes = atts;  
+                        $scope.attributes = $scope.generateAttributeFilters($scope.attributes);
                         $scope.gridColumns = $scope.generateGridColumns($scope.attributes);
                     });
                 }, 100);
@@ -166,7 +173,7 @@
         }
         else if( mode === $scope.searchMode.attributeBased ){
             $scope.showTrackedEntityDiv = true;                  
-            attributeUrl = EntityQueryFactory.getQueryForAttributes($scope.attributes);
+            attributeUrl = EntityQueryFactory.getQueryForAttributes($scope.attributes, $scope.enrollment);
             
             if(!attributeUrl.hasValue && !$scope.selectedProgram){
                 $scope.emptySearchAttribute = true;
@@ -176,9 +183,9 @@
         }
         else if( mode === $scope.searchMode.listAll ){   
             $scope.showTrackedEntityDiv = true;    
-        }      
-
-        $scope.gridColumns = $scope.generateGridColumns($scope.attributes);
+        } 
+        
+        //$scope.gridColumns = $scope.generateGridColumns($scope.attributes);
 
         //get events for the specified parameters
         TEIService.search($scope.selectedOrgUnit.id, 
@@ -190,6 +197,42 @@
         });
     };
     
+    $scope.generateAttributeFilters = function(attributes){
+
+        angular.forEach(attributes, function(attribute){
+            var filter = {operand: '', value: ''};
+
+            if(attribute.valueType === 'number'){
+                filter.operand = $scope.numberOperands[0];
+                attribute.filters = [filter];
+            }
+        });
+                    
+        return attributes;
+    };
+    
+    $scope.addFilter = function(attribute, filter){
+        
+        var filter = { operand: '', value: ''};
+                    
+        if(attribute.valueType === 'number'){
+            filter.operand = $scope.numberOperands[0];
+        }
+        attribute.filters.push(filter);
+    };
+    
+    $scope.removeFilter = function(filter, attribute){
+        
+        var index = attribute.filters.indexOf(filter);        
+        attribute.filters.splice(index, 1);    
+        
+        //this is a bit strange, removing a filter toggles off search drop down.
+        //to avoid this, had to do stop poropagation.
+        if (window.event) {
+            window.event.stopPropagation();
+        }
+    };
+    
     //generate grid columns from teilist attributes
     $scope.generateGridColumns = function(attributes){
         var columns = attributes ? angular.copy(attributes) : [];

=== modified file 'dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/scripts/services.js'
--- dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/scripts/services.js	2014-06-20 14:23:28 +0000
+++ dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/scripts/services.js	2014-06-26 13:35:30 +0000
@@ -444,50 +444,120 @@
 
 .service('EntityQueryFactory', function(){  
     
-    this.getQueryForAttributes = function(attributes){
+    this.getQueryForAttributes = function(attributes, enrollment){
         
         var query = {url: null, hasValue: false};
         
         angular.forEach(attributes, function(attribute){           
 
-            if(attribute.value && attribute.value !== ''){                    
-                query.hasValue = true;                
-                if(angular.isArray(attribute.value)){
-                    var index = 0, q = '';
-                    
-                    angular.forEach(attribute.value, function(val){
-                        
-                        if(index < attribute.value.length-1){
-                            q = q + val + ';';
-                        }
-                        else{
-                            q = q + val;
-                        }                        
-                        index++;
+            if(attribute.valueType === 'date'){
+                var q = '';
+                
+                if(attribute.startDate && attribute.startDate !== ''){
+                    query.hasValue = true;    
+                    q += 'GE:' + attribute.startDate + ':';
+                }
+                
+                if(attribute.endDate && attribute.endDate !== ''){
+                    query.hasValue = true;    
+                    q += 'GE:' + attribute.endDate + ':';
+                }
+                
+                if(query.url){
+                    if(q){
+                        q = q.substr(0,q.length-1);
+                        query.url = query.url + '&filter=' + attribute.id + q;
+                    }
+                }
+                else{
+                    if(q){
+                        q = q.substr(0,q.length-1);
+                        query.url = 'filter=' + attribute.id + q;
+                    }
+                }
+            }
+            else{
+                if(attribute.value && attribute.value !== ''){                    
+                    query.hasValue = true;                
+
+                    if(angular.isArray(attribute.value)){
+                        var q = '';
+                        angular.forEach(attribute.value, function(val){                        
+                            q += val + ';';
+                        });
+
+                        q = q.substr(0,q.length-1);
+
+                        if(query.url){
+                            if(q){
+                                query.url = query.url + '&filter=' + attribute.id + ':IN:' + q;
+                            }
+                        }
+                        else{
+                            if(q){
+                                query.url = 'filter=' + attribute.id + ':IN:' + q;
+                            }
+                        }                    
+                    }
+                    else{                        
+                        if(query.url){
+                            query.url = query.url + '&filter=' + attribute.id + ':LIKE:' + attribute.value;
+                        }
+                        else{
+                            query.url = 'filter=' + attribute.id + ':LIKE:' + attribute.value;
+                        }
+                    }
+
+                }
+
+                if(attribute.filters){
+                    var q = '';
+                    angular.forEach(attribute.filters, function(filter){
+                        if(filter.value !== ''){
+                            q += filter.operand + ':' + filter.value + ':';
+                        }
                     });
-                    
-                    if(query.url){
-                        if(q){
-                            query.url = query.url + '&filter=' + attribute.id + ':IN:' + q;
-                        }
-                    }
-                    else{
-                        if(q){
-                            query.url = 'filter=' + attribute.id + ':IN:' + q;
-                        }
-                    }                    
-                }
-                else{                        
-                    if(query.url){
-                        query.url = query.url + '&filter=' + attribute.id + ':LIKE:' + attribute.value;
-                    }
-                    else{
-                        query.url = 'filter=' + attribute.id + ':LIKE:' + attribute.value;
-                    }
+                    q = q.substr(0,q.length-1);
+
+                    if(query.url){
+                        if(q){
+                            query.url = query.url + '&filter=' + attribute.id + ':' + q;
+                        }
+                    }
+                    else{
+                        if(q){
+                            query.url = 'filter=' + attribute.id + ':' + q;
+                        }
+                    }
+                }
+            }
+            
+            
+        });
+        
+        if(enrollment){
+            console.log('there is enrollment is:  ', enrollment);
+            var q = '';
+            if(enrollment.programStartDate && enrollment.programStartDate !== ''){                
+                query.hasValue = true;
+                q += '&programStartDate=' + enrollment.programStartDate;
+            }
+            if(enrollment.programEndDate && enrollment.programEndDate !== ''){
+                query.hasValue = true;
+                q += '&programEndDate=' + enrollment.programEndDate;
+            }
+            
+            if(q){
+                if(query.url){
+                    query.url = query.url + q;
+                }
+                else{
+                    query.url = q;
                 }
             }            
-        });
+        }
         return query;
+        
     };    
 })
 

=== modified file 'dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/styles/style.css'
--- dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/styles/style.css	2014-06-25 14:08:18 +0000
+++ dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/styles/style.css	2014-06-26 13:35:30 +0000
@@ -24,7 +24,7 @@
 }
 
 div#leftBar {
-	width: 236px;
+    width: 236px;
 }
 
 div#orgUnitTree {
@@ -500,7 +500,7 @@
 }
 
 .radio-label {
-	margin-left: 5px;
+    margin-left: 5px;
 }
 
 /*----------------------------------------------------------------------------*/
@@ -772,23 +772,43 @@
 }
 
 .filter-operand {
-    width: 20%;
-    float: left;
+    width: 45%;
+    float: left; 
+    font-size: 14px;
+    line-height: 1.0;
 }
 
 .filter-value {
-    width: 70%;
-    float: left;
+    width: 40%;
+    float: left;   
+    font-size: 14px;
+    line-height: 1.0;
+}
+
+.form-control-filter{
+    height: 30px;
+    font-size: 14px;
+    line-height: 1.0;
+    color: #555;
+    vertical-align: middle;
+    background-color: #fff;
+    background-image: none;
+    border: 1px solid #ccc;
+    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
+    box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
+    -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+    transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s
 }
 
 .filter-add {
-    width: 5%;
+    width: 7.5%;
     float: left;
     padding-top: 5px;
     padding-left: 5px;
 }
+
 .filter-remove {
-    width: 5%;
+    width: 7.5%;
     float: left;
     padding-top: 5px;
     padding-left: 5px;
@@ -818,7 +838,6 @@
     box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
     -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
     transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s
-
 }
 
 .form-control {
@@ -832,7 +851,6 @@
     margin-bottom: 5px;
     margin-top: 5px;
     vertical-align: middle;
-    background-color: #fff;
     background-image: none;
     border: 1px solid #ccc;
     border-radius: 4px;
@@ -896,3 +914,7 @@
     margin-top: -5px;
 }
 
+.btn-link {
+    background-color: transparent;
+    border: none;
+}
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/views/home.html'
--- dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/views/home.html	2014-06-19 10:31:04 +0000
+++ dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/views/home.html	2014-06-26 13:35:30 +0000
@@ -12,7 +12,7 @@
 
     <!-- top bar begins -->
     <div class="row top-bar">        
-        <div class="col-md-12">            
+        <div class="col-sm-12">            
             <span ng-if='showSearchDiv || !showRegistrationDiv'>
                 {{'search'| translate}} {{selectedProgram.trackedEntity.name}}
             </span>
@@ -21,8 +21,8 @@
             </span>        
             <div class="pull-right">
                 <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 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>
@@ -38,8 +38,8 @@
     <!--- selected org unit ends  -->
 
     <!--- search and registration menu begins -->
-    <div class="row">        
-        <div id="selectDropDownParent" class="input-group col-md-4">            
+    <div class="row"> 
+        <div id="selectDropDownParent" class="input-group col-md-3">            
             <button type="button" class="select-drop-down-button form-control" >{{selectedProgram ? selectedProgram.name : 'please_select_a_program'| translate}}</button>
             <div class="input-group-btn">
                 <button class="btn btn-default trim" type="button" title="{{'list_programs'| translate}}" data-toggle="dropdown"><i class="fa fa-caret-down"></i></button>
@@ -53,7 +53,7 @@
                 </ul>
             </div>                
         </div>
-        <div id="searchDropDownParent" class="input-group col-md-4">
+        <div id="searchDropDownParent" class="input-group col-md-5">
             <input type="text" placeholder="{{'your_search_criteria_here'| translate}}" ng-model="searchText" class="form-control expanded" ng-class="{true: 'invalid - input'} [!searchText && emptySearchText]" ng-focus="hideSearch()" ng-disabled="showRegistrationDiv">
             <div class="input-group-btn">
                 <button class="btn btn-default trim" type="button" title="{{'advanced_search'| translate}}" data-toggle="dropdown" ng-disabled="showRegistrationDiv"><i class="fa fa-caret-down"></i></button>
@@ -66,7 +66,7 @@
         </div>        
         <div class="col-md-4 trim">            
             <button type="button" 
-                    class="btn btn-default small-horizonal-spacing"
+                    class="btn btn-default"
                     ng-disabled="showRegistrationDiv"
                     ng-click="search(searchMode.listAll)">
                 {{'list_all'| translate}}
@@ -76,7 +76,7 @@
                     ng-click="showRegistration()">                    
                 {{'register'| translate}} {{selectedProgram.trackedEntity.name}}
             </button>
-        </div>        
+        </div>
     </div>
     <!--- search and registration menu ends -->
 

=== modified file 'dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/views/search.html'
--- dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/views/search.html	2014-06-19 12:56:21 +0000
+++ dhis-2/dhis-web/dhis-web-tracker-capture/src/main/webapp/dhis-web-tracker-capture/views/search.html	2014-06-26 13:35:30 +0000
@@ -8,46 +8,70 @@
                 <input type="radio" ng-model="ouMode.name" id="descendants" value="DESCENDANTS"> {{'all_children'| translate}}
             </td>
         </tr>
-        <tr>
-            <td>{{'registration_date'| translate}}</td>
+        <tr ng-if="selectedProgram">
+            <td>{{'enrollment_date'| translate}}</td>
             <td>
-                <input type="text" class="form-control-select2" ng-date ng-model="attribute.value" />
+                <div class="dataelement-filter">
+                    <div class="container-1-2">
+                        <input type="text" placeholder="{{'from'| translate}}" class="form-control-select2" ng-date ng-model="enrollment.programStartDate"/>
+                    </div>
+                    <div class="container-1-2">
+                        <input type="text" placeholder="{{'to'| translate}}" class="form-control-select2" ng-date ng-model="enrollment.programEndDate"/>                
+                    </div>
+                </div>                
             </td>
         </tr>
         <tr ng-repeat="attribute in attributes">
             <td>
-                {{attribute.name}} - {{attribute.valueType}}
+                {{attribute.name}}
             </td>
             <td>
                 <div ng-switch="attribute.valueType">
+                    <div ng-switch-when="number">
+                        <div class="dataelement-filter" ng-repeat="filter in attribute.filters">
+                            <div class="filter-operand">
+                                <select ng-model="filter.operand" class="form-control-select2" ng-options="operand | translate for operand in numberOperands">
+                                </select>
+                            </div>
+                            <div class="filter-value">
+                                <input type="number" ng-model="filter.value" class="form-control-select2">
+                            </div>
+                            <div class="filter-add">
+                                <button class="btn-link" ng-click="addFilter(attribute)" title="{{'add_filter'| translate}}"><span class="black"><i class="fa fa-plus"></i></span></button>
+                            </div>
+                            <div class="filter-remove">
+                                <button class="btn-link" ng-click="removeFilter(filter, attribute)" title="{{'remove_filter'| translate}}" ng-disabled="attribute.filters.length < 2"><span class="black"><i class="fa fa-trash-o"></i></span></button>
+                            </div>
+                        </div>                        
+                    </div>
                     <div ng-switch-when="date">
-                        <input type="text" class="form-control-select2" ng-date ng-model="attribute.value" />
-                    </div>
-                    <div ng-switch-when="trueOnly">
-                        <input type="checkbox" class="form-control-select2" ng-model="attribute.value" />
-                    </div>
-                    <div ng-switch-when="bool">
-                        <select multiple ui-select2 ng-model="attribute.value" data-placeholder="{{'please_select'| translate}}" style="width:100%;">
-                            <option value="0">{{'no'| translate}}</option>
-                            <option value="1">{{'yes'| translate}}</option>
-                        </select>
+                        <div class="dataelement-filter">
+                            <div class="container-1-2">
+                                <input type="text" placeholder="{{'from'| translate}}" class="form-control-select2" ng-date ng-model="attribute.startDate"/>
+                            </div>
+                            <div class="container-1-2">
+                                <input type="text" placeholder="{{'to'| translate}}" class="form-control-select2" ng-date ng-model="attribute.endDate"/>                
+                            </div>
+                        </div> 
+                    </div>
+                    <div ng-switch-when="string">
+                        <input type="text" class="form-control-select2" ng-model="attribute.value" /> 
                     </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 attribute.optionSet.options" value="{{option}}">{{option}}</option>
                         </select>
                     </div>
-                    <div ng-switch-when="number">
-                        <input type="number" class="form-control-select2" ng-model="attribute.value"/>
-                    </div>
-                    <div ng-switch-default>
-                        <input type="text" class="form-control-select2" ng-model="attribute.value" />                                        
-                    </div>
-                </div>                                                                                                    
+                    <div ng-switch-when="bool">
+                        <select multiple ui-select2  ng-model="attribute.value" data-placeholder="{{'please_select'| translate}}" style="width:100%;">
+                            <option ng-repeat="option in boolOperands" value="{{option}}">{{option}}</option>
+                        </select>
+                    </div>                    
+                </div>
             </td>
         </tr>         
     </table>
-    
+
     <button type="button"
             class="btn btn-default"
             ng-click="search(searchMode.attributeBased)">