← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 19408: event-capture: better UI for options

 

------------------------------------------------------------
revno: 19408
committer: Abyot Asalefew Gizaw <abyota@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2015-06-15 13:04:20 +0200
message:
  event-capture: better UI for options
added:
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/ng-infinite-scroll.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select2.css
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select2.png
modified:
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app.properties
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/app.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/controllers.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/directives.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/styles/style.css
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/defaultForm.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/eventList.html
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select.css
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.validations.js


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

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache	2015-06-02 12:59:39 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache	2015-06-15 11:04:20 +0000
@@ -27,6 +27,7 @@
 
 ../dhis-web-commons/javascripts/jQuery/ui/css/redmond/jquery-ui.css
 ../dhis-web-commons/javascripts/jQuery/calendars/css/ui-redmond.calendars.picker.css    
+../dhis-web-commons/javascripts/jQuery/calendars/css/ui.calendars.picker.css
 
 ../dhis-web-commons/bootstrap/js/bootstrap.min.js
 
@@ -69,6 +70,9 @@
 
 ../dhis-web-commons/javascripts/angular/plugins/angularLocalStorage.js
 ../dhis-web-commons/javascripts/angular/plugins/angular-translate.min.js
+../dhis-web-commons/javascripts/angular/plugins/select.js
+../dhis-web-commons/javascripts/angular/plugins/select2.js
+../dhis-web-commons/javascripts/angular/plugins/ng-infinite-scroll.js
 ../dhis-web-commons/javascripts/dhis2/dhis2.angular.directives.js
 ../dhis-web-commons/javascripts/dhis2/dhis2.angular.validations.js
 ../dhis-web-commons/javascripts/dhis2/dhis2.angular.filters.js
@@ -91,6 +95,9 @@
 ../dhis-web-commons/css/widgets.css
 ../dhis-web-commons/css/menu.css
 ../dhis-web-commons/css/print.css
+../dhis-web-commons/javascripts/angular/plugins/select.css
+../dhis-web-commons/javascripts/angular/plugins/select2.css
+../dhis-web-commons/javascripts/angular/plugins/select2.png
 
 styles/style.css
 

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app.properties'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app.properties	2015-06-11 11:18:14 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app.properties	2015-06-15 11:04:20 +0000
@@ -34,7 +34,8 @@
 string_required=Value must be a text
 date_required=Value must be date
 option_required=Value must be selected from drop-down
-bool_required=Value must be a boolean
+bool_required=Value must be a 
+option_required=Option is required. Please select one.
 ok=Ok
 find=Find
 done=Done

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html	2015-06-02 12:59:39 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html	2015-06-15 11:04:20 +0000
@@ -32,10 +32,10 @@
         <script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/calendars/jquery.calendars.thai.min.js"></script>      
 
         <link type="text/css" rel="stylesheet" href="../dhis-web-commons/javascripts/jQuery/ui/css/redmond/jquery-ui.css">
-        <link type="text/css" rel="stylesheet" href="../dhis-web-commons/javascripts/jQuery/calendars/css/ui-redmond.calendars.picker.css">    
+        <link type="text/css" rel="stylesheet" href="../dhis-web-commons/javascripts/jQuery/calendars/css/ui.calendars.picker.css">
+        <link type="text/css" rel="stylesheet" href="../dhis-web-commons/javascripts/jQuery/calendars/css/ui-redmond.calendars.picker.css">        
         
-        <script type="text/javascript" src="../dhis-web-commons/bootstrap/js/bootstrap.min.js"></script>
-      
+        <script type="text/javascript" src="../dhis-web-commons/bootstrap/js/bootstrap.min.js"></script>        
                 
         <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/angular.js"></script>
         <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/angular-resource.js"></script>
@@ -76,12 +76,14 @@
         
         <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/angularLocalStorage.js"></script>
         <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/angular-translate.min.js"></script>
+        <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/select.js"></script>                
+        <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/ng-infinite-scroll.js"></script>
         <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.angular.directives.js"></script>
         <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.angular.validations.js"></script>
         <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.angular.filters.js"></script>
         <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js"></script>
         <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.angular.controllers.js"></script>
-
+        
         <script type="text/javascript" src="scripts/app.js"></script>        
         <script type="text/javascript" src="scripts/services.js"></script>
         <script type="text/javascript" src="scripts/directives.js"></script>        
@@ -97,9 +99,11 @@
         <link type="text/css" rel="stylesheet" href="../dhis-web-commons/font-awesome/css/font-awesome.min.css"/>
         <link type="text/css" rel="stylesheet" media="screen" href="../dhis-web-commons/css/widgets.css"/>
         <link type="text/css" rel="stylesheet" media="screen" href="../dhis-web-commons/css/menu.css">
-        <link type="text/css" rel="stylesheet" media="print" href="../dhis-web-commons/css/print.css">
+        <link type="text/css" rel="stylesheet" media="print" href="../dhis-web-commons/css/print.css">        
+        <link type="text/css" rel="stylesheet" href="../dhis-web-commons/javascripts/angular/plugins/select.css">
+        <link type="text/css" rel="stylesheet" href="../dhis-web-commons/javascripts/angular/plugins/select2.css">
         
-        <link type="text/css" rel="stylesheet" href="styles/style.css">        
+        <link type="text/css" rel="stylesheet" href="styles/style.css"> 
 
     </head>
 

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/app.js	2015-06-02 12:25:03 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/app.js	2015-06-15 11:04:20 +0000
@@ -16,6 +16,8 @@
                     'd2Directives',
                     'd2Services',
                     'd2Controllers',
+                    'ui.select',
+                    //'infinite-scroll',
                     'angularLocalStorage',
                     'pascalprecht.translate',
                     'd2HeaderBar'])

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/controllers.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/controllers.js	2015-06-11 11:18:14 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/controllers.js	2015-06-15 11:04:20 +0000
@@ -872,4 +872,29 @@
         }
         return status;        
     };
+    
+    //Infinite Scroll
+    $scope.infiniteScroll = {};
+    $scope.infiniteScroll.optionsToAdd = 20;
+    $scope.infiniteScroll.currentOptions = 20;
+    
+    $scope.resetInfScroll = function() {
+        $scope.infiniteScroll.currentOptions = $scope.infiniteScroll.optionsToAdd;
+    };
+  
+    $scope.addMoreOptions = function(){
+        $scope.infiniteScroll.currentOptions += $scope.infiniteScroll.optionsToAdd;
+    };
+    
+    /*$scope.getInputNotifcationClass = function(id, custom, event){
+        var style = "";
+        if($scope.currentElement.id && $scope.currentElement.id === id){            
+            style = $scope.currentElement.updated ? 'update-success' : 'update-error';
+        }
+        return style + ' form-control'; 
+    };*/
+    
+    $scope.getInputNotifcationClass = function(id, custom){        
+        return '; ';
+    };
 });
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/directives.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/directives.js	2014-12-09 23:24:16 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/directives.js	2015-06-15 11:04:20 +0000
@@ -2,4 +2,31 @@
 
 /* Directives */
 
-var eventCaptureDirectives = angular.module('eventCaptureDirectives', []);
\ No newline at end of file
+var eventCaptureDirectives = angular.module('eventCaptureDirectives', [])
+
+/*.directive('d2Options', function ($parse) {
+    var linker = function (scope, element, attr) {
+
+        scope.$watchCollection(['ngModel', 'options'], function () {
+            element.trigger('chosen:updated');
+        });
+
+
+        var allowSingleDeselect = $parse(attr.allowSingleDeselect)(scope);
+        var options = {
+            no_results_text: "Oops, nothing found!",
+            allow_single_deselect: allowSingleDeselect ? allowSingleDeselect : false
+        };
+        
+        element.chosen(options);
+    };
+
+    return {
+        restrict: 'A',
+        scope: {// isolate scope 
+            ngModel: '=',
+            options: '='
+        },
+        link: linker
+    };
+})*/;
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/styles/style.css'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/styles/style.css	2015-06-10 11:58:22 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/styles/style.css	2015-06-15 11:04:20 +0000
@@ -673,7 +673,7 @@
 }
 .panel-group .panel {
     margin-bottom: 0;
-    overflow: hidden;
+    //overflow: hidden;
     border-radius: 4px
 }
 .panel-group .panel+ .panel {
@@ -871,10 +871,12 @@
 {
   border: 1px solid #aaa;
   padding: 5px 0 !important;
+  //border-radius: 4px;
 }
 
 select {
     padding: 3px 0 !important;
+    //border-radius: 4px;
 }
 
 .clear {
@@ -939,6 +941,14 @@
     margin-left: 5px;    
 }
 
+.small-vertical-spacing{
+    margin-top: 5px;    
+}
+
+.vertical-spacing{
+    margin-top: 20px;    
+}
+
 .form-control {
     width: 100%;
 }
@@ -946,4 +956,15 @@
 div#orgUnitTree {
     height: 50%;
     border: 1px solid #e3e3e3;
-}
\ No newline at end of file
+}
+
+.calendars-popup {
+    z-index: 2000 !important;
+}
+
+.section-label{
+    font-size: 14pt;
+    color: #585D61;
+    border-bottom: 1px solid #e3e3e3;
+    //text-align: center;
+}

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/defaultForm.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/defaultForm.html	2015-06-11 11:18:14 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/defaultForm.html	2015-06-15 11:04:20 +0000
@@ -76,16 +76,19 @@
                     <ng-form name="innerForm">
                         <div ng-if="prStDes[eventGridColumn.id].dataElement.optionSetValue">
                             <div ng-if="!selectedProgram.dataEntryMethod || optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options.length >= 7">                                
