begin
This commit is contained in:
19
ui/apply/components/NavBar.js
Normal file
19
ui/apply/components/NavBar.js
Normal file
@@ -0,0 +1,19 @@
|
||||
css(`
|
||||
nav-bar {
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
}
|
||||
`)
|
||||
|
||||
export default class NavBar extends HTMLElement {
|
||||
|
||||
connectedCallback() {
|
||||
|
||||
this.innerHTML += /* html */ `
|
||||
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("nav-bar", NavBar)
|
||||
581
ui/apply/components/Questionnaire.js
Normal file
581
ui/apply/components/Questionnaire.js
Normal file
@@ -0,0 +1,581 @@
|
||||
css(`
|
||||
questionnaire- {
|
||||
display: grid;
|
||||
grid-template-columns: 250px 1fr;
|
||||
gap: 20px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
margin-top: 17vh;
|
||||
}
|
||||
|
||||
.toc {
|
||||
position: sticky;
|
||||
top: 17vh;
|
||||
align-self: start;
|
||||
background: var(--tan);
|
||||
padding: 10px;
|
||||
border: 1px solid var(--brown);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.toc h2 {
|
||||
margin-top: 0;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.toc a {
|
||||
display: block;
|
||||
margin: 5px 0;
|
||||
text-decoration: none;
|
||||
color: var(--green);
|
||||
}
|
||||
|
||||
.toc a.active {
|
||||
font-weight: bold;
|
||||
color: var(--red);
|
||||
}
|
||||
|
||||
section {
|
||||
border: 1px solid var(--brown);
|
||||
margin-bottom: 2vh;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
background: none;
|
||||
user-select: none;
|
||||
transition: background 0.2s, border 0.2s, color 0.2s;
|
||||
}
|
||||
|
||||
.section-content {
|
||||
scroll-margin-top: 20px;
|
||||
padding-bottom: 40px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
textarea:focus,
|
||||
select:focus {
|
||||
outline: 1px solid #ddbb36;
|
||||
border: 1px solid #c4a52f
|
||||
}
|
||||
|
||||
/* Normal state */
|
||||
form button {
|
||||
transition: all 0.3s ease;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Loading: morph into circle + pulse */
|
||||
form button.loading {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
animation: pulse 1s infinite;
|
||||
}
|
||||
|
||||
/* Success state */
|
||||
button.success {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
width: auto;
|
||||
animation: none;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% { transform: scale(1); opacity: 1; }
|
||||
50% { transform: scale(1.1); opacity: 0.7; }
|
||||
100% { transform: scale(1); opacity: 1; }
|
||||
}
|
||||
`)
|
||||
|
||||
export default class Questionnaire extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.pages = [
|
||||
{ title: "Demographic Information", slug: "demographic", content: this.demographicContent() },
|
||||
{ title: "Contact Information", slug: "contact", content: this.contactContent() },
|
||||
{ title: "Personal History", slug: "personal-history", content: this.personalHistoryContent() },
|
||||
{ title: "Ancestry", slug: "ancestry", content: this.ancestryContent() },
|
||||
{ title: "Skills", slug: "skills", content: this.skillsContent() },
|
||||
{ title: "Interest", slug: "interest", content: this.interestContent() },
|
||||
{ title: "Criminal Record", slug: "criminal", content: this.criminalContent() },
|
||||
{ title: "Political Perspectives", slug: "political", content: this.politicalContent() },
|
||||
{ title: "Religious/Philosophical Views", slug: "religious", content: this.religiousContent() },
|
||||
{ title: "Federal Employment", slug: "federal-employment", content: this.federalEmploymentContent() },
|
||||
{ title: "Social Perspectives", slug: "social", content: this.socialContent() },
|
||||
];
|
||||
this.pageHTML = {};
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.fetchData();
|
||||
}
|
||||
|
||||
async fetchData() {
|
||||
try {
|
||||
const res = await fetch("/api/get-application");
|
||||
if (!res.ok) throw new Error(`HTTP error ${res.status}`);
|
||||
this.data = await res.json();
|
||||
console.log(this.data)
|
||||
} catch (err) {
|
||||
console.error("Failed to fetch questionnaire:", err);
|
||||
this.data = {};
|
||||
}
|
||||
this.render()
|
||||
}
|
||||
|
||||
render() {
|
||||
this.Layout();
|
||||
this.Forms();
|
||||
this.setupScrollSpy();
|
||||
this.populateFormData();
|
||||
this.markSectionsComplete();
|
||||
}
|
||||
|
||||
Layout() {
|
||||
this.innerHTML = /* html */`
|
||||
<nav class="toc">
|
||||
<h2>Contents</h2>
|
||||
${this.pages.map(p => `
|
||||
<a href="#${p.slug}" data-slug="${p.slug}">${p.title}</a>
|
||||
`).join("")}
|
||||
<a href="#submit">Submit</a>
|
||||
</nav>
|
||||
<div class="sections">
|
||||
${this.pages.map(p => /* html */`
|
||||
<section id="${p.slug}" class="section-content">
|
||||
<h1 style="margin-left: 3rem; margin-top: 3rem">${p.title}</h1>
|
||||
<div class="form-container">
|
||||
<form></form>
|
||||
</div>
|
||||
</section>
|
||||
`).join("")}
|
||||
<section id="submit" class="section-content">
|
||||
<h1 style="margin-left: 3rem; margin-top: 3rem">Submit Application</h1>
|
||||
<button style="margin-left: 3rem; margin-top: 3rem; background-color: gray" disabled>Submit</button>
|
||||
</section>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
Forms() {
|
||||
this.pages.forEach(page => {
|
||||
const form = this.querySelector(`#${page.slug} form`);
|
||||
if (form) form.innerHTML = page.content;
|
||||
form.innerHTML += `<button type="submit">Save</button>`
|
||||
form.addEventListener("submit", this.onFormSubmit)
|
||||
});
|
||||
}
|
||||
|
||||
populateFormData() {
|
||||
Object.entries(this.data).forEach(([key, value]) => {
|
||||
const fields = document.querySelectorAll(`[name="${key}"]`);
|
||||
if (!fields.length) return;
|
||||
|
||||
fields.forEach(field => {
|
||||
if (field.type === "checkbox" || field.type === "radio") {
|
||||
if (Array.isArray(value)) {
|
||||
field.checked = value.includes(field.value);
|
||||
} else {
|
||||
field.checked = field.value === value;
|
||||
}
|
||||
} else if (field.tagName === "SELECT" && field.multiple && Array.isArray(value)) {
|
||||
Array.from(field.options).forEach(opt => {
|
||||
opt.selected = value.includes(opt.value);
|
||||
});
|
||||
} else {
|
||||
field.value = value;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
markSectionsComplete() {
|
||||
let allFormsComplete = true
|
||||
let forms = document.querySelectorAll("form")
|
||||
for(let i =0; i<forms.length; i++) {
|
||||
let form = forms[i]
|
||||
if(form.checkValidity()) {
|
||||
form.closest("section").style.backgroundColor = "#0080003d"
|
||||
let toc = document.querySelector(`[data-slug=${form.closest("section").id}]`)
|
||||
if(!toc.innerHTML.includes("✓"))
|
||||
toc.innerHTML += " ✓"
|
||||
} else {
|
||||
allFormsComplete = false
|
||||
}
|
||||
}
|
||||
|
||||
if(allFormsComplete) {
|
||||
let button = document.querySelector("section#submit button")
|
||||
button.style.backgroundColor = ""
|
||||
button.removeAttribute("disabled")
|
||||
button.addEventListener("click", () => window.location.href = "/complete")
|
||||
}
|
||||
}
|
||||
|
||||
setupScrollSpy() {
|
||||
const tocLinks = this.querySelectorAll(".toc a");
|
||||
const sections = this.querySelectorAll(".section-content");
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
const id = entry.target.id;
|
||||
history.replaceState(null, "", `#${id}`);
|
||||
tocLinks.forEach(link => {
|
||||
link.classList.toggle("active", link.dataset.slug === id);
|
||||
});
|
||||
}
|
||||
});
|
||||
}, {
|
||||
rootMargin: "-50% 0px -50% 0px", // middle of screen
|
||||
threshold: 0
|
||||
});
|
||||
|
||||
sections.forEach(section => observer.observe(section));
|
||||
}
|
||||
|
||||
onFormSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
let form = e.target
|
||||
let button = form.querySelector('button[type="submit"]');
|
||||
|
||||
if (!form.checkValidity()) {
|
||||
// Let the browser display native validation errors
|
||||
return;
|
||||
}
|
||||
|
||||
const showButtonLoading = () => {
|
||||
button.classList.add('loading');
|
||||
button.disabled = true;
|
||||
button.textContent = '';
|
||||
}
|
||||
|
||||
const showButtonError = () => {
|
||||
button.classList.remove('loading');
|
||||
button.disabled = false;
|
||||
button.textContent = 'Save';
|
||||
if(!form.querySelector("p .error")) {
|
||||
form.parentElement.appendChild(html(`<p class="error" style="color: red">There has been an error. Please try again.</p>`))
|
||||
}
|
||||
}
|
||||
|
||||
const showButtonSuccess = () => {
|
||||
if(form.parentElement.querySelector("p")) {
|
||||
form.parentElement.querySelector("p").remove()
|
||||
}
|
||||
button.classList.remove('loading');
|
||||
button.classList.add('success');
|
||||
button.textContent = 'Success!';
|
||||
console.log(this)
|
||||
this.markSectionsComplete()
|
||||
}
|
||||
|
||||
showButtonLoading()
|
||||
|
||||
// Collect form data
|
||||
const data = new FormData(form);
|
||||
const values = {};
|
||||
data.forEach((v, k) => {
|
||||
if (values[k]) {
|
||||
// Already an array? push new value
|
||||
if (Array.isArray(values[k])) {
|
||||
values[k].push(v);
|
||||
} else {
|
||||
values[k] = [values[k], v];
|
||||
}
|
||||
} else {
|
||||
values[k] = v;
|
||||
}
|
||||
});
|
||||
|
||||
fetch('/api/application-save', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(values)
|
||||
})
|
||||
.then(res => {
|
||||
if (!res.ok) {
|
||||
throw new Error(`Server error: ${res.status}`);
|
||||
}
|
||||
return res.text();
|
||||
})
|
||||
.then(responseData => {
|
||||
console.log(form, form.parentElement)
|
||||
showButtonSuccess()
|
||||
console.log('Server response:', responseData);
|
||||
})
|
||||
.catch(err => {
|
||||
showButtonError()
|
||||
console.error('Submission error:', err);
|
||||
});
|
||||
|
||||
console.log("Form submitted:", values);
|
||||
}
|
||||
|
||||
demographicContent() {
|
||||
return /* html */`
|
||||
<label for="firstName">First Name *</label>
|
||||
<input type="text" name="firstName" class="form-control" required>
|
||||
<br><br>
|
||||
|
||||
<label for="lastName">Last Name *</label>
|
||||
<input type="text" name="lastName" class="form-control" required>
|
||||
<br><br>
|
||||
|
||||
<label for="age">Age *</label>
|
||||
<input type="text" name="age" class="form-control" required>
|
||||
<br><br>
|
||||
|
||||
<label for="gender">Gender *</label>
|
||||
<select name="gender" class="form-control" required>
|
||||
<option value="">Select...</option>
|
||||
<option value="male">Male</option>
|
||||
<option value="female">Female</option>
|
||||
</select>
|
||||
<br><br>
|
||||
|
||||
<label for="ethnicity">Type of Application *</label>
|
||||
<select name="applicationType" class="form-control" required>
|
||||
<option value="">Select...</option>
|
||||
<option value="single">Single</option>
|
||||
<option value="couple">Couple</option>
|
||||
<option value="family">Family</option>
|
||||
</select>
|
||||
<br><br>
|
||||
|
||||
<label for="sexualOrientation">Sexual Orientation *</label>
|
||||
<select name="sexualOrientation" class="form-control" required>
|
||||
<option value="">Select...</option>
|
||||
<option value="straight">Straight</option>
|
||||
<option value="gay">Gay</option>
|
||||
<option value="bisexual">Bisexual</option>
|
||||
<option value="other">Other</option>
|
||||
</select>
|
||||
<br><br>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
contactContent() {
|
||||
return /* html */`
|
||||
<div class="form-group">
|
||||
<label for="telegram">Telegram Username *</label>
|
||||
<input type="text" name="telegram" class="form-control" required>
|
||||
<small style="display:block;margin-top:.25rem;color:#666;">A Telegram account is required to be interviewed by the PMA</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email-2">Secondary Email</label>
|
||||
<input type="email" name="email-2" class="form-control">
|
||||
<small style="display:block;margin-top:.25rem;color:#666;">Not required - you may add a secondary email in case our messages don't reach you</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="phone">Phone Number</label>
|
||||
<input type="tel" name="phone" class="form-control">
|
||||
<small style="display:block;margin-top:.25rem;color:#666;">Not required, but recommended if you don't provide a Telegram handle.</small>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
personalHistoryContent() {
|
||||
return /* html */`
|
||||
<div class="form-group">
|
||||
<label for="personalHistory">Where did you come from, where did you grow up, and where do you live now? *</label>
|
||||
<textarea name="personalHistory" class="form-control" required minlength="10"></textarea>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
ancestryContent() {
|
||||
return /* html */`
|
||||
<div class="form-group">
|
||||
<p>Please select all that apply to your ancestry/heritage:</p>
|
||||
<div class="ancestry-grid">
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="english"> English</label>
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="irish"> Irish</label>
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="scottish"> Scottish</label>
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="welsh"> Welsh</label>
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="german"> German</label>
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="french"> French</label>
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="dutch"> Dutch</label>
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="scandinavian"> Scandinavian</label>
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="slavic"> Slavic</label>
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="balkan"> Balkan</label>
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="iberian"> Iberian</label>
|
||||
<label class="ancestry-option"><input type="checkbox" name="ancestry" value="other">Other</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ancestryDetails">Tell us more about your ancestry and family history *</label>
|
||||
<textarea name="ancestryDetails" class="form-control" required minlength="20" placeholder="Please provide details about your family background, heritage, and any ancestral connections you're aware of."></textarea>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
skillsContent() {
|
||||
return /* html */`
|
||||
<div class="form-group">
|
||||
<label for="skills">Describe any special skills or trades you have. *</label>
|
||||
<textarea name="skills" class="form-control" required minlength="50" placeholder="e.g., carpentry, plumbing, electrical, masonry, welding"></textarea>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
interestContent() {
|
||||
return /* html */`
|
||||
<div class="form-group">
|
||||
<label for="interest">Why are you interested in Return To The Land, and how did you find out about us? *</label>
|
||||
<textarea name="interest" class="form-control" required minlength="20"></textarea>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
criminalContent() {
|
||||
return /* html */`
|
||||
<label for="criminal">Do you have a criminal record? If so, please explain. Otherwise, just say "no". *</label>
|
||||
<textarea name="criminal" class="form-control" required></textarea>
|
||||
<br><br>
|
||||
`;
|
||||
}
|
||||
|
||||
politicalContent() {
|
||||
return /* html */`
|
||||
<label for="politicsNotes">Give a quick summary of your political ideas. *</label>
|
||||
<textarea name="politicsNotes" class="form-control" style="width:100%;min-height:120px" required minlength="40"></textarea>
|
||||
<br><br>
|
||||
|
||||
`;
|
||||
}
|
||||
|
||||
religiousContent() {
|
||||
return /* html */`
|
||||
<div class="form-group">
|
||||
<label>Do you identify with a particular religion? *</label>
|
||||
<div class="radio-row">
|
||||
<label><input type="radio" name="religionIdent" value="yes" required> Yes</label>
|
||||
<label><input type="radio" name="religionIdent" value="no"> No</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="religionName">If yes, which?</label>
|
||||
<input name="religionName" class="form-control" placeholder="e.g., Catholic, Orthodox, Protestant, Deist, Other">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Do you regularly attend services or observances?</label>
|
||||
<div class="radio-row">
|
||||
<label><input type="radio" name="attendance" value="weekly"> Weekly</label>
|
||||
<label><input type="radio" name="attendance" value="monthly"> Monthly</label>
|
||||
<label><input type="radio" name="attendance" value="occasionally"> Occasionally</label>
|
||||
<label><input type="radio" name="attendance" value="never"> Never</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="philosophy">Briefly describe your moral or philosophical outlook *</label>
|
||||
<textarea name="philosophy" class="form-control" required></textarea>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
federalEmploymentContent() {
|
||||
return /* html */`
|
||||
<div class="form-group">
|
||||
<label>Are you currently employed by, or otherwise receive funds to perform work for, the United States federal government or a contractor/affiliate/partner? *</label>
|
||||
<div class="radio-row">
|
||||
<label><input type="radio" name="employedByGovernment" value="yes" required> Yes</label>
|
||||
<label><input type="radio" name="employedByGovernment" value="no"> No</label>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
socialContent() {
|
||||
return /* html */`
|
||||
<p class="note">Please answer these questions regarding controversial topics. Anything that needs further explanation can be done in the interview.</p>
|
||||
<br>
|
||||
<div class="form-group">
|
||||
<label>I support gay marriage *</label>
|
||||
<div class="radio-row">
|
||||
<label><input type="radio" name="gays" value="yes" required> Yes</label>
|
||||
<label><input type="radio" name="gays" value="no"> No</label>
|
||||
<label><input type="radio" name="gays" value="neutral"> Neutral</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>I support transgenderism *</label>
|
||||
<div class="radio-row">
|
||||
<label><input type="radio" name="trannies" value="yes" required> Yes</label>
|
||||
<label><input type="radio" name="trannies" value="no"> No</label>
|
||||
<label><input type="radio" name="trannies" value="neutral"> Neutral</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>I support foreign immigration *</label>
|
||||
<div class="radio-row">
|
||||
<label><input type="radio" name="immigration" value="yes" required> Yes</label>
|
||||
<label><input type="radio" name="immigration" value="no"> No</label>
|
||||
<label><input type="radio" name="immigration" value="neutral"> Neutral</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>I support the COVID vaccine and mask *</label>
|
||||
<div class="radio-row">
|
||||
<label><input type="radio" name="vax" value="yes" required> Yes</label>
|
||||
<label><input type="radio" name="vax" value="no"> No</label>
|
||||
<label><input type="radio" name="vax" value="neutral"> Neutral</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>I support abortion *</label>
|
||||
<div class="form-group">
|
||||
<label><input type="radio" name="abortion" value="yes" required> Yes</label>
|
||||
<label><input type="radio" name="abortion" value="no"> No</label>
|
||||
<label><input type="radio" name="abortion" value="neutral"> Neutral</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>I support segregation *</label>
|
||||
<div class="radio-row">
|
||||
<label><input type="radio" name="segregation" value="yes" required> Yes</label>
|
||||
<label><input type="radio" name="segregation" value="no"> No</label>
|
||||
<label><input type="radio" name="segregation" value="neutral"> Neutral</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>I support procreation *</label>
|
||||
<div class="radio-row">
|
||||
<label><input type="radio" name="procreation" value="yes" required> Yes</label>
|
||||
<label><input type="radio" name="procreation" value="no"> No</label>
|
||||
<label><input type="radio" name="procreation" value="neutral"> Neutral</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Multiculturalism preference *</label>
|
||||
<div class="radio-row">
|
||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="multiculturalism" value="yes" required> I prefer a community with a variety of different ancestral origins</label>
|
||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="multiculturalism" value="no"> I prefer a community where everyone shares common continental ancestry</label>
|
||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="multiculturalism" value="neutral"> Neutral</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>How often do you think about the Roman empire? *</label>
|
||||
<div class="radio-row">
|
||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="romanEmpire" value="daily" required> Every day, at least once</label>
|
||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="romanEmpire" value="weekly"> A few times a week, probably</label>
|
||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="romanEmpire" value="rarely"> Very rarely</label>
|
||||
<label style="display:block;margin:.35rem 0"><input type="radio" name="romanEmpire" value="never"> Never</label>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("questionnaire-", Questionnaire);
|
||||
Reference in New Issue
Block a user