(function() { 'use strict'; var app = angular.module('myforms'); var templatePath = modulesSharedResourcesUrl + 'Modules/MyForms/Views/'; //a directive show all the templates available to complete for the user app.directive('myAvailableFormTemplates', ['myFormsDataContext', 'myFormsConfig', 'myUsersDataContext', 'myFormsService', '$rootScope', 'user', function (myFormsDataContext, config, myUsersDataContext, myFormsService, $rootScope, user) { return { restrict: 'E', scope: { publicOnly: '=', //just show public templates onFormSelected: '&', //tell the directive host when a form template has been selected noUser: '=', }, templateUrl: templatePath + 'myavailableforms.html', link: link }; function link(scope, elem, attrs) { scope.loadedyet = false; scope.myAvailibleFormsLoaded = false; scope.formIconBlank = config.formIconBlank; scope.orderByPredicate = '-lastPublishedOn'; scope.orderByChoice = 'Order by date'; function getUser() { user.getProfile().then(function(user) { scope.user = user; //get all forms available to the user getMyFormTemplates(); }); } if (typeof mobile != 'undefined') { scope.isMobile = mobile; } if (!scope.noUser) { getUser(); } else { getMyFormTemplates(); } //user selected a template to complete scope.completeForm = function (simpleFormTemplate) { var selectedForm; if (simpleFormTemplate.inProgress) { myFormsDataContext.getForm(simpleFormTemplate.inProgressFormId).then(function (theForm) { // handleChoiceQuestionsOnLoading(theForm); selectedForm = theForm; scope.onFormSelected()(selectedForm); }); } else { myFormsDataContext.getFormTemplate(simpleFormTemplate.id).then(function (formTemplate) { if (scope.user) { formTemplate.externalId = scope.user.id; } selectedForm = myFormsService.createFormFromTemplate(formTemplate); //$location.path('/completeform/' + selectedForm.formTemplateId); scope.onFormSelected()(selectedForm); }); } } //get all the form templates available to the user function getMyFormTemplates() { //if we are showing only public forms call the appropriate api if (scope.publicOnly) { myFormsDataContext.getPublicFormTemplates().then(function(formTemplates) { scope.formTemplates = formTemplates; }); } //we need to get all the forms available to the organisations that the user is a member of else { if (scope.user) { myFormsDataContext.getAvailableTemplates(scope.user.id).then(function (formTemplates) { scope.formTemplates = formTemplates; scope.myAvailibleFormsLoaded = true; }); } else { myFormsDataContext.getAllAvailableTemplates().then(function (formTemplates) { scope.formTemplates = formTemplates; scope.myAvailibleFormsLoaded = true; }); } } } } }]); //a directive show all the activities available for the user to log entries against app.directive('myAvailableActivities', ['myFormsDataContext', 'myFormsConfig', 'myUsersDataContext', 'myFormsService', '$rootScope', 'user', '$modal', function (myFormsDataContext, config, myUsersDataContext, myFormsService, $rootScope, user, $modal) { return { restrict: 'E', scope: { publicOnly: '=', //just show public templates onFormSelected: '&', //tell the directive host when a form template has been selected noUser: '=', onActivityEntriesRequested: '&' //tell the directive host when an activity's entries have been fetched }, templateUrl: templatePath + 'myavailableactivities.html', link: link }; function link(scope, elem, attrs) { scope.loadedyet = false; scope.myAvailibleFormsLoaded = false; scope.formIconBlank = config.formIconBlank; scope.orderByPredicate = '-lastPublishedOn'; scope.orderByChoice = 'Order by date'; function getUser() { user.getProfile().then(function(user) { scope.user = user; //get all forms available to the user getMyFormTemplates(); }); } if (typeof mobile != 'undefined') { scope.isMobile = mobile; } if (!scope.noUser) { getUser(); } else { getMyFormTemplates(); } //user selected an activity template to complete scope.completeActivity = function(simpleFormTemplate) { var selectedForm; if (simpleFormTemplate.inProgress) { myFormsDataContext.getForm(simpleFormTemplate.inProgressFormId).then(function(theForm) { //handleChoiceQuestionsOnLoading(theForm); selectedForm = theForm; scope.onFormSelected()(selectedForm); $modal.open({ templateUrl: 'app/activities/completeactivity.html', controller: completeActivityController, size: 'sm', backdrop: 'static', resolve: { selectedForm: function () { return selectedForm; } } }); }); } else { myFormsDataContext.getFormTemplate(simpleFormTemplate.id).then(function(formTemplate) { if (scope.user) { formTemplate.externalId = scope.user.id; } selectedForm = myFormsService.createFormFromTemplate(formTemplate); scope.onFormSelected()(selectedForm); $modal.open({ templateUrl: 'app/activities/completeactivity.html', controller: completeActivityController, size: 'sm', backdrop: 'static', resolve: { selectedForm: function () { return selectedForm; } } }); }); } } var completeActivityController = function (common, $scope, $modalInstance, selectedForm) { scope.selectedForm = selectedForm; //close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } //user selected an activity to view entries for scope.viewActivityEntries = function (simpleFormTemplate) { myFormsDataContext.getActivityEntries(simpleFormTemplate.id).then(function (entries) { scope.onActivityEntriesRequested()(simpleFormTemplate, entries); }); }; //get all the activity templates allocated to the user either by individual or group allocation function getMyFormTemplates() { if (scope.user) { myFormsDataContext.getAvailableActivityTemplates(scope.user.id).then(function (formTemplates) { scope.formTemplates = formTemplates; scope.myAvailibleFormsLoaded = true; }); } else { myFormsDataContext.getAllAvailableTemplates().then(function(formTemplates) { scope.formTemplates = formTemplates; scope.myAvailibleFormsLoaded = true; }); } } } }]); //a directive show all the forms completed by a user app.directive('myCompletedForms', ['myFormsDataContext', 'myFormsConfig', 'myUsersDataContext', 'myFormsService', '$rootScope', 'user', '$location', function (myFormsDataContext, config, myUsersDataContext, myFormsService, $rootScope, user, $location) { return { restrict: 'E', scope: { onFormSelected: '&', //tell the directive host when a form template has been selected noUser: '=' }, templateUrl: templatePath + 'mycompletedforms.html', link: link }; function link(scope, elem, attrs) { scope.loadedyet = false; scope.myAvailibleFormsLoaded = false; scope.formIconBlank = config.formIconBlank; scope.orderByPredicate = '-lastPublishedOn'; scope.orderByChoice = 'Order by date'; function getUser() { user.getProfile().then(function (user) { scope.user = user; //get all forms completed by the user getMyCompletedForms(); }); } if (typeof mobile != 'undefined') { scope.isMobile = mobile; } if (!scope.noUser) { getUser(); } else { getMyCompletedForms(); } //user selected a completed form to view scope.viewForm = function(formId) { $location.path('viewform/' + formId); }; ////user selected a completed form to continue completing //scope.continueForm = function (formId) { // $location.path('completeform/' + formId); //}; //user selected a template to continue scope.continueForm = function (simpleFormTemplate) { var selectedForm; if (simpleFormTemplate.inProgress) { myFormsDataContext.getForm(simpleFormTemplate.id).then(function (theForm) { // handleChoiceQuestionsOnLoading(theForm); selectedForm = theForm; scope.onFormSelected()(selectedForm); }); } else { myFormsDataContext.getFormTemplate(simpleFormTemplate.id).then(function (formTemplate) { if (scope.user) { formTemplate.externalId = scope.user.id; } selectedForm = myFormsService.createFormFromTemplate(formTemplate); //$location.path('/completeform/' + selectedForm.formTemplateId); scope.onFormSelected()(selectedForm); }); } } //get all the forms completed by the user function getMyCompletedForms() { if (scope.user) { myFormsDataContext.getForms(scope.user.id).then(function (forms) { setStatuses(forms); scope.formTemplates = forms; scope.myAvailibleFormsLoaded = true; }); } else { myFormsDataContext.getForms().then(function (forms) { setStatuses(forms); scope.formTemplates = forms; scope.myAvailibleFormsLoaded = true; }); } } function setStatuses(forms) { for (var i in forms) { forms[i].status = forms[i].inProgress ? "InProgress" : "Completed"; } } } }]); //a directive that renders a form for completion app.directive('formRenderer', ['myFormsDataContext', '$filter', 'user', 'myBadgesAdminDataContext', function (myFormsDataContext, $filter, user, myBadgesAdminDataContext) { return { restrict: 'E', scope: { selectedForm: '=', //the form to render formId: '=', hideSave: '=', hideCancel:'=', hideComplete:'=', onFormCreated: '&', //the form has been created onFormUpdated: '&', //the form has been updated onCancel: '&', formValidation: '=', externalId: '=', noUser: '=', isTaskView: '=' }, templateUrl: templatePath + 'formrenderer.html', link: link }; function link(scope, elem, attrs) { function getUser() { user.getProfile().then(function (user) { scope.user = user; }); } if (scope.selectedForm) { handleChoiceQuestionsOnLoading(scope.selectedForm); //we need to do a bit of extra work to get choice questions to work correctly if (!scope.noUser) { getUser(); } } //when a form is selected get the form details scope.$watch('formId', function() { if (scope.formId) { myFormsDataContext.getForm(scope.formId).then(function(theForm) { handleChoiceQuestionsOnLoading(theForm); scope.selectedForm = theForm; }); } }); scope.$watchCollection('outerForm', function () { scope.formValidation = scope.outerForm.$invalid; }); scope.$on('saveFormResponse', function (event, args) { scope.submitForm(args.isComplete, args.isHosted); }); //cancel filling in the form scope.cancel = function () { if (scope.onCancel) scope.onCancel()(scope.selectedForm); } //workaround to make ie perform properly on 'selectList' class elements (it selects very slowly otherwise) scope.bruteForceSelect = function () { var selectLists = document.querySelectorAll(".selectList"); for (var x = 0; x < selectLists.length; x++) { selectLists[x].parentNode.insertBefore(selectLists[x], selectLists[x]); } }; //submit the form scope.submitForm = function(isFormComplete, isFormHosted) { scope.isSaving = true; scope.selectedForm.isHosted = isFormHosted; //fool about with the choice questions so the data is in the correct format for the myforms API handleAnswerFormatsOnSaving(scope.selectedForm); scope.selectedForm.isFormComplete = isFormComplete; if (!scope.noUser) { scope.selectedForm.externalId = scope.user.id; } else { scope.selectedForm.externalId = scope.externalId; } if (scope.selectedForm.formId) { //edit the form myFormsDataContext.editForm(scope.selectedForm.formId, scope.selectedForm).then(function(result) { updateOrCreateForm(isFormComplete, scope.selectedForm, scope.selectedForm); }); } else { //create a new form myFormsDataContext.createForm(scope.selectedForm).then(function(result) { scope.selectedForm.formId = result.formId; updateOrCreateForm(isFormComplete, scope.selectedForm, result); }); } }; //call the passed in functions when the form is created or updated function updateOrCreateForm(isFormComplete, selectedForm, result) { console.log(result); if (isFormComplete) { scope.onFormCreated()(selectedForm, result); if (result.formRewards) { if (result.formRewards.issueRewards) { issueBadges(result); } } } else scope.onFormUpdated()(selectedForm, result); } /* * Create issuedbadge records for each of the form template reward record badge ids, * Then bake and issue the badges to the form completer */ function issueBadges(completedForm) { if (completedForm.formRewards != null) { //For each of the badge ids on the form template create an issuedbadge record var badgeTemplateIds = []; for (var i in completedForm.formRewards.externalRewardIds) { badgeTemplateIds.push(completedForm.formRewards.externalRewardIds[i]); } for (var b in badgeTemplateIds) { //This creates an issuedbadge record and immediately bakes it myBadgesAdminDataContext.issueBadgeThenBake({ email: completedForm.formRewards.rewarderEmail, name: '', badgeTemplateId: badgeTemplateIds[b], createdBy: completedForm.formRewards.rewardee, status: 0 // 0 - Not baked 1 - Baked }).then(function(data) { //done }); //myBadgesAdminDataContext.issueBadge({ // email: completedForm.formRewards.rewarderEmail, // name: '', // badgeTemplateId: badgeTemplateIds[b], // createdBy: completedForm.formRewards.rewardee, // status: 0 // 0 - Not baked 1 - Baked //}).then(function (data) { // //Now we have an issuedbadge record for form template reward, bake and issue the badge // myBadgesAdminDataContext.bakeAndIssue([data.id], completedForm.formRewards.rewarderName).then(function () { // //console.log('A badge was issued to you!'); // }); //}); } } } //to get the choice quetion response data in the form data into the format expected by MyForms we need to do some work function handleAnswerFormatsOnSaving(theForm) { //loop through the questionanswers (a question and answer pair) for (var i = 0; i < theForm.sections[0].questionAnswers.length; i++) { var questionAnswers = theForm.sections[0].questionAnswers[i]; //only for choice questions if (questionAnswers.question.isChoiceQuestion) { //create a choice array for the answer questionAnswers.answer.choices = []; //loop through the choices in the question for (var j = 0; j < questionAnswers.question.choices.length; j++) { //create the choice object var choice = { choice: questionAnswers.question.choices[j].choice, choiceId: questionAnswers.question.choices[j].choiceId, isChosen: false }; //if the choice has already been selected (i.e. we are editing the form with existing answers) set its flag if (questionAnswers.answer && questionAnswers.answer.chosen) { if (questionAnswers.answer.chosen.choiceId === questionAnswers.question.choices[j].choiceId) choice.isChosen = true; } //add the choice to the answer choice array if (choice.choiceId !== -1) questionAnswers.answer.choices.push(choice); } } //do a similar thing for checklist questions else if (questionAnswers.question.isCheckListQuestion) { if(questionAnswers.answer.chosen != null){ for (j = 0; j < questionAnswers.answer.chosen.length; j++) { questionAnswers.answer.chosen[j].isChosen = true; } questionAnswers.answer.choices = questionAnswers.answer.chosen; } if (questionAnswers.question.choices) { for (var j = 0; j < questionAnswers.question.choices.length; j++) { var isChosen = false; if (questionAnswers.answer.choices) { for (var k = 0; k < questionAnswers.answer.choices.length; k++) { if (questionAnswers.answer.choices[k].choiceId === questionAnswers.question.choices[j].choiceId) { isChosen = true; break; } } if (!isChosen) { questionAnswers.answer.choices.push( { choice: questionAnswers.question.choices[j].choice, choiceId: questionAnswers.question.choices[j].choiceId, isChosen: false }); } } } } } //Convert date and time to string to strip timezone info else if (questionAnswers.question.isDateQuestion) { questionAnswers.answer.dateAnswer = $filter('date')(questionAnswers.answer.dateAnswer, "dd MMMM yyyy"); } else if (questionAnswers.question.isTimeQuestion) { var hours = $filter('date')(questionAnswers.answer.timeAnswer, "HH"); var mins = $filter('date')(questionAnswers.answer.timeAnswer, "mm"); var timeAsDate = new Date(); timeAsDate.setUTCHours(hours); timeAsDate.setUTCMinutes(mins); questionAnswers.answer.timeAnswer = timeAsDate; } } } function handleChoiceQuestionsOnLoading(theForm) { if (theForm.sections[0].questionAnswers) { for (var i = 0; i < theForm.sections[0].questionAnswers.length; i++) { var questionAnswers = theForm.sections[0].questionAnswers[i]; if (questionAnswers.question.isDateQuestion) { questionAnswers.answer.dateAnswer = $filter('date')(questionAnswers.answer.dateAnswer, "dd MMMM yyyy"); } if (questionAnswers.question.isTimeQuestion) { if (questionAnswers.answer.timeAnswer == null || questionAnswers.answer.timeAnswer == undefined) questionAnswers.answer.timeAnswer = new Date(); else { var m = moment(questionAnswers.answer.timeAnswer); var hours = m.hours(); var mins = m.minutes(); var timeAsDate = new Date(); timeAsDate.setHours(hours); timeAsDate.setMinutes(mins); questionAnswers.answer.timeAnswer = timeAsDate; } } if (questionAnswers.question.isChoiceQuestion) { if (questionAnswers.answer.choices) { for (var j = 0; j < questionAnswers.answer.choices.length; j++) { if (questionAnswers.answer.choices[j].isChosen) { questionAnswers.answer.chosen = { choice: questionAnswers.answer.choices[j].choice, choiceId: questionAnswers.answer.choices[j].choiceId }; break; } } } } if (questionAnswers.question.isCheckListQuestion) { questionAnswers.answer.chosen = []; if(questionAnswers.answer.choices){ for (var k = 0; k < questionAnswers.answer.choices.length; k++) { if (questionAnswers.answer.choices[k].isChosen) questionAnswers.answer.chosen.push(questionAnswers.answer.choices[k]); } } } } } } } }]); //a directive that renders an activity form for completion app.directive('activityFormRenderer', ['myFormsDataContext', '$filter', 'user', 'myBadgesAdminDataContext', function (myFormsDataContext, $filter, user, myBadgesAdminDataContext) { return { restrict: 'E', scope: { selectedForm: '=', //the activity form to render formId: '=', hideSave: '=', hideCancel: '=', hideComplete: '=', onFormCreated: '&', //the activity form has been created onFormUpdated: '&', //the activity form has been updated onCancelAdd: '&', onCancelUpdate: '&', formValidation: '=', externalId: '=', noUser: '=', isTaskView: '=', entryMode: '=' }, templateUrl: templatePath + 'activityformrenderer.html', link: link }; function link(scope, elem, attrs) { function getUser() { user.getProfile().then(function (user) { scope.user = user; }); } if (scope.selectedForm) { handleChoiceQuestionsOnLoading(scope.selectedForm); //we need to do a bit of extra work to get choice questions to work correctly if (!scope.noUser) { getUser(); } } //when a form is selected get the form details scope.$watch('formId', function () { if (scope.formId) { myFormsDataContext.getForm(scope.formId).then(function (theForm) { handleChoiceQuestionsOnLoading(theForm); scope.selectedForm = theForm; }); } }); scope.$watchCollection('outerForm', function () { scope.formValidation = scope.outerForm.$invalid; }); scope.$on('saveFormResponse', function (event, args) { scope.submitForm(args.isComplete, args.isHosted); }); //cancel adding the entry scope.cancelEntryAdd = function () { scope.isSaving = true; if (scope.onCancelAdd) scope.onCancelAdd()('/viewactivities'); //(scope.selectedForm); } //cancel editing in the entry scope.cancelEntryUpdate = function () { scope.isSaving = true; if (scope.onCancelUpdate) scope.onCancelUpdate()('/viewactivities'); //(scope.selectedForm); } //workaround to make ie perform properly on 'selectList' class elements (it selects very slowly otherwise) scope.bruteForceSelect = function () { var selectLists = document.querySelectorAll(".selectList"); for (var x = 0; x < selectLists.length; x++) { selectLists[x].parentNode.insertBefore(selectLists[x], selectLists[x]); } }; //submit the form scope.submitForm = function (isCreate, isFormHosted) { scope.isSaving = true; scope.selectedForm.isHosted = isFormHosted; //fool about with the choice questions so the data is in the correct format for the myforms API handleAnswerFormatsOnSaving(scope.selectedForm); scope.selectedForm.isFormComplete = true; if (!scope.noUser) { scope.selectedForm.externalId = scope.user.id; } else { scope.selectedForm.externalId = scope.externalId; } if (scope.selectedForm.formId) { //edit the form myFormsDataContext.editForm(scope.selectedForm.formId, scope.selectedForm).then(function (result) { updateOrCreateForm(isCreate, scope.selectedForm, scope.selectedForm); }); } else { //create a new form myFormsDataContext.createForm(scope.selectedForm).then(function (result) { scope.selectedForm.formId = result.formId; updateOrCreateForm(isCreate, scope.selectedForm, result); }); } }; //scope.setCurrentTime = function (answer) { // if (answer == null || answer == undefined) // return answer = moment().toString(); // else { // var m = moment(answer); // var hours = m.hours(); // var mins = m.minutes(); // var timeAsDate = new Date(); // timeAsDate.setHours(hours); // timeAsDate.setMinutes(mins); // answer = timeAsDate; // $scope.timezonedate = timeAsDate; // return answer; // } //} //call the passed in functions when the form is created or updated function updateOrCreateForm(isCreate, selectedForm, result) { console.log(result); if (isCreate) { scope.onFormCreated()(selectedForm, result); if (result.formRewards) { if (result.formRewards.issueRewards) { issueBadges(result); } } } else scope.onFormUpdated()(selectedForm, result); } /* * Create issuedbadge records for each of the form template reward record badge ids, * Then bake and issue the badges to the form completer */ function issueBadges(completedForm) { if (completedForm.formRewards != null) { //For each of the badge ids on the form template create an issuedbadge record var badgeTemplateIds = []; for (var i in completedForm.formRewards.externalRewardIds) { badgeTemplateIds.push(completedForm.formRewards.externalRewardIds[i]); } for (var b in badgeTemplateIds) { //This creates an issuedbadge record and immediately bakes it myBadgesAdminDataContext.issueBadgeThenBake({ email: completedForm.formRewards.rewarderEmail, name: '', badgeTemplateId: badgeTemplateIds[b], createdBy: completedForm.formRewards.rewardee, status: 0 // 0 - Not baked 1 - Baked }).then(function (data) { //done }); //myBadgesAdminDataContext.issueBadge({ // email: completedForm.formRewards.rewarderEmail, // name: '', // badgeTemplateId: badgeTemplateIds[b], // createdBy: completedForm.formRewards.rewardee, // status: 0 // 0 - Not baked 1 - Baked //}).then(function (data) { // //Now we have an issuedbadge record for form template reward, bake and issue the badge // myBadgesAdminDataContext.bakeAndIssue([data.id], completedForm.formRewards.rewarderName).then(function () { // //console.log('A badge was issued to you!'); // }); //}); } } } //to get the choice quetion response data in the form data into the format expected by MyForms we need to do some work function handleAnswerFormatsOnSaving(theForm) { //loop through the questionanswers (a question and answer pair) for (var i = 0; i < theForm.sections[0].questionAnswers.length; i++) { var questionAnswers = theForm.sections[0].questionAnswers[i]; //only for choice questions if (questionAnswers.question.isChoiceQuestion) { //create a choice array for the answer var choicesArray = []; //loop through the choices in the question for (var j = 0; j < questionAnswers.question.choices.length; j++) { //create the choice object var choice = { choice: questionAnswers.question.choices[j].choice, choiceId: questionAnswers.question.choices[j].choiceId, isChosen: false, }; //if the choice has already been selected (i.e. we are editing the form with existing answers) set its flag if (questionAnswers.answer && questionAnswers.answer.chosen) { if (questionAnswers.answer.chosen.choiceId === questionAnswers.question.choices[j].choiceId) { choice.isChosen = true; if (questionAnswers.answer.choices != null) { var choiceAnswer = $filter('filter')(questionAnswers.answer.choices, {choiceId: questionAnswers.answer.chosen.choiceId})[0]; // var choiceAnswer = questionAnswers.answer.choices.find(function(c) { // return c.choiceId == questionAnswers.answer.chosen.choiceId; // }); if (choiceAnswer != null) { choice.choiceAnswerId = choiceAnswer.choiceAnswerId; } } } } //add the choice to the answer choice array if (choice.choiceId !== -1) choicesArray.push(choice); } questionAnswers.answer.choices = choicesArray; } //do a similar thing for checklist questions else if (questionAnswers.question.isCheckListQuestion) { for (j = 0; j < questionAnswers.answer.chosen.length; j++) { questionAnswers.answer.chosen[j].isChosen = true; } questionAnswers.answer.choices = questionAnswers.answer.chosen; for (var j = 0; j < questionAnswers.question.choices.length; j++) { var isChosen = false; for (var k = 0; k < questionAnswers.answer.choices.length; k++) { if (questionAnswers.answer.choices[k].choiceId === questionAnswers.question.choices[j].choiceId) { isChosen = true; break; } } if (!isChosen) { questionAnswers.answer.choices.push( { choice: questionAnswers.question.choices[j].choice, choiceId: questionAnswers.question.choices[j].choiceId, isChosen: false }); } } } //convert date and time to string to strip timezone information else if (questionAnswers.question.isDateQuestion) { questionAnswers.answer.dateAnswer = $filter('date')(questionAnswers.answer.dateAnswer, "dd MMMM yyyy"); } else if (questionAnswers.question.isTimeQuestion) { var hours = $filter('date')(questionAnswers.answer.timeAnswer, "HH"); var mins = $filter('date')(questionAnswers.answer.timeAnswer, "mm"); var timeAsDate = new Date(); timeAsDate.setUTCHours(hours); timeAsDate.setUTCMinutes(mins); questionAnswers.answer.timeAnswer = timeAsDate; } } } function handleChoiceQuestionsOnLoading(theForm) { if (theForm.sections[0].questionAnswers) { for (var i = 0; i < theForm.sections[0].questionAnswers.length; i++) { var questionAnswers = theForm.sections[0].questionAnswers[i]; if (questionAnswers.question.isDateQuestion) { questionAnswers.answer.dateAnswer = $filter('date')(questionAnswers.answer.dateAnswer, "dd MMMM yyyy"); } if (questionAnswers.question.isTimeQuestion) { if (questionAnswers.answer.timeAnswer == null || questionAnswers.answer.timeAnswer == undefined) questionAnswers.answer.timeAnswer = new Date(); else { var m = moment(questionAnswers.answer.timeAnswer); var hours = m.hours(); var mins = m.minutes(); var timeAsDate = new Date(); timeAsDate.setHours(hours); timeAsDate.setMinutes(mins); questionAnswers.answer.timeAnswer = timeAsDate; } } if (!questionAnswers.answer.timeAnswer) { questionAnswers.answer.timeAnswer = new Date(); } if (questionAnswers.question.isChoiceQuestion) { if (questionAnswers.answer.choices) { for (var j = 0; j < questionAnswers.answer.choices.length; j++) { if (questionAnswers.answer.choices[j].isChosen) { questionAnswers.answer.chosen = { choice: questionAnswers.answer.choices[j].choice, choiceId: questionAnswers.answer.choices[j].choiceId }; break; } } } } } if (questionAnswers != null && questionAnswers.question != null && questionAnswers.question.isCheckListQuestion) { questionAnswers.answer.chosen = []; if (questionAnswers.answer.choices) { for (var k = 0; k < questionAnswers.answer.choices.length; k++) { if (questionAnswers.answer.choices[k].isChosen) questionAnswers.answer.chosen.push(questionAnswers.answer.choices[k]); } } } } } } }]); //a directive that renders an activity form for completion app.directive('activityEntriesRenderer', ['myFormsDataContext', 'myFormsService', '$modal', '$rootScope', 'user', '$filter', function (myFormsDataContext, myFormsService, $modal, $rootScope, user, $filter) { return { restrict: 'E', scope: { onCancel: '&', externalId: '=', noUser: '=', isTaskView: '=', onEditSelectedEntry: '&', onDeleteSelectedEntry: '&', activityEntries: '=', onFormSelected: '&' }, templateUrl: templatePath + 'activityentriesrenderer.html', link: link }; function link(scope) { scope.startDate = $filter('date')(moment().startOf('year').toDate(), "yyyy-MM-dd"); scope.endDate = $filter('date')(moment().endOf('year').add(1, 'days').toDate(), "yyyy-MM-dd"); scope.date = { startDate: scope.startDate, endDate: scope.endDate }; scope.orderByPredicate = '-activityEntry.userFullName'; scope.datePickerOptions = { locale: { separator: ' - ' }, eventHandlers: { 'apply.daterangepicker': function (ev, picker) { var start = $filter('date')(ev.model.startDate._d, "yyyy-MM-dd"); var end = $filter('date')(ev.model.endDate._d, "yyyy-MM-dd"); } } } //cancel viewing activity entries scope.cancel = function() { scope.onCancel()(); }; $rootScope.$on('updateForms', function (event, args) { myFormsDataContext.getActivityEntries(args.formId).then(function (entries) { scope.activityEntries = entries; }); }); scope.myActivityEntriesLoaded = true; scope.selectedForm = myFormsDataContext.getCurrentForm(); if (scope.activityEntries == null) { scope.activityEntries = myFormsDataContext.getCurrentActivityEntries(); } var completeActivityController = function (common, $scope, $modalInstance, selectedForm, template) { //scope.selectedForm = selectedForm; myFormsDataContext.getFormTemplate(template.id).then(function (formTemplate) { scope.selectedForm = myFormsService.createFormFromTemplate(formTemplate, selectedForm.id); }); //close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } //user selected an activity entry to edit scope.editEntry = function (simpleFormTemplate) { var selectedForm; myFormsDataContext.getForm(simpleFormTemplate.id).then(function (theForm) { selectedForm = theForm; scope.onFormSelected()(selectedForm); $modal.open({ templateUrl: 'app/activities/completeactivity.html', controller: completeActivityController, size: 'sm', backdrop: 'static', resolve: { selectedForm: function() { return selectedForm; }, template: function(){ return simpleFormTemplate; } } }); }); }; //user selected an activity entry to edit scope.deleteEntry = function (simpleForm) { myFormsDataContext.deleteForm(simpleForm.id).then(function () { myFormsDataContext.getActivityEntries(scope.selectedForm.id).then(function(entries){ scope.activityEntries = entries; }) scope.onDeleteSelectedEntry()(simpleForm); }); }; scope.getUserDetails = function (entry) { user.getUserDetail(entry.createdBy).then(function (data) { entry.user = data[0]; entry.user.fullName = entry.user != null ? entry.user.firstName + ' ' + entry.user.lastName : ""; entry.userFullName = entry.user.fullName; }); } function valueFunction(entry, fieldId) { for (i in entry.values) { if (fieldId == entry.values[i].fieldId) { console.log(entry.values[i].value) return entry.values[i].value; } } } scope.sortList = function (fieldId, reverse) { if (!reverse) { scope.activityEntries.entries.sort(function (a, b) { return valueFunction(b, fieldId) < valueFunction(a, fieldId); }); } else { scope.activityEntries.entries.sort(function (a, b) { return valueFunction(b, fieldId) > valueFunction(a, fieldId); }); } reverse = !reverse; } //user selected an activity template to complete scope.completeActivity = function (simpleFormTemplate) { var selectedForm; if (simpleFormTemplate.inProgress) { myFormsDataContext.getForm(simpleFormTemplate.inProgressFormId).then(function (theForm) { //handleChoiceQuestionsOnLoading(theForm); selectedForm = theForm; scope.onFormSelected()(selectedForm); $modal.open({ templateUrl: 'app/activities/completeactivity.html', controller: completeActivityController, size: 'sm', backdrop: 'static', resolve: { selectedForm: function () { return selectedForm; }, template: function(){ return simpleFormTemplate; } } }); }); } else { myFormsDataContext.getFormTemplate(simpleFormTemplate.id).then(function (formTemplate) { if (scope.user) { formTemplate.externalId = scope.user.id; } selectedForm = myFormsService.createFormFromTemplate(formTemplate, simpleFormTemplate.id); scope.onFormSelected()(selectedForm); if (selectedForm.individualCanCreate) { $modal.open({ templateUrl: 'app/activities/completeactivity.html', controller: completeActivityController, size: 'sm', backdrop: 'static', resolve: { selectedForm: function() { return selectedForm; }, template: function(){ return simpleFormTemplate; } } }); } else { scope.selectedForm.individualCanCreate = false; } }); } } } }]); //directive to render an individual question app.directive('questionView', ['myFormsConfig', function (myFormsConfig) { return { restrict: 'E', scope: { questionAnswer: '=', isDisabled: '@', isTemplateBuilder: '@', isFeedbackGivenDuringQuiz: '=' }, templateUrl: templatePath + 'questionview.html', link: link }; function link(scope, elem, attrs) { //if (scope.questionAnswer.question.isChoiceQuestion && scope.isTemplateBuilder==='false') // addEmptyOption(scope.questionAnswer); if (scope.questionAnswer.question.isCheckListQuestion) validateChoices(); //if (scope.questionAnswer.question.isTimeQuestion) // initTime(); //get the image url for a question scope.getImageUrl = function (question) { var publicId = 'v1441893874/placeholder_vlosor'; if (question && question.imageUrl) publicId = question.imageUrl; return myFormsConfig.formIconBlank + 'h_250/' + publicId + '.png'; } //scope.setCurrentTime = function (answer) { // if (answer == null || answer == undefined) // return new Date(); // else { // var m = moment(answer); // var hours = m.hours(); // var mins = m.minutes(); // var timeAsDate = new Date(); // timeAsDate.setHours(hours); // timeAsDate.setMinutes(mins); // //answer = timeAsDate; // scope.timezonedate = timeAsDate; // return timeAsDate; // } //} scope.checkDate = function (form, value, max, questionId) { if (value) { if (max) { if (value < max) { scope.innerForm.$invalid = false; scope.innerForm.$dirty = true; return; } } else { scope.innerForm.$invalid = false; scope.innerForm.$dirty = true; return; } } } //called whenvever a user clicks on a checklist checkbox scope.updateCheckListSelection = function () { if (scope.questionAnswer.question.isSingleChoiceOnly && scope.questionAnswer.answer.chosen.length>1) scope.questionAnswer.answer.chosen = scope.questionAnswer.answer.chosen.slice(1); }; scope.compareChoices = function (choice1, choice2) { if (scope.$parent.$parent.isSaving) return choice1.choiceId === choice2.choiceId && choice1.isChosen; return choice1.choiceId === choice2.choiceId; }; scope.filterNumber = function ($event) { if (($event.charCode >= 48 && $event.charCode <= 57) || $event.charCode === 46 || $event.charCode === 45 || $event.keyCode === 8 || $event.keyCode === 46) return; $event.preventDefault(); }; scope.openDatePicker = function ($event) { if ($event) { $event.preventDefault(); $event.stopPropagation(); // This is the magic } scope.datePickerIsOpen = true; }; //work out what is the max word count is for text type questions scope.getValidationTextMaxLength = function (question) { if (question.validation && question.validation.maxTextLength > 0) return question.validation.maxTextLength; return 0; } //work out what is the min word count is for text type questions scope.getValidationTextMinLength = function (question) { if (question.validation && question.validation.minTextLength >= 0) return question.validation.minTextLength; return 0; } scope.feedbackShown = false; //check if the user is trying to select more than the number of selected scope.selectMCQ = function (question, choice) { if (!choice.isChosen) { var numberOfSelectedLeft = checkAgainstNumCorrectChoices(); if (numberOfSelectedLeft === 0) { return; } if (!scope.feedbackShown && numberOfSelectedLeft === 1 && scope.isFeedbackGivenDuringQuiz) { choice.isChosen = !choice.isChosen; scope.feedbackShown = true; return; } } if (!scope.feedbackShown) choice.isChosen = !choice.isChosen; function checkAgainstNumCorrectChoices() { var limit = question.numCorrectChoices; angular.forEach(question.choices, function (choice) { if (choice.isChosen) limit = limit - 1; }); return limit; } } //workaround to validate that the choices made are valid according to the question settings scope.$watch(function ($scope) { if (!scope.questionAnswer.answer.chosen || !scope.questionAnswer.answer.chosen.map) return; return scope.questionAnswer.answer.chosen.map(function (obj) { return obj; }); }, function (newVal, oldVal) { if (!newVal || !oldVal) return; if (newVal.length === oldVal.length) return; validateChoices(); scope.$apply; }, true); function addEmptyOption(questionAnswer) { questionAnswer.question.choices.unshift({ choiceId: -1, choice: null }); if (!questionAnswer.answer.chosen) questionAnswer.answer.chosen = questionAnswer.question.choices[0]; } //validate the question choices function validateChoices() { //the number of answers chosen could be less than the mim specified by the question author if (scope.questionAnswer.answer.chosen) { if (scope.questionAnswer.answer.chosen.length < scope.questionAnswer.question.validation.minChoicesRequired) { scope.questionAnswer.tooFewAnswers = true; scope.isCheckListValid = false; } //otherwise the min choices is ok if (scope.questionAnswer.answer.chosen.length >= scope.questionAnswer.question.validation.minChoicesRequired) { scope.questionAnswer.tooFewAnswers = false; scope.isCheckListValid = true; } } //if the min choices are ok check the max choices allowed meets the validation rule if (scope.isCheckListValid) { if (scope.questionAnswer.question.validation.maxChoicesRequired > 0 && scope.questionAnswer.answer.chosen.length > scope.questionAnswer.question.validation.maxChoicesRequired) { scope.questionAnswer.tooManyAnswers = true; scope.isCheckListValid = false; } //it does meet the rule so set as valid if (scope.questionAnswer.question.validation.maxChoicesRequired > 0 && scope.questionAnswer.answer.chosen.length <= scope.questionAnswer.question.validation.maxChoicesRequired) { scope.questionAnswer.tooManyAnswers = false; scope.isCheckListValid = true; } } } //function initTime() { // if (scope.questionAnswer.answer.timeAnswer == null || scope.questionAnswer.answer.timeAnswer == undefined) // scope.questionAnswer.answer.timeAnswer = new Date(); // else { // var m = moment(scope.questionAnswer.answer.timeAnswer); // var hours = m.hours(); // var mins = m.minutes(); // var timeAsDate = new Date(); // timeAsDate.setHours(hours); // timeAsDate.setMinutes(mins); // //answer = timeAsDate; // scope.timezonedate = timeAsDate; // scope.questionAnswer.answer.timeAnswer = timeAsDate; // } //} } }]); //directive to render an individual question app.directive('activityQuestionView', ['myFormsConfig', function (myFormsConfig) { return { restrict: 'E', scope: { questionAnswer: '=', isDisabled: '@', isTemplateBuilder: '@', isFeedbackGivenDuringQuiz: '=' }, templateUrl: templatePath + 'activityquestionview.html', link: link }; function link(scope, elem, attrs) { //if (scope.questionAnswer.question.isChoiceQuestion && scope.isTemplateBuilder==='false') // addEmptyOption(scope.questionAnswer); if (scope.questionAnswer.question.isCheckListQuestion) validateChoices(); //get the image url for a question scope.getImageUrl = function (question) { var publicId = 'v1441893874/placeholder_vlosor'; if (question && question.imageUrl) publicId = question.imageUrl; return myFormsConfig.formIconBlank + 'h_250/' + publicId + '.png'; } //scope.setCurrentTime = function (answer) { // if (answer == null || answer == undefined) // return answer = new Date(); // else { // var m = moment(answer); // var hours = m.hours(); // var mins = m.minutes(); // var timeAsDate = new Date(); // timeAsDate.setHours(hours); // timeAsDate.setMinutes(mins); // answer = timeAsDate; // return answer; // } //} scope.checkDate = function (form, value, max, questionId) { if (value) { if (max) { if (value < max) { scope.innerForm.$invalid = false; scope.innerForm.$dirty = true; return; } } else { scope.innerForm.$invalid = false; scope.innerForm.$dirty = true; return; } } } //called whenvever a user clicks on a checklist checkbox scope.updateCheckListSelection = function () { if (scope.questionAnswer.question.isSingleChoiceOnly && scope.questionAnswer.answer.chosen.length > 1) scope.questionAnswer.answer.chosen = scope.questionAnswer.answer.chosen.slice(1); }; scope.compareChoices = function (choice1, choice2) { if (scope.$parent.$parent.isSaving) return choice1.choiceId === choice2.choiceId && choice1.isChosen; return choice1.choiceId === choice2.choiceId; }; scope.filterNumber = function ($event) { if (($event.charCode >= 48 && $event.charCode <= 57) || $event.charCode === 46 || $event.charCode === 45 || $event.keyCode === 8 || $event.keyCode === 46) return; $event.preventDefault(); }; scope.openDatePicker = function ($event) { if ($event) { $event.preventDefault(); $event.stopPropagation(); // This is the magic } scope.datePickerIsOpen = true; }; //work out what is the max word count is for text type questions scope.getValidationTextMaxLength = function (question) { if (question.validation && question.validation.maxTextLength > 0) return question.validation.maxTextLength; return 0; } //work out what is the min word count is for text type questions scope.getValidationTextMinLength = function (question) { if (question.validation && question.validation.minTextLength >= 0) return question.validation.minTextLength; return 0; } scope.feedbackShown = false; //check if the user is trying to select more than the number of selected scope.selectMCQ = function (question, choice) { if (!choice.isChosen) { var numberOfSelectedLeft = checkAgainstNumCorrectChoices(); if (numberOfSelectedLeft === 0) { return; } if (!scope.feedbackShown && numberOfSelectedLeft === 1 && scope.isFeedbackGivenDuringQuiz) { choice.isChosen = !choice.isChosen; scope.feedbackShown = true; return; } } if (!scope.feedbackShown) choice.isChosen = !choice.isChosen; function checkAgainstNumCorrectChoices() { var limit = question.numCorrectChoices; angular.forEach(question.choices, function (choice) { if (choice.isChosen) limit = limit - 1; }); return limit; } } //workaround to validate that the choices made are valid according to the question settings scope.$watch(function ($scope) { if (!scope.questionAnswer.answer.chosen || !scope.questionAnswer.answer.chosen.map) return; return scope.questionAnswer.answer.chosen.map(function (obj) { return obj; }); }, function (newVal, oldVal) { if (!newVal || !oldVal) return; if (newVal.length === oldVal.length) return; validateChoices(); scope.$apply; }, true); function addEmptyOption(questionAnswer) { questionAnswer.question.choices.unshift({ choiceId: -1, choice: null }); if (!questionAnswer.answer.chosen) questionAnswer.answer.chosen = questionAnswer.question.choices[0]; } //validate the question choices function validateChoices() { //the number of answers chosen could be less than the mim specified by the question author if (scope.questionAnswer.answer.chosen) { if (scope.questionAnswer.answer.chosen.length < scope.questionAnswer.question.validation.minChoicesRequired) { scope.questionAnswer.tooFewAnswers = true; scope.isCheckListValid = false; } //otherwise the min choices is ok if (scope.questionAnswer.answer.chosen.length >= scope.questionAnswer.question.validation.minChoicesRequired) { scope.questionAnswer.tooFewAnswers = false; scope.isCheckListValid = true; } } //if the min choices are ok check the max choices allowed meets the validation rule if (scope.isCheckListValid) { if (scope.questionAnswer.question.validation.maxChoicesRequired > 0 && scope.questionAnswer.answer.chosen.length > scope.questionAnswer.question.validation.maxChoicesRequired) { scope.questionAnswer.tooManyAnswers = true; scope.isCheckListValid = false; } //it does meet the rule so set as valid if (scope.questionAnswer.question.validation.maxChoicesRequired > 0 && scope.questionAnswer.answer.chosen.length <= scope.questionAnswer.question.validation.maxChoicesRequired) { scope.questionAnswer.tooManyAnswers = false; scope.isCheckListValid = true; } } } } }]); //directive to display a form in either readonly or edit mode app.directive('addEditFormRenderer', ['myFormsDataContext', '$rootScope', function (myFormsDataContext, $rootScope) { return { restrict: 'E', scope: { formId: '=', onFormEdited: '&', //the form has been updated }, templateUrl: templatePath + 'addeditformrenderer.html', link: link }; function link(scope, elem, attrs) { scope.showEdit = false; myFormsDataContext.getForm(scope.formId).then(function (theForm) { scope.selectedForm = theForm; }); scope.editMode = function (showEdit) { scope.showEdit = showEdit; $rootScope.$broadcast('showEdit'); } scope.cancel=function() { scope.showEdit = false; } scope.onFormItemUpdated = function () { scope.onFormEdited()(scope.selectedForm); scope.showEdit = false; } } }]); app.directive('styler', function ($compile) { return { restrict: 'E', link: function postLink(scope, element) { if (element.html()) { var template = $compile(''); element.replaceWith(template(scope)); } } }; }); //apply the palette styles to a rendered form app.directive('addFormStyles', function () { return { restrict: 'E', templateUrl: templatePath+'styles.html' }; }); app.directive('templateFormStyles', function () { return { restrict: 'E', templateUrl: templatePath+'templatestyles.html' }; }); })();