-                                <input type="text"
-                                       class="typeahead form-control"
-                                       placeholder="&#xf0d7;&nbsp;&nbsp;"                                                 
-                                       ng-model="currentEvent[eventGridColumn.id]"                                          
-                                       typeahead="option.name as option.name for option in optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options | filter:$viewValue | limitTo:20" 
-                                       typeahead-focus-first="false"  
-                                       typeahead-editable=false
-                                       ng-required={{eventGridColumn.compulsory}}
-                                       name="foo" 
-                                       input-field-id={{eventGridColumn.id}}/>                                
+                                <ui-select ng-model="currentEvent[eventGridColumn.id]" 
+                                           theme="select2" 
+                                           ng-required={{eventGridColumn.compulsory}}
+                                           name="foo" 
+                                           input-field-id={{eventGridColumn.id}}
+                                           class='form-control'>
+                                    <ui-select-match allow-clear="true" class="form-control" placeholder="{{'select_or_search' | translate}}">{{$select.selected.name  || $select.selected}}</ui-select-match>
+                                    <ui-select-choices  infinite-scroll="addMoreOptions()"
+                                                        infinite-scroll-distance="2"
+                                                        repeat="option.name as option in optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options | filter: $select.search | limitTo:infiniteScroll.currentOptions">
+                                      <span ng-bind-html="option.name | highlight: $select.search"></span>
+                                    </ui-select-choices>
+                                </ui-select>
                             </div>                                    
                             <div ng-if="selectedProgram.dataEntryMethod && optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options.length < 7">                                    
                                 <label>
@@ -248,138 +251,142 @@
             </tr>        
         </tbody>
     </table>    
