dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #36417
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 18630: tracker-capture: period-wise data entry for events
------------------------------------------------------------
revno: 18630
committer: Abyot Asalefew Gizaw <abyota@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2015-03-19 11:18:00 +0100
message:
tracker-capture: period-wise data entry for events
modified:
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event.html
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/tei-report-controller.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/index.html
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/controllers.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/styles/style.css
dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.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/scripts/event-capture.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js 2015-03-04 11:34:55 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js 2015-03-19 10:18:00 +0000
@@ -32,17 +32,6 @@
objectStores: ['programs', 'programStages', 'geoJsons', 'optionSets', 'events', 'programValidations', 'ouLevels']
});
-(function($) {
- $.safeEach = function(arr, fn)
- {
- if (arr)
- {
- $.each(arr, fn);
- }
- };
-})(jQuery);
-
-
/**
* Page init. The order of events is:
*
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js 2015-03-11 15:02:58 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js 2015-03-19 10:18:00 +0000
@@ -43,8 +43,8 @@
{color: 'alert-danger', description: 'overdue'},
{color: 'alert-default', description: 'skipped'}
];
- $scope.showEventColors = false;
-
+ $scope.showEventColors = false;
+
//listen for the selected items
$scope.$on('dashboardWidgets', function() {
$scope.showDataEntryDiv = false;
@@ -152,7 +152,7 @@
$scope.showCreateEvent = function(stage){
- var dummyEvent = EventUtils.createDummyEvent($scope.eventsByStage[stage.id], stage, $scope.selectedOrgUnit, $scope.selectedEnrollment);
+ var dummyEvent = EventUtils.createDummyEvent($scope.eventsByStage[stage.id], $scope.selectedEntity, $scope.selectedProgram, stage, $scope.selectedOrgUnit, $scope.selectedEnrollment);
var modalInstance = $modal.open({
templateUrl: 'components/dataentry/new-event.html',
@@ -164,11 +164,8 @@
dummyEvent: function(){
return dummyEvent;
},
- programId: function () {
- return $scope.selectedProgram.id;
- },
- trackedEntityInstanceId: function(){
- return $scope.selectedEntity.trackedEntityInstance;
+ eventPeriods: function(){
+ return $scope.eventPeriods;
}
}
});
@@ -187,9 +184,10 @@
if(dummyEvent.coordinate){
newEvent.coordinate = {};
- }
+ }
$scope.eventsByStage[newEvent.programStage].push(newEvent);
+ sortEventsByStage();
$scope.showDataEntry(newEvent, false);
}
}, function () {
@@ -415,6 +413,7 @@
};
$scope.saveDueDate = function(){
+
$scope.dueDateSaved = false;
if($scope.currentEvent.dueDate === ''){
@@ -440,10 +439,23 @@
trackedEntityInstance: $scope.currentEvent.trackedEntityInstance
};
+ if($scope.currentStage.periodType){
+ e.eventDate = e.dueDate;
+ }
+
+ if($scope.currentEvent.coordinate){
+ e.coordinate = $scope.currentEvent.coordinate;
+ }
+
DHIS2EventFactory.update(e).then(function(data){
$scope.invalidDate = false;
$scope.dueDateSaved = true;
- $scope.currentEvent.sortingDate = $scope.currentEvent.dueDate;
+
+ if(e.eventDate && !$scope.currentEvent.eventDate && $scope.currentStage.periodType){
+ $scope.currentEvent.eventDate = $scope.currentEvent.dueDate;
+ }
+
+ $scope.currentEvent.sortingDate = $scope.currentEvent.dueDate;
$scope.currentEvent.statusColor = EventUtils.getEventStatusColor($scope.currentEvent);
$scope.schedulingEnabled = !$scope.schedulingEnabled;
sortEventsByStage();
@@ -682,22 +694,29 @@
};
var sortEventsByStage = function(){
+
$scope.eventFilteringRequired = false;
- for(var key in $scope.eventsByStage){
+
+ for(var key in $scope.eventsByStage){
+
var stage = $scope.stagesById[key];
+
if($scope.eventsByStage.hasOwnProperty(key) && stage){
+
var sortedEvents = $filter('orderBy')($scope.eventsByStage[key], function(event) {
return DateUtils.getDate(event.sortingDate);
- });
- var periods = PeriodService.getPeriods(sortedEvents, stage);
+ }, true);
+
+ var periods = PeriodService.getPeriods(sortedEvents, stage, $scope.selectedEnrollment).occupiedPeriods;
$scope.eventPeriods[key] = periods;
$scope.currentPeriod[key] = periods.length > 0 ? periods[0] : null;
$scope.eventFilteringRequired = $scope.eventFilteringRequired ? $scope.eventFilteringRequired : periods.length > 1;
+
}
}
};
- $scope.showDataEntryForEvent = function(period){
+ $scope.showDataEntryForEvent = function(period){
var event = null;
for(var i=0; i<$scope.eventsByStage[period.stage].length; i++){
if($scope.eventsByStage[period.stage][i].event === period.event){
@@ -744,16 +763,21 @@
DialogService,
stagesById,
dummyEvent,
- programId,
- trackedEntityInstanceId){
+ eventPeriods){
$scope.stagesById = stagesById;
$scope.programStageId = dummyEvent.programStage;
- $scope.programId = programId;
- $scope.orgUnitId = dummyEvent.orgUnit;
- $scope.trackedEntityInstanceId = trackedEntityInstanceId;
+ $scope.eventPeriods = eventPeriods;
+ $scope.selectedStage = $scope.stagesById[dummyEvent.programStage];
$scope.dhis2Event = {eventDate: '', dueDate: dummyEvent.dueDate, reportDateDescription: dummyEvent.reportDateDescription, name: dummyEvent.name, invalid: true};
+ if($scope.selectedStage.periodType){
+ $scope.dhis2Event.eventDate = dummyEvent.dueDate;
+ $scope.dhis2Event.periodName = dummyEvent.periodName;
+ $scope.dhis2Event.periods = dummyEvent.periods;
+ $scope.dhis2Event.selectedPeriod = dummyEvent.periods[0];
+ }
+
$scope.dueDateInvalid = false;
$scope.eventDateInvalid = false;
@@ -785,14 +809,20 @@
return false;
}
+ if($scope.selectedStage.periodType){
+ $scope.dhis2Event.eventDate = $scope.dhis2Event.selectedPeriod.endDate;
+ $scope.dhis2Event.dueDate = $scope.dhis2Event.selectedPeriod.endDate;
+ }
+
var eventDate = DateUtils.formatFromUserToApi($scope.dhis2Event.eventDate);
var dueDate = DateUtils.formatFromUserToApi($scope.dhis2Event.dueDate);
var newEvents = {events: []};
var newEvent = {
- trackedEntityInstance: $scope.trackedEntityInstanceId,
- program: $scope.programId,
- programStage: $scope.programStageId,
- orgUnit: $scope.orgUnitId,
+ trackedEntityInstance: dummyEvent.trackedEntityInstance,
+ program: dummyEvent.program,
+ programStage: dummyEvent.programStage,
+ enrollment: dummyEvent.enrollment,
+ orgUnit: dummyEvent.orgUnit,
dueDate: dueDate,
eventDate: eventDate,
notes: [],
@@ -800,7 +830,6 @@
status: 'ACTIVE'
};
newEvents.events.push(newEvent);
-
DHIS2EventFactory.create(newEvents).then(function(data){
if (data.importSummaries[0].status === 'ERROR') {
var dialogOptions = {
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html 2015-03-11 11:21:40 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html 2015-03-19 10:18:00 +0000
@@ -72,7 +72,8 @@
<form name="outerForm" novalidate>
<div ng-if="currentEvent">
- <!-- event dates begin -->
+
+ <!-- event dates/scheduling begin -->
<div class="row">
<div class="col-md-6">
{{currentEvent.reportDateDescription}}
@@ -105,7 +106,7 @@
<span ng-if="invalidDate" class="error">{{'date_required'| translate}}</span>
</div>
</div>
- <!-- event dates end -->
+ <!-- event dates/scheduling end -->
<!-- coordinates begin -->
<div class="row" ng-if="currentStage.captureCoordinates && currentEvent.eventDate">
@@ -140,11 +141,14 @@
</div>
<!-- coordinates begin -->
+ <!-- data entry form begins -->
<div ng-if="currentEvent.eventDate">
<div class="clear vertical-spacing" ng-if="displayCustomForm" ng-include="'../dhis-web-commons/customform/custom-form.html'"></div>
<div class="clear vertical-spacing" ng-if="!displayCustomForm" ng-include="'components/dataentry/default-form.html'"></div>
</div>
-
+ <!-- data entry form ends -->
+
+ <!-- data entry/event buttons begins -->
<div class="form-group">
<div class='row'><hr></div>
<a href ng-click="completeIncompleteEvent()"
@@ -167,6 +171,8 @@
ng-disabled="currentEvent.enrollmentStatus === 'COMPLETED' || currentEvent.editingNotAllowed"
class="btn btn-danger">{{'delete'| translate}}</a>
</div>
+ <!-- data entry/event buttons ends -->
+
</div>
</form>
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event.html 2015-02-20 12:08:37 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event.html 2015-03-19 10:18:00 +0000
@@ -3,31 +3,47 @@
</div>
<div class="modal-body page">
<form name="eventCreationForm" class="form-horizontal" role="form" novalidate>
- <div class="form-group">
- <label class="col-sm-2 control-label">{{'due_date'| translate}}</label>
- <div class="col-sm-10">
- <input type="text"
- class="form-control"
- name="dueDate"
- placeholder="{{dhis2CalendarFormat.keyDateFormat}}"
- ng-rquired="true"
- d2-date
- ng-model="dhis2Event.dueDate">
- <span ng-if="dueDateInvalid" class="error">{{'required'| translate}}</span>
+ <div ng-if="!selectedStage.periodType">
+ <div class="form-group">
+ <label class="col-sm-2 control-label">{{'due_date'| translate}}</label>
+ <div class="col-sm-10">
+ <input type="text"
+ class="form-control"
+ name="dueDate"
+ placeholder="{{dhis2CalendarFormat.keyDateFormat}}"
+ ng-rquired="true"
+ d2-date
+ ng-model="dhis2Event.dueDate">
+ <span ng-if="dueDateInvalid" class="error">{{'required'| translate}}</span>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-2 control-label">{{dhis2Event.reportDateDescription}}</label>
+ <div class="col-sm-10">
+ <input type="text"
+ class="form-control"
+ name="eventDate"
+ placeholder="{{dhis2CalendarFormat.keyDateFormat}}"
+ ng-rquired="false"
+ d2-date
+ ng-model="dhis2Event.eventDate">
+ <span ng-if="eventDateInvalid" class="error">{{'required'| translate}}</span>
+ </div>
</div>
</div>
- <div class="form-group">
- <label class="col-sm-2 control-label">{{dhis2Event.reportDateDescription}}</label>
- <div class="col-sm-10">
- <input type="text"
- class="form-control"
- name="eventDate"
- placeholder="{{dhis2CalendarFormat.keyDateFormat}}"
- ng-rquired="false"
- d2-date
- ng-model="dhis2Event.eventDate">
- <span ng-if="eventDateInvalid" class="error">{{'required'| translate}}</span>
- </div>
+ <div ng-if="selectedStage.periodType">
+ <div class="form-group">
+ <label class="control-label">
+ {{'period'| translate}}
+ </label>
+ <select class="form-control-program"
+ ng-model="dhis2Event.selectedPeriod"
+ ng-options="period.name for period in dhis2Event.periods">
+ </select>
+ <button ng-disabled="true" type="button" class="btn btn-default small-horizonal-spacing trim" ng-click="fetchPeriod('PREV')" title="{{'prev_period'| translate}}"><i class="fa fa-backward"></i></button>
+ <button ng-disabled="true" type="button" class="btn btn-default small-horizonal-spacing trim" ng-click="fetchPeriod('NEXT')" title="{{'nxt_period'| translate}}"><i class="fa fa-forward"></i></button>
+
+ </div>
</div>
</form>
</div>
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/tei-report-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/tei-report-controller.js 2015-03-16 14:15:34 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/tei-report-controller.js 2015-03-19 10:18:00 +0000
@@ -120,7 +120,7 @@
providedElsewhereExists = true;
$scope.allowProvidedElsewhereExists[st.id] = true;
}
- }
+ }
});
});
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties 2015-03-19 03:43:44 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties 2015-03-19 10:18:00 +0000
@@ -291,6 +291,7 @@
completed_enrollment=Only those with completed enrollment
filter_events=Filter events
list_events=List all events
+period=Period
jan=January
feb=February
mar=March
@@ -302,4 +303,5 @@
sep=September
oct=October
nov=November
-dec=December
\ No newline at end of file
+dec=December
+week=Week
\ No newline at end of file
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/index.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/index.html 2015-03-05 15:48:50 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/index.html 2015-03-19 10:18:00 +0000
@@ -20,6 +20,7 @@
<script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/ui/jquery-ui.min.js"></script>
<script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/jquery.plugin.min.js"></script>
+
<script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/calendars/jquery.calendars.min.js"></script>
<script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/calendars/jquery.calendars.picker.min.js"></script>
<script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/calendars/jquery.calendars.plus.min.js"></script>
@@ -61,8 +62,7 @@
<script type="text/javascript" src="../dhis-web-commons/javascripts/commons.js"></script>
<script type="text/javascript" src="../dhis-web-commons/javascripts/commons.ajax.js"></script>
<script type="text/javascript" src="../dhis-web-commons/javascripts/lists.js"></script>
- <script type="text/javascript" src="../dhis-web-commons/javascripts/periodType.js"></script>
- <script type="text/javascript" src="../dhis-web-commons/javascripts/date.js"></script>
+ <script type="text/javascript" src="../dhis-web-commons/javascripts/periodTypeNoDep.js"></script>
<script type="text/javascript" src="../dhis-web-commons/javascripts/json2.js"></script>
<script type="text/javascript" src="../dhis-web-commons/javascripts/validationRules.js"></script>
<script type="text/javascript" src="../dhis-web-commons/javascripts/dhis2/dhis2.array.js"></script>
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/controllers.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/controllers.js 2015-03-12 10:55:00 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/controllers.js 2015-03-19 10:18:00 +0000
@@ -263,7 +263,7 @@
$scope.doSearch = true;
if(!$scope.sortColumn.id){
- $scope.sortGrid({id: 'created', name: $translate('registration_date'), valueType: 'date', displayInListNoProgram: false, showFilter: false, show: true});
+ $scope.sortGrid({id: 'created', name: $translate('registration_date'), valueType: 'date', displayInListNoProgram: false, showFilter: false, show: false});
}
});
};
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js 2015-03-16 14:14:10 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js 2015-03-19 10:18:00 +0000
@@ -1,4 +1,4 @@
-/* global angular */
+/* global angular, moment, dhis2 */
'use strict';
@@ -51,52 +51,11 @@
})
/* current selections */
-.service('PeriodService', function($translate, CalendarService){
+.service('PeriodService', function($translate, $filter, DateUtils, CalendarService){
var calendarSetting = CalendarService.getSetting();
- var months = [
- $translate('jan'),
- $translate('feb'),
- $translate('mar'),
- $translate('apr'),
- $translate('may'),
- $translate('jun'),
- $translate('jul'),
- $translate('aug'),
- $translate('sep'),
- $translate('oct'),
- $translate('nov'),
- $translate('dec')
- ];
-
- this.getMonths = function(){
- return months;
- };
-
- this.getPeriods = function(events, stage){
- var periods = [];
- if(stage){
- angular.forEach(events, function(event){
- periods.push({event: event.event, name: event.sortingDate, stage: stage.id});
- });
- /*if(stage.standardInterval === 30){
- angular.forEach(events, function(event){
- var obj = {year: moment(event.sortingDate, calendarSetting.momentFormat).year(), month: moment(event.sortingDate, calendarSetting.momentFormat).month(), week: moment(event.sortingDate, calendarSetting.momentFormat).week(), day: moment(event.sortingDate, calendarSetting.momentFormat).day()};
- periods.push({event: event.event, name: months[obj.month] + ' ' + obj.year, stage: stage.id});
- });
- }
- else{
- angular.forEach(events, function(event){
- periods.push({event: event.event, name: event.sortingDate, stage: stage.id});
- });
- }*/
- }
-
- return periods;
- };
-
-
- this.splitDate = function(dateValue){
+
+ var splitDate = function(dateValue){
if(!dateValue){
return;
}
@@ -104,6 +63,53 @@
return {year: moment(dateValue, calendarSetting.momentFormat).year(), month: moment(dateValue, calendarSetting.momentFormat).month(), week: moment(dateValue, calendarSetting.momentFormat).week(), day: moment(dateValue, calendarSetting.momentFormat).day()};
};
+
+ this.getPeriods = function(events, stage, enrollment){
+
+ if(!stage){
+ return;
+ }
+
+ var referenceDate = enrollment.dateOfIncident ? enrollment.dateOfIncident : enrollment.dateOfEnrollment;
+ var offset = stage.minDaysFromStart;
+
+ if(stage.generatedByEnrollmentDate){
+ referenceDate = enrollment.dateOfEnrollment;
+ }
+
+ var occupiedPeriods = [];
+ var availablePeriods = [];
+ if(!stage.periodType){
+ angular.forEach(events, function(event){
+ occupiedPeriods.push({event: event.event, name: event.sortingDate, stage: stage.id});
+ });
+
+ }
+ else{
+
+ var startDate = DateUtils.format( moment(referenceDate, calendarSetting.momentFormat).add(offset, 'days') );
+ var periodOffet = splitDate(DateUtils.getToday()).year - splitDate(startDate).year;
+
+ //generate availablePeriods
+ var pt = new PeriodType();
+ var d2Periods = pt.get(stage.periodType).generatePeriods({offset: periodOffet, filterFuturePeriods: false, reversePeriods: false});
+ angular.forEach(d2Periods, function(p){
+ p.endDate = DateUtils.formatFromApiToUser(p.endDate);
+ p.startDate = DateUtils.formatFromApiToUser(p.startDate);
+ availablePeriods[p.endDate] = p;
+ });
+
+ //get occupied periods
+ angular.forEach(events, function(event){
+ var p = availablePeriods[event.sortingDate];
+ if(p){
+ occupiedPeriods.push({event: event.event, name: p.name, stage: stage.id, eventDate: event.sortingDate});
+ delete availablePeriods[event.sortingDate];
+ }
+ });
+ }
+ return {occupiedPeriods: occupiedPeriods, availablePeriods: availablePeriods};
+ };
})
/* Factory to fetch optionSets */
@@ -1214,8 +1220,7 @@
column.show = false;
if( (column.id === 'orgUnitName' && ouMode !== 'SELECTED') ||
column.displayInListNoProgram ||
- column.displayInList ||
- column.id === 'created'){
+ column.displayInList){
column.show = true;
}
column.showFilter = false;
@@ -1251,12 +1256,14 @@
};
})
-.service('EventUtils', function(DateUtils, CalendarService, OptionSetService, $filter, orderByFilter){
+.service('EventUtils', function(DateUtils, PeriodService, CalendarService, OptionSetService, $filter, orderByFilter){
- var getEventDueDate = function(eventsByStage, programStage, enrollment){
+ var getEventDueDate = function(eventsByStage, programStage, enrollment){
+
var referenceDate = enrollment.dateOfIncident ? enrollment.dateOfIncident : enrollment.dateOfEnrollment,
offset = programStage.minDaysFromStart,
- calendarSetting = CalendarService.getSetting();
+ calendarSetting = CalendarService.getSetting(),
+ dueDate;
if(programStage.generatedByEnrollmentDate){
referenceDate = enrollment.dateOfEnrollment;
@@ -1271,30 +1278,71 @@
});
if(evs.length > 0){
- evs = orderByFilter(evs, '-eventDate');
- referenceDate = evs[0].eventDate;
- offset = programStage.standardInterval ? programStage.standardInterval : 0;
- }
+ evs = orderByFilter(evs, '-eventDate');
+ if(programStage.periodType){
+
+ }
+ else{
+ referenceDate = evs[0].eventDate;
+ offset = programStage.standardInterval;
+ }
+ }
}
-
- var dueDate = moment(referenceDate, calendarSetting.momentFormat).add('d', offset)._d;
- dueDate = $filter('date')(dueDate, calendarSetting.keyDateFormat);
+ dueDate = moment(referenceDate, calendarSetting.momentFormat).add('d', offset)._d;
+ dueDate = $filter('date')(dueDate, calendarSetting.keyDateFormat);
return dueDate;
};
+ var getEventDuePeriod = function(eventsByStage, programStage, enrollment){
+
+ var evs = [];
+ angular.forEach(eventsByStage, function(ev){
+ if(ev.eventDate){
+ evs.push(ev);
+ }
+ });
+
+ if(evs.length > 0){
+ evs = orderByFilter(evs, '-eventDate');
+ }
+
+ var availabelPeriods = PeriodService.getPeriods(evs,programStage, enrollment).availablePeriods;
+ var periods = [];
+ for(var k in availabelPeriods){
+ if(availabelPeriods.hasOwnProperty(k)){
+ periods.push( availabelPeriods[k] );
+ }
+ }
+ return periods;
+ };
+
return {
- createDummyEvent: function(eventsPerStage, programStage, orgUnit, enrollment){
- var today = DateUtils.getToday();
- var dueDate = getEventDueDate(eventsPerStage, programStage, enrollment);
- var dummyEvent = {programStage: programStage.id,
+ createDummyEvent: function(eventsPerStage, tei, program, programStage, orgUnit, enrollment){
+ var today = DateUtils.getToday();
+ var dummyEvent = {trackedEntityInstance: tei.trackedEntityInstance,
+ programStage: programStage.id,
+ program: program.id,
orgUnit: orgUnit.id,
orgUnitName: orgUnit.name,
- dueDate: dueDate,
- sortingDate: dueDate,
name: programStage.name,
reportDateDescription: programStage.reportDateDescription,
enrollmentStatus: 'ACTIVE',
+ enrollment: enrollment.enrollment,
status: 'SCHEDULED'};
+
+ if(programStage.periodType){
+ var periods = getEventDuePeriod(eventsPerStage, programStage, enrollment);
+ dummyEvent.dueDate = periods[0].endDate;
+ dummyEvent.periodName = periods[0].name;
+ dummyEvent.eventDate = dummyEvent.dueDate;
+ dummyEvent.periods = periods;
+ }
+ else{
+ dummyEvent.dueDate = getEventDueDate(eventsPerStage, programStage, enrollment);
+ }
+
+ dummyEvent.sortingDate = dummyEvent.dueDate;
+
if(programStage.captureCoordinates){
dummyEvent.coordinate = {};
@@ -1342,10 +1390,20 @@
program: program.id,
programStage: stage.id,
orgUnit: orgUnit.id,
- dueDate: DateUtils.formatFromUserToApi(getEventDueDate(null,stage, enrollment)),
+ enrollment: enrollment.enrollment,
status: 'SCHEDULE'
};
-
+ if(stage.periodType){
+ var periods = getEventDuePeriod(null, stage, enrollment);
+ newEvent.dueDate = DateUtils.formatFromUserToApi(periods[0].dueDate);;
+ newEvent.eventDate = newEvent.dueDate;
+ //newEvent.periodName = periods[0].name;
+ //newEvent.periods = periods;
+ }
+ else{
+ newEvent.dueDate = DateUtils.formatFromUserToApi(getEventDueDate(null,stage, enrollment));
+ }
+
if(stage.openAfterEnrollment){
if(stage.reportDateToUse === 'dateOfIncident'){
newEvent.eventDate = DateUtils.formatFromUserToApi(enrollment.dateOfIncident);
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js 2015-03-16 14:14:10 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js 2015-03-19 10:18:00 +0000
@@ -29,16 +29,6 @@
objectStores: ['programs', 'programStages', 'trackedEntities', 'trackedEntityForms', 'attributes', 'relationshipTypes', 'optionSets', 'programValidations', 'ouLevels']
});
-(function($) {
- $.safeEach = function(arr, fn)
- {
- if (arr)
- {
- $.each(arr, fn);
- }
- };
-})(jQuery);
-
/**
* Page init. The order of events is:
*
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/styles/style.css'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/styles/style.css 2015-03-11 15:02:58 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/styles/style.css 2015-03-19 10:18:00 +0000
@@ -90,7 +90,6 @@
.vertical-center {
line-height: inherit;
vertical-align: middle;
-
}
.empty-event-container {
@@ -1011,4 +1010,9 @@
.mouse-pointer {
cursor: pointer;
+}
+
+ .form-horizontal .control-label {
+ display: table-cell;
+ vertical-align: middle;
}
\ No newline at end of file
=== 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-02-12 14:25:04 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js 2015-03-19 10:18:00 +0000
@@ -237,93 +237,98 @@
if(attributes.hasOwnProperty('name')){
attributes['name'] = fieldId;
}
+
+ var prStDe = programStageDataElements[fieldId];
+
+ if( prStDe && prStDe.dataElement && prStDe.dataElement.type ){
- //check data element type and generate corresponding angular input field
- if(programStageDataElements[fieldId].dataElement.type === "int"){
- newInputField = '<input type="text" ' +
- this.getAttributesAsString(attributes) +
- ' d2-validation ' +
- ' d2-number-validation ' +
- ' number-type="' + programStageDataElements[fieldId].dataElement.numberType + '" ' +
- ' ng-model="currentEvent.' + fieldId + '"' +
- ' input-field-id="' + fieldId + '"' +
- ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
- ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent.editingNotAllowed"' +
- ' ng-blur="saveDatavalue(prStDes.'+ fieldId + ')"' +
- ' ng-required="{{prStDes.' + fieldId + '.compulsory}}">';
- }
- if(programStageDataElements[fieldId].dataElement.type === "string"){
- if(programStageDataElements[fieldId].dataElement.optionSet){
- var optionSetId = programStageDataElements[fieldId].dataElement.optionSet.id;
- newInputField = '<input type="text" ' +
- this.getAttributesAsString(attributes) +
- ' d2-validation ' +
- ' ng-model="currentEvent.' + fieldId + '" ' +
- ' input-field-id="' + fieldId + '"' +
- ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent[uid]==\'uid\' || currentEvent.editingNotAllowed"' +
- ' ng-required="{{prStDes.' + fieldId + '.compulsory}}"' +
- ' typeahead="option.name as option.name for option in optionSets.'+optionSetId+'.options | filter:$viewValue | limitTo:20"' +
- ' typeahead-editable="false" ' +
- ' d2-typeahead-validation ' +
- ' class="typeahead" ' +
- ' placeholder=" " ' +
- ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
- ' ng-blur="saveDatavalue(prStDes.'+ fieldId + ')"' +
- ' typeahead-open-on-focus ng-required="prStDes.'+fieldId+'.compulsory"> ';
- }
- else{
- newInputField = '<input type="text" ' +
- this.getAttributesAsString(attributes) +
- ' d2-validation ' +
- ' ng-model="currentEvent.' + fieldId + '" ' +
- ' input-field-id="' + fieldId + '"' +
- ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent[uid]==\'uid\' || currentEvent.editingNotAllowed"' +
- ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
- ' ng-blur="saveDatavalue(prStDes.'+ fieldId + ')"' +
- ' ng-required="prStDes.' + fieldId + '.compulsory"> ';
- }
- }
- if(programStageDataElements[fieldId].dataElement.type === "bool"){
- newInputField = '<select ' +
- this.getAttributesAsString(attributes) +
- ' d2-validation ' +
- ' ng-model="currentEvent.' + fieldId + '" ' +
- ' input-field-id="' + fieldId + '"' +
- ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
- ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent.editingNotAllowed"' +
- ' ng-change="saveDatavalue(prStDes.'+ fieldId + ')"' +
- ' ng-required="{{prStDes.' + fieldId + '.compulsory}}">' +
- '<option value="">{{\'please_select\'| translate}}</option>' +
- '<option value="false">{{\'no\'| translate}}</option>' +
- '<option value="true">{{\'yes\'| translate}}</option>' +
- '</select> ';
- }
- if(programStageDataElements[fieldId].dataElement.type === "date"){
- var maxDate = programStageDataElements[fieldId].allowFutureDate ? '' : 0;
- newInputField = '<input type="text" ' +
- this.getAttributesAsString(attributes) +
- ' d2-validation ' +
- ' ng-model="currentEvent.' + fieldId + '"' +
- ' input-field-id="' + fieldId + '"' +
- ' placeholder="{{dhis2CalendarFormat.keyDateFormat}}" ' +
- ' d2-date ' +
- ' max-date="' + maxDate + '"' +
- ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
- ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent.editingNotAllowed"' +
- ' blur-or-change="saveDatavalue(prStDes.'+ fieldId + ')"' +
- ' ng-required="{{prStDes.' + fieldId + '.compulsory}}"> ';
- }
- if(programStageDataElements[fieldId].dataElement.type === "trueOnly"){
- newInputField = '<input type="checkbox" ' +
- this.getAttributesAsString(attributes) +
- ' d2-validation ' +
- ' ng-model="currentEvent.' + fieldId + '"' +
- ' input-field-id="' + fieldId + '"' +
- ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
- ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent.editingNotAllowed"' +
- ' ng-change="saveDatavalue(prStDes.'+ fieldId + ')"' +
- ' ng-required="{{prStDes.' + fieldId + '.compulsory}}"> ';
- }
+ //check data element type and generate corresponding angular input field
+ if(prStDe.dataElement.type === "int"){
+ newInputField = '<input type="text" ' +
+ this.getAttributesAsString(attributes) +
+ ' d2-validation ' +
+ ' d2-number-validation ' +
+ ' number-type="' + prStDe.dataElement.numberType + '" ' +
+ ' ng-model="currentEvent.' + fieldId + '"' +
+ ' input-field-id="' + fieldId + '"' +
+ ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
+ ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent.editingNotAllowed"' +
+ ' ng-blur="saveDatavalue(prStDes.'+ fieldId + ')"' +
+ ' ng-required="{{prStDes.' + fieldId + '.compulsory}}">';
+ }
+ if(prStDe.dataElement.type === "string"){
+ if(prStDe.dataElement.optionSet){
+ var optionSetId = prStDe.dataElement.optionSet.id;
+ newInputField = '<input type="text" ' +
+ this.getAttributesAsString(attributes) +
+ ' d2-validation ' +
+ ' ng-model="currentEvent.' + fieldId + '" ' +
+ ' input-field-id="' + fieldId + '"' +
+ ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent[uid]==\'uid\' || currentEvent.editingNotAllowed"' +
+ ' ng-required="{{prStDes.' + fieldId + '.compulsory}}"' +
+ ' typeahead="option.name as option.name for option in optionSets.'+optionSetId+'.options | filter:$viewValue | limitTo:20"' +
+ ' typeahead-editable="false" ' +
+ ' d2-typeahead-validation ' +
+ ' class="typeahead" ' +
+ ' placeholder=" " ' +
+ ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
+ ' ng-blur="saveDatavalue(prStDes.'+ fieldId + ')"' +
+ ' typeahead-open-on-focus ng-required="prStDes.'+fieldId+'.compulsory"> ';
+ }
+ else{
+ newInputField = '<input type="text" ' +
+ this.getAttributesAsString(attributes) +
+ ' d2-validation ' +
+ ' ng-model="currentEvent.' + fieldId + '" ' +
+ ' input-field-id="' + fieldId + '"' +
+ ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent[uid]==\'uid\' || currentEvent.editingNotAllowed"' +
+ ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
+ ' ng-blur="saveDatavalue(prStDes.'+ fieldId + ')"' +
+ ' ng-required="prStDes.' + fieldId + '.compulsory"> ';
+ }
+ }
+ if(prStDe.dataElement.type === "bool"){
+ newInputField = '<select ' +
+ this.getAttributesAsString(attributes) +
+ ' d2-validation ' +
+ ' ng-model="currentEvent.' + fieldId + '" ' +
+ ' input-field-id="' + fieldId + '"' +
+ ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
+ ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent.editingNotAllowed"' +
+ ' ng-change="saveDatavalue(prStDes.'+ fieldId + ')"' +
+ ' ng-required="{{prStDes.' + fieldId + '.compulsory}}">' +
+ '<option value="">{{\'please_select\'| translate}}</option>' +
+ '<option value="false">{{\'no\'| translate}}</option>' +
+ '<option value="true">{{\'yes\'| translate}}</option>' +
+ '</select> ';
+ }
+ if(prStDe.dataElement.type === "date"){
+ var maxDate = prStDe.allowFutureDate ? '' : 0;
+ newInputField = '<input type="text" ' +
+ this.getAttributesAsString(attributes) +
+ ' d2-validation ' +
+ ' ng-model="currentEvent.' + fieldId + '"' +
+ ' input-field-id="' + fieldId + '"' +
+ ' placeholder="{{dhis2CalendarFormat.keyDateFormat}}" ' +
+ ' d2-date ' +
+ ' max-date="' + maxDate + '"' +
+ ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
+ ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent.editingNotAllowed"' +
+ ' blur-or-change="saveDatavalue(prStDes.'+ fieldId + ')"' +
+ ' ng-required="{{prStDes.' + fieldId + '.compulsory}}"> ';
+ }
+ if(prStDe.dataElement.type.type === "trueOnly"){
+ newInputField = '<input type="checkbox" ' +
+ this.getAttributesAsString(attributes) +
+ ' d2-validation ' +
+ ' ng-model="currentEvent.' + fieldId + '"' +
+ ' input-field-id="' + fieldId + '"' +
+ ' ng-class="getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id,true)"' +
+ ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent.editingNotAllowed"' +
+ ' ng-change="saveDatavalue(prStDes.'+ fieldId + ')"' +
+ ' ng-required="{{prStDes.' + fieldId + '.compulsory}}"> ';
+ }
+ }
}
newInputField = newInputField + ' <span ng-show="(outerForm.'+ fieldId +'.$dirty && outerForm.'+ fieldId +'.$invalid) || (outerForm.submitted && outerForm.'+ fieldId +'.$invalid) || (currentEvent.' + fieldId + ' && outerForm.' + fieldId + '.$invalid)" class="required">{{getErrorMessage(' + errorMessageId + ')}}</span> ';
@@ -371,105 +376,111 @@
var fieldName = attId;
var attMaxDate = trackedEntityFormAttributes[attId].allowFutureDate ? '' : 0;
- //check attribute type and generate corresponding angular input field
- if(trackedEntityFormAttributes[attId].valueType === "number"){
- newInputField = '<input type="text" ' +
- ' name="' + fieldName + '"' +
- ' element-id="' + i + '"' +
- this.getAttributesAsString(attributes) +
- ' d2-validation ' +
- ' d2-number-validation ' +
- ' d2-focus-next-on-enter' +
- ' ng-model="selectedTei.' + attId + '" ' +
- ' ng-disabled="editingDisabled"' +
- ' ng-blur="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
- ' ng-required=" ' + trackedEntityFormAttributes[attId].mandatory + '"> ';
- }
- else if(trackedEntityFormAttributes[attId].valueType === "optionSet"){
- var optionSetId = trackedEntityFormAttributes[attId].optionSet.id;
- newInputField = '<input type="text" ' +
- ' name="' + fieldName + '"' +
- ' element-id="' + i + '"' +
- this.getAttributesAsString(attributes) +
- ' d2-focus-next-on-enter' +
- ' ng-model="selectedTei.' + attId + '" ' +
- ' ng-disabled="editingDisabled"' +
- ' d2-validation ' +
- ' d2-typeahead-validation ' +
- ' class="typeahead" ' +
- ' placeholder=" " ' +
- ' typeahead-editable="false" ' +
- ' typeahead="option.name as option.name for option in optionSets.' + optionSetId + '.options | filter:$viewValue | limitTo:50"' +
- ' typeahead-open-on-focus ' +
- ' ng-blur="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
- ' ng-required=" ' + trackedEntityFormAttributes[attId].mandatory + '"> ';
- }
- else if(trackedEntityFormAttributes[attId].valueType === "bool"){
- newInputField = '<select ' +
- ' name="' + fieldName + '"' +
- ' element-id="' + i + '"' +
- this.getAttributesAsString(attributes) +
- ' d2-focus-next-on-enter' +
- ' ng-model="selectedTei.' + attId + '" ' +
- ' ng-disabled="editingDisabled"' +
- ' ng-change="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
- ' ng-required=" ' + trackedEntityFormAttributes[attId].mandatory + '"> ' +
- ' <option value="">{{\'please_select\'| translate}}</option>' +
- ' <option value="false">{{\'no\'| translate}}</option>' +
- ' <option value="true">{{\'yes\'| translate}}</option>' +
- '</select> ';
- }
- else if(trackedEntityFormAttributes[attId].valueType === "date"){
- newInputField = '<input type="text" ' +
- ' name="' + fieldName + '"' +
- ' element-id="' + i + '"' +
- this.getAttributesAsString(attributes) +
- ' d2-focus-next-on-enter' +
- ' placeholder="{{dhis2CalendarFormat.keyDateFormat}}" ' +
- ' ng-model="selectedTei.' + attId + '" ' +
- ' ng-disabled="editingDisabled"' +
- ' max-date="' + attMaxDate + '"' + '\'' +
- ' d2-date' +
- ' d2-validation ' +
- ' blur-or-change="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
- ' ng-required=" ' + trackedEntityFormAttributes[attId].mandatory + '"> ';
- }
- else if(trackedEntityFormAttributes[attId].valueType === "trueOnly"){
- newInputField = '<input type="checkbox" ' +
- ' name="' + fieldName + '"' +
- ' element-id="' + i + '"' +
- this.getAttributesAsString(attributes) +
- ' d2-validation ' +
- ' d2-focus-next-on-enter' +
- ' ng-model="selectedTei.' + attId + '" ' +
- ' ng-disabled="editingDisabled"' +
- ' ng-change="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
- ' ng-required=" ' + trackedEntityFormAttributes[attId].mandatory + '"> ';
- }
- else if(trackedEntityFormAttributes[attId].valueType === "email"){
- newInputField = '<input type="email" ' +
- ' name="' + fieldName + '"' +
- ' element-id="' + i + '"' +
- this.getAttributesAsString(attributes) +
- ' d2-validation ' +
- ' d2-focus-next-on-enter' +
- ' ng-model="selectedTei.' + attId + '" ' +
- ' ng-disabled="editingDisabled"' +
- ' ng-blur="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
- ' ng-required=" ' + trackedEntityFormAttributes[attId].mandatory + '"> ';
- }
- else {
- newInputField = '<input type="text" ' +
- ' name="' + fieldName + '"' +
- ' element-id="' + i + '"' +
- this.getAttributesAsString(attributes) +
- ' d2-validation ' +
- ' d2-focus-next-on-enter' +
- ' ng-model="selectedTei.' + attId + '" ' +
- ' ng-disabled="editingDisabled"' +
- ' ng-blur="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
- ' ng-required=" ' + trackedEntityFormAttributes[attId].mandatory + '"> ';
- }
+ var att = trackedEntityFormAttributes[attId];
+
+ if( att ){
+
+ //check attribute type and generate corresponding angular input field
+ if(att.valueType === "number"){
+ newInputField = '<input type="text" ' +
+ ' name="' + fieldName + '"' +
+ ' element-id="' + i + '"' +
+ this.getAttributesAsString(attributes) +
+ ' d2-validation ' +
+ ' d2-number-validation ' +
+ ' d2-focus-next-on-enter' +
+ ' ng-model="selectedTei.' + attId + '" ' +
+ ' ng-disabled="editingDisabled"' +
+ ' ng-blur="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
+ ' ng-required=" ' + att.mandatory + '"> ';
+ }
+ else if(att.valueType === "optionSet"){
+ var optionSetId = att.optionSet.id;
+ newInputField = '<input type="text" ' +
+ ' name="' + fieldName + '"' +
+ ' element-id="' + i + '"' +
+ this.getAttributesAsString(attributes) +
+ ' d2-focus-next-on-enter' +
+ ' ng-model="selectedTei.' + attId + '" ' +
+ ' ng-disabled="editingDisabled"' +
+ ' d2-validation ' +
+ ' d2-typeahead-validation ' +
+ ' class="typeahead" ' +
+ ' placeholder=" " ' +
+ ' typeahead-editable="false" ' +
+ ' typeahead="option.name as option.name for option in optionSets.' + optionSetId + '.options | filter:$viewValue | limitTo:50"' +
+ ' typeahead-open-on-focus ' +
+ ' ng-blur="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
+ ' ng-required=" ' + att.mandatory + '"> ';
+ }
+ else if(att.valueType === "bool"){
+ newInputField = '<select ' +
+ ' name="' + fieldName + '"' +
+ ' element-id="' + i + '"' +
+ this.getAttributesAsString(attributes) +
+ ' d2-focus-next-on-enter' +
+ ' ng-model="selectedTei.' + attId + '" ' +
+ ' ng-disabled="editingDisabled"' +
+ ' ng-change="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
+ ' ng-required=" ' + att.mandatory + '"> ' +
+ ' <option value="">{{\'please_select\'| translate}}</option>' +
+ ' <option value="false">{{\'no\'| translate}}</option>' +
+ ' <option value="true">{{\'yes\'| translate}}</option>' +
+ '</select> ';
+ }
+ else if(att.valueType === "date"){
+ newInputField = '<input type="text" ' +
+ ' name="' + fieldName + '"' +
+ ' element-id="' + i + '"' +
+ this.getAttributesAsString(attributes) +
+ ' d2-focus-next-on-enter' +
+ ' placeholder="{{dhis2CalendarFormat.keyDateFormat}}" ' +
+ ' ng-model="selectedTei.' + attId + '" ' +
+ ' ng-disabled="editingDisabled"' +
+ ' max-date="' + attMaxDate + '"' + '\'' +
+ ' d2-date' +
+ ' d2-validation ' +
+ ' blur-or-change="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
+ ' ng-required=" ' + att.mandatory + '"> ';
+ }
+ else if(att.valueType === "trueOnly"){
+ newInputField = '<input type="checkbox" ' +
+ ' name="' + fieldName + '"' +
+ ' element-id="' + i + '"' +
+ this.getAttributesAsString(attributes) +
+ ' d2-validation ' +
+ ' d2-focus-next-on-enter' +
+ ' ng-model="selectedTei.' + attId + '" ' +
+ ' ng-disabled="editingDisabled"' +
+ ' ng-change="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
+ ' ng-required=" ' + att.mandatory + '"> ';
+ }
+ else if(att.valueType === "email"){
+ newInputField = '<input type="email" ' +
+ ' name="' + fieldName + '"' +
+ ' element-id="' + i + '"' +
+ this.getAttributesAsString(attributes) +
+ ' d2-validation ' +
+ ' d2-focus-next-on-enter' +
+ ' ng-model="selectedTei.' + attId + '" ' +
+ ' ng-disabled="editingDisabled"' +
+ ' ng-blur="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
+ ' ng-required=" ' + att.mandatory + '"> ';
+ }
+ else {
+ newInputField = '<input type="text" ' +
+ ' name="' + fieldName + '"' +
+ ' element-id="' + i + '"' +
+ this.getAttributesAsString(attributes) +
+ ' d2-validation ' +
+ ' d2-focus-next-on-enter' +
+ ' ng-model="selectedTei.' + attId + '" ' +
+ ' ng-disabled="editingDisabled"' +
+ ' ng-blur="validationAndSkipLogic(selectedTei,\'' + attId + '\')" ' +
+ ' ng-required=" ' + att.mandatory + '"> ';
+ }
+ }
+
}
if(attributes.hasOwnProperty('programid')){