dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #34999
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 17959: event capture - live input validation
------------------------------------------------------------
revno: 17959
committer: Abyot Asalefew Gizaw <abyota@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2015-01-13 18:31:37 +0100
message:
event capture - live input validation
modified:
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/controllers.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js
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/ec-custom-form.html
dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/directives.js
dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/services.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/i18n/i18n_app.properties'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app.properties 2014-12-18 11:50:32 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app.properties 2015-01-13 17:31:37 +0000
@@ -29,7 +29,6 @@
go_back=Go back
form_invalid=Form is invalid. Please check for required fields.
required=Required
-value_must_be=Value must be
int_required=Value must be a number
string_required=Value must be a text
date_required=Value must be a date
@@ -114,11 +113,18 @@
update_event=Update Event
missing_translation_file=Missing Translation File
missing_translation_using_default=No translation file is found for the selected locale. Using default translation (English).
+value_must_be=Value must be
number=Number
+value_must_be_Number=Value must be number
+value_must_be_posInt=Value must be positive integer
+value_must_be_negInt=Value must be negative integer
+value_must_be_zeroPositiveInt=Value must be zero or positive integer
+value_must_be_int=Value must be integer
posInt=Positive Integer
negInt=Negative Integer
zeroPostitiveInt=Zero or Positive Integer
loading_tree=Loading orgunit tree
loading_metadata=Loading meta-data
+future_date_not_allowed=Future date is not allowed
=== 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-01-12 18:24:10 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html 2015-01-13 17:31:37 +0000
@@ -1,6 +1,5 @@
<!DOCTYPE html>
-<html ng-app="eventCapture">
-<!--<html manifest="cacheManifest.action" ng-app="eventCapture">-->
+<html manifest="cacheManifest.action" ng-app="eventCapture">
<head>
<title>Event Capture</title>
@@ -60,7 +59,7 @@
<script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.storage.memory.js"></script>
<script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.storage.js"></script>
<script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.contextmenu.js"></script>
- <!--<script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.appcache.js"></script>-->
+ <script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.appcache.js"></script>
<script type="text/javascript" src="../dhis-web-commons/ouwt/ouwt.js"></script>
<script type="text/javascript" src="scripts/event-capture.js"></script>
=== 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-01-12 18:24:10 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/controllers.js 2015-01-13 17:31:37 +0000
@@ -8,6 +8,7 @@
function($scope,
$modal,
$timeout,
+ $translate,
storage,
Paginator,
OptionSetService,
@@ -19,11 +20,12 @@
DateUtils,
CalendarService,
CustomFormService,
+ ErrorMessageService,
ModalService,
DialogService) {
//selected org unit
$scope.selectedOrgUnit = '';
- $scope.treeLoaded = false;
+ $scope.treeLoaded = false;
$scope.calendarSetting = CalendarService.getSetting();
@@ -148,9 +150,16 @@
$scope.eventGridColumns.push({name: $scope.selectedProgramStage.reportDateDescription ? $scope.selectedProgramStage.reportDateDescription : 'incident_date', id: 'event_date', type: 'date', compulsory: false, showFilter: false, show: true});
$scope.filterTypes['event_date'] = 'date';
$scope.filterText['event_date']= {};
-
+
+ var errorMessages = {};
+ errorMessages['eventDate'] = $translate('required');
angular.forEach($scope.selectedProgramStage.programStageDataElements, function(prStDe){
- $scope.prStDes[prStDe.dataElement.id] = prStDe;
+ $scope.prStDes[prStDe.dataElement.id] = prStDe;
+
+ errorMessages[prStDe.dataElement.id] = "";
+ if(prStDe.compulsory){
+ errorMessages[prStDe.dataElement.id] = $translate('required');
+ }
//$scope.newDhis2Event.dataValues.push({id: prStDe.dataElement.id, value: ''});
$scope.newDhis2Event[prStDe.dataElement.id] = '';
@@ -173,7 +182,9 @@
if(prStDe.dataElement.type === 'date' || prStDe.dataElement.type === 'int' ){
$scope.filterText[prStDe.dataElement.id]= {};
}
- });
+ });
+
+ ErrorMessageService.setErrorMessages(errorMessages);
//Load events for the selected program stage and orgunit
DHIS2EventFactory.getByStage($scope.selectedOrgUnit.id, $scope.selectedProgramStage.id, $scope.pager ).then(function(data){
@@ -730,13 +741,41 @@
$scope.formIsChanged = function(){
var isChanged = false;
- for (var k in $scope.currentEvent) {
- if ($scope.currentEvent.hasOwnProperty(k)) {
- if($scope.currentEvent[k] && $scope.currentEventOrginialValue[k] !== $scope.currentEvent[k]){
- isChanged = true;
- }
+ for(var i=0; i<$scope.selectedProgramStage.programStageDataElements.length && !isChanged; i++){
+ var deId = $scope.selectedProgramStage.programStageDataElements[i].dataElement.id;
+ if($scope.currentEvent[deId] && $scope.currentEventOrginialValue[deId] !== $scope.currentEvent[deId]){
+ isChanged = true;
+ }
+ }
+ if(!isChanged){
+ if($scope.currentEvent.eventDate !== $scope.currentEventOrginialValue.eventDate){
+ isChanged = true;
}
}
+
return isChanged;
};
+
+ $scope.isFormInvalid = function(){
+ if($scope.outerForm.submitted){
+ return $scope.outerForm.$invalid;
+ }
+
+ var errorMessages = ErrorMessageService.getErrorMessages();
+
+ for(var k in errorMessages){
+ if( errorMessages.hasOwnProperty(k) &&
+ errorMessages[k] !== "" &&
+ errorMessages[k] !== $translate('required') &&
+ $scope.currentEvent[k]){
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+ $scope.getErrorMessage = function(deId){
+ return ErrorMessageService.get(deId);
+ };
});
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js 2015-01-08 16:39:10 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js 2015-01-13 17:31:37 +0000
@@ -313,4 +313,21 @@
return e;
}
};
+})
+
+/* Error messages*/
+.service('ErrorMessageService', function(){
+ this.errorMessages = {};
+
+ this.setErrorMessages = function(errorMessages){
+ this.errorMessages = errorMessages;
+ };
+
+ this.getErrorMessages = function(){
+ return this.errorMessages;
+ };
+
+ this.get = function(id){
+ return this.errorMessages[id];
+ };
});
\ No newline at end of file
=== 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-01-12 18:24:10 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/defaultForm.html 2015-01-13 17:31:37 +0000
@@ -10,7 +10,7 @@
</th>
</tr>
</thead>
- <tbody id="list">
+ <tbody>
<tr ng-if="selectedProgramStage.preGenerateUID || editingEventInFull">
<td>
{{'form_id' | translate}}
@@ -21,10 +21,10 @@
</tr>
<tr>
<td>
- {{selectedProgramStage.reportDateDescription ? selectedProgramStage.reportDateDescription : 'incident_date'| translate }}
+ {{selectedProgramStage.reportDateDescription ? selectedProgramStage.reportDateDescription : 'incident_date'| translate }}<span class="required">*</span>
</td>
<td>
- <input type="text"
+ <input type="text"
placeholder="{{dhis2CalendarFormat.keyDateFormat}}"
d2-date
max-date='0'
@@ -32,8 +32,9 @@
ng-disabled="editingEventInFull"
ng-required="true"
name="eventDate"
+ input-field-id="eventDate"
style="width:99%;"/>
- <span ng-show="currentEvent.eventDate && outerForm.eventDate.$invalid || outerForm.submitted && outerForm.eventDate.$invalid" class="required">{{'date_required'| translate}}</span>
+ <span ng-show="currentEvent.eventDate && outerForm.eventDate.$invalid || outerForm.submitted && outerForm.eventDate.$invalid" class="required">{{getErrorMessage('eventDate')}}</span>
</td>
</tr>
<tr ng-if="selectedProgramStage.captureCoordinates">
@@ -71,29 +72,27 @@
</span>-->
<tr ng-repeat="eventGridColumn in eventGridColumns" ng-if="eventGridColumn.id !== 'comment' && eventGridColumn.id !== 'uid' && eventGridColumn.id !== 'event_date'">
<td >
- {{eventGridColumn.name}}
+ {{eventGridColumn.name}}<span ng-if="eventGridColumn.compulsory" class="required">*</span>
</td>
<td >
<ng-form name="innerForm">
<div ng-switch="eventGridColumn.type">
<div ng-switch-when="int">
- <input type="number"
-
+ <input type="text"
d2-number-validation
number-type={{prStDes[eventGridColumn.id].dataElement.numberType}}
ng-model="currentEvent[eventGridColumn.id]"
ng-required={{eventGridColumn.compulsory}}
name="foo"
+ input-field-id={{eventGridColumn.id}}
style="width:99%;"/>
- <span ng-show="currentEvent[eventGridColumn.id] && innerForm.foo.$invalid" class="required">{{'value_must_be'| translate}} - {{prStDes[eventGridColumn.id].dataElement.numberType | translate}}</span>
</div>
<div ng-switch-when="string">
<div class="container-fluid" ng-if="prStDes[eventGridColumn.id].dataElement.optionSet">
<span ng-if="!selectedProgram.dataEntryMethod || optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options.length >= 7">
<input type="text"
class="typeahead"
- placeholder=" "
-
+ 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-open-on-focus
@@ -101,14 +100,14 @@
d2-typeahead-validation
ng-required={{eventGridColumn.compulsory}}
name="foo"
+ input-field-id={{eventGridColumn.id}}
style="width:99%;"/>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'option_required'| translate}}</span>
</span>
<span ng-if="selectedProgram.dataEntryMethod && optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options.length < 7">
<label>
<input type="radio"
name="foo"
-
+ input-field-id={{eventGridColumn.id}}
ng-required={{eventGridColumn.compulsory}}
ng-model="currentEvent[eventGridColumn.id]"
value=""> {{'no_value' | translate}}<br>
@@ -116,57 +115,53 @@
<label ng-repeat="option in optionSets[prStDes[eventGridColumn.id].dataElement.optionSet.id].options">
<input type="radio"
name={{eventGridColumn.id}}
-
+ input-field-id={{eventGridColumn.id}}
ng-required={{eventGridColumn.compulsory}}
ng-model="currentEvent[eventGridColumn.id]"
value={{option.name}}> {{option.name}}<br>
</label>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'required'| translate}}</span>
</span>
</div>
<div ng-if="!prStDes[eventGridColumn.id].dataElement.optionSet">
- <input type="text"
-
+ <input type="text"
ng-model="currentEvent[eventGridColumn.id]"
ng-required={{eventGridColumn.compulsory}}
name="foo"
+ input-field-id={{eventGridColumn.id}}
style="width:99%;"/>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'string_required'| translate}}</span>
</div>
</div>
<div ng-switch-when="bool">
- <select
- ng-model="currentEvent[eventGridColumn.id]"
+ <select ng-model="currentEvent[eventGridColumn.id]"
ng-required={{eventGridColumn.compulsory}}
name="foo"
+ input-field-id={{eventGridColumn.id}}
style="width:99%;">
<option value="">{{'please_select'| translate}}</option>
<option value="false">{{'no'| translate}}</option>
<option value="true">{{'yes'| translate}}</option>
</select>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'bool_required'| translate}}</span>
</div>
<div ng-switch-when="date">
<input type="text"
placeholder="{{dhis2CalendarFormat.keyDateFormat}}"
d2-date
- max-date="prStDes[eventGridColumn.id].allowFutureDate ? '' : 0"
-
+ max-date="prStDes[eventGridColumn.id].allowFutureDate ? '' : 0"
ng-model="currentEvent[eventGridColumn.id]"
ng-required={{eventGridColumn.compulsory}}
name="foo"
+ input-field-id={{eventGridColumn.id}}
style="width:99%;"/>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'date_required'| translate}}</span>
</div>
<div ng-switch-when="trueOnly">
- <input type="checkbox"
-
+ <input type="checkbox"
ng-model="currentEvent[eventGridColumn.id]"
ng-required={{eventGridColumn.compulsory}}
- name="foo"/>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'required'| translate}}</span>
+ name="foo"
+ input-field-id={{eventGridColumn.id}} />
</div>
</div>
+ <span ng-show="currentEvent[eventGridColumn.id] && innerForm.foo.$invalid || outerForm.submitted && innerForm.foo.$invalid" class="required">{{getErrorMessage(eventGridColumn.id)}}</span>
</ng-form>
</td>
</tr>
@@ -196,7 +191,7 @@
</tr>
<tr>
<td>
- {{selectedProgramStage.reportDateDescription ? selectedProgramStage.reportDateDescription : 'incident_date'| translate }}
+ {{selectedProgramStage.reportDateDescription ? selectedProgramStage.reportDateDescription : 'incident_date'| translate }}<span class="required">*</span>
</td>
<td>
<input type="text"
@@ -207,8 +202,9 @@
ng-disabled="editingEventInFull"
ng-required="true"
name="eventDate"
+ input-field-id='eventDate'
style="width:99%;">
- <span ng-show="outerForm.eventDate.$invalid" class="required">{{'date_required'| translate}}</span>
+ <span ng-show="currentEvent.eventDate && outerForm.eventDate.$invalid || outerForm.submitted && outerForm.eventDate.$invalid" class="required">{{getErrorMessage('eventDate') | translate}}</span>
</td>
</tr>
<tr ng-if="selectedProgramStage.captureCoordinates">
@@ -259,29 +255,27 @@
<tbody id="list">
<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}}
+ {{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-switch="prStDes[de.dataElement.id].dataElement.type">
<div ng-switch-when="int">
- <input type="number"
-
+ <input type="number"
d2-number-validation
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}}
style="width:99%;"/>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'value_must_be'| translate}} - {{prStDes[de.dataElement.id].dataElement.numberType | translate}}</span>
</div>
<div ng-switch-when="string">
<div class="container-fluid" ng-if="prStDes[de.dataElement.id].dataElement.optionSet">
<span ng-if="!selectedProgram.dataEntryMethod || optionSets[prStDes[de.dataElement.id].dataElement.optionSet.id].options.length > 8">
<input type="text"
class="typeahead"
- placeholder=" "
-
+ 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-open-on-focus
@@ -289,72 +283,68 @@
d2-typeahead-validation
ng-required={{prStDes[de.dataElement.id].compulsory}}
name="foo"
+ input-field-id={{de.dataElement.id}}
style="width:99%;"/>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'option_required'| translate}}</span>
</span>
<span ng-if="selectedProgram.dataEntryMethod && prStDes[de.dataElement.id].dataElement.optionSet.options.length < 7">
<label>
<input type="radio"
- name="foo"
-
+ 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}}
-
+ 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 ng-show="innerForm.foo.$invalid" class="required">{{'required'| translate}}</span>
</span>
</div>
<div ng-if="!prStDes[de.dataElement.id].dataElement.optionSet">
- <input type="text"
-
+ <input type="text"
ng-model="currentEvent[de.dataElement.id]"
ng-required={{prStDes[de.dataElement.id].compulsory}}
name="foo"
+ input-field-id={{de.dataElement.id}}
style="width:99%;"/>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'string_required'| translate}}</span>
</div>
</div>
<div ng-switch-when="bool">
- <select
- ng-model="currentEvent[de.dataElement.id]"
+ <select ng-model="currentEvent[de.dataElement.id]"
ng-required={{prStDes[de.dataElement.id].compulsory}}
name="foo"
+ input-field-id={{de.dataElement.id}}
style="width:99%;">
<option value="">{{'please_select'| translate}}</option>
<option value="false">{{'no'| translate}}</option>
<option value="true">{{'yes'| translate}}</option>
</select>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'bool_required'| translate}}</span>
</div>
<div ng-switch-when="date">
<input type="text"
placeholder="{{dhis2CalendarFormat.keyDateFormat}}"
d2-date
- max-date="prStDes[de.dataElement.id].allowFutureDate ? '' : 0"
-
+ max-date="prStDes[de.dataElement.id].allowFutureDate ? '' : 0"
ng-model="currentEvent[de.dataElement.id]"
ng-required={{prStDes[de.dataElement.id].compulsory}}
name="foo"
+ input-field-id={{de.dataElement.id}}
style="width:99%;"/>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'date_required'| translate}}</span>
</div>
<div ng-switch-when="trueOnly">
- <input type="checkbox"
-
+ <input type="checkbox"
ng-model="currentEvent[de.dataElement.id]"
ng-required={{prStDes[de.dataElement.id].compulsory}}
- name="foo"/>
- <span ng-show="innerForm.foo.$invalid" class="required">{{'required'| translate}}</span>
+ name="foo"
+ input-field-id={{de.dataElement.id}}/>
</div>
</div>
+ <span ng-show="currentEvent[de.dataElement.id] && innerForm.foo.$invalid || outerForm.submitted && innerForm.foo.$invalid" class="required">{{getErrorMessage(de.dataElement.id)}}</span>
</ng-form>
</td>
</tr>
@@ -401,7 +391,7 @@
<button ng-click="addEvent()" class="button not-printable">{{'save_and_back'| translate}}</button>
<button ng-click="showEventList(null)" class="button not-printable">{{'go_back'| translate}}</button>
</span>
- <span ng-if="outerForm.$invalid && formIsChanged()" class="horizontal-spacing red">{{'form_invalid' | translate}}</span>
+ <span ng-if="isFormInvalid()" class="horizontal-spacing red">{{'form_invalid' | translate}}</span>
</div>
-<!-- buttons for event registration / update ends -->
\ No newline at end of file
+<!-- buttons for event registration / update ends -->
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/ec-custom-form.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/ec-custom-form.html 2014-12-09 23:24:16 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/ec-custom-form.html 2015-01-13 17:31:37 +0000
@@ -19,8 +19,9 @@
ng-model="currentEvent.eventDate"
ng-disabled="editingEventInFull"
ng-required="true"
+ input-field-id="eventDate"
name="eventDate"/>
- <span ng-show="outerForm.submitted && outerForm.eventDate.$invalid" class="required">{{'date_required'| translate}}</span>
+ <span ng-show="currentEvent.eventDate && outerForm.eventDate.$invalid || outerForm.submitted && outerForm.eventDate.$invalid" class="required">{{getErrorMessage('eventDate')}}</span>
</td>
</tr>
<tr ng-if="selectedProgramStage.captureCoordinates">
@@ -37,7 +38,7 @@
max="90"
ng-required="false"
style="min-width:128px"/>
- <span ng-show="outerForm.submitted && outerForm.latitude.$invalid" class="required">{{'int_required'| translate}} [-90 ... 90]</span>
+ <span ng-show="outerForm.latitude.$invalid" class="required">{{'int_required'| translate}} [-90 ... 90]</span>
</span>
<span class="coordinate-container">
<input type="number"
@@ -48,7 +49,7 @@
max="180"
ng-required="false"
style="min-width:128px"/>
- <span ng-show="outerForm.submitted && outerForm.longitude.$invalid" class="required">{{'int_required'| translate}}[-180 ... 180]</span>
+ <span ng-show="outerForm.longitude.$invalid" class="required">{{'int_required'| translate}}[-180 ... 180]</span>
</span>
<!--<span class='pull-right'>
<a href ng-click="showMap(currentEvent)" title="{{'get_from_map'| translate}}"><i class="fa fa-map-marker fa-2x"></i></a>
@@ -56,7 +57,8 @@
</td>
</tr>
</table>
-<div ng-include="'../dhis-web-commons/customform/custom-form.html'"></div>
+<div ng-include="'../dhis-web-commons/customform/custom-form.html'"></div>
+
<div class="clear">
<hr>
<h4>
@@ -82,6 +84,7 @@
</table>
</div>
</div>
+
<!-- buttons for event registration / update begins -->
<div style="clear: both;">
<span ng-if="editingEventInFull">
@@ -93,6 +96,6 @@
<button ng-click="addEvent()" class="button not-printable">{{'save_and_back'| translate}}</button>
<button ng-click="showEventList(null)" class="button not-printable">{{'go_back'| translate}}</button>
</span>
- <span ng-if="outerForm.submitted && outerForm.$invalid" class="horizontal-spacing red">{{'form_invalid' | translate}}</span>
+ <span ng-if="isFormInvalid()" class="horizontal-spacing red">{{'form_invalid' | translate}}</span>
</div>
<!-- buttons for event registration / update ends -->
\ 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/dhis2/directives.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/directives.js 2015-01-12 18:24:10 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/directives.js 2015-01-13 17:31:37 +0000
@@ -4,8 +4,6 @@
var d2Directives = angular.module('d2Directives', [])
-
-
.directive('inputValidator', function() {
return {
@@ -86,7 +84,7 @@
};
})
-.directive('d2NumberValidation', function() {
+.directive('d2NumberValidation', function(ErrorMessageService, $translate) {
return {
require: 'ngModel',
@@ -117,28 +115,49 @@
return isValid;
}
- var fieldName = element.attr('name');
+ var errorMessages = ErrorMessageService.getErrorMessages();
+ var fieldName = attrs.inputFieldId;
var numberType = attrs.numberType;
var isRequired = attrs.ngRequired === 'true';
ctrl.$parsers.unshift(function(value) {
if(value){
- var isValid = checkValidity(numberType, value);
- ctrl.$setValidity(fieldName, isValid);
- //return isValid ? value : undefined;
+ var isValid = checkValidity(numberType, value);
+ if(!isValid){
+ errorMessages[fieldName] = $translate('value_must_be_' + numberType);
+ }
+ else{
+ if(isRequired){
+ errorMessages[fieldName] = $translate('required');
+ }
+ else{
+ errorMessages[fieldName] = "";
+ }
+ }
+
+ ErrorMessageService.setErrorMessages(errorMessages);
+ ctrl.$setValidity(fieldName, isValid);
return value;
}
- if(value === '' && !isRequired){
- ctrl.$setValidity(fieldName, true);
+ if(value === ''){
+ if(isRequired){
+ errorMessages[fieldName] = $translate('required');
+ }
+ else{
+ ctrl.$setValidity(fieldName, true);
+ errorMessages[fieldName] = "";
+ }
+
+ ErrorMessageService.setErrorMessages(errorMessages);
return undefined;
- }
+ }
});
ctrl.$formatters.unshift(function(value) {
if(value){
var isValid = checkValidity(numberType, value);
- ctrl.$setValidity(fieldName, isValid);
+ ctrl.$setValidity(fieldName, isValid);
return value;
}
});
@@ -152,8 +171,7 @@
require: ['typeahead', 'ngModel'],
link: function (scope, element, attr, ctrls) {
element.bind('focus', function () {
- ctrls[0].getMatchesAsync(ctrls[1].$viewValue);
-
+ ctrls[0].getMatchesAsync(ctrls[1].$viewValue);
scope.$watch(attr.ngModel, function(value) {
if(value === '' || angular.isUndefined(value)){
ctrls[0].getMatchesAsync(ctrls[1].$viewValue);
@@ -453,13 +471,14 @@
};
})
-.directive('d2Date', function(DateUtils, CalendarService, storage, $parse) {
+.directive('d2Date', function(DateUtils, CalendarService, ErrorMessageService, $translate, $parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ctrl) {
- var fieldName = element.attr('name');
+ var errorMessages = ErrorMessageService.getErrorMessages();
+ var fieldName = attrs.inputFieldId;
var isRequired = attrs.ngRequired === 'true';
var calendarSetting = CalendarService.getSetting();
var dateFormat = 'yyyy-mm-dd';
@@ -485,27 +504,46 @@
$(this).change();
}
})
- .change(function() {
- if(this.value){
+ .change(function() {
+ if(this.value){
var rawDate = this.value;
var convertedDate = DateUtils.format(this.value);
var isValid = rawDate == convertedDate;
+ if(!isValid){
+ errorMessages[fieldName] = $translate('date_required');
+ }
+
if(isValid && maxDate === 0){
isValid = !moment(convertedDate, calendarSetting.momentFormat).isAfter(DateUtils.getToday());
- }
-
+ if(!isValid){
+ errorMessages[fieldName] = $translate('future_date_not_allowed');
+ }
+ else{
+ if(isRequired){
+ errorMessages[fieldName] = $translate('required');
+ }
+ else{
+ errorMessages[fieldName] = "";
+ }
+ }
+ }
ctrl.$setViewValue(this.value);
ctrl.$setValidity(fieldName, isValid);
}
else{
if(!isRequired){
ctrl.$setViewValue(this.value);
- ctrl.$setValidity(fieldName, !isRequired);
+ ctrl.$setValidity(fieldName, !isRequired);
+ errorMessages[fieldName] = "";
+ }
+ else{
+ errorMessages[fieldName] = $translate('required');
}
}
+ ErrorMessageService.setErrorMessages(errorMessages);
this.focus();
scope.$apply();
});
=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/services.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/services.js 2015-01-08 09:11:32 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/services.js 2015-01-13 17:31:37 +0000
@@ -212,20 +212,18 @@
attributes['name'] = deId;
}
- var maxDate = programStageDataElements[deId].allowFutureDate ? '' : 0;
-
//check data element type and generate corresponding angular input field
if(programStageDataElements[deId].dataElement.type == "int"){
- newInputField = '<input type="number" ' +
+ newInputField = '<input type="text" ' +
this.getAttributesAsString(attributes) +
' d2-validation ' +
' d2-number-validation ' +
' number-type="' + programStageDataElements[deId].dataElement.numberType + '" ' +
' ng-model="currentEvent.' + deId + '"' +
+ ' input-field-id=" ' + deId + '"' +
' ng-class="getInputNotifcationClass(prStDes.' + deId + '.dataElement.id,true)"' +
' ng-blur="saveDatavalue(prStDes.'+ deId + ')"' +
- ' ng-required="prStDes.' + deId + '.compulsory"> ' +
- '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'value_must_be\'| translate}} - {{ "' + programStageDataElements[deId].dataElement.numberType + '" | translate}}</span>';
+ ' ng-required="prStDes.' + deId + '.compulsory"> ';
}
if(programStageDataElements[deId].dataElement.type == "string"){
if(programStageDataElements[deId].dataElement.optionSet){
@@ -234,6 +232,7 @@
this.getAttributesAsString(attributes) +
' d2-validation ' +
' ng-model="currentEvent.' + deId + '" ' +
+ ' input-field-id=" ' + deId + '"' +
' ng-disabled="currentEvent[uid] == \'uid\'" ' +
' ng-required="prStDes.' + deId + '.compulsory"' +
' typeahead="option.name as option.name for option in optionSets.'+optionSetId+'.options | filter:$viewValue | limitTo:20"' +
@@ -243,19 +242,18 @@
' placeholder=" " ' +
' ng-class="getInputNotifcationClass(prStDes.' + deId + '.dataElement.id,true)"' +
' ng-blur="saveDatavalue(prStDes.'+ deId + ')"' +
- ' typeahead-open-on-focus ng-required="prStDes.'+deId+'.compulsory"> ' +
- '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'option_required\'| translate}}</span>';
+ ' typeahead-open-on-focus ng-required="prStDes.'+deId+'.compulsory"> ';
}
else{
newInputField = '<input type="text" ' +
this.getAttributesAsString(attributes) +
' d2-validation ' +
' ng-model="currentEvent.' + deId + '" ' +
+ ' input-field-id=" ' + deId + '"' +
' ng-disabled="currentEvent[uid] == \'uid\'" ' +
' ng-class="getInputNotifcationClass(prStDes.' + deId + '.dataElement.id,true)"' +
' ng-blur="saveDatavalue(prStDes.'+ deId + ')"' +
- ' ng-required="prStDes.' + deId + '.compulsory"> ' +
- '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'string_required\'| translate}}</span>';
+ ' ng-required="prStDes.' + deId + '.compulsory"> ';
}
}
if(programStageDataElements[deId].dataElement.type == "bool"){
@@ -263,38 +261,41 @@
this.getAttributesAsString(attributes) +
' d2-validation ' +
' ng-model="currentEvent.' + deId + '" ' +
+ ' input-field-id=" ' + deId + '"' +
' ng-class="getInputNotifcationClass(prStDes.' + deId + '.dataElement.id,true)"' +
' ng-change="saveDatavalue(prStDes.'+ deId + ')"' +
' ng-required="prStDes.' + deId + '.compulsory">' +
'<option value="">{{\'please_select\'| translate}}</option>' +
'<option value="false">{{\'no\'| translate}}</option>' +
'<option value="true">{{\'yes\'| translate}}</option>' +
- '</select> ' +
- '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'bool_required\'| translate}}</span>';
+ '</select> ';
}
if(programStageDataElements[deId].dataElement.type == "date"){
+ var maxDate = programStageDataElements[deId].allowFutureDate ? '' : 0;
newInputField = '<input type="text" ' +
this.getAttributesAsString(attributes) +
' d2-validation ' +
' ng-model="currentEvent.' + deId + '"' +
+ ' input-field-id=" ' + deId + '"' +
' d2-date ' +
' max-date="' + maxDate + '"' + '\'' +
' ng-class="getInputNotifcationClass(prStDes.' + deId + '.dataElement.id,true)"' +
' blur-or-change="saveDatavalue(prStDes.'+ deId + ')"' +
- ' ng-required="prStDes.' + deId + '.compulsory"> ' +
- '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'date_required\'| translate}}</span>';
+ ' ng-required="prStDes.' + deId + '.compulsory"> ';
}
if(programStageDataElements[deId].dataElement.type == "trueOnly"){
newInputField = '<input type="checkbox" ' +
this.getAttributesAsString(attributes) +
' d2-validation ' +
' ng-model="currentEvent.' + deId + '"' +
+ ' input-field-id=" ' + deId + '"' +
' ng-class="getInputNotifcationClass(prStDes.' + deId + '.dataElement.id,true)"' +
' ng-change="saveDatavalue(prStDes.'+ deId + ')"' +
- ' ng-required="prStDes.' + deId + '.compulsory"> ' +
- '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'required\'| translate}}</span>';
+ ' ng-required="prStDes.' + deId + '.compulsory"> ';
}
-
+
+ newInputField = newInputField + '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid || currentEvent.' + deId + ' && outerForm.'+ deId +'.$invalid" class="required">{{getErrorMessage(prStDes.' + deId + '.dataElement.id)}}</span>';
+
htmlCode = htmlCode.replace(inputField, newInputField);
}
}