-    <accordion close-others='false'>
-        <accordion-group heading="{{section.name}}"
-                         is-open="section.open"
-                         ng-repeat='section in selectedProgramStage.programStageSections'
-                         ng-if="section.id === selectedSection.id || selectedSection.id === 'ALL'">
-            <table class="dhis2-list-table-striped">                    
-                <thead>                        
-                    <tr>
-                        <th>
-                            {{'data_element'| translate}}                    
-                        </th>
-                        <th>
-                            {{'value'| translate}}                    
-                        </th>         
-                    </tr>                        
-                </thead>
-                <tbody>       
-                    <tr ng-repeat="de in section.programStageDataElements">
-                        <td >
-                            {{prStDes[de.dataElement.id].dataElement.formName ? prStDes[de.dataElement.id].dataElement.formName : prStDes[de.dataElement.id].dataElement.name}}<span ng-if="prStDes[de.dataElement.id].compulsory" class="required">*</span>                        </td>
-                        <td >
-                            <ng-form name="innerForm">
-                                <div ng-if="prStDes[de.dataElement.id].dataElement.optionSetValue">
-                                    <span ng-if="!selectedProgram.dataEntryMethod || optionSets[prStDes[de.dataElement.id].dataElement.optionSet.id].options.length > 8">
-                                        <input type="text"
-                                               class="typeahead form-control"
-                                               placeholder="&#xf0d7;&nbsp;&nbsp;"                                                         
-                                               ng-model="currentEvent[de.dataElement.id]"
-                                               typeahead="option.name as option.name for option in optionSets[prStDes[de.dataElement.id].dataElement.optionSet.id].options | filter:$viewValue | limitTo:20" 
-                                               typeahead-focus-first="false"  
-                                               typeahead-editable=false
-                                               ng-required={{prStDes[de.dataElement.id].compulsory}}
-                                               name="foo" 
-                                               input-field-id={{de.dataElement.id}}>
-                                    </span>
-                                    <span ng-if="selectedProgram.dataEntryMethod && prStDes[de.dataElement.id].dataElement.optionSet.options.length < 7">                                    
-                                        <label>
-                                            <input type="radio" 
-                                                   name="foo"  
-                                                   input-field-id={{de.dataElement.id}} 
-                                                   ng-required={{prStDes[de.dataElement.id].compulsory}}
-                                                   ng-model="currentEvent[de.dataElement.id]"
-                                                   value="">{{'no_value' | translate}}<br>
-                                        </label>                                    
-                                        <label ng-repeat="option in optionSets[prStDes[de.dataElement.id].dataElement.optionSet.id].options">
-                                            <input type="radio" 
-                                                   name={{de.dataElement.id}}   
-                                                   input-field-id={{de.dataElement.id}} 
-                                                   ng-required={{prStDes[de.dataElement.id].compulsory}}
-                                                   ng-model="currentEvent[de.dataElement.id]"
-                                                   value={{option.name}}> {{option.name}}<br>                                        
-                                        </label>
-                                    </span>
-                                </div>
-                                <div ng-if="!prStDes[de.dataElement.id].dataElement.optionSetValue" ng-switch="prStDes[de.dataElement.id].dataElement.type">
-                                    <div ng-switch-when="int">
-                                        <input type="number"                                                
-                                               d2-number-validator 
-                                               number-type={{prStDes[de.dataElement.id].dataElement.numberType}}
-                                               ng-model="currentEvent[de.dataElement.id]"                                                
-                                               ng-required={{prStDes[de.dataElement.id].compulsory}}
-                                               name="foo" 
-                                               input-field-id={{de.dataElement.id}} 
-                                               class="form-control"/>
-                                    </div>
-                                    <div ng-switch-when="string">
-                                        <span ng-if="prStDes[de.dataElement.id].dataElement.textType==='longText'">
-                                            <textarea rows="3"
-                                                ng-model="currentEvent[de.dataElement.id]"                                       
-                                                ng-required={{prStDes[de.dataElement.id].compulsory}}
-                                                name="foo" 
-                                                input-field-id={{de.dataElement.id}} 
-                                                class="form-control">
-                                            </textarea>
-                                        </span>
-                                        <span ng-if="prStDes[de.dataElement.id].dataElement.textType!=='longText'">
-                                            <input type="text"                                             
-                                                ng-model="currentEvent[de.dataElement.id]"                                   
-                                                ng-required={{prStDes[de.dataElement.id].compulsory}}
-                                                name="foo" 
-                                                input-field-id={{de.dataElement.id}} 
-                                                class="form-control">                  
-                                        </span>
-                                    </div>
-                                    <div ng-switch-when="bool">
-                                        <select ng-model="currentEvent[de.dataElement.id]"                                                 
-                                                ng-required={{prStDes[de.dataElement.id].compulsory}}
-                                                name="foo" 
-                                                input-field-id={{de.dataElement.id}} 
-                                                class="form-control">
-                                        <option value="">{{'please_select'| translate}}</option>                        
-                                        <option value="false">{{'no'| translate}}</option>
-                                        <option value="true">{{'yes'| translate}}</option>
-                                        </select>
-                                    </div>
-                                    <div ng-switch-when="date">
-                                        <input type="text"                                                                
-                                               placeholder="{{dhis2CalendarFormat.keyDateFormat}}"
-                                               d2-date
-                                               max-date="prStDes[de.dataElement.id].allowFutureDate ? '' : 0"                                                  
-                                               d2-date-validator
-                                               ng-model="currentEvent[de.dataElement.id]"                                                               
-                                               ng-required={{prStDes[de.dataElement.id].compulsory}}
-                                               name="foo" 
-                                               input-field-id={{de.dataElement.id}} 
-                                               class="form-control"/>
-                                    </div>
-                                    <div ng-switch-when="trueOnly">
-                                        <input type="checkbox"                                                  
-                                               ng-model="currentEvent[de.dataElement.id]"                                                               
-                                               ng-required={{prStDes[de.dataElement.id].compulsory}}
-                                               name="foo" 
-                                               input-field-id={{de.dataElement.id}}/>
-                                    </div>
-                                    <div ng-switch-default>
-                                        <input type="text"                                                  
-                                            ng-model="currentEvent[de.dataElement.id]"                                                 
-                                            ng-required={{prStDes[de.dataElement.id].compulsory}}
-                                            name="foo" 
-                                            input-field-id={{de.dataElement.id}} 
-                                            class="form-control"/>
-                                    </div>
-                                </div>
-                                <div ng-messages="innerForm.foo.$error" ng-if="interacted(innerForm.foo)" class="required" ng-messages-include="../dhis-web-commons/angular-forms/error-messages.html">                                         
-                                </div>
-                            </ng-form>                            
-                        </td>
-                    </tr>
-                </tbody>
-            </table>
-        </accordion-group> 
-    </accordion>
+
+    <div ng-repeat='section in selectedProgramStage.programStageSections' ng-if="section.id === selectedSection.id || selectedSection.id === 'ALL'">
+        <div class="vertical-spacing section-label">
+           {{section.name}}
+        </div>
+        
+        <table class="dhis2-list-table-striped">                    
+            <thead>                        
+                <tr>
+                    <th>
+                        {{'data_element'| translate}}                    
+                    </th>
+                    <th>
+                        {{'value'| translate}}                    
+                    </th>         
+                </tr>                        
+            </thead>
+            <tbody>       
+                <tr ng-repeat="de in section.programStageDataElements">
+                    <td >
+                        {{prStDes[de.dataElement.id].dataElement.formName ? prStDes[de.dataElement.id].dataElement.formName : prStDes[de.dataElement.id].dataElement.name}}<span ng-if="prStDes[de.dataElement.id].compulsory" class="required">*</span>                        </td>
+                    <td >
+                        <ng-form name="innerForm">
+                            <div ng-if="prStDes[de.dataElement.id].dataElement.optionSetValue">
+                                <span ng-if="!selectedProgram.dataEntryMethod || optionSets[prStDes[de.dataElement.id].dataElement.optionSet.id].options.length > 8">
+                                    <ui-select ng-model="currentEvent[de.dataElement.id]" 
+                                               theme="select2" 
+                                               ng-required={{prStDes[de.dataElement.id].compulsory}}
+                                               ng-app=""name="foo" 
+                                               ng-app=""input-field-id={{de.dataElement.id}}
+                                               class='form-control'>
+                                        <ui-select-match allow-clear="true" class="form-control" placeholder="{{'select_or_search' | translate}}">{{$select.selected.name || $select.selected}}</ui-select-match>
+                                        <ui-select-choices  infinite-scroll="addMoreOptions()"
+                                                            infinite-scroll-distance="2"
+                                                            repeat="option.name as option in optionSets[prStDes[de.dataElement.id].dataElement.optionSet.id].options | filter: $select.search | limitTo:infiniteScroll.currentOptions">
+                                          <span ng-bind-html="option.name | highlight: $select.search"></span>
+                                        </ui-select-choices>
+                                    </ui-select>
+                                </span>
+                                <span ng-if="selectedProgram.dataEntryMethod && prStDes[de.dataElement.id].dataElement.optionSet.options.length < 7">                                    
+                                    <label>
+                                        <input type="radio" 
+                                               name="foo"  
+                                               input-field-id={{de.dataElement.id}} 
+                                               ng-required={{prStDes[de.dataElement.id].compulsory}}
+                                               ng-model="currentEvent[de.dataElement.id]"
+                                               value="">{{'no_value' | translate}}<br>
+                                    </label>                                    
+                                    <label ng-repeat="option in optionSets[prStDes[de.dataElement.id].dataElement.optionSet.id].options">
+                                        <input type="radio" 
+                                               name={{de.dataElement.id}}   
+                                               input-field-id={{de.dataElement.id}} 
+                                               ng-required={{prStDes[de.dataElement.id].compulsory}}
+                                               ng-model="currentEvent[de.dataElement.id]"
+                                               value={{option.name}}> {{option.name}}<br>                                        
+                                    </label>
+                                </span>
+                            </div>
+                            <div ng-if="!prStDes[de.dataElement.id].dataElement.optionSetValue" ng-switch="prStDes[de.dataElement.id].dataElement.type">
+                                <div ng-switch-when="int">
+                                    <input type="number"                                                
+                                           d2-number-validator 
+                                           number-type={{prStDes[de.dataElement.id].dataElement.numberType}}
+                                           ng-model="currentEvent[de.dataElement.id]"                                                
+                                           ng-required={{prStDes[de.dataElement.id].compulsory}}
+                                           name="foo" 
+                                           input-field-id={{de.dataElement.id}} 
+                                           class="form-control"/>
+                                </div>
+                                <div ng-switch-when="string">
+                                    <span ng-if="prStDes[de.dataElement.id].dataElement.textType==='longText'">
+                                        <textarea rows="3"
+                                            ng-model="currentEvent[de.dataElement.id]"                                       
+                                            ng-required={{prStDes[de.dataElement.id].compulsory}}
+                                            name="foo" 
+                                            input-field-id={{de.dataElement.id}} 
+                                            class="form-control">
+                                        </textarea>
+                                    </span>
+                                    <span ng-if="prStDes[de.dataElement.id].dataElement.textType!=='longText'">
+                                        <input type="text"                                             
+                                            ng-model="currentEvent[de.dataElement.id]"                                   
+                                            ng-required={{prStDes[de.dataElement.id].compulsory}}
+                                            name="foo" 
+                                            input-field-id={{de.dataElement.id}} 
+                                            class="form-control">                  
+                                    </span>
+                                </div>
+                                <div ng-switch-when="bool">
+                                    <select ng-model="currentEvent[de.dataElement.id]"                                                 
+                                            ng-required={{prStDes[de.dataElement.id].compulsory}}
+                                            name="foo" 
+                                            input-field-id={{de.dataElement.id}} 
+                                            class="form-control">
+                                    <option value="">{{'please_select'| translate}}</option>                        
+                                    <option value="false">{{'no'| translate}}</option>
+                                    <option value="true">{{'yes'| translate}}</option>
+                                    </select>
+                                </div>
+                                <div ng-switch-when="date">
+                                    <input type="text"                                                                
+                                           placeholder="{{dhis2CalendarFormat.keyDateFormat}}"
+                                           d2-date
+                                           max-date="prStDes[de.dataElement.id].allowFutureDate ? '' : 0"                                                  
+                                           d2-date-validator
+                                           ng-model="currentEvent[de.dataElement.id]"                                                               
+                                           ng-required={{prStDes[de.dataElement.id].compulsory}}
+                                           name="foo" 
+                                           input-field-id={{de.dataElement.id}} 
+                                           class="form-control"/>
+                                </div>
+                                <div ng-switch-when="trueOnly">
+                                    <input type="checkbox"                                                  
+                                           ng-model="currentEvent[de.dataElement.id]"                                                               
+                                           ng-required={{prStDes[de.dataElement.id].compulsory}}
+                                           name="foo" 
+                                           input-field-id={{de.dataElement.id}}/>
+                                </div>
+                                <div ng-switch-default>
+                                    <input type="text"                                                  
+                                        ng-model="currentEvent[de.dataElement.id]"                                                 
+                                        ng-required={{prStDes[de.dataElement.id].compulsory}}
+                                        name="foo" 
+                                        input-field-id={{de.dataElement.id}} 
+                                        class="form-control"/>
+                                </div>
+                            </div>
+                            <div ng-messages="innerForm.foo.$error" ng-if="interacted(innerForm.foo)" class="required" ng-messages-include="../dhis-web-commons/angular-forms/error-messages.html">                                         
+                            </div>
+                        </ng-form>                            
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+    </div> 
+
 </div>
 
 <!-- comment section starts -->

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/eventList.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/eventList.html	2015-06-02 12:25:03 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/eventList.html	2015-06-15 11:04:20 +0000
@@ -125,133 +125,136 @@
                                 <div style="cursor:default;"
                                     ng-if="(currentEvent.event == dhis2Event.event) && eventGridColumn.show && eventGridColumn.id !== 'comment'">
                                     <ng-form name="innerFormGrid">
