=== 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-15 11:04:20 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/controllers.js 2015-06-17 11:50:16 +0000 @@ -7,7 +7,8 @@ //Controller for settings page .controller('MainController', - function($scope, + function($rootScope, + $scope, $modal, $timeout, $anchorScroll, @@ -29,11 +30,14 @@ CurrentSelection, ModalService, DialogService, - AuthorityService) { + AuthorityService, + TrackerRulesExecutionService) { //selected org unit $scope.selectedOrgUnit = ''; $scope.treeLoaded = false; - $scope.selectedSection = {id: 'ALL'}; + $scope.selectedSection = {id: 'ALL'}; + $rootScope.ruleeffects = {}; + $scope.hiddenFields = {}; $scope.calendarSetting = CalendarService.getSetting(); @@ -300,7 +304,7 @@ } $scope.eventFetched = true; }); - } + } }; $scope.jumpToPage = function(){ @@ -886,6 +890,73 @@ $scope.infiniteScroll.currentOptions += $scope.infiniteScroll.optionsToAdd; }; + //listen for rule effect changes + $scope.$on('ruleeffectsupdated', function(event, args) { + if($rootScope.ruleeffects[args.event]) { + //Establish which event was affected: + var affectedEvent = $scope.currentEvent; + //In most cases the updated effects apply to the current event. In case the affected event is not the current event, fetch the correct event to affect: + if(args.event !== affectedEvent.event) { + angular.forEach($scope.currentStageEvents, function(searchedEvent) { + if(searchedEvent.event === args.event) { + affectedEvent = searchedEvent; + } + }); + } + + angular.forEach($rootScope.ruleeffects[args.event], function(effect) { + if( effect.dataElement ) { + //in the data entry controller we only care about the "hidefield" actions + if(effect.action === "HIDEFIELD") { + if(effect.dataElement) { + if(effect.ineffect && affectedEvent[effect.dataElement.id]) { + //If a field is going to be hidden, but contains a value, we need to take action; + if(effect.content) { + //TODO: Alerts is going to be replaced with a proper display mecanism. + alert(effect.content); + } + else { + //TODO: Alerts is going to be replaced with a proper display mecanism. + alert($scope.prStDes[effect.dataElement.id].dataElement.formName + "Was blanked out and hidden by your last action"); + } + + //Blank out the value: + affectedEvent[effect.dataElement.id] = ""; + $scope.saveDatavalueForEvent($scope.prStDes[effect.dataElement.id],null,affectedEvent); + } + + $scope.hiddenFields[effect.dataElement.id] = effect.ineffect; + } + else { + $log.warn("ProgramRuleAction " + effect.id + " is of type HIDEFIELD, bot does not have a dataelement defined"); + } + } + } + }); + } + }); + + $scope.executeRules = function() { + $scope.eventsByStage = []; + $scope.eventsByStage[$scope.selectedProgramStage.id] = [$scope.currentEvent]; + TrackerRulesExecutionService.executeRules($scope.selectedProgram.id,$scope.currentEvent,$scope.eventsByStage,$scope.prStDes,null); + }; + + //check if field is hidden + $scope.isHidden = function(id) { + //In case the field contains a value, we cant hide it. + //If we hid a field with a value, it would falsely seem the user was aware that the value was entered in the UI. + if($scope.currentEvent[id]) { + return false; + } + else { + return $scope.hiddenFields[id]; + } + }; + + $scope.saveDatavalue = function(){ + $scope.executeRules(); + }; /*$scope.getInputNotifcationClass = function(id, custom, event){ var style = ""; if($scope.currentElement.id && $scope.currentElement.id === id){ === 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-06-16 12:17:07 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js 2015-06-17 11:50:16 +0000 @@ -497,7 +497,7 @@ function getProgramRuleVariables( programRuleVariables ) { - return getD2Objects( programRuleVariables, 'programRuleVariables', '../api/programRuleVariables', 'fields=id,name,displayName,programRuleVariableSourceType,program[id],dataElement[id]'); + return getD2Objects( programRuleVariables, 'programRuleVariables', '../api/programRuleVariables', 'fields=id,name,displayName,programRuleVariableSourceType,program[id],programStage[id],dataElement[id]'); } function getD2MetaObject( programs, objNames, url, filter ) === 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-06-16 09:57:57 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js 2015-06-17 11:50:16 +0000 @@ -399,6 +399,80 @@ }; }) + /* Returns a function for getting rules for a specific program */ +.factory('TrackerRulesFactory', function($q,$rootScope,ECStorageService){ + return{ + getOldProgramStageRules :function(programUid, programstageUid) { + var rules = this.getProgramRules(programUid); + + //Only keep the rules actually matching the program stage we are in, or rules with no program stage defined. + var programStageRules = []; + angular.forEach(rules, function(rule) { + if(rule.programstage_uid == null || rule.programstage_uid == "" || rule.programstage_uid == programstageUid) { + programStageRules.push(rule); + } + }); + + return programStageRules; + }, + + getProgramStageRules : function(programUid, programStageUid){ + var def = $q.defer(); + + ECStorageService.currentStore.open().done(function(){ + ECStorageService.currentStore.getAll('programRules').done(function(rules){ + //The array will ultimately be returned to the caller. + var programRulesArray = []; + //Loop through and add the rules belonging to this program and program stage + angular.forEach(rules, function(rule){ + if(rule.program.id == programUid) { + if(!rule.programStage || !rule.programStage.id || rule.programStage.id == programStageUid) { + programRulesArray.push(rule); + } + } + }); + + $rootScope.$apply(function(){ + def.resolve(programRulesArray); + }); + }); + }); + + return def.promise; + } + }; +}) + +/* Returns user defined variable names and their corresponding UIDs and types for a specific program */ +.factory('TrackerRuleVariableFactory', function($rootScope, $q, ECStorageService){ + return{ + getProgramRuleVariables : function(programUid){ + var def = $q.defer(); + + ECStorageService.currentStore.open().done(function(){ + + ECStorageService.currentStore.getAll('programRuleVariables').done(function(variables){ + + //The array will ultimately be returned to the caller. + var programRuleVariablesArray = []; + //Loop through and add the variables belonging to this program + angular.forEach(variables, function(variable){ + if(variable.program.id == programUid) { + programRuleVariablesArray.push(variable); + } + }); + + $rootScope.$apply(function(){ + def.resolve(programRuleVariablesArray); + }); + }); + }); + + return def.promise; + } + }; +}) + /* service for dealing with events */ .service('DHIS2EventService', function(){ return { === 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-15 11:04:20 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/defaultForm.html 2015-06-17 11:50:16 +0000 @@ -68,7 +68,7 @@ - + {{eventGridColumn.name}}* @@ -81,6 +81,7 @@ ng-required={{eventGridColumn.compulsory}} name="foo" input-field-id={{eventGridColumn.id}} + on-select="saveDatavalue()" class='form-control'> {{$select.selected.name || $select.selected}} {{'no_value' | translate}}
@@ -103,6 +105,7 @@ {{option.name}}
@@ -118,6 +121,7 @@ ng-required={{eventGridColumn.compulsory}} name="foo" input-field-id={{eventGridColumn.id}} + ng-blur="saveDatavalue()" class="form-control"/>
@@ -127,6 +131,7 @@ ng-required={{eventGridColumn.compulsory}} name="foo" input-field-id={{eventGridColumn.id}} + ng-blur="saveDatavalue()" class="form-control"> @@ -136,6 +141,7 @@ ng-required={{eventGridColumn.compulsory}} name="foo" input-field-id={{eventGridColumn.id}} + ng-blur="saveDatavalue()" class="form-control"/>
@@ -144,6 +150,7 @@ ng-required={{eventGridColumn.compulsory}} name="foo" input-field-id={{eventGridColumn.id}} + ng-change="saveDatavalue()" class="form-control"> @@ -160,6 +167,7 @@ ng-required={{eventGridColumn.compulsory}} name="foo" input-field-id={{eventGridColumn.id}} + blur-or-change="saveDatavalue()" class="form-control">
@@ -167,7 +175,8 @@ ng-model="currentEvent[eventGridColumn.id]" ng-required={{eventGridColumn.compulsory}} name="foo" - input-field-id={{eventGridColumn.id}} /> + input-field-id={{eventGridColumn.id}} + ng-change="saveDatavalue()" />
@@ -269,7 +279,7 @@ - + {{prStDes[de.dataElement.id].dataElement.formName ? prStDes[de.dataElement.id].dataElement.formName : prStDes[de.dataElement.id].dataElement.name}}* @@ -280,7 +290,8 @@ theme="select2" ng-required={{prStDes[de.dataElement.id].compulsory}} ng-app=""name="foo" - ng-app=""input-field-id={{de.dataElement.id}} + ng-app=""input-field-id={{de.dataElement.id}} + on-select="saveDataValue()" class='form-control'> {{$select.selected.name || $select.selected}} {{'no_value' | translate}}
@@ -303,6 +315,7 @@ {{option.name}}
@@ -318,6 +331,7 @@ ng-required={{prStDes[de.dataElement.id].compulsory}} name="foo" input-field-id={{de.dataElement.id}} + ng-blur="saveDatavalue()" class="form-control"/>
@@ -327,6 +341,7 @@ ng-required={{prStDes[de.dataElement.id].compulsory}} name="foo" input-field-id={{de.dataElement.id}} + ng-blur="saveDatavalue()" class="form-control"> @@ -336,6 +351,7 @@ ng-required={{prStDes[de.dataElement.id].compulsory}} name="foo" input-field-id={{de.dataElement.id}} + ng-blur="saveDatavalue()" class="form-control">
@@ -344,6 +360,7 @@ ng-required={{prStDes[de.dataElement.id].compulsory}} name="foo" input-field-id={{de.dataElement.id}} + ng-change="saveDatavalue()" class="form-control"> @@ -360,6 +377,7 @@ ng-required={{prStDes[de.dataElement.id].compulsory}} name="foo" input-field-id={{de.dataElement.id}} + blur-or-change="saveDatavalue()" class="form-control"/>
@@ -367,7 +385,8 @@ ng-model="currentEvent[de.dataElement.id]" ng-required={{prStDes[de.dataElement.id].compulsory}} name="foo" - input-field-id={{de.dataElement.id}}/> + input-field-id={{de.dataElement.id}} + ng-change="saveDatavalue()" />
=== 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-17 08:54:51 +0000 +++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js 2015-06-17 11:50:16 +0000 @@ -280,7 +280,7 @@ ' style="width:100%;" ' + ' input-field-id="' + fieldId + '"' + ' ng-class="{{getInputNotifcationClass(prStDes.' + fieldId + '.dataElement.id, true)}}" ' + - ' ng-disabled="selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent[uid]==\'uid\' || currentEvent.editingNotAllowed"' + + ' ng-disabled="isHidden(prStDes.' + fieldId + '.dataElement.id) || selectedEnrollment.status===\'CANCELLED\' || selectedEnrollment.status===\'COMPLETED\' || currentEvent[uid]==\'uid\' || currentEvent.editingNotAllowed"' + ' ng-required="{{prStDes.' + fieldId + '.compulsory}}" '; if (prStDe && prStDe.dataElement && prStDe.dataElement.type) {