------------------------------------------------------------ revno: 19408 committer: Abyot Asalefew Gizaw <aby...@gmail.com> 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=" " - 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=" " - 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=" " - 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=" " ' + - ' 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=" " ' + - ' 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
_______________________________________________ Mailing list: https://launchpad.net/~dhis2-devs Post to : dhis2-devs@lists.launchpad.net Unsubscribe : https://launchpad.net/~dhis2-devs More help : https://help.launchpad.net/ListHelp