-                                        <div ng-switch="eventGridColumn.type">
-                                            <div ng-switch-when="int">
-                                                <input type="number" 
-                                                       program-stage-data-element={{prStDes[eventGridColumn.id]}}
-                                                       d2-number-validator
-                                                       number-type={{prStDes[eventGridColumn.id].dataElement.numberType}}
-                                                       ng-model="currentEvent[eventGridColumn.id]" 
-                                                       ng-blur="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
-                                                       ng-required={{eventGridColumn.compulsory}}
-                                                       input-field-id={{eventGridColumn.id}} 
-                                                       name="foo" 
-                                                       style="width:98%;"
-                                                       ng-class="{true: 'update-success'} [currentElement.updated == true && currentElement.id == eventGridColumn.id]"
-                                                       ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]"/>
-                                            </div>
-                                            <div ng-switch-when="string">                                        
-                                                <div ng-if="eventGridColumn.id == 'uid'">
-                                                    <input type="text"
-                                                           ng-model="currentEvent[eventGridColumn.id]"                                                                    
-                                                           ng-disabled=true 
-                                                           name="foo" 
-                                                           style="width:99%;"/>                                                    
-                                                </div>
-                                                <div ng-if="eventGridColumn.id !== 'uid'">
-                                                    <div class="container-fluid" ng-if="optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id]">                                                
-                                                        <span ng-if="!selectedProgram.dataEntryMethod || optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options.length > 7">
-                                                            <input type="text" 
-                                                               class="typeahead"
-                                                               placeholder="&#xf0d7;&nbsp;&nbsp;"                                                 
-                                                               ng-model="currentEvent[eventGridColumn.id]" 
-                                                               ng-blur="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
-                                                               typeahead="option.name as option.name for option in optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options | filter:$viewValue | limitTo:20" 
-                                                               typeahead-open-on-focus
-                                                               typeahead-editable="false" 
+                                        <div ng-if="eventGridColumn.id === 'uid'">
+                                            <input type="text"
+                                                    ng-model="currentEvent[eventGridColumn.id]"                                                                    
+                                                    ng-disabled=true 
+                                                    name="foo" 
+                                                    class="form-control"/>
+                                        </div>
+                                        <div ng-if="eventGridColumn.id !== 'uid'">
+                                            <div ng-if="prStDes[eventGridColumn.id].dataElement.optionSetValue">
+                                                <span ng-if="!selectedProgram.dataEntryMethod || optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options.length > 7">
+                                                    <ui-select ng-model="currentEvent[eventGridColumn.id]" 
+                                                               theme="select2" 
                                                                ng-required={{eventGridColumn.compulsory}}
-                                                               ng-disabled="eventGridColumn.id == 'uid'"
-                                                               input-field-id={{eventGridColumn.id}} 
                                                                name="foo" 
-                                                               style="width:98%;"
+                                                               d2-option-validator
+                                                               on-select="updateEventDataValue(dhis2Event,eventGridColumn.id)" 
+                                                               on-remove="validateOptionOnRemove(eventGridColumn.compulsory)"
+                                                               input-field-id={{eventGridColumn.id}}
+                                                               style="width:100%;"
+                                                               class={{getInputNotifcationClass(eventGridColumn.id,false)}}>
+                                                        <ui-select-match allow-clear="true" class="form-control" placeholder="{{'select_or_search' | translate}}">{{$select.selected.name || $select.selected}}</ui-select-match>
+                                                        <ui-select-choices  infinite-scroll="addMoreOptions()" 
+                                                                             infinite-scroll-distance="2" 
+                                                                             repeat="option.name as option in optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options | filter: $select.search | limitTo:infiniteScroll.currentOptions">
+                                                            <span ng-bind-html="option.name | highlight: $select.search"></span>
+                                                        </ui-select-choices>
+                                                    </ui-select>
+                                                </span>
+                                                <span ng-if="selectedProgram.dataEntryMethod && optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options.length < 7">                                    
+                                                    <label>
+                                                        <input type="radio" 
+                                                               input-field-id={{eventGridColumn.id}} 
+                                                               name="foo"
+                                                               ng-required={{eventGridColumn.compulsory}}
+                                                               ng-model="currentEvent[eventGridColumn.id]" 
+                                                               ng-change="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
+                                                               value=""> {{'no_value' | translate}}<br>                                     
+                                                    </label>                                    
+                                                    <label ng-repeat="option in  optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options">
+                                                        <input type="radio" 
+                                                               input-field-id={{eventGridColumn.id}} 
+                                                               name={{eventGridColumn.id}}   
+                                                               ng-required={{eventGridColumn.compulsory}}
+                                                               ng-model="currentEvent[eventGridColumn.id]" 
+                                                               ng-change="updateEventDataValue(dhis2Event, eventGridColumn.id)"
                                                                ng-class="{true: 'update-success'} [currentElement.updated == true && currentElement.id == eventGridColumn.id]"
                                                                ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]"
-                                                               />
-                                                        </span>
-                                                        <span ng-if="selectedProgram.dataEntryMethod && optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options.length < 7">                                    
-                                                            <label>
-                                                                <input type="radio" 
-                                                                       input-field-id={{eventGridColumn.id}} 
-                                                                       name="foo"
-                                                                       ng-required={{eventGridColumn.compulsory}}
-                                                                       ng-model="currentEvent[eventGridColumn.id]" 
-                                                                       ng-change="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
-                                                                       value=""> {{'no_value' | translate}}<br>                                     
-                                                            </label>                                    
-                                                            <label ng-repeat="option in  optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options">
-                                                                <input type="radio" 
-                                                                       input-field-id={{eventGridColumn.id}} 
-                                                                       name={{eventGridColumn.id}}   
-                                                                       ng-required={{eventGridColumn.compulsory}}
-                                                                       ng-model="currentEvent[eventGridColumn.id]" 
-                                                                       ng-change="updateEventDataValue(dhis2Event, eventGridColumn.id)"
-                                                                       ng-class="{true: 'update-success'} [currentElement.updated == true && currentElement.id == eventGridColumn.id]"
-                                                                       ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]"
-                                                                       value={{option.name}}> {{option.name}}<br>                                    
-                                                            </label>
-                                                        </span>                                                
+                                                               value={{option.name}}> {{option.name}}<br>                                    
+                                                    </label>
+                                                </span> 
+                                            </div>
+                                            <div ng-if="!prStDes[eventGridColumn.id].dataElement.optionSetValue" ng-switch="eventGridColumn.type">                                            
+                                                <div ng-switch-when="int">
+                                                    <input type="number"                                                            
+                                                           d2-number-validator
+                                                           number-type={{prStDes[eventGridColumn.id].dataElement.numberType}}
+                                                           ng-model="currentEvent[eventGridColumn.id]" 
+                                                           ng-blur="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
+                                                           ng-required={{eventGridColumn.compulsory}}
+                                                           input-field-id={{eventGridColumn.id}} 
+                                                           name="foo" 
+                                                           class="form-control"
+                                                           ng-class="{true: 'update-success'} [currentElement.updated == true && currentElement.id == eventGridColumn.id]"
+                                                           ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]"/>
+                                                </div>
+                                                <div ng-switch-when="string">                                        
+                                                    <div ng-if="eventGridColumn.textType==='longText'">
+                                                        <textarea rows="3"
+                                                            ng-model="currentEvent[eventGridColumn.id]"                                        
+                                                            ng-required={{eventGridColumn.compulsory}}
+                                                            name="foo" 
+                                                            input-field-id={{eventGridColumn.id}} 
+                                                            ng-class="{true: 'update-success'} [currentElement.updated == true && currentElement.id == eventGridColumn.id]"
+                                                            ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]"
+                                                            class="form-control">
+                                                        </textarea>
                                                     </div>
-                                                    <div ng-if="!optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id]">
-                                                        <input type="text" 
-                                                            ng-model="currentEvent[eventGridColumn.id]" 
-                                                            ng-blur="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
+                                                    <div ng-if="eventGridColumn.textType!=='longText'">
+                                                        <input type="text"
+                                                               ng-model="currentEvent[eventGridColumn.id]" 
+                                                               ng-required={{eventGridColumn.compulsory}}
+                                                               name="foo" 
+                                                               class="form-control"/>                                                    
+                                                    </div>                                                    
+                                                </div>                                        
+                                                <div ng-switch-when="bool">
+                                                    <select ng-model="currentEvent[eventGridColumn.id]" 
+                                                            ng-change="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
                                                             ng-required={{eventGridColumn.compulsory}}
-                                                            ng-disabled="eventGridColumn.id == 'uid'"
                                                             input-field-id={{eventGridColumn.id}} 
                                                             name="foo" 
                                                             style="width:98%;"
                                                             ng-class="{true: 'update-success'} [currentElement.updated == true && currentElement.id == eventGridColumn.id]"
-                                                            ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]"
-                                                            />
-                                                    </div>
-                                                </div>
-                                            </div>                                        
-                                            <div ng-switch-when="bool">
-                                                <select ng-model="currentEvent[eventGridColumn.id]" 
-                                                        ng-change="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
-                                                        ng-required={{eventGridColumn.compulsory}}
-                                                        input-field-id={{eventGridColumn.id}} 
-                                                        name="foo" 
-                                                        style="width:98%;"
-                                                        ng-class="{true: 'update-success'} [currentElement.updated == true && currentElement.id == eventGridColumn.id]"
-                                                        ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]">
-                                                    <option value="">{{'please_select'| translate}}</option>                        
-                                                    <option value="false">{{'no'| translate}}</option>
-                                                    <option value="true">{{'yes'| translate}}</option>
-                                                </select>
-                                            </div>
-                                            <div ng-switch-when="date">
-                                                <input type="text" 
-                                                       placeholder="{{dhis2CalendarFormat.keyDateFormat}}"
-                                                       d2-date
-                                                       max-date="prStDes[eventGridColumn.id].allowFutureDate ? '' : 0" 
-                                                       d2-date-validator
-                                                       ng-model="currentEvent[eventGridColumn.id]"
-                                                       blur-or-change="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
-                                                       ng-required={{eventGridColumn.compulsory}}
-                                                       ng-disabled="eventGridColumn.id == 'event_date'"
-                                                       input-field-id={{eventGridColumn.id}} 
-                                                       name="foo" 
-                                                       style="width:98%;"
-                                                       ng-class="{true: 'update-success'} [currentElement.updated == true && currentElement.id == eventGridColumn.id]"
-                                                       ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]"
-                                                       />
-                                            </div>
-                                            <div ng-switch-when="trueOnly">
-                                                <input type="checkbox"
-                                                       d2-validation 
-                                                       ng-model="currentEvent[eventGridColumn.id]"
-                                                       ng-change="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
-                                                       ng-required={{eventGridColumn.compulsory}} 
-                                                       input-field-id={{eventGridColumn.id}} 
-                                                       name="foo" 
-                                                       ng-class="{true: 'update-success'} [currentElement.updated == true && currentElement.id == eventGridColumn.id]"
-                                                       ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]"
-                                                       />
-                                            </div>
-                                        </div>                                        
-                                        <div ng-messages="innerFormGrid.foo.$error" ng-if="interacted(innerFormGrid.foo)" class="required" ng-messages-include="../dhis-web-commons/angular-forms/error-messages.html">
-                                        </div>                                    
+                                                            ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]">
+                                                        <option value="">{{'please_select'| translate}}</option>                        
+                                                        <option value="false">{{'no'| translate}}</option>
+                                                        <option value="true">{{'yes'| translate}}</option>
+                                                    </select>
+                                                </div>
+                                                <div ng-switch-when="date">
+                                                    <input type="text" 
+                                                           placeholder="{{dhis2CalendarFormat.keyDateFormat}}"
+                                                           d2-date
+                                                           max-date="prStDes[eventGridColumn.id].allowFutureDate ? '' : 0" 
+                                                           d2-date-validator
+                                                           ng-model="currentEvent[eventGridColumn.id]"
+                                                           blur-or-change="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
+                                                           ng-required={{eventGridColumn.compulsory}}
+                                                           ng-disabled="eventGridColumn.id == 'event_date'"
+                                                           input-field-id={{eventGridColumn.id}}                                                            
+                                                           style="width:98%;"
+                                                           ng-class="{true: 'update-success'} [currentElement.updated == true && currentElement.id == eventGridColumn.id]"
+                                                           ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]"
+                                                           name="foo"/>
+                                                </div>
+                                                <div ng-switch-when="trueOnly">
+                                                    <input type="checkbox"
+                                                           d2-validation 
+                                                           ng-model="currentEvent[eventGridColumn.id]"
+                                                           ng-change="updateEventDataValue(dhis2Event, eventGridColumn.id)" 
+                                                           ng-required={{eventGridColumn.compulsory}} 
+                                                           input-field-id={{eventGridColumn.id}}                                                            
+                                                           ng-class="{true: 'update-success'} [currentElement.updated == true && currentElement.id == eventGridColumn.id]"
+                                                           ng-class="{true: 'update-error'} [!currentElement.updated == true && currentElement.id == eventGridColumn.id]"
+                                                           name="foo"/>
+                                                </div>
+                                                <div ng-messages="innerFormGrid.foo.$error" ng-if="interacted(innerFormGrid.foo)" class="required" ng-messages-include="../dhis-web-commons/angular-forms/error-messages.html">
+                                                </div>
+                                            </div>
+                                        </div>                                                                            
                                     </ng-form>
                                 </div>
                                 <!-- Visible when event is under editing in grid -->

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/ng-infinite-scroll.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/ng-infinite-scroll.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/ng-infinite-scroll.js	2015-06-15 11:04:20 +0000
@@ -0,0 +1,61 @@
+/* ng-infinite-scroll - v1.0.0 - 2013-02-23 */
+var mod;
+
+mod = angular.module('infinite-scroll', []);
+
+mod.directive('infiniteScroll', [
+  '$rootScope', '$window', '$timeout', function($rootScope, $window, $timeout) {
+    return {
+      link: function(scope, elem, attrs) {
+        var checkWhenEnabled, handler, scrollDistance, scrollEnabled;
+        $window = angular.element($window);
+        scrollDistance = 0;
+        if (attrs.infiniteScrollDistance != null) {
+          scope.$watch(attrs.infiniteScrollDistance, function(value) {
+            return scrollDistance = parseInt(value, 10);
+          });
+        }
+        scrollEnabled = true;
+        checkWhenEnabled = false;
+        if (attrs.infiniteScrollDisabled != null) {
+          scope.$watch(attrs.infiniteScrollDisabled, function(value) {
+            scrollEnabled = !value;
+            if (scrollEnabled && checkWhenEnabled) {
+              checkWhenEnabled = false;
+              return handler();
+            }
+          });
+        }
+        handler = function() {
+          var elementBottom, remaining, shouldScroll, windowBottom;
+          windowBottom = $window.height() + $window.scrollTop();
+          elementBottom = elem.offset().top + elem.height();
+          remaining = elementBottom - windowBottom;
+          shouldScroll = remaining <= $window.height() * scrollDistance;
+          if (shouldScroll && scrollEnabled) {
+            if ($rootScope.$$phase) {
+              return scope.$eval(attrs.infiniteScroll);
+            } else {
+              return scope.$apply(attrs.infiniteScroll);
+            }
+          } else if (shouldScroll) {
+            return checkWhenEnabled = true;
+          }
+        };
+        $window.on('scroll', handler);
+        scope.$on('$destroy', function() {
+          return $window.off('scroll', handler);
+        });
+        return $timeout((function() {
+          if (attrs.infiniteScrollImmediateCheck) {
+            if (scope.$eval(attrs.infiniteScrollImmediateCheck)) {
+              return handler();
+            }
+          } else {
+            return handler();
+          }
+        }), 0);
+      }
+    };
+  }
+]);
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select.css'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select.css	2015-06-02 12:23:22 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select.css	2015-06-15 11:04:20 +0000
@@ -29,7 +29,7 @@
 
 /* Mark invalid Select2 */
 .ng-dirty.ng-invalid > a.select2-choice {
-    border-color: #D44950;
+    //border-color: #D44950;
 }
 
 .select2-result-single {

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select2.css'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select2.css	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select2.css	2015-06-15 11:04:20 +0000
@@ -0,0 +1,625 @@
+/*
+Version: 3.4.5 Timestamp: Mon Nov  4 08:22:42 PST 2013
+*/
+.select2-container {
+    margin: 0;
+    position: relative;
+    display: inline-block;
+    /* inline-block for ie7 */
+    zoom: 1;
+    *display: inline;
+    vertical-align: middle;
+}
+
+.select2-container,
+.select2-drop,
+.select2-search,
+.select2-search input {
+  /*
+    Force border-box so that % widths fit the parent
+    container without overlap because of margin/padding.
+
+    More Info : http://www.quirksmode.org/css/box.html
+  */
+  -webkit-box-sizing: border-box; /* webkit */
+     -moz-box-sizing: border-box; /* firefox */
+          box-sizing: border-box; /* css3 */
+}
+
+.select2-container .select2-choice {
+    display: block;
+    overflow: hidden;
+    position: relative;
+    border: 1px solid #aaa;
+    padding: 5px 0 !important;
+    white-space: nowrap;
+    text-decoration: none;
+    color: #000;
+    background-color: #fff;
+    
+    /*display: block;
+    height: 26px;
+    padding: 0 0 0 8px;
+    overflow: hidden;
+    position: relative;
+
+    border: 1px solid #aaa;
+    white-space: nowrap;
+    line-height: 26px;
+    color: #444;
+    text-decoration: none;
+
+    border-radius: 4px;
+
+    background-clip: padding-box;
+
+    -webkit-touch-callout: none;
+      -webkit-user-select: none;
+         -moz-user-select: none;
+          -ms-user-select: none;
+              user-select: none;
+
+    background-color: #fff;
+    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.5, #fff));
+    background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 50%);
+    background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 50%);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0);
+    background-image: linear-gradient(top, #fff 0%, #eee 50%);*/
+}
+
+.select2-container.select2-drop-above .select2-choice {
+    border-bottom-color: #aaa;
+
+    border-radius: 0 0 4px 4px;
+
+    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.9, #fff));
+    background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 90%);
+    background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 90%);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+    background-image: linear-gradient(top, #eee 0%, #fff 90%);
+}
+
+.select2-container.select2-allowclear .select2-choice .select2-chosen {
+    margin-right: 42px;
+}
+
+.select2-container .select2-choice > .select2-chosen {
+    margin-right: 26px;
+    display: block;
+    overflow: hidden;
+
+    white-space: nowrap;
+
+    text-overflow: ellipsis;
+}
+
+.select2-container .select2-choice abbr {
+    display: none;
+    width: 12px;
+    height: 12px;
+    position: absolute;
+    right: 24px;
+    top: 8px;
+
+    font-size: 1px;
+    text-decoration: none;
+
+    border: 0;
+    background: url('select2.png') right top no-repeat;
+    cursor: pointer;
+    outline: 0;
+}
+
+.select2-container.select2-allowclear .select2-choice abbr {
+    display: inline-block;
+}
+
+.select2-container .select2-choice abbr:hover {
+    background-position: right -11px;
+    cursor: pointer;
+}
+
+.select2-drop-mask {
+    border: 0;
+    margin: 0;
+    padding: 0;
+    position: fixed;
+    left: 0;
+    top: 0;
+    min-height: 100%;
+    min-width: 100%;
+    height: auto;
+    width: auto;
+    opacity: 0;
+    z-index: 9998;
+    /* styles required for IE to work */
+    background-color: #fff;
+    filter: alpha(opacity=0);
+}
+
+.select2-drop {
+    width: 100%;
+    margin-top: -1px;
+    position: absolute;    
+    z-index: 9999;
+    top: 100%;
+
+    background: #fff;
+    color: #000;
+    border: 1px solid #aaa;
+    border-top: 0;
+
+    border-radius: 0 0 4px 4px;
+
+    -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
+            box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
+}
+
+.select2-drop-auto-width {
+    border-top: 1px solid #aaa;
+    width: auto;
+}
+
+.select2-drop-auto-width .select2-search {
+    padding-top: 4px;
+}
+
+.select2-drop.select2-drop-above {
+    margin-top: 1px;
+    border-top: 1px solid #aaa;
+    border-bottom: 0;
+
+    border-radius: 4px 4px 0 0;
+
+    -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
+            box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
+}
+
+.select2-drop-active {
+    border: 1px solid #5897fb;
+    border-top: none;
+}
+
+.select2-drop.select2-drop-above.select2-drop-active {
+    border-top: 1px solid #5897fb;
+}
+
+.select2-container .select2-choice .select2-arrow {
+    display: inline-block;
+    width: 18px;
+    height: 100%;
+    position: absolute;
+    right: 0;
+    top: 0;
+
+    border-left: 1px solid #aaa;
+    border-radius: 0 4px 4px 0;
+
+    background-clip: padding-box;
+
+    background: #ccc;
+    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
+    background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
+    background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0);
+    background-image: linear-gradient(top, #ccc 0%, #eee 60%);
+}
+
+.select2-container .select2-choice .select2-arrow b {
+    display: block;
+    width: 100%;
+    height: 100%;
+    background: url('select2.png') no-repeat 0 1px;
+}
+
+.select2-search {
+    display: inline-block;
+    width: 100%;
+    min-height: 26px;
+    margin: 0;
+    padding-left: 4px;
+    padding-right: 4px;
+
+    position: relative;
+    z-index: 10000;
+
+    white-space: nowrap;
+}
+
+.select2-search input {
+    width: 100%;
+    height: auto !important;
+    min-height: 26px;
+    padding: 4px 20px 4px 5px;
+    margin: 0;
+
+    outline: 0;
+    font-family: sans-serif;
+    font-size: 1em;
+
+    border: 1px solid #aaa;
+    border-radius: 0;
+
+    -webkit-box-shadow: none;
+            box-shadow: none;
+
+    background: #fff url('select2.png') no-repeat 100% -22px;
+    background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
+    background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
+    background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
+    background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #fff 85%, #eee 99%);
+}
+
+.select2-drop.select2-drop-above .select2-search input {
+    margin-top: 4px;
+}
+
+.select2-search input.select2-active {
+    background: #fff url('select2-spinner.gif') no-repeat 100%;
+    background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
+    background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
+    background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
+    background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(top, #fff 85%, #eee 99%);
+}
+
+.select2-container-active .select2-choice,
+.select2-container-active .select2-choices {
+    border: 1px solid #5897fb;
+    outline: none;
+
+    -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+            box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+}
+
+.select2-dropdown-open .select2-choice {
+    border-bottom-color: transparent;
+    -webkit-box-shadow: 0 1px 0 #fff inset;
+            box-shadow: 0 1px 0 #fff inset;
+
+    border-bottom-left-radius: 0;
+    border-bottom-right-radius: 0;
+
+    background-color: #eee;
+    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(0.5, #eee));
+    background-image: -webkit-linear-gradient(center bottom, #fff 0%, #eee 50%);
+    background-image: -moz-linear-gradient(center bottom, #fff 0%, #eee 50%);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
+    background-image: linear-gradient(top, #fff 0%, #eee 50%);
+}
+
+.select2-dropdown-open.select2-drop-above .select2-choice,
+.select2-dropdown-open.select2-drop-above .select2-choices {
+    border: 1px solid #5897fb;
+    border-top-color: transparent;
+
+    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(0.5, #eee));
+    background-image: -webkit-linear-gradient(center top, #fff 0%, #eee 50%);
+    background-image: -moz-linear-gradient(center top, #fff 0%, #eee 50%);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
+    background-image: linear-gradient(bottom, #fff 0%, #eee 50%);
+}
+
+.select2-dropdown-open .select2-choice .select2-arrow {
+    background: transparent;
+    border-left: none;
+    filter: none;
+}
+.select2-dropdown-open .select2-choice .select2-arrow b {
+    background-position: -18px 1px;
+}
+
+/* results */
+.select2-results {
+    max-height: 200px;
+    padding: 0 0 0 4px;
+    margin: 4px 4px 4px 0;
+    position: relative;
+    overflow-x: hidden;
+    overflow-y: auto;
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+.select2-results ul.select2-result-sub {
+    margin: 0;
+    padding-left: 0;
+}
+
+.select2-results ul.select2-result-sub > li .select2-result-label { padding-left: 20px }
+.select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 40px }
+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 60px }
+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 80px }
+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 100px }
+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 110px }
+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 120px }
+
+.select2-results li {
+    list-style: none;
+    display: list-item;
+    background-image: none;
+}
+
+.select2-results li.select2-result-with-children > .select2-result-label {
+    font-weight: bold;
+}
+
+.select2-results .select2-result-label {
+    padding: 3px 7px 4px;
+    margin: 0;
+    cursor: pointer;
+
+    min-height: 1em;
+
+    -webkit-touch-callout: none;
+      -webkit-user-select: none;
+         -moz-user-select: none;
+          -ms-user-select: none;
+              user-select: none;
+}
+
+.select2-results .select2-highlighted {
+    background: #3875d7;
+    color: #fff;
+}
+
+.select2-results li em {
+    background: #feffde;
+    font-style: normal;
+}
+
+.select2-results .select2-highlighted em {
+    background: transparent;
+}
+
+.select2-results .select2-highlighted ul {
+    background: #fff;
+    color: #000;
+}
+
+
+.select2-results .select2-no-results,
+.select2-results .select2-searching,
+.select2-results .select2-selection-limit {
+    background: #f4f4f4;
+    display: list-item;
+}
+
+/*
+disabled look for disabled choices in the results dropdown
+*/
+.select2-results .select2-disabled.select2-highlighted {
+    color: #666;
+    background: #f4f4f4;
+    display: list-item;
+    cursor: default;
+}
+.select2-results .select2-disabled {
+  background: #f4f4f4;
+  display: list-item;
+  cursor: default;
+}
+
+.select2-results .select2-selected {
+    display: none;
+}
+
+.select2-more-results.select2-active {
+    background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;
+}
+
+.select2-more-results {
+    background: #f4f4f4;
+    display: list-item;
+}
+
+/* disabled styles */
+
+.select2-container.select2-container-disabled .select2-choice {
+    background-color: #f4f4f4;
+    background-image: none;
+    border: 1px solid #ddd;
+    cursor: default;
+}
+
+.select2-container.select2-container-disabled .select2-choice .select2-arrow {
+    background-color: #f4f4f4;
+    background-image: none;
+    border-left: 0;
+}
+
+.select2-container.select2-container-disabled .select2-choice abbr {
+    display: none;
+}
+
+
+/* multiselect */
+
+.select2-container-multi .select2-choices {
+    height: auto !important;
+    height: 1%;
+    margin: 0;
+    padding: 0;
+    position: relative;
+
+    border: 1px solid #aaa;
+    cursor: text;
+    overflow: hidden;
+
+    background-color: #fff;
+    background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eee), color-stop(15%, #fff));
+    background-image: -webkit-linear-gradient(top, #eee 1%, #fff 15%);
+    background-image: -moz-linear-gradient(top, #eee 1%, #fff 15%);
+    background-image: linear-gradient(top, #eee 1%, #fff 15%);
+}
+
+.select2-locked {
+  padding: 3px 5px 3px 5px !important;
+}
+
+.select2-container-multi .select2-choices {
+    min-height: 26px;
+}
+
+.select2-container-multi.select2-container-active .select2-choices {
+    border: 1px solid #5897fb;
+    outline: none;
+
+    -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+            box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+}
+.select2-container-multi .select2-choices li {
+    float: left;
+    list-style: none;
+}
+.select2-container-multi .select2-choices .select2-search-field {
+    margin: 0;
+    padding: 0;
+    white-space: nowrap;
+}
+
+.select2-container-multi .select2-choices .select2-search-field input {
+    padding: 5px;
+    margin: 1px 0;
+
+    font-family: sans-serif;
+    font-size: 100%;
+    color: #666;
+    outline: 0;
+    border: 0;
+    -webkit-box-shadow: none;
+            box-shadow: none;
+    background: transparent !important;
+}
+
+.select2-container-multi .select2-choices .select2-search-field input.select2-active {
+    background: #fff url('select2-spinner.gif') no-repeat 100% !important;
+}
+
+.select2-default {
+    color: #999 !important;
+}
+
+.select2-container-multi .select2-choices .select2-search-choice {
+    padding: 3px 5px 3px 18px;
+    margin: 3px 0 3px 5px;
+    position: relative;
+
+    line-height: 13px;
+    color: #333;
+    cursor: default;
+    border: 1px solid #aaaaaa;
+
+    border-radius: 3px;
+
+    -webkit-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
+            box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
+
+    background-clip: padding-box;
+
+    -webkit-touch-callout: none;
+      -webkit-user-select: none;
+         -moz-user-select: none;
+          -ms-user-select: none;
+              user-select: none;
+
+    background-color: #e4e4e4;
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0);
+    background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));
+    background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
+    background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
+    background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
+}
+.select2-container-multi .select2-choices .select2-search-choice .select2-chosen {
+    cursor: default;
+}
+.select2-container-multi .select2-choices .select2-search-choice-focus {
+    background: #d4d4d4;
+}
+
+.select2-search-choice-close {
+    display: block;
+    width: 12px;
+    height: 13px;
+    position: absolute;
+    right: 3px;
+    top: 4px;
+
+    font-size: 1px;
+    outline: none;
+    background: url('select2.png') right top no-repeat;
+}
+
+.select2-container-multi .select2-search-choice-close {
+    left: 3px;
+}
+
+.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
+  background-position: right -11px;
+}
+.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
+    background-position: right -11px;
+}
+
+/* disabled styles */
+.select2-container-multi.select2-container-disabled .select2-choices {
+    background-color: #f4f4f4;
+    background-image: none;
+    border: 1px solid #ddd;
+    cursor: default;
+}
+
+.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
+    padding: 3px 5px 3px 5px;
+    border: 1px solid #ddd;
+    background-image: none;
+    background-color: #f4f4f4;
+}
+
+.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close {    display: none;
+    background: none;
+}
+/* end multiselect */
+
+
+.select2-result-selectable .select2-match,
+.select2-result-unselectable .select2-match {
+    text-decoration: underline;
+}
+
+.select2-offscreen, .select2-offscreen:focus {
+    clip: rect(0 0 0 0) !important;
+    width: 1px !important;
+    height: 1px !important;
+    border: 0 !important;
+    margin: 0 !important;
+    padding: 0 !important;
+    overflow: hidden !important;
+    position: absolute !important;
+    outline: 0 !important;
+    left: 0px !important;
+    top: 0px !important;
+}
+
+.select2-display-none {
+    display: none;
+}
+
+.select2-measure-scrollbar {
+    position: absolute;
+    top: -10000px;
+    left: -10000px;
+    width: 100px;
+    height: 100px;
+    overflow: scroll;
+}
+/* Retina-ize icons */
+
+@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi)  {
+  .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice .select2-arrow b {
+      background-image: url('select2x2.png') !important;
+      background-repeat: no-repeat !important;
+      background-size: 60px 40px !important;
+  }
+  .select2-search input {
+      background-position: 100% -21px !important;
+  }
+}
\ No newline at end of file

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select2.png'
Binary files dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select2.png	1970-01-01 00:00:00 +0000 and dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/select2.png	2015-06-15 11:04:20 +0000 differ
=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js	2015-06-02 12:23:22 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js	2015-06-15 11:04:20 +0000
@@ -214,7 +214,7 @@
 })
 
 /* service for dealing with custom form */
-.service('CustomFormService', function () {
+.service('CustomFormService', function ($translate) {
 
     return {
         getForProgramStage: function (programStage, programStageDataElements) {
@@ -255,7 +255,7 @@
 
                             newInputField = '<input type="text" ' +
                                     this.getAttributesAsString(attributes) +
-                                    ' ng-model="currentEvent.' + fieldId + '"' +                                    
+                                    ' ng-model="currentEvent.' + fieldId + '"' +
                                     ' input-field-id="' + fieldId + '"' +
                                     ' d2-date ' +
                                     ' d2-date-validator ' +
@@ -276,30 +276,28 @@
                             var prStDe = programStageDataElements[fieldId];
 
                             var commonInputFieldProperty = this.getAttributesAsString(attributes) +
-                                    ' ng-model="currentEvent.' + fieldId + '" ' +                                   
+                                    ' ng-model="currentEvent.' + fieldId + '" ' +
                                     ' input-field-id="' + fieldId + '"' +
-                                    ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
+                                    ' ng-class="{{getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id, true)}}" ' +
                                     ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent[uid]==\'uid\' || currentEvent.editingNotAllowed"' +
                                     ' ng-required="{{prStDes.' + fieldId + '.compulsory}}" ';
 
                             if (prStDe && prStDe.dataElement && prStDe.dataElement.type) {
                                 //check if dataelement has optionset								
                                 if (prStDe.dataElement.optionSetValue) {
-                                    var optionSetId = prStDe.dataElement.optionSet.id;
-                                    newInputField = '<input type="text" ' +
-                                            ' typeahead="option.name as option.name for option in optionSets.' + optionSetId + '.options | filter:$viewValue | limitTo:20"' +
-                                            ' typeahead-editable="false" ' +
-                                            ' d2-typeahead-validator ' +
-                                            ' class="typeahead" ' +
-                                            ' placeholder="&#xf0d7;&nbsp;&nbsp;" ' +
-                                            ' ng-blur="saveDatavalue(prStDes.' + fieldId + ', outerForm.' + fieldId + ')"' +
-                                            ' typeahead-focus-first="false"' +
-                                            commonInputFieldProperty + ' >';
+                                    var optionSetId = prStDe.dataElement.optionSet.id;                 
+                                    newInputField = '<ui-select class="form-control" theme="select2" ' + commonInputFieldProperty + ' ng-blur="saveDatavalue(prStDes.' + fieldId + ', outerForm.' + fieldId + ')" >' +
+                                            '<ui-select-match allow-clear="true" class="form-control" placeholder="' + $translate.instant('select_or_search') + '">{{$select.selected.name || $select.selected}}</ui-select-match>' +
+                                            '<ui-select-choices  infinite-scroll="addMoreOptions()" infinite-scroll-distance="2"' +
+                                            ' repeat="option.name as option in optionSets.' + optionSetId + '.options | filter: $select.search | limitTo:infiniteScroll.currentOptions">' +
+                                            '<span ng-bind-html="option.name | highlight: $select.search"></span>' +
+                                            '</ui-select-choices>' +
+                                            '</ui-select>';
                                 }
                                 else {
                                     //check data element type and generate corresponding angular input field
                                     if (prStDe.dataElement.type === "int") {
-                                        newInputField = '<input type="number" ' +
+                                        newInputField = '<input type="number" class="form-control" ' +
                                                 ' d2-number-validator ' +
                                                 ' number-type="' + prStDe.dataElement.numberType + '" ' +
                                                 ' ng-blur="saveDatavalue(prStDes.' + fieldId + ', outerForm.' + fieldId + ')"' +
@@ -326,7 +324,7 @@
                                     }
                                     else if (prStDe.dataElement.type.type === "trueOnly") {
                                         newInputField = '<input type="checkbox" ' +
-                                                ' ng-change="saveDatavalue(prStDes.' + fieldId + ', outerForm.' + fieldId +')"' +
+                                                ' ng-change="saveDatavalue(prStDes.' + fieldId + ', outerForm.' + fieldId + ')"' +
                                                 commonInputFieldProperty + ' >';
                                     }
                                     else {
@@ -335,8 +333,8 @@
                                                 commonInputFieldProperty + ' >';
                                     }
                                 }
-                            }                            
-                        }                        
+                            }
+                        }
                         newInputField = newInputField + ' <div ng-messages="outerForm.' + fieldId + '.$error" class="required" ng-if="interacted(outerForm.' + fieldId + ')" ng-messages-include="../dhis-web-commons/angular-forms/error-messages.html"></div>';
 
                         htmlCode = htmlCode.replace(inputField, newInputField);
@@ -398,16 +396,13 @@
                             //check if attribute has optionset
                             if (att.optionSetValue) {
                                 var optionSetId = att.optionSet.id;
-                                newInputField = '<input type="text" ' +
-                                        ' class="typeahead" ' +
-                                        ' placeholder="&#xf0d7;&nbsp;&nbsp;" ' +
-                                        ' typeahead-editable="false" ' +
-                                        ' d2-typeahead-validator ' +
-                                        ' typeahead="option.name as option.name for option in optionSets.' + optionSetId + '.options | filter:$viewValue | limitTo:50"' +
-                                        ' typeahead-focus-first="false"' +
-                                        ' ng-blur="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
-                                        commonInputFieldProperty + ' >';
-
+                                newInputField = '<ui-select theme="select2" ' + commonInputFieldProperty + ' >' +
+                                        '<ui-select-match allow-clear="true" placeholder="{{"select_or_search" | translate}}">{{$select.selected.name || $select.selected}}</ui-select-match>' +
+                                        '<ui-select-choices  	infinite-scroll="addMoreOptions()" infinite-scroll-distance="2"' +
+                                        'repeat="option.name as option in optionSets.' + optionSetId + '.options | filter: $select.search | limitTo:infiniteScroll.currentOptions">' +
+                                        '<span ng-bind-html="option.name | highlight: $select.search"></span>' +
+                                        '</ui-select-choices>' +
+                                        '</ui-select>';
                             }
                             else {
                                 //check attribute type and generate corresponding angular input field
@@ -487,8 +482,8 @@
                                     ' max-date="' + inMaxDate + '"> ';
                         }
                     }
-                    
-                    newInputField = newInputField + ' <div ng-messages="outerForm.' + fieldName + '.$error" class="required" ng-if="interacted(outerForm.' + fieldName + ')" ng-messages-include="../dhis-web-commons/angular-forms/error-messages.html"></div>';                    
+
+                    newInputField = newInputField + ' <div ng-messages="outerForm.' + fieldName + '.$error" class="required" ng-if="interacted(outerForm.' + fieldName + ')" ng-messages-include="../dhis-web-commons/angular-forms/error-messages.html"></div>';
 
                     htmlCode = htmlCode.replace(inputField, newInputField);
                 }

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.validations.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.validations.js	2015-06-02 12:23:22 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.validations.js	2015-06-15 11:04:20 +0000
@@ -42,18 +42,25 @@
 
 .directive("d2DateValidator", function(DateUtils, CalendarService, $parse) {
     return {
-        restrict: "A",
-         
-        require: "ngModel",
-         
+        restrict: "A",         
+        require: "ngModel",         
         link: function(scope, element, attrs, ngModel) {
+        	
+        	var isRequired = attrs.ngRequired === 'true';
+        	
             ngModel.$validators.dateValidator = function(value) {
+                if(!value){
+                    return !isRequired;
+                }                
                 var convertedDate = DateUtils.format(angular.copy(value));
                 var isValid = value === convertedDate;
                 return isValid;
             };
             
             ngModel.$validators.futureDateValidator = function(value) {
+                if(!value){
+                    return !isRequired;
+                }
                 var maxDate = $parse(attrs.maxDate)(scope);
                 var convertedDate = DateUtils.format(angular.copy(value));
                 var isValid = value === convertedDate;
@@ -69,14 +76,13 @@
 
 .directive("d2CoordinateValidator", function() {
     return {
-        restrict: "A",
-         
-        require: "ngModel",
-         
+        restrict: "A",         
+        require: "ngModel",         
         link: function(scope, element, attrs, ngModel) {
-            ngModel.$validators.latitudeValidator = function(value) { 
-                var isRequired = attrs.ngRequired === 'true';
-                
+        	
+        	var isRequired = attrs.ngRequired === 'true';
+        	
+            ngModel.$validators.latitudeValidator = function(value) {
                 if(!value){
                     return !isRequired;
                 }
@@ -87,9 +93,7 @@
                 return value >= -90 && value <= 90;
             };
             
-            ngModel.$validators.longitudeValidator = function(value) { 
-                var isRequired = attrs.ngRequired === 'true';
-                
+            ngModel.$validators.longitudeValidator = function(value) {
                 if(!value){
                     return !isRequired;
                 }
@@ -101,4 +105,26 @@
             };
         }
     };
+})
+
+.directive("d2OptionValidator", function($translate) {
+    return {
+        restrict: "A",         
+        require: "ngModel",         
+        link: function(scope, element, attrs, ngModel) {
+        	
+            var isRequired = attrs.ngRequired === 'true';
+            
+            ngModel.$validators.optionValidator = function(value) {               
+                
+                var res = !value ? !isRequired : true;
+                
+                if(!res){
+                    alert($translate.instant('option_required'));
+                }
+                
+                return res;
+            };
+        }
+    };
 });
\ No newline at end of file