1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> 5 <meta charset="UTF-8" /> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 7 <meta name="viewport" content="width=device-width, initial-scale=1" /> 8 <title data-translate="vf.site.title">Virtual Finland</title> 9
9<script type="text/javascript" src="resources/jquery-3.2.1.min.js"></script>
9 10
10<script type="text/javascript" src="resources/bootstrap.min.js"></script>
10 11
11<script type="text/javascript" src="resources/dictionary.js"></script>
11 12
12<script> 13 $(document).ready(function () { 14 $("div[data-include]").each(function () { 15 $(this).load($(this).attr("data-include")); 16 }); 17 }); 18 </script>
18 19
19<script src="https://ulkoministerio.boost.ai/chatPanel/chatPanel.js"></script>
19 20 <link type="text/css" href="resources/bootstrap.min.css" rel="stylesheet" /> 21 <link 22 type="text/css" 23 href="resources/Finlandica-webfont.css" 24 rel="stylesheet" 25 /> 26 <link 27 type="text/css" 28 href="resources/online-forms-vf.css" 29 rel="stylesheet" 30 /> 31 <link type="image/png" href="resources/images/favicon.png" rel="icon" /> 32 </head> 33 <body> 34 <div data-include="resources/header.html"></div> 35 <main> 36 37 <div class="container white container-hero comingtofinland"> 38 <h1 class="centered"> 39 <span data-translate="vf.enteringfinland.title"></span> 40 </h1> 41 </div> 42 43 <div class="container white container-main"> 44 <div class="col-md-1"></div> 45 <div class="col-md-9 text-main breadcrumbs"> 46 <a href="/" class="home-link" aria-label="Open UM Virtual Finland Index page"> 47 <img alt="" src="resources/images/home.png" /> 48 </a> 49 <span class="separator">/</span> 50 <span data-translate="vf.enteringfinland.title"></span> 51 </div> 52 <div class="col-md-1"></div> 53 </div> 54 55 <div class="container container-main white"> 56 <div class="col-md-1"></div> 57 <div class="col-md-9" poisstyle="padding: 16px 39px;"> 58 <div class=""> 59<div> 60<h2>Foreign nationals entering Finland</h2> 61<p>Services and guidance for foreign nationals planning to travel to Finland.<br/> 62<a href-translate="vf.enteringfinland.url" target="_blank" class="btn-link" id="immigration" aria-label="Open Ministry for Foreign Affairs" href="https://um.fi/entering-finland"> 63 <span data-translate="vf.enteringfinland.url.text">um.fi/entering-finland</span><img alt="" src="resources/images/arrow-up-right.svg" class="bi-arrow"> 64 </a> 65</p> 66</div> 67 </div> 68 </div> 69 <div class="col-md-1"></div> 70 </div> 71 72 <div class="container container-main white"> 73 <div class="col-md-1"></div> 74 <div class="col-md-9" poisstyle="padding: 16px 39px;"> 75 <div class=""> 76<div> 77<h2>A visa to visit Finland</h2> 78<p><!--<span style="font-size:300%; font-weight: 600; color: orange">! </span>-->Please note that you can submit a visa application only in the country where you are registered and legally residing.</p> 79</div> 80 <!-- <h3>Choose country</h3> --> 81 <div id="countryselection" style="padding-top: 1em;"></div> 82 </div> 83 </div> 84 <div class="col-md-1"></div> 85 </div> 86 87 <div class="container container-main white"> 88 <div class="col-md-1"></div> 89 <div class="col-md-5 links"> 90 <div id="requireddocumentsinfo" style="white-space: pre-wrap;"></div> 91 <div id="requireddocumentsselection"></div> 92 <div id="requireddocuments" style="white-space: pre-wrap; word-break: break-word;"></div> 93 </div> 94 <div class="col-md-5 links" id="appointmentslots"></div> 95 <div class="col-md-1"></div> 96 </div> 97 98 <div class="container"><div style="margin-bottom: 5em;"><br></div></div> 99 100 </main> 101 <div data-include="resources/footer.html"></div> 102
103<script> 104var debug = true; 105var pageLan = 'en'; 106var availableVisaAppointments = []; 107var maat = []; 108var nimet = []; 109var maakoodit = []; 110const apit = [ 111 '/api/finlandappointment/visa', 112 'resources/maakooditjanimet.json' 113]; 114var excludeCountries = ["CA","CO","CZ","IS","IT","LV","NL","SA","SG","CH"]; 115 116function markdownlinks2html(md) { 117 let markdownLinkRegex = /\[([^\]]+)\]\(([^)]+)\)/g; 118 var html = md.replaceAll('] (','](').replace(markdownLinkRegex, function(match, text, url) { 119 return '<a href="' + url + '" target="_blank">' + text + '</a>'; 120 }); 121 html = html.replaceAll(`\n`,`<br/>`); 122 return html 123} 124 125function naytaajat(edustustokoodi, lan) { 126 document.querySelector('#appointmentslots').innerHTML = edustustonajat(availableVisaAppointments, edustustokoodi, lan); 127} 128 129function edustustovalintalista(locationsdata, lan) { 130 var valintalista = `<select id="missions" onchange="naytaajat(this.value, '${lan}')">`; 131 locationsdata.locations.forEach(edustusto => { 132 console.log(`\n___________\n` + edustusto.location.country); 133 valintalista += `<option value="${edustusto.location.locationId}">${edustusto.location.locationName[lan]}</option>`; 134 }); 135 valintalista += `</select>`; 136 return valintalista 137} 138 139function naytatoimipisteet(maakoodi2, lan) { 140 document.querySelector('#appointmentslots').innerHTML = ''; 141 availableVisaAppointments.locations.filter(e => e.location.countryCode == maakoodi2).forEach(location => { 142 console.log(location.location.locationId); 143 document.querySelector('#appointmentslots').innerHTML += edustustonajat(availableVisaAppointments, location.location.locationId, lan); 144 }); 145} 146 147function maavalintalista(maalista, lan) {
148 var valintalista = `Choose country <select id="countries" onchange="naytatoimipisteet(this.value, '${lan}'); vaadittavatAsiakirjat(this.value, '${lan}');">`; 149 valintalista += `<option value="">-- select --</option>`; 150 maalista.forEach(maakoodi2 => { 151 console.log(`\n___________\n` + maakoodi2); 152 valintalista += `<option value="${maakoodi2}">${maat.find(maa => maa.maakoodi2 == maakoodi2).nimi[lan]}</option>`; 153 }); 154 valintalista += `</select>`; 155 return valintalista 156} 157 158function haeDocumentsinfo(maakoodi3) { 159 fetch(`/api/finlandvisa/documentsinfo_${maakoodi3}.txt`) 160 .then(response => response.text()) 161 .then(text => { 162 document.querySelector('#documentsinfo').innerHTML = `<p>${markdownlinks2html(text)}</p>`; 163 }) 164} 165 166function edustustonajat(locationsdata, edustustokoodi, lan) { 167 var ajanvaraustiedot = ''; 168 var edustusto = locationsdata.locations.find(e => e.location.locationId == edustustokoodi); 169 console.log(`\n___________\n` + edustusto.location.locationName[lan]); 170 ajanvaraustiedot += `<div id="locationinfo" class="poislink">`; 171 ajanvaraustiedot += `<h3>${edustusto.location.locationName[lan]}</h3>`; 172 //ajanvaraustiedot += `<p>${edustusto.location.countryCode}</p>`; 173 // HACK: 174 var requireddocumentsinfo = ''; 175 if(edustusto.generalInfo[lan] != '') requireddocumentsinfo += `<h3>General info</h3><p>${markdownlinks2html(edustusto.generalInfo[lan])}</p>`; 176 if(edustusto.requiredDocuments[lan] != '') requireddocumentsinfo += `<h3>Required documents</h3><p>${markdownlinks2html(edustusto.requiredDocuments[lan])}</p>`; 177 document.querySelector('#requireddocumentsinfo').innerHTML = requireddocumentsinfo; 178 // <- HACK 179 ajanvaraustiedot += `<div id="documentsinfo"></div>`; 180 //ajanvaraustiedot += `</div>`; 181 ajanvaraustiedot += `<div id="appointmentslots" class="poislink">`; 182 ajanvaraustiedot += `<p>Available appointment slots</p>`; 183 var pvm = ''; 184 var ajat = ''; 185 edustusto.availableTimes.forEach(slot => { 186 var slottime = new Date(slot); 187 var aika = { 188 "date": slottime.toLocaleDateString(lan, {"weekday": "long", "year": "numeric", "month": "numeric", "day": "numeric", "timeZone": slot.substr(19)}), 189 "time": slottime.toLocaleTimeString(lan, {"timeStyle":"short", "timeZone": slot.substr(19)}) 190 }; 191 if(aika.date != pvm) { 192 console.log(aika.date); 193 ajat += `<div style="margin-top: 1em;">${aika.date}</div>`; 194 } 195 console.log(' ' + aika.time); 196 ajat += `<button disabled>${aika.time}</button> `; 197 pvm = aika.date; 198 }); 199 ajanvaraustiedot += `<div>${ajat}</div>`; 200 ajanvaraustiedot += `<!--<div><a target="_blank" class="btn-link" id="appointmentsite" aria-label="Open Finland Appointment" href="https://finlandappointment.fi/?country=${edustusto.location.countryCode}&lang=${lan}&servicetype=${locationsdata.serviceType}">Go to the Appointment Service<img alt="" src="resources/images/arrow-up-right.svg" class="bi-arrow"></a></div>-->`; 201 ajanvaraustiedot += `<h4 style="margin-top: 2em;">Go to the Appointment Service</h4><div class="col-md-12 links" id="appointmentservice" style="padding-left: 0;">`; 202 ajanvaraustiedot += `<div style="width: 45%;margin-right: 5%;">Create a new user account<br/> 203<a class="btn-link" id="appointmentsite" aria-label="Register to Finland Appointment" 204href="https://finlandappointment.fi/register?country=${edustusto.location.countryCode}&lang=${lan}&servicetype=${locationsdata.serviceType}">Register 205<img alt="" src="resources/images/arrow-up-right.svg" class="bi-arrow"></a></div>`; 206 ajanvaraustiedot += `<div style="width: 45%;margin-right: 5%;">Already have an account?<br/> 207<a class="btn-link" id="appointmentsite" aria-label="Login to Finland Appointment" 208href="https://finlandappointment.fi/login?country=${edustusto.location.countryCode}&lang=${lan}&servicetype=${locationsdata.serviceType}">Login 209<img alt="" src="resources/images/arrow-up-right.svg" class="bi-arrow"></a></div>`; 210 ajanvaraustiedot += `</div></div>`; 211 //haeDocumentsinfo(maat.find(maa => maa.maakoodi2 == edustusto.location.countryCode).maakoodi3); 212 if(ajat == '') { 213 var sivustokoodi = maat.find(maa => maa.maakoodi2 == edustusto.location.countryCode).maakoodi3.toLowerCase(); 214 if(sivustokoodi == 'xkx') sivustokoodi = 'xkv'; 215 ajanvaraustiedot = `<div id="locationinfo"><h3>${edustusto.location.locationName[lan]}</h3><p>Please visit the Embassy webpage for more information</p><div><a class="btn-link" href="https://finlandabroad.fi/web/${sivustokoodi}/">finlandabroad.fi/web/${sivustokoodi}<img alt="" src="resources/images/arrow-up-right.svg" class="bi-arrow"></a></div>`; 216 } 217 return ajanvaraustiedot 218} 219 220function listaaVaadittavatAsiakirjat(vaadittavatAsiakirjat, id) { 221 console.log(vaadittavatAsiakirjat); 222 console.log(id); 223 var requiredDocumentsObj = JSON.parse(vaadittavatAsiakirjat.replaceAll(`¤`,`"`)); 224 var checklist = requiredDocumentsObj.find(e => e.checklistId == id); 225 var description = checklist.description; 226 var documents = '<div>';
227 checklist.documentCategories.forEach(e => { 228 console.log(e); 229 documents += `<h4>${e.description}</h4><ul>`; 230 e.documents.forEach(f => documents += `<li>${f.name}<br/>${f.description}</li>`); 231 documents += `</ul>`; 232 }); 233 documents += `</div>`; 234 document.querySelector('#requireddocuments').innerHTML = documents; 235 } 236 237function vaadittavatAsiakirjat(maakoodi2, lan) { 238 //document.querySelector('#requireddocumentsinfo').innerHTML = ''; 239 document.querySelector('#requireddocumentsselection').innerHTML = ''; 240 document.querySelector('#requireddocuments').innerHTML = ''; 241 var maakoodi3 = maat.find(maa => maa.maakoodi2 == maakoodi2).maakoodi3; 242 var requiredDocumentsApi = `/api/finlandvisa/requireddocuments_${maakoodi3}.json`; 243 fetch(requiredDocumentsApi) 244 .then(value => value.json()) 245 .then(requiredDocuments => { 246 var maanimi = maat.find(maa => maa.maakoodi2 == maakoodi2).nimi[lan]; 247 var requiredDocumentsString = JSON.stringify(requiredDocuments).replaceAll(`"`,`¤`); 248 var requiredDocumentsSelect = `<h3>Required documents in ${maanimi}</h3>`; 249 requiredDocumentsSelect += `<div id="documentsinfo"></div>`; 250 requiredDocumentsSelect += `<p>Select the checklist of the required documents based on the main purpose of travel.</p>`; 251 requiredDocumentsSelect += `<p>Please note that the checklist of required documents shall be filled in and printed out together with the online visa application form.</p>`; 252 requiredDocumentsSelect += `<p><select name="requiredDocumentsSelect" style="width: 100%;" data-requireddocuments="${requiredDocumentsString}" onchange="if(this.value != '') listaaVaadittavatAsiakirjat(this.dataset.requireddocuments, this.value);">`; 253 requiredDocumentsSelect += `<option value="" title="">-- select --</option>`; 254 requiredDocuments.forEach(checklist => { 255 console.log(`${checklist.checklistId} ${checklist.name}\n${checklist.description}`); 256 requiredDocumentsSelect += `<option value="${checklist.checklistId}" title="${checklist.description}"><span>${checklist.name}</span></option>`; 257 }); 258 requiredDocumentsSelect += `</select></p>`; 259 document.querySelector('#requireddocumentsselection').innerHTML = requiredDocumentsSelect; 260 haeDocumentsinfo(maakoodi3); 261 }); 262} 263 264 265const haedatat = async () => { 266 Promise.all(apit.map(a => {return fetch(a).then(value => value.json())})) 267 .then(responses => { 268 availableVisaAppointments = responses[0]; 269 maat = responses[1]; 270 if(debug) console.log(availableVisaAppointments); 271 if(debug) console.log(maat); 272 var valittavatmaat = []; 273 availableVisaAppointments.locations.forEach(loc => { 274 if(!valittavatmaat.includes(loc.location.countryCode) && !excludeCountries.includes(loc.location.countryCode)) valittavatmaat.push(loc.location.countryCode); 275 }); 276 document.querySelector('#countryselection').innerHTML = edustustovalintalista(availableVisaAppointments, pageLan); 277 document.querySelector('#countryselection').innerHTML = maavalintalista(valittavatmaat, pageLan); 278 const optionNodes = Array.from(document.querySelectorAll('#countries option')); 279 const comparator = new Intl.Collator(pageLan.slice(0, 2)).compare; 280 optionNodes.sort((a, b) => comparator(a.textContent, b.textContent)); 281 optionNodes.forEach((option) => document.querySelector('#countries').appendChild(option)); 282 }) 283}; 284 285haedatat(); 286 287 288</script>
288 289 290 </body> 291</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.