const store = new Vuex.Store( { state: { remainingq: -1 } }); Vue.component('sel', { props: { header: String, menulength: String, params: Object }, template: `
{{header.toUpperCase()}}
` }); Vue.component('search', { template: `

{{quiztitle}}

Velg flere element i en meny med Shift+Klikk
Overordnet nivå (f.eks. Thorax) inkluderer
alle underliggende nivå (f.eks. Lunger)

Antall ubesvarte spørsmål i testen: {{remainingq}}

`, mixins: [ajaxmixin], data: function() { return dataobject; }, computed: { remainingq: function() { return store.state.remainingq; } }, methods: { presentcases: function(parcel) { if (parcel == '') { document.getElementById('testfield').innerHTML = '

Dessverre er det ingen spørsmål som oppfyller disse søkekriteriene.

Forsøk gjerne noe annet!

'; } else { window.packet = JSON.parse(parcel); window.static = window.packet.static; window.reactive = window.packet.reactive; document.getElementById('testfield').innerHTML = ''; window.vturf = new Vue({ el: '#testfield' }); } }, sendsearch: function() { store.state.remainingq = -1; parcel = new Object(); for (p in this.searchterms) { parcel[p] = this.searchterms[p].selected.join(','); } parcel['authenticity_token'] = document.querySelector('meta[name=csrf-token]').content; this.ajaxtalk(parcel, this.findquestions, 'POST', this.presentcases); } } }); Vue.component('searchfield', { template: `
Søk etter navngitte kasus:
`, mixins: [ajaxmixin], data: function() { dataobject.searchstring = ''; return dataobject; }, methods: { loadsearch: function() { alert('ok'); }, sendsearch: function() { parcel = {'searchstring': this.searchstring}; this.ajaxtalk(parcel, 'findforedit', 'POST', loadsearch); } } }); Vue.component('tagcase', { template: `
Spørsmål/VP navn
{{p}}
`, mixins: [ajaxmixin], data: function() { dataobject.caseid = null; dataobject.lastcase = null; dataobject.selected = {'Fag': [], 'Modalitet': [], 'Patologi': []}; return dataobject; }, computed: { caselength: function() { return (Object.keys(this.candidates).length > 10 ? 10 : Object.keys(this.candidates).length); }, tagused: function() { if ((this.caseid != null) && (this.candidates[this.caseid][2][this.p].includes(this.c[1]))) { return true } else { return false } } }, methods: { removecase: function(parcel) { if (this.rediger) { for (p in this.selected) { this.candidates[this.caseid][2][p] = this.selected[p].slice(0); this.selected[p] = []; } this.caseid = null; } else { minuscase = JSON.parse(parcel); Vue.delete(this.candidates, minuscase.caseid); } }, loadcases: function(parcel) { newcases = JSON.parse(parcel); this.caseid = null; for (i in this.candidates) { Vue.delete(this.candidates, i); } for (i in newcases) { Vue.set(this.candidates, i, newcases[i]); } }, switchmode: function() { this.rediger = !this.rediger; parcel = {rediger: this.rediger}; this.ajaxtalk(parcel, 'casetagging', 'GET', this.loadcases); }, switchcase: function() { for (p in this.selected) { this.selected[p] = this.candidates[this.caseid][2][p]; } this.lastcase = this.caseid; }, lagre: function() { parcel = Object.assign({caseid: this.caseid, authenticity_token: document.getElementsByTagName('META')['csrf-token'].content}, this.selected); this.ajaxtalk(parcel, 'storecase', 'POST', this.removecase); } } }); Vue.component('testpage', { template: `

{{casetitle}}

Ved å besvare denne testen aksepterer du at svar og tidspunkt lagres anonymt for statistiske formål.

Du klarte {{score}}%

Du kan prøve ut andre svar nedenfor



  
Testen er ferdig.

Takk for nå!

`, data: function() { reactive.score = 0; reactive.verdict = ""; reactive.showscore = false; if (reactive.rating) { reactive.enbloc = true; } return reactive }, created: function() { var fb = ""; var nofb = true; store.state.remainingq = 0; static.url = window.location.href; for (ia in static.assm) { for (ib in static.assm[ia].blocks) { for (iq in static.assm[ia].blocks[ib].questions) { store.state.remainingq++; question = static.assm[ia].blocks[ib].questions[iq]; if (question.type != 'ESSAY') { nofb = true; fb = ""; for (ic in question.choices) { ch = question.choices[ic]; if ((question.type == 'SEL') || (question.type == 'MAT')) { for (j in ch.alternatives) { ch.alternatives[j].feedback.replace(/^(feil|galt)[\.\!]?\ ?/i,""); ch.alternatives[j].feedback = (ch.alternatives[j].correct ? "Riktig. " : "Galt. ") + ch.alternatives[j].feedback; } } else { ch.feedback.replace(/^(feil|galt)[\.\!]?\ ?/i,""); if ((question.type == 'MC') && (!ch.correct)) { if (ch.feedback != '') { nofb = false; } fb += "
" + ((ch.feedback.length == 0) ? '-' : ch.feedback); } ch.feedback = (ch.correct ? "Riktig. " : "Galt. ") + ch.feedback; } } if (!static.oneline && (question.type == 'MC')) { if (nofb) { fb = '

(Det er ingen forklaringer til de gale svarene)

'; } else { fb = '

Nyttig å vite om de gale svarene:' + fb + '

' } for (ic in question.choices) { if (question.choices[ic].correct) { question.choices[ic].feedback += fb; } } } } } } } this.$options = Vue.util.mergeOptions(this.$options, static, this); }, mounted: function() { window.scrollTo(0,0); }, updated: function() { window.scrollTo(0,0); }, computed: { moretocome: function() { return ((this.blknr < this.$options.assm[this.assnr].blocks.length - 1) || (this.assnr < this.$options.assm.length - 1)); }, casetitle: function() { if (this.$options.testtype == 'mixed') { if (this.$options.assm[this.assnr].blocks[0].block_id == 0) { return "FRITTSTÅENDE SPØRSMÅL" } else { caseno = ((this.$options.assm[0].blocks[0].block_id == 0) ? this.assnr : this.assnr + 1); return "VIRTUELL PASIENT NR. " + caseno.toString(); } } else { return this.title; } }, remainingq: function() { return store.state.remainingq; } }, methods: { prevblk: function() { if (this.blknr == 0) { this.assnr--; this.blknr = this.$options.assm[this.assnr].blocks.length - 1; } else { this.blknr--; } }, nextblk: function() { if (this.blknr >= this.$options.assm[this.assnr].blocks.length - 1) { this.blknr = 0; this.assnr++; } else { this.blknr++; } }, makecheck: function() { if (this.$options.rating) { var sum=0.0; var maxs = 0.0; var qsum = 0.0; var qpcondition = []; var qblk = this.$options.assm[this.assnr].blocks[this.blknr].questions; var qr = this.assm[this.assnr][this.blknr].questions; for (iq in qblk) { q = qblk[iq]; qpcondition.length = q.choices.length; qpcondition.fill(false); for (i in qr[iq].selected) { qpcondition[qr[iq].selected[i]] = true; } maxs = 0.0; qsum = 0.0; for (cid in q.tests) { c = q.tests[cid]; maxs += c.score; if (eval(c.test)) { qsum += c.score; } } sum += qsum/maxs; } sum = Math.round(sum * 100.0 / qblk.length); limits = Object.keys(this.messages); mylim = "101"; for(i=limits.length-1;i>=0;i--) { if (sum < parseInt(limits[i])) { mylim = limits[i]; } } this.score = sum; this.verdict = this.messages[mylim]; } this.enbloc = false; this.showscore = true; } } }); Vue.component('xessay', { props: { res: Object }, template: `
`, methods: { checked: function() { if (!this.res.tainted) { this.res.tainted = true; store.state.remainingq--; } } } }); Vue.component('xmcq', { props: { res: Object, enbloc: Boolean, showscore: Boolean }, template: `

`, methods: { checked: function(cid,correct) { id = cid.split('_').pop(); if ((this.$attrs.spm.type == 'MC') && (this.$attrs.record && !this.res.tainted)) { ids = cid.split('_'); answer = [id, "", correct.toString()].join('\x1f') tid = new Date(); stid = tid.toISOString().substring(0,19); let resultat = { qmid: ids[0], qlid: ids[1], revision: ids[2], answer: answer, tid: stid, ip: "", uname: "" } if ((typeof socket === undefined) || (socket === undefined)) { var socket = io.connect('https://studmed.uio.no:50313'); } if (socket.disconnected) { socket.open(); } socket.on('connect', function() { socket.emit('resultat',resultat); }); } if ((!this.res.tainted) || (!this.$attrs.tryonce)) { if (this.$attrs.spm.type == 'MC') { this.res.selected = [id]; } else if (this.$attrs.spm.type == 'MR') { i = this.res.selected.indexOf(id); if (i == -1) { this.res.selected.push(id); } else { this.res.selected.splice(i,1); } } if (!this.res.tainted) { this.res.tainted = true; store.state.remainingq--; } } } } });