/** * When attached to an eventListener of an element, opens or closes element in full screen. */ const fullScreenHTML = 'Ikon for ekspansjon av skjerm'; const notFullScreenHTML = '×'; function toggleFullscreen(realm,screen) { if (realm.innerHTML == fullScreenHTML){ if (screen.requestFullscreen) { screen.requestFullscreen(); } else if (screen.webkitRequestFullscreen) { /* Safari */ screen.webkitRequestFullscreen(); } else if (screen.msRequestFullscreen) { /* IE11 */ screen.msRequestFullscreen(); } else if (document.mozRequestFullScreen) { /* Firefox 9-63 */ screen.mozRequestFullScreen(); } }else{ if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.webkitExitFullscreen) { /* Safari */ document.webkitExitFullscreen(); } else if (document.msExitFullscreen) { /* IE11 */ document.msExitFullscreen(); } else if (document.mozCancelFullScreen) { /* Firefox 9-63 */ document.mozCancelFullScreen(); } } } /** * Draws out HTML framework and adds functionality to it for a visual and interactive calculator tool. * @author Ole Brede, Terje Rudi. */ async function startPoengKalkulator(){ document.currentScript.insertAdjacentHTML('afterend', `
Poeng­kalkulator for master- og videre­utdanning
`) const pointCalculator = document.querySelector('#poengKalkulator') pointCalculator.appendChild(document.currentScript) pointCalculator.querySelector('summary').insertAdjacentHTML('afterend', `

Karakterpoeng

Bokstav­karakter Studie­poeng Tall­verdi
× studie­poeng
Sum:

Vektet snitt:

Tilleggspoeng
Utdanningspoeng

Du får bare poeng for studiepoeng du har i tillegg til graden din.

Ekstra studie­poeng
Praksispoeng

Du får som hovedregel bare praksispoeng på utdanninger som har krav om praksis.

Du får ikke poeng for praksis som dekker kravet.

Hvor mange år med praksis inngår i opptakskravet?
Stillingsforhold 1
Startdato
Sluttdato
Stillingsprosent
Ekstravakter
Sum mnd. i 100% stilling: 
Karakterpoeng 0
Utdanningspoeng 0
Praksispoeng 0
Konkurransepoeng 0
`) //Handles changing of fullscreen if ((document.fullscreenEnabled || document.msFullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled) && (document.webkitFullScreenKeyboardInputAllowed === undefined || document.webkitFullScreenKeyboardInputAllowed === true)) { function handleFullscreenchange() { const realm = pointCalculator.querySelector('.menuBtn') if (document.fullscreenElement || document.msFullscreenElement || document.webkitFullscreenElement || document.webkitIsFullScreen || document.mozFullScreenElement) { realm.innerHTML = notFullScreenHTML; realm.parentNode.parentNode.setAttribute('open','open'); } else { realm.innerHTML = fullScreenHTML; } } pointCalculator.addEventListener('fullscreenchange', () => { handleFullscreenchange() }) pointCalculator.addEventListener("webkitfullscreenchange", () => { handleFullscreenchange() }) pointCalculator.addEventListener("msfullscreenchange", () => { handleFullscreenchange() }) pointCalculator.addEventListener("mozfullscreenchange", () => { handleFullscreenchange() }); pointCalculator.querySelector('summary').insertAdjacentHTML('beforeend', ` `) } //Handles gradeCalculator let gradePointsValue = 0 { const form = document.querySelector('.gradeCalculatorTable') /** * Adds a clone of row below row * @param {object} row htmldomobject */ function addGradeInputRow(row) { if (row.parentElement.querySelectorAll('.gradeInputsRow')[row.parentElement.querySelectorAll('.gradeInputsRow').length - 1] !== row) {return} clone = row.cloneNode(true) for (let index = 0; index < clone.querySelectorAll('INPUT').length; index++) { const input = clone.querySelectorAll('INPUT')[index]; input.value = '' handleGradeInputsRowInputs(input) } for (let index = 0; index < clone.querySelectorAll('OUTPUT').length; index++) { const element = clone.querySelectorAll('OUTPUT')[index]; element.value = '' } row.insertAdjacentElement('afterend', clone) return clone } /** * calculates individual row and shows results * @param {object} row htmldomobject */ function showCalculationsRow(row) { const gradeInput = row.querySelector('.gradeInput') const pointInput = row.querySelector('.pointInput') const pointValue = row.querySelector('.pointValue') if (gradeInput.checkValidity() && pointInput.checkValidity() && gradeInput.value !== '' && pointInput.value !== '') { pointValue.value = (pointInput.value * ((gradeInput.value.toUpperCase().charCodeAt(0) / -1) + 70)).toLocaleString('no-NO', {minimumFractionDigits: 0, maximumFractionDigits: 1}) addGradeInputRow(row) } else { pointValue.value = '' } showCalculationsOverall() } /** * calculates all rows and shows results */ function showCalculationsOverall() { const sumPoints = form.querySelector('.sumPoints > output') const sumNumxPoints = form.querySelector('.sumNumxPoints > output') const gradeAvg = form.parentElement.querySelector('.gradeAvg > output') const gradePoints = pointCalculator.querySelector('.gradePoints') let sumPointsValue = 0 let sumNumxPointsValue = 0 for (let index = 0; index < form.querySelectorAll('.gradeInputsRow').length; index++) { const row = form.querySelectorAll('.gradeInputsRow')[index]; const gradeInput = row.querySelector('.gradeInput') const pointInput = row.querySelector('.pointInput') const pointValue = row.querySelector('.pointValue') if (pointInput.value !== '' && pointValue.value !== '') { sumPointsValue += parseFloat(pointInput.value) sumNumxPointsValue += pointInput.value * ((gradeInput.value.toUpperCase().charCodeAt(0) / -1) + 70) } } if (sumPointsValue !== 0 || sumNumxPointsValue !== 0) { sumPoints.value = sumPointsValue.toLocaleString('no-NO', {minimumFractionDigits: 0, maximumFractionDigits: 1}) sumNumxPoints.value = sumNumxPointsValue.toLocaleString('no-NO', {minimumFractionDigits: 0, maximumFractionDigits: 1}) gradeAvg.value = (sumNumxPointsValue / sumPointsValue).toLocaleString('no-NO', {minimumFractionDigits: 0, maximumFractionDigits: 2}) gradePointsValue = (sumNumxPointsValue / sumPointsValue * 10) gradePoints.value = gradePointsValue.toLocaleString('no-NO', {minimumFractionDigits: 0, maximumFractionDigits: 2}) } else { sumPoints.value = '' sumNumxPoints.value = '' gradeAvg.value = '' gradePointsValue = 0 gradePoints.value = '0' } updateCompCalculator() } /** * removes excess input rows */ function removeEmptyGradeInput() { const activeElementClass = document.activeElement.classList.contains('gradeInput') ? 'gradeInput' : document.activeElement.classList.contains('pointInput') ? 'pointInput' : undefined for (let index = form.querySelectorAll('.gradeInputsRow').length - 2; index >= 0; index--) { const row = form.querySelectorAll('.gradeInputsRow')[index] const gradeInput = row.querySelector('.gradeInput') const pointInput = row.querySelector('.pointInput') const lastRow = form.querySelectorAll('.gradeInputsRow')[form.querySelectorAll('.gradeInputsRow').length - 1] const lastGradeInput = lastRow.querySelector('.gradeInput') const lastPointInput = lastRow.querySelector('.pointInput') if (lastGradeInput.value !== '' || lastPointInput.value !== '') {return} if (gradeInput.value === '' && pointInput.value === '') { if (document.activeElement.parentElement.parentElement === row) { lastRow.querySelector(`.${activeElementClass}`).select() } row.remove() } else if (gradeInput.value === '' || pointInput.value === '') { if (document.activeElement.parentElement.parentElement === lastRow) { row.querySelector(`.${activeElementClass}`).select() } lastRow.remove() return } else { return } } } /** * Handles all the events for elements with the gradeInputsRow class * @param {object} element htmldomobject */ function handleGradeInputsRowInputs(input) { input.addEventListener('input', () => { let row = input.parentElement.parentElement if (input.classList.contains('gradeInput')) { if (parseInt(input.value) <= 5 && parseInt(input.value) >= 0) { input.value = String.fromCharCode((input.value / -1) + 70) } if (input.checkValidity() && input.value !== '') { input.value = input.value.toUpperCase() row.querySelector('.pointInput').select() } } showCalculationsRow(row) removeEmptyGradeInput() }) reportValidityBlur(input) enterToNextInput(input, form) } //Add events to already existing inputs for (let index = 0; index < form.querySelectorAll('.gradeInputsRow input').length; index++) { const input = form.querySelectorAll('.gradeInputsRow input')[index]; handleGradeInputsRowInputs(input) } } //Handle eduCalculator { const form = document.querySelector('.eduCalculatorTable') const eduPointInput = form.querySelector('.eduPointInput') eduPointInput.addEventListener('input', () => { const eduPointValue = pointCalculator.querySelector('.eduPointValue') eduPointValue.value = (eduPointInput.checkValidity() && eduPointInput.value !== '0') ? Math.min(Math.floor(eduPointInput.value / 30), 4) : '0' updateCompCalculator() }) } //Handle practiceCalculator { const form = document.querySelector('.Praksispoeng') let rowCount = 1 function addPraksisInputRow(row) { if (row.parentElement.querySelectorAll('.praksisInputRow')[row.parentElement.querySelectorAll('.praksisInputRow').length - 1] !== row) {return} clone = row.cloneNode(true) for (let index = 0; index < clone.querySelectorAll('INPUT').length; index++) { const input = clone.querySelectorAll('INPUT')[index]; input.value = '' handlePraksisInputRowInputs(input) } if (clone.open) { clone.open = false } rowCount++ clone.querySelector('summary').innerHTML = `Stillingsforhold ${rowCount}` handlePraksisInputRowDetails(clone) row.insertAdjacentElement('afterend', clone) return clone } function monthDayCount(date) { const count = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] //account for leap years count[1] = (date.getFullYear() % 4 === 0 && (date.getFullYear() % 100 !== 0 || date.getFullYear() % 400 === 0)) ? 29 : count[1] return count[date.getMonth()] } function monthDiff(date1, date2) { if (date1 > date2) {return 0} let months = (date2.getFullYear() - date1.getFullYear()) * 12 months -= date1.getMonth() months += date2.getMonth() if ((date1.getDate() === date2.getDate()) || ((date1.getDate() / monthDayCount(date1) === 1) && (date2.getDate() / monthDayCount(date2) === 1))) {return months} if (date1.getDate() > date2.getDate()) { months -= (date1.getDate() - date2.getDate()) / 31 } else { months -= ((31 - date2.getDate() + date1.getDate()) / 31) - 1 } return months } //Potentional alternative way of calculating fractional months /* function monthDiff(date1, date2) { if (date1 > date2) {return} let months = (date2.getFullYear() - date1.getFullYear()) * 12 months -= date1.getMonth() months += date2.getMonth() if (date1.getDate() === date2.getDate()) {return months} if (date1.getDate() > date2.getDate()) { date2.setMonth(date2.getMonth() - 1) months -= (date1.getDate() - date2.getDate()) / monthDayCount(date2) } else { months += (date2.getDate() - date1.getDate()) / monthDayCount(date2) } return months } */ function CalculateRow(row) { const beginDateInput = row.querySelector('.beginDateInput') const endDateInput = row.querySelector('.endDateInput') const percentInput = row.querySelector('.percentInput') const extraInput = row.querySelector('.extraInput') let monthsValue = 0 if (beginDateInput.checkValidity() && endDateInput.checkValidity() && percentInput.checkValidity() && beginDateInput.value !== '' && endDateInput.value !== '' && percentInput.value !== '') { const monthsValueRaw = monthDiff(beginDateInput.valueAsDate, endDateInput.valueAsDate) const monthsValueAdjusted = monthsValueRaw * percentInput.value / 100 monthsValue = monthsValueAdjusted if (extraInput.checkValidity() && extraInput.value !== '') { const extraMonths = extraInput.value / 150 if (extraMonths + monthsValueAdjusted > monthsValueRaw) { monthsValue = monthsValueRaw } else { monthsValue = monthsValue + extraInput.value / 150 } } addPraksisInputRow(row) } return monthsValue } function showCalculationsOverall() { const sumMonths = form.querySelector('.sumMonths') const obligatedYears = form.querySelector('.obligatedYears') const praksisPoints = pointCalculator.querySelector('.praksisPoints') let sumMonthsValue = 0 for (let index = 0; index < form.querySelectorAll('.praksisInputRow').length; index++) { const row = form.querySelectorAll('.praksisInputRow')[index]; const monthsValue = CalculateRow(row) sumMonthsValue += monthsValue } sumMonths.value = sumMonthsValue.toLocaleString('no-NO', {minimumFractionDigits: 0, maximumFractionDigits: 2}) const monthsSubtract = obligatedYears.checkValidity() && obligatedYears.value !== '' ? obligatedYears.value * 12 : 0 if (sumMonthsValue !== 0 && sumMonthsValue - monthsSubtract > 0 && monthsSubtract > 0) { praksisPoints.value = Math.min((Math.floor((sumMonthsValue - monthsSubtract) / 12) * 2), 6).toLocaleString('no-NO', {minimumFractionDigits: 0, maximumFractionDigits: 0}) } else { praksisPoints.value = '0' } if (sumMonthsValue === 0) { sumMonths.value = '' } updateCompCalculator() } function handlePraksisInputRowInputs(input) { input.addEventListener('input', () => { showCalculationsOverall() }) reportValidityBlur(input) enterToNextInput(input, form) } { const obligatedYears = form.querySelector('.obligatedYears') obligatedYears.addEventListener('input', () => { showCalculationsOverall() }) reportValidityBlur(obligatedYears) enterToNextInput(obligatedYears, form) } function handlePraksisInputRowDetails(details) { details.addEventListener('toggle', () => { if (details.open) { for (let index = 0; index < form.querySelectorAll('.praksisInputRow').length; index++) { const otherdetails = form.querySelectorAll('.praksisInputRow')[index]; if (details !== otherdetails && otherdetails.open) { otherdetails.open = false } } } }) } //Add events to already existing inputs for (let index = 0; index < form.querySelectorAll('.praksisInputRow input').length; index++) { const input = form.querySelectorAll('.praksisInputRow input')[index]; handlePraksisInputRowInputs(input) } //Add events to already existing details for (let index = 0; index < form.querySelectorAll('.praksisInputRow').length; index++) { const details = form.querySelectorAll('.praksisInputRow')[index]; handlePraksisInputRowDetails(details) } } /** * report the validity of the element on blur * @param {object} element htmldomobject */ function reportValidityBlur(element) { element.addEventListener('blur', () => { element.reportValidity() }) } /** * If enter is pressed then selects next input in form * If shift + enter is pressed then selects previous input in form * @param {object} element htmldomobject */ function enterToNextInput(element, table) { element.addEventListener('keypress', (event) => { if (event.keyCode === 13) { const inputs = Array.from(table.querySelectorAll('INPUT')) const next = event.shiftKey ? -1 : 1 const input = inputs[inputs.indexOf(element) + next] if (input) { input.select() } } }) } function updateCompCalculator() { const compTable = document.querySelector('.compCalculatorTable') const eduPointValue = parseInt(document.querySelector('.eduPointValue').value) const praksisPoints = parseInt(document.querySelector('.praksisPoints').value) const compPoint = compTable.querySelector('.compPoint') compPoint.value = (gradePointsValue + eduPointValue + praksisPoints).toLocaleString('no-NO', {minimumFractionDigits: 0, maximumFractionDigits: 2}) } } startPoengKalkulator()