diff --git a/html/test_02.04.20/oppgaver/.keep b/html/test_02.04.20/oppgaver/.keep
deleted file mode 100644
index e69de29..0000000
diff --git a/html/test_02.04.20/oppgaver/oppgave1/oppgave.html b/html/test_02.04.20/oppgaver/oppgave1/oppgave.html
deleted file mode 100644
index 505a4d7..0000000
--- a/html/test_02.04.20/oppgaver/oppgave1/oppgave.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
diff --git a/html/test_03.04.20/oppgaver/oppgave1/center.css b/html/test_03.04.20/oppgaver/oppgave1/center.css
new file mode 100644
index 0000000..b57338d
--- /dev/null
+++ b/html/test_03.04.20/oppgaver/oppgave1/center.css
@@ -0,0 +1,5 @@
+.centerBlock {
+ display: block;
+ margin: 20px auto;
+ text-align: center;
+}
\ No newline at end of file
diff --git a/html/test_03.04.20/oppgaver/oppgave1/images/cow.jpg b/html/test_03.04.20/oppgaver/oppgave1/images/cow.jpg
new file mode 100644
index 0000000..fb7eb43
Binary files /dev/null and b/html/test_03.04.20/oppgaver/oppgave1/images/cow.jpg differ
diff --git a/html/test_03.04.20/oppgaver/oppgave1/images/dog.jpg b/html/test_03.04.20/oppgaver/oppgave1/images/dog.jpg
new file mode 100644
index 0000000..1e5225b
Binary files /dev/null and b/html/test_03.04.20/oppgaver/oppgave1/images/dog.jpg differ
diff --git a/html/test_03.04.20/oppgaver/oppgave1/images/giraffe.jpg b/html/test_03.04.20/oppgaver/oppgave1/images/giraffe.jpg
new file mode 100644
index 0000000..d1493b2
Binary files /dev/null and b/html/test_03.04.20/oppgaver/oppgave1/images/giraffe.jpg differ
diff --git a/html/test_03.04.20/oppgaver/oppgave1/images/lion.jpg b/html/test_03.04.20/oppgaver/oppgave1/images/lion.jpg
new file mode 100644
index 0000000..f7f75d9
Binary files /dev/null and b/html/test_03.04.20/oppgaver/oppgave1/images/lion.jpg differ
diff --git a/html/test_03.04.20/oppgaver/oppgave1/oppgave.html b/html/test_03.04.20/oppgaver/oppgave1/oppgave.html
new file mode 100644
index 0000000..cc3b6e8
--- /dev/null
+++ b/html/test_03.04.20/oppgaver/oppgave1/oppgave.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
Oppgave 1
+
+
+
+
+
+
+
Oppgave 1
+
+
+
+
![]()
+
+
+
+
+
+
+
+
+
+
+
diff --git a/html/test_03.04.20/oppgaver/oppgave1/oppgave.js b/html/test_03.04.20/oppgaver/oppgave1/oppgave.js
new file mode 100644
index 0000000..9353fb1
--- /dev/null
+++ b/html/test_03.04.20/oppgaver/oppgave1/oppgave.js
@@ -0,0 +1,86 @@
+// @ts-check
+
+/* Initialize variables */
+
+const animals = [
+ {
+ sound: './sound/silence.mp3',
+ image: {
+ link: './images/giraffe.jpg',
+ src: 'https://pixabay.com/photos/giraffe-portrait-safari-4312090/',
+ },
+ name: 'Giraffe',
+ info: 'This is a giraffe. It has a long neck',
+ },
+ {
+ sound: './sound/lion.mp3',
+ image: {
+ link: './images/lion.jpg',
+ src:
+ 'https://pixabay.com/photos/african-lion-lion-male-mane-lazy-951778/',
+ },
+ name: 'Lion',
+ info: 'This is a lion. It can bite you',
+ },
+ {
+ sound: './sound/dog.mp3',
+ image: {
+ link: './images/dog.jpg',
+ src: 'https://pixabay.com/photos/dog-labrador-light-brown-pet-1210559/',
+ },
+ name: 'Dog',
+ info: "This is a dog. It's so cute",
+ },
+ {
+ sound: './sound/cow.mp3',
+ image: {
+ link: './images/cow.jpg',
+ src:
+ 'https://pixabay.com/photos/cow-head-cow-head-animal-livestock-1715829/',
+ },
+ name: 'Cow',
+ info: 'This is a cow. It goes moooooooo',
+ },
+];
+
+let animal;
+
+/* Register HTML DOM elements by variables */
+
+const animalName = document.getElementById('animalName');
+const image = document.getElementById('animalImage');
+const imageSource = document.getElementById('imageSource');
+const info = document.getElementById('animalInfo');
+const sound = document.getElementById('animalAudio');
+const soundButton = document.getElementById('soundButton');
+const newAnimalButton = document.getElementById('changeAnimal');
+const audioError = document.getElementById('error1');
+
+/* Add event listeners */
+
+soundButton.addEventListener('click', () => sound.play());
+newAnimalButton.addEventListener('click', setAnimal);
+
+/* Initialize HTML with functions */
+
+image.style.width = '1280px';
+image.style.height = '720px';
+
+setAnimal();
+
+/* Functions */
+
+function setAnimal() {
+ audioError.innerHTML = ''; // clear error message
+
+ animal = animals[Math.floor(Math.random() * 4)];
+ image.setAttribute('src', animal.image.link);
+ imageSource.innerHTML = `Image source: ${animal.image.src}`;
+ sound.setAttribute('src', animal.sound);
+ if (animal.sound === './sound/silence.mp3') {
+ const error = createError('This animal has no sound that a human can hear'); //Global function. Can be found at resources/js/error.js
+ audioError.appendChild(error);
+ }
+ animalName.innerHTML = animal.name;
+ info.innerHTML = animal.info;
+}
diff --git a/html/test_03.04.20/oppgaver/oppgave1/sound/cow.mp3 b/html/test_03.04.20/oppgaver/oppgave1/sound/cow.mp3
new file mode 100644
index 0000000..018a59a
Binary files /dev/null and b/html/test_03.04.20/oppgaver/oppgave1/sound/cow.mp3 differ
diff --git a/html/test_03.04.20/oppgaver/oppgave1/sound/dog.mp3 b/html/test_03.04.20/oppgaver/oppgave1/sound/dog.mp3
new file mode 100644
index 0000000..6355edd
Binary files /dev/null and b/html/test_03.04.20/oppgaver/oppgave1/sound/dog.mp3 differ
diff --git a/html/test_03.04.20/oppgaver/oppgave1/sound/lion.mp3 b/html/test_03.04.20/oppgaver/oppgave1/sound/lion.mp3
new file mode 100644
index 0000000..5a07839
Binary files /dev/null and b/html/test_03.04.20/oppgaver/oppgave1/sound/lion.mp3 differ
diff --git a/html/test_03.04.20/oppgaver/oppgave1/sound/silence.mp3 b/html/test_03.04.20/oppgaver/oppgave1/sound/silence.mp3
new file mode 100644
index 0000000..9e0d7da
Binary files /dev/null and b/html/test_03.04.20/oppgaver/oppgave1/sound/silence.mp3 differ
diff --git a/html/test_03.04.20/oppgaver/oppgave2/oppgave.html b/html/test_03.04.20/oppgaver/oppgave2/oppgave.html
new file mode 100644
index 0000000..96e1df8
--- /dev/null
+++ b/html/test_03.04.20/oppgaver/oppgave2/oppgave.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
Oppgave 2
+
+
+
+
+
+
+
+
+
Oppgave 2
+
+
Rentekalkulator
+
+
+
+
+
+
+
+
+
+
+
diff --git a/html/test_03.04.20/oppgaver/oppgave2/oppgave.js b/html/test_03.04.20/oppgaver/oppgave2/oppgave.js
new file mode 100644
index 0000000..4c8aecc
--- /dev/null
+++ b/html/test_03.04.20/oppgaver/oppgave2/oppgave.js
@@ -0,0 +1,59 @@
+// @ts-check
+
+/* Initialize variables */
+
+const houseValueMax = 10000000;
+
+/* Register HTML DOM elements by variables */
+
+const form = document.getElementById('input');
+const houseValue = document.getElementById('houseValue');
+const rentSum = document.getElementById('rentingSum');
+const submitButton = document.getElementById('submit');
+const formError = document.getElementById('error1');
+const result = document.getElementById('result');
+
+/* Add event listeners */
+
+form.addEventListener('submit', evt => {
+ evt.preventDefault();
+ formError.innerHTML = '';
+
+ const house = parseInt(houseValue.value);
+ const rent = parseInt(rentSum.value);
+
+ /* Error checking
+ * I'm aware that I could've just used max and min for checking some of the errors
+ * but I wanted the error format to be consistent.
+ */
+ try {
+ if (house > houseValueMax) throw `Boligverdien kan ikke være større enn ${houseValueMax}kr`;
+ if (rent > house) throw 'Lånesummen kan ikke være større enn boligverdien';
+ if (house <= 0) throw 'Boligverdi må være større enn 0';
+ if (rent <= 0) throw 'Lånesum må være større enn 0';
+ if (isNaN(house)) throw 'Fyll ut Boligverdi';
+ if (isNaN(rent)) throw 'Fyll ut lånesum';
+ } catch (error) {
+ result.innerHTML = '';
+ const errorMessage = createError(error);
+ formError.appendChild(errorMessage);
+ return;
+ }
+
+ /* Result based on input */
+
+ if (rent < 0.75 * house) {
+ result.innerHTML = 'Renten er satt til 2,29%';
+ return;
+ }
+
+ if (rent >= 0.75 * house && rent < 0.9 * house) {
+ result.innerHTML = 'Renten er satt til 2,49%';
+ return;
+ }
+
+ if (rent >= 0.9 * house) {
+ result.innerHTML = 'Renten er satt til 2,69% og du må ha en kausjonist';
+ return;
+ }
+});
diff --git a/html/test_03.04.20/oppgaver/oppgave3/chartOptions.js b/html/test_03.04.20/oppgaver/oppgave3/chartOptions.js
new file mode 100644
index 0000000..e532ef7
--- /dev/null
+++ b/html/test_03.04.20/oppgaver/oppgave3/chartOptions.js
@@ -0,0 +1,24 @@
+const histogramConfig = {
+ chart: {
+ type: 'column',
+ },
+
+ xAxis: {
+ title: {text: 'Test'},
+ categories: chartData.names,
+ },
+
+ plotOptions: {
+ column: {
+ groupPadding: 0,
+ pointPadding: 0,
+ borderWidth: 0,
+ },
+ },
+
+ series: [
+ {
+ data: chartData.casesPerPop,
+ },
+ ],
+};
diff --git a/html/test_03.04.20/oppgaver/oppgave3/data.js b/html/test_03.04.20/oppgaver/oppgave3/data.js
new file mode 100644
index 0000000..ed6ae18
--- /dev/null
+++ b/html/test_03.04.20/oppgaver/oppgave3/data.js
@@ -0,0 +1,25 @@
+const data = [
+ {
+ name: "USA",
+ cases: 176518,
+ deaths: 3431,
+ recovered: 6241,
+ population: 324459000
+ },
+ {
+ name: "UK",
+ cases: 25150,
+ deaths: 1789,
+ recovered: 135,
+ population: 66182000
+ },
+ {
+ name: "Norway",
+ cases: 4605,
+ deaths: 39,
+ recovered: 13,
+ population: 5305000
+ }
+];
+
+const dataDate = '31st March 2020';
\ No newline at end of file
diff --git a/html/test_03.04.20/oppgaver/oppgave3/oppgave.html b/html/test_03.04.20/oppgaver/oppgave3/oppgave.html
new file mode 100644
index 0000000..0f0e177
--- /dev/null
+++ b/html/test_03.04.20/oppgaver/oppgave3/oppgave.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
Oppgave 3
+
+
+
+
+
+
+
+
+
+
+
+
+
Oppgave 3
+
+
Corona outbreak statistics
+
+
+ | Country |
+ Total Cases |
+ Total Deaths |
+ Total Recovered |
+ Total Cases/1M pop |
+ Total Cases/1M pop |
+
+
+
Data taken from:
+ Wikipedia
+ Worldometers
+
Downloaded:
+
+
+
+
Type the first letter of the country you're looking for after clicking on the selector in order to search
+
+
+
+
+
+
+
+
+
diff --git a/html/test_03.04.20/oppgaver/oppgave3/oppgave.js b/html/test_03.04.20/oppgaver/oppgave3/oppgave.js
new file mode 100644
index 0000000..7fc9bc3
--- /dev/null
+++ b/html/test_03.04.20/oppgaver/oppgave3/oppgave.js
@@ -0,0 +1,156 @@
+// @ts-check
+
+/* Initialize variables */
+
+class Country {}
+
+const countries = [];
+
+/* Map data from json file */
+for (let index = 0; index < data.length; index++) {
+ countries[index] = {
+ name: data[index].name,
+ cases: data[index].cases,
+ deaths: data[index].deaths,
+ recovered: data[index].recovered,
+ casesPerPop: Math.round((data[index].cases * 1000000) / data[index].population),
+ deathsPerPop: Math.round((data[index].cases * 1000000) / data[index].population),
+ };
+}
+
+/* Prepare data in arrays */
+const chartData = {
+ names: countries.map(country => country.name),
+ casesPerPop: countries.map(country => country.casesPerPop),
+};
+
+/* Configuration for the chart */
+const histogramConfig = {
+ chart: {
+ type: 'column', //Bruker kolonnekart uten padding og border for å lage et histogram
+ },
+
+ title: {text: 'Overview of cases per 1M people'},
+
+ xAxis: {
+ title: {text: 'Countries'},
+ categories: chartData.names,
+ },
+
+ yAxis: {
+ title: {text: 'Cases per 1M people'},
+ },
+
+ plotOptions: {
+ column: {
+ groupPadding: 0,
+ pointPadding: 0,
+ borderWidth: 0,
+ },
+ },
+
+ series: [
+ {
+ name: 'Cases per 1M people',
+ data: chartData.casesPerPop,
+ },
+ ],
+};
+
+/* Register HTML DOM elements by variables */
+
+const table = document.getElementById('statisticsTable');
+const selector = document.getElementById('countrySelector');
+const selectTable = document.getElementById('selectTable');
+const date = document.getElementById("date");
+
+/* Add event listeners */
+
+selector.addEventListener('change', evt => {
+ selectTable.innerHTML = '';
+
+ selectTable.innerHTML = table.querySelectorAll('tr')[0].innerHTML;
+ selectTable.appendChild(countryRow(countries[selector.value]));
+});
+
+/* Initialize HTML with functions */
+
+for (let index = 0; index < countries.length; index++) {
+ /* Select options */
+ const option = document.createElement('option');
+ option.value = String(index);
+ option.innerHTML = countries[index].name;
+ selector.appendChild(option);
+
+ /* Add row to statisticsTable */
+ table.appendChild(countryRow(countries[index]));
+}
+
+table.appendChild(totalRow());
+
+date.innerHTML = dataDate;
+
+document.getElementById('chart').style.height = '500px';
+Highcharts.setOptions(Highcharts.theme);
+Highcharts.chart('chart', histogramConfig);
+
+/* Functions */
+
+/**
+ * Makes a row
+ * @param {Object} country
+ */
+function countryRow(country) {
+ const row = document.createElement('tr');
+
+ const countryBox = document.createElement('td');
+ countryBox.innerHTML = country.name;
+
+ const casesBox = document.createElement('td');
+ casesBox.innerHTML = country.cases;
+
+ const deathBox = document.createElement('td');
+ deathBox.innerHTML = country.deaths;
+
+ const recoveredBox = document.createElement('td');
+ recoveredBox.innerHTML = country.recovered;
+
+ const casesPerPopBox = document.createElement('td');
+ casesPerPopBox.innerHTML = country.casesPerPop;
+
+ const deathPerPopBox = document.createElement('td');
+ deathPerPopBox.innerHTML = country.deathsPerPop;
+
+ row.appendChild(countryBox);
+ row.appendChild(casesBox);
+ row.appendChild(deathBox);
+ row.appendChild(recoveredBox);
+ row.appendChild(casesPerPopBox);
+ row.appendChild(deathPerPopBox);
+
+ return row;
+}
+
+/**
+ * Produces a row containing the totals of countries
+ */
+function totalRow() {
+ const country = {
+ name: 'Total',
+ cases: sumAll('cases'),
+ deaths: sumAll('deaths'),
+ recovered: sumAll('recovered'),
+ casesPerPop: null,
+ deathsPerPop: null,
+ };
+
+ function sumAll(type) {
+ let result = 0;
+ for (let index = 0; index < countries.length; index++) {
+ result += countries[index][type];
+ }
+ return result;
+ }
+
+ return countryRow(country);
+}
diff --git a/html/test_02.04.20/resources/css/main.css b/html/test_03.04.20/resources/css/main.css
similarity index 100%
rename from html/test_02.04.20/resources/css/main.css
rename to html/test_03.04.20/resources/css/main.css
diff --git a/html/test_02.04.20/resources/external-lib/highcharts.js b/html/test_03.04.20/resources/external-lib/highcharts.js
similarity index 100%
rename from html/test_02.04.20/resources/external-lib/highcharts.js
rename to html/test_03.04.20/resources/external-lib/highcharts.js
diff --git a/html/test_02.04.20/resources/external-lib/highchartsTheme.js b/html/test_03.04.20/resources/external-lib/highchartsTheme.js
similarity index 100%
rename from html/test_02.04.20/resources/external-lib/highchartsTheme.js
rename to html/test_03.04.20/resources/external-lib/highchartsTheme.js
diff --git a/html/test_02.04.20/resources/external-lib/jquery.js b/html/test_03.04.20/resources/external-lib/jquery.js
similarity index 100%
rename from html/test_02.04.20/resources/external-lib/jquery.js
rename to html/test_03.04.20/resources/external-lib/jquery.js
diff --git a/html/test_02.04.20/resources/js/error.js b/html/test_03.04.20/resources/js/error.js
similarity index 100%
rename from html/test_02.04.20/resources/js/error.js
rename to html/test_03.04.20/resources/js/error.js
diff --git a/html/test_02.04.20/resources/js/linkConnector.js b/html/test_03.04.20/resources/js/linkConnector.js
similarity index 100%
rename from html/test_02.04.20/resources/js/linkConnector.js
rename to html/test_03.04.20/resources/js/linkConnector.js
diff --git a/html/test_02.04.20/resources/js/tasksJSON.js b/html/test_03.04.20/resources/js/tasksJSON.js
similarity index 100%
rename from html/test_02.04.20/resources/js/tasksJSON.js
rename to html/test_03.04.20/resources/js/tasksJSON.js
diff --git a/index.html b/index.html
index 5e39681..689d2ce 100755
--- a/index.html
+++ b/index.html
@@ -58,7 +58,7 @@
Heldagsprøve 15. November 2019
Totimers Prøve 13. Februar 2020
Totimers Prøve 13. Februar 2020 V2
-
Heldagsprøve 02. April 2020
+
Heldagsprøve 02. April 2020