Removed incorrect validation of tutor selections.

This commit is contained in:
neviyn 2018-10-08 12:27:31 +01:00
parent 9e198fdaa5
commit 462e86bd36
2 changed files with 298 additions and 265 deletions

View File

@ -65,8 +65,7 @@
<p v-if="site == null">Select a site first.</p> <p v-if="site == null">Select a site first.</p>
<v-icon name="spinner" spin v-if="loadingTutors"/> <v-icon name="spinner" spin v-if="loadingTutors"/>
<b-form-checkbox-group :value="tutors" @input="setTutors" <b-form-checkbox-group :value="tutors" @input="setTutors"
:options="tutorOptions" :options="tutorOptions"></b-form-checkbox-group>
required></b-form-checkbox-group>
</b-form-group> </b-form-group>
</b-col> </b-col>
</b-row> </b-row>
@ -144,10 +143,12 @@
console.log("submit"); console.log("submit");
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
let form = document.getElementById("submission-form"); var form = document.getElementById("submission-form");
if (form.checkValidity()) { if (form.checkValidity() && this.tutors.length > 0) {
console.log("valid");
this.$router.push("/observation"); this.$router.push("/observation");
} }
form.classList.add("was-validated");
} }
} }
}; };

View File

@ -1,272 +1,304 @@
<template> <template>
<b-container> <b-container>
<h3> <h3>
<v-icon name="tag" scale="1.5" />{{type}}/{{description}}</h3> <v-icon name="tag" scale="1.5"/>
<b-container class="sidebar"> {{type}}/{{description}}
<b-row align-v="center" class="sidebar-vert-padding"> </h3>
<b-col class="centered-image"> <b-container class="sidebar">
<img src="../assets/Monitoring.svg" class="image-opacity" object-fill="contain" /> <b-row align-v="center" class="sidebar-vert-padding">
<div class="image-centered-text">{{ totals[0] }}</div> <b-col class="centered-image">
</b-col> <img src="../assets/Monitoring.svg" class="image-opacity" object-fill="contain"/>
</b-row> <div class="image-centered-text">{{ totals[0] }}</div>
<b-row align-v="center" class="sidebar-vert-padding"> </b-col>
<b-col class="centered-image"> </b-row>
<img src="../assets/Control.svg" class="image-opacity" object-fill="contain" /> <b-row align-v="center" class="sidebar-vert-padding">
<div class="image-centered-text">{{ totals[1] }}</div> <b-col class="centered-image">
</b-col> <img src="../assets/Control.svg" class="image-opacity" object-fill="contain"/>
</b-row> <div class="image-centered-text">{{ totals[1] }}</div>
<b-row align-v="center" class="sidebar-vert-padding"> </b-col>
<b-col class="centered-image"> </b-row>
<img src="../assets/Conservatism.svg" class="image-opacity" object-fill="contain" /> <b-row align-v="center" class="sidebar-vert-padding">
<div class="image-centered-text">{{ totals[2] }}</div> <b-col class="centered-image">
</b-col> <img src="../assets/Conservatism.svg" class="image-opacity" object-fill="contain"/>
</b-row> <div class="image-centered-text">{{ totals[2] }}</div>
<b-row align-v="center" class="sidebar-vert-padding"> </b-col>
<b-col class="centered-image"> </b-row>
<img src="../assets/Teamwork.svg" class="image-opacity" object-fill="contain" /> <b-row align-v="center" class="sidebar-vert-padding">
<div class="image-centered-text">{{ totals[3] }}</div> <b-col class="centered-image">
</b-col> <img src="../assets/Teamwork.svg" class="image-opacity" object-fill="contain"/>
</b-row> <div class="image-centered-text">{{ totals[3] }}</div>
<b-row align-v="center"> </b-col>
<b-col class="centered-image"> </b-row>
<img src="../assets/Knowledge.svg" class="image-opacity" object-fill="contain" /> <b-row align-v="center">
<div class="image-centered-text">{{ totals[4] }}</div> <b-col class="centered-image">
</b-col> <img src="../assets/Knowledge.svg" class="image-opacity" object-fill="contain"/>
</b-row> <div class="image-centered-text">{{ totals[4] }}</div>
</b-col>
</b-row>
</b-container>
<b-form @submit="onSubmit" id="submission-form" novalidate>
<b-container v-for="(item, index) in observations" v-bind:key="index" class="border bottom-buffer">
<b-row class="top-buffer">
<b-col cols="3">
<b-form-group label="Type">
<b-form-select v-bind:value="item.type" @change="changeType(index, $event)" required>
<option :value=null>Please select an option</option>
<option value="MONITORING">Monitoring</option>
<option value="CONTROL">Control</option>
<option value="CONSERVATISM">Conservatism</option>
<option value="TEAMWORK">Teamwork</option>
<option value="KNOWLEDGE">Knowledge</option>
</b-form-select>
</b-form-group>
<b-form-group label="Rating">
<b-form-radio-group buttons button-variant="outline-info" size="lg"
v-bind:value="item.rating" @change="changeRating(index, $event)"
required>
<b-form-radio value=1>1</b-form-radio>
<b-form-radio value=2>2</b-form-radio>
<b-form-radio value=3>3</b-form-radio>
<b-form-radio value=4>4</b-form-radio>
<b-form-radio value=5>5</b-form-radio>
</b-form-radio-group>
</b-form-group>
</b-col>
<b-col>
<b-form-group label="Strengths">
<b-form-textarea v-model="item.strengths" placeholder="Enter Strengths" :rows="3"
:max-rows="6" required no-resize>
</b-form-textarea>
</b-form-group>
<b-form-group label="Areas of Improvement">
<b-form-textarea v-model="item.improvements" placeholder="Enter Areas of Improvement"
:rows="3" :max-rows="6" required no-resize>
</b-form-textarea>
</b-form-group>
</b-col>
</b-row>
<b-row class="bottom-buffer">
<b-col>
<b-button v-on:click="deleteObservation(index)">Delete</b-button>
</b-col>
</b-row>
</b-container>
<b-row align-h="center">
<b-col cols="1">
<b-button type="submit" variant="primary">Submit</b-button>
</b-col>
<b-col offset="1" cols="1">
<b-button v-on:click="this.addAnotherObservation">Add Entry</b-button>
</b-col>
</b-row>
</b-form>
<b-modal id="submissionModal"
ref="modal"
title="Enter password to confirm submission"
@ok="handleOk"
@shown="clearPassword">
<form @submit.stop.prevent="handleSubmit">
<b-form-input type="password"
placeholder="Enter password"
v-model="name"></b-form-input>
</form>
</b-modal>
</b-container> </b-container>
<b-form @submit="onSubmit" id="submission-form" novalidate>
<b-container v-for="(item, index) in observations" v-bind:key="index" class="border bottom-buffer">
<b-row class="top-buffer">
<b-col cols="3">
<b-form-group label="Type">
<b-form-select v-bind:value="item.type" @change="changeType(index, $event)" required>
<option :value=null>Please select an option</option>
<option value="MONITORING">Monitoring</option>
<option value="CONTROL">Control</option>
<option value="CONSERVATISM">Conservatism</option>
<option value="TEAMWORK">Teamwork</option>
<option value="KNOWLEDGE">Knowledge</option>
</b-form-select>
</b-form-group>
<b-form-group label="Rating">
<b-form-radio-group buttons button-variant="outline-info" size="lg" v-bind:value="item.rating" @change="changeRating(index, $event)" required>
<b-form-radio value=1>1</b-form-radio>
<b-form-radio value=2>2</b-form-radio>
<b-form-radio value=3>3</b-form-radio>
<b-form-radio value=4>4</b-form-radio>
<b-form-radio value=5>5</b-form-radio>
</b-form-radio-group>
</b-form-group>
</b-col>
<b-col>
<b-form-group label="Strengths">
<b-form-textarea v-model="item.strengths" placeholder="Enter Strengths" :rows="3" :max-rows="6" required no-resize>
</b-form-textarea>
</b-form-group>
<b-form-group label="Areas of Improvement">
<b-form-textarea v-model="item.improvements" placeholder="Enter Areas of Improvement" :rows="3" :max-rows="6" required no-resize>
</b-form-textarea>
</b-form-group>
</b-col>
</b-row>
<b-row class="bottom-buffer">
<b-col>
<b-button v-on:click="deleteObservation(index)">Delete</b-button>
</b-col>
</b-row>
</b-container>
<b-row align-h="center">
<b-col cols="1">
<b-button type="submit" variant="primary">Submit</b-button>
</b-col>
<b-col offset="1" cols="1">
<b-button v-on:click="this.addAnotherObservation">Add Entry</b-button>
</b-col>
</b-row>
</b-form>
</b-container>
</template> </template>
<script> <script>
import "bootstrap/dist/css/bootstrap.css"; import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-vue/dist/bootstrap-vue.css"; import "bootstrap-vue/dist/bootstrap-vue.css";
import "vue-awesome/icons/tag"; import "vue-awesome/icons/tag";
import { mapState } from "vuex"; import {mapState} from "vuex";
import Vue from "vue"; import Vue from "vue";
export default {
name: "observation", export default {
data: function() { name: "observation",
return { data: function () {
observations: [ return {
{ observations: [
type: null, {
rating: null, type: null,
strengths: null, rating: null,
improvements: null strengths: null,
improvements: null
}
],
totals: [0, 0, 0, 0, 0],
submitPassword: null
};
},
computed: {
...mapState(["description", "type", "whom", "site", "tutors"])
},
methods: {
addAnotherObservation: function () {
this.observations.push({
type: null,
rating: null,
strengths: null,
improvements: null
});
Vue.nextTick(function () {
window.scrollTo(
0,
document.body.scrollHeight || document.documentElement.scrollHeight
);
});
},
deleteObservation: function (index) {
this.observations.splice(index, 1);
if (this.observations.length === 0) {
this.addAnotherObservation();
}
this.updateTotals();
},
changeType: function (index, ev) {
this.observations[index].type = ev;
this.updateTotals();
},
changeRating: function (index, ev) {
this.observations[index].rating = parseInt(ev);
this.updateTotals();
},
updateTotals: function () {
var iTotals = [0, 0, 0, 0, 0];
var counts = [0, 0, 0, 0, 0];
this.observations.forEach(function (element) {
if (element.rating > 0) {
switch (element.type) {
case "MONITORING":
iTotals[0] += element.rating;
counts[0] += 1;
break;
case "CONTROL":
iTotals[1] += element.rating;
counts[1] += 1;
break;
case "CONSERVATISM":
iTotals[2] += element.rating;
counts[2] += 1;
break;
case "TEAMWORK":
iTotals[3] += element.rating;
counts[3] += 1;
break;
case "KNOWLEDGE":
iTotals[4] += element.rating;
counts[4] += 1;
break;
}
}
});
for (var i = 0; i < iTotals.length; i++) {
if (counts[i] !== 0) {
this.totals[i] = (iTotals[i] / counts[i]).toFixed(1);
} else {
this.totals[i] = 0;
}
}
},
onSubmit: function (e) {
e.preventDefault();
e.stopPropagation();
var form = document.getElementById("submission-form");
if (form.checkValidity()) {
this.showModal();
}
form.classList.add("was-validated");
},
showModal() {
this.$refs.submissionModal.show();
},
hideModal() {
this.$refs.submissionModal.hide();
this.submitPassword = null;
},
clearPassword() {
this.submitPassword = null
},
handleOk(evt) {
// Prevent modal from closing
evt.preventDefault();
if(this.password) {
this.handleSubmit()
}
},
handleSubmit() {
var form = document.getElementById("submission-form");
if (form.checkValidity()) {
Vue.axios
.post("/observation", {
site: this.site,
tutors: this.tutors,
observed: this.description,
whom: this.whom,
type: this.type,
entries: JSON.parse(JSON.stringify(this.observations))
})
.then(function (response) {
this.hideModal();
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
this.clearPassword();
form.classList.add("was-validated");
}
} }
],
totals: [0, 0, 0, 0, 0],
submitPassword: null
}; };
},
computed: {
...mapState(["description", "type", "whom", "site", "tutors"])
},
methods: {
addAnotherObservation: function() {
this.observations.push({
type: null,
rating: null,
strengths: null,
improvements: null
});
Vue.nextTick(function() {
window.scrollTo(
0,
document.body.scrollHeight || document.documentElement.scrollHeight
);
});
},
deleteObservation: function(index) {
this.observations.splice(index, 1);
if (this.observations.length == 0) {
this.addAnotherObservation();
}
this.updateTotals();
},
changeType: function(index, ev) {
this.observations[index].type = ev;
this.updateTotals();
},
changeRating: function(index, ev) {
this.observations[index].rating = parseInt(ev);
this.updateTotals();
},
updateTotals: function() {
var iTotals = [0, 0, 0, 0, 0];
var counts = [0, 0, 0, 0, 0];
this.observations.forEach(function(element) {
if (element.rating > 0) {
switch (element.type) {
case "MONITORING":
iTotals[0] += element.rating;
counts[0] += 1;
break;
case "CONTROL":
iTotals[1] += element.rating;
counts[1] += 1;
break;
case "CONSERVATISM":
iTotals[2] += element.rating;
counts[2] += 1;
break;
case "TEAMWORK":
iTotals[3] += element.rating;
counts[3] += 1;
break;
case "KNOWLEDGE":
iTotals[4] += element.rating;
counts[4] += 1;
break;
}
}
});
for (var i = 0; i < iTotals.length; i++) {
if (counts[i] != 0) {
this.totals[i] = (iTotals[i] / counts[i]).toFixed(1);
} else {
this.totals[i] = 0;
}
}
},
onSubmit: function(e) {
e.preventDefault();
e.stopPropagation();
var form = document.getElementById("submission-form");
console.log({
siteId: this.site,
tutorIds: this.tutors,
observed: this.description,
whom: this.whom,
type: this.type,
monitoring: this.totals[0],
control: this.totals[1],
conservatism: this.totals[2],
teamwork: this.totals[3],
knowledge: this.totals[4],
rawData: JSON.parse(JSON.stringify(this.observations))
});
if (form.checkValidity()) {
Vue.axios
.post("/observation", {
site: this.site,
tutors: this.tutors,
observed: this.description,
whom: this.whom,
type: this.type,
entries: JSON.parse(JSON.stringify(this.observations))
})
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
}
form.classList.add("was-validated");
},
showModal() {
this.$refs.submissionModal.show();
},
hideModal() {
this.$refs.submissionModal.hide();
this.submitPassword = null;
}
}
};
</script> </script>
<style> <style>
.top-buffer { .top-buffer {
margin-top: 10px; margin-top: 10px;
} }
.bottom-buffer {
margin-bottom: 10px; .bottom-buffer {
} margin-bottom: 10px;
.image-centered-text { }
position: absolute;
top: 50%; .image-centered-text {
left: 50%; position: absolute;
transform: translate(-50%, -50%); top: 50%;
font-size: 50px; left: 50%;
color: white; transform: translate(-50%, -50%);
text-shadow: -2px 0 black, 0 2px black, 2px 0 black, 0 -2px black; font-size: 50px;
} color: white;
.image-opacity { text-shadow: -2px 0 black, 0 2px black, 2px 0 black, 0 -2px black;
opacity: 0.5; }
}
.centered-image { .image-opacity {
position: relative; opacity: 0.5;
text-align: center; }
}
.sidebar { .centered-image {
width: 160px; /* Set the width of the sidebar */ position: relative;
position: fixed; /* Fixed Sidebar (stay in place on scroll) */ text-align: center;
z-index: 1; /* Stay on top */ }
top: 20%; /* Stay at the top */
left: 0; .sidebar {
overflow-x: hidden; /* Disable horizontal scroll */ width: 160px; /* Set the width of the sidebar */
padding-top: 20px; position: fixed; /* Fixed Sidebar (stay in place on scroll) */
} z-index: 1; /* Stay on top */
.sidebar-vert-padding { top: 20%; /* Stay at the top */
margin-bottom: 25%; left: 0;
} overflow-x: hidden; /* Disable horizontal scroll */
@media screen and (max-height: 500px) { padding-top: 20px;
.sidebar { }
top: 0; /* Stay at the top */
} .sidebar-vert-padding {
} margin-bottom: 25%;
img { }
height: 80px;
} @media screen and (max-height: 500px) {
.sidebar {
top: 0; /* Stay at the top */
}
}
img {
height: 80px;
}
</style> </style>