242 lines
8 KiB
JavaScript
242 lines
8 KiB
JavaScript
|
|
||
|
const politicians_data_path = "./data/meps_dk.json";
|
||
|
|
||
|
|
||
|
class Riksdagen {
|
||
|
constructor (members) {
|
||
|
this.members = members;
|
||
|
|
||
|
// Add internal reference to party for each member.
|
||
|
for (const party of Object.keys(this.members)) {
|
||
|
for (let index = 0; index < this.members[party].length; index++) {
|
||
|
this.members[party][index]['parti'] = party
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
getPartyName (abbreviation) {
|
||
|
/*
|
||
|
Get full party name from abbreviated form.
|
||
|
*/
|
||
|
|
||
|
switch (abbreviation) {
|
||
|
case 'Greens':
|
||
|
return 'Group of the Greens/European Free Alliance'
|
||
|
case 'Renew':
|
||
|
return 'Renew Europe Group'
|
||
|
case 'S':
|
||
|
return 'Socialdemokraterne'
|
||
|
case 'V':
|
||
|
return 'Venstre'
|
||
|
case 'ID':
|
||
|
return 'Identitet og Demokrati'
|
||
|
case 'EPP':
|
||
|
return 'Det Europæiske Folkepartis Gruppe'
|
||
|
default:
|
||
|
return abbreviation
|
||
|
}
|
||
|
}
|
||
|
|
||
|
get parties () {
|
||
|
/*
|
||
|
Get list of abbreviations of all parties.
|
||
|
*/
|
||
|
return Object.keys(this.members).sort()
|
||
|
}
|
||
|
|
||
|
get recipient () {
|
||
|
/*
|
||
|
Get information about selected member.
|
||
|
*/
|
||
|
|
||
|
const member = this.memberSelector.querySelector(':checked')
|
||
|
|
||
|
if (!member) return null;
|
||
|
|
||
|
const party = member.dataset.party
|
||
|
const index = parseInt(member.dataset.index)
|
||
|
|
||
|
return this.members[party][index]
|
||
|
}
|
||
|
|
||
|
configureRecipientSelection (recipientSelectorId) {
|
||
|
/*
|
||
|
Load list of parties and members for recipient selection.
|
||
|
*/
|
||
|
|
||
|
// Create elements to host list of parties
|
||
|
// and list of members of the selected party
|
||
|
const recipientSelector = document.getElementById(recipientSelectorId)
|
||
|
|
||
|
this.partySelector = document.createElement('fieldset')
|
||
|
this.partySelector.setAttribute('class', 'select-party')
|
||
|
recipientSelector.appendChild(this.partySelector)
|
||
|
|
||
|
this.memberSelector = document.createElement('div')
|
||
|
this.memberSelector.setAttribute('class', 'select-member')
|
||
|
recipientSelector.appendChild(this.memberSelector)
|
||
|
|
||
|
|
||
|
// Set up party selection
|
||
|
for (const party of this.parties) {
|
||
|
const partyId = `party-${party}`
|
||
|
|
||
|
// Create radio button
|
||
|
const input = document.createElement('input')
|
||
|
input.setAttribute('type', 'radio')
|
||
|
input.setAttribute('id', partyId)
|
||
|
input.setAttribute('name', 'party')
|
||
|
input.setAttribute('value', party)
|
||
|
input.setAttribute('required', 'required')
|
||
|
|
||
|
// Create label
|
||
|
const label = document.createElement('label')
|
||
|
label.setAttribute('for', partyId)
|
||
|
label.setAttribute('class', partyId)
|
||
|
label.append(this.getPartyName(party))
|
||
|
|
||
|
// Add elements to list
|
||
|
this.partySelector.append(input)
|
||
|
this.partySelector.append(label)
|
||
|
}
|
||
|
|
||
|
// On selecting a party,
|
||
|
// generate list for member selection.
|
||
|
this.partySelector.addEventListener('input', () => {
|
||
|
const activeElement = document.activeElement
|
||
|
|
||
|
this.memberSelector.innerHTML = ""
|
||
|
|
||
|
const selectedParty = this.partySelector.querySelector('input[name="party"]:checked').value
|
||
|
|
||
|
const prio = {
|
||
|
"MEP": 0,
|
||
|
/*
|
||
|
"Partiledare": 1,
|
||
|
"EU-parlamentet": 2,
|
||
|
"Gruppledare": 3,
|
||
|
"Konstitutionsutskottet": 4,
|
||
|
"Justitieutskottet": 5,
|
||
|
"EU-nämnden": 6,
|
||
|
*/
|
||
|
};
|
||
|
// Sort members beforehand
|
||
|
// First show the members with uppdrag "Partiledare",
|
||
|
// then the people with uppdrag "EU-parlamentet", etc.
|
||
|
const members = this.members[selectedParty].sort((a, b) => {
|
||
|
if (prio[a['uppdrag'][0]] > prio[b['uppdrag'][0]]) {
|
||
|
return 1;
|
||
|
} else if (prio[a['uppdrag'][0]] < prio[b['uppdrag'][0]]) {
|
||
|
return -1;
|
||
|
} else {
|
||
|
return a['namn'] > b['namn'] ? 1 : -1
|
||
|
}
|
||
|
})
|
||
|
|
||
|
// let euHeader = document.createElement('h2')
|
||
|
// euHeader.innerHTML = "EU-parlamentet"
|
||
|
// this.memberSelector.appendChild(euHeader)
|
||
|
|
||
|
for (const [index, member] of members.entries()) {
|
||
|
const memberId = `member-${selectedParty}-${index}`
|
||
|
|
||
|
const radio = document.createElement('input')
|
||
|
radio.setAttribute('type', 'radio')
|
||
|
radio.setAttribute('class', 'member')
|
||
|
radio.setAttribute('name', 'member')
|
||
|
radio.setAttribute('id', memberId)
|
||
|
radio.setAttribute('value', index)
|
||
|
radio.setAttribute('data-party', selectedParty)
|
||
|
radio.setAttribute('data-index', index)
|
||
|
|
||
|
const label = document.createElement('label')
|
||
|
label.setAttribute('for', memberId)
|
||
|
label.setAttribute('class', 'member')
|
||
|
label.setAttribute('title', member['namn'])
|
||
|
//label.append(member['namn'])
|
||
|
const uppdragString = member["uppdrag"].join(", ")
|
||
|
label.append(member['namn']+" ("+uppdragString+")")
|
||
|
|
||
|
this.memberSelector.appendChild(radio)
|
||
|
this.memberSelector.appendChild(label)
|
||
|
|
||
|
// Select the first option.
|
||
|
if (index == 0) label.click();
|
||
|
}
|
||
|
|
||
|
// Return focus to the selected party
|
||
|
activeElement.focus()
|
||
|
})
|
||
|
|
||
|
// On selecting a member,
|
||
|
// set placeholders for recipient information.
|
||
|
this.memberSelector.addEventListener('input', () => {
|
||
|
const recipient = this.recipient
|
||
|
|
||
|
setPlaceholder('recipient__party', this.getPartyName(recipient['parti']))
|
||
|
setPlaceholder('recipient__name', recipient['namn'])
|
||
|
setPlaceholder('recipient__epostadress', recipient['epostadress'])
|
||
|
})
|
||
|
}
|
||
|
|
||
|
|
||
|
get subject () {
|
||
|
/*
|
||
|
Get selected subject.
|
||
|
*/
|
||
|
const subjectInput = document.querySelector('.options__subject input:checked')
|
||
|
const subjectLabel = document.querySelector(`.options__subject label[for="${subjectInput.id}"]`)
|
||
|
return subjectLabel.innerText
|
||
|
}
|
||
|
|
||
|
get senderName () {
|
||
|
/*
|
||
|
Get sender name.
|
||
|
*/
|
||
|
return document.getElementById('sender__name').value
|
||
|
}
|
||
|
|
||
|
generateOutput () {
|
||
|
/*
|
||
|
Generate subject and body for E-mail.
|
||
|
*/
|
||
|
|
||
|
const recipient = this.recipient
|
||
|
|
||
|
// Don't generate email if recipient is not selected.
|
||
|
if (!recipient) return;
|
||
|
if (!this.senderName) return;
|
||
|
|
||
|
|
||
|
// Set subject
|
||
|
const subject = document.getElementById('output__subject')
|
||
|
subject.innerText = this.subject
|
||
|
|
||
|
// Set body
|
||
|
const body = document.getElementById('output__body')
|
||
|
let bodyContents = ""
|
||
|
for (const options of document.querySelectorAll('.options__body input:checked + label')) {
|
||
|
bodyContents += `${options.innerText.trim()}\n\n`;
|
||
|
}
|
||
|
body.innerText = bodyContents.trim()
|
||
|
|
||
|
// Set mailto-link
|
||
|
const email = document.getElementById('output__email')
|
||
|
const emailAddress = recipient['epostadress']
|
||
|
email.innerText = emailAddress
|
||
|
|
||
|
const encodedSubject = encodeURIComponent(this.subject)
|
||
|
const encodedBody = encodeURIComponent(bodyContents)
|
||
|
|
||
|
const mailto = document.getElementById('output__mailto')
|
||
|
const mailtoURL = `mailto:${emailAddress}?subject=${encodedSubject}&body=${encodedBody}`
|
||
|
mailto.setAttribute('href', mailtoURL)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async function load_mep_data() {
|
||
|
const response = await fetch(politicians_data_path);
|
||
|
const result = await response.json();
|
||
|
return result;
|
||
|
}
|