Client-side poll creation
This commit is contained in:
parent
44d0940e23
commit
4572e730f9
@ -2,5 +2,9 @@
|
||||
|
||||
require_once __DIR__ .'/bootstrap.php';
|
||||
|
||||
// Support the old Dragonpolls links
|
||||
if (isset($_GET['poll'])) {
|
||||
redirect('view_poll.php?id='.$_GET['poll']);
|
||||
}
|
||||
echo get_page_header();
|
||||
echo get_page_footer();
|
||||
|
38
new_poll.php
38
new_poll.php
@ -11,11 +11,43 @@ use APnutI\Entities\Poll;
|
||||
use APnutI\Entities\User;
|
||||
|
||||
try {
|
||||
echo get_page_header('New Poll', true, ['poll']);
|
||||
echo get_page_header('New Poll', true, ['new_poll']);
|
||||
} catch (\Exception $e) {
|
||||
die('Something went wrong :( "'.$e->getMessage().'"');
|
||||
die('Something went wrong :( "'.$e->getMessage().'"' . get_page_footer());
|
||||
}
|
||||
|
||||
if (!$api->isAuthenticated(false, true)) {
|
||||
die('You need to be logged in to create a new poll!');
|
||||
die('You need to be logged in to create a new poll!' . get_page_footer());
|
||||
}
|
||||
?>
|
||||
|
||||
<form method="POST" class="create-poll">
|
||||
<label for="prompt">Prompt</label>
|
||||
<input type="text" name="prompt" placeholder="What would you like to poll about?" id="prompt" required/>
|
||||
<label for="options">Options</label>
|
||||
<div id="options">
|
||||
<?php
|
||||
for ($i = 0; $i < 10; $i++) { ?>
|
||||
<input
|
||||
type="text"
|
||||
name="option[]"
|
||||
placeholder="This will be option #<?= $i+1 ?>" <?= $i < 2 ? 'required' : '' ?>/>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<label for="anonymous">Anonymous</label>
|
||||
<input type="checkbox" name="anonymous" id="anonymous" />
|
||||
<label for="public">Public</label>
|
||||
<input type="checkbox" name="public" id="public" />
|
||||
<label for="max_options">Max Options</label>
|
||||
<input type="number" name="max_options" id="max_options" min="1" max="10" value="1" required/>
|
||||
<label for="duration">Duration</label>
|
||||
<div id="duration">
|
||||
<input type="number" name="duration_days" value="1" min="0" required/><span>day(s)</span>
|
||||
<input type="number" name="duration_hours" value="0" min="0" required/><span>hour(s)</span>
|
||||
<input type="number" name="duration_minutes" value="0" min="0" required/><span>minute(s)</span><br>
|
||||
<span id="openUntil"></span>
|
||||
</div>
|
||||
<span class="error"></span>
|
||||
<button type="submit" name="submit" value="submit">Create poll</button>
|
||||
</form>
|
||||
</form>
|
52
scripts/new_poll.js
Normal file
52
scripts/new_poll.js
Normal file
@ -0,0 +1,52 @@
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
for (const el of document.querySelectorAll('.create-poll input')) {
|
||||
el.onchange = validatePoll;
|
||||
}
|
||||
});
|
||||
|
||||
function validatePoll() {
|
||||
let errors = [];
|
||||
const form = document.querySelector('.create-poll');
|
||||
if (!form.querySelector('input[name=prompt]').value) {
|
||||
errors.push('Prompt cannot be empty');
|
||||
}
|
||||
const numOptionsProvided = Array.from(form.querySelectorAll('input[name="option[]"]'))
|
||||
.map(x => !!x.value)
|
||||
.filter(x => x)
|
||||
.length;
|
||||
if (numOptionsProvided <= 1) {
|
||||
errors.push('At least two options must be provided');
|
||||
}
|
||||
|
||||
const maxOptions = parseInt(form.querySelector('input[name=max_options]').value);
|
||||
if (numOptionsProvided > 1 && (isNaN(maxOptions) || maxOptions <= 0 || maxOptions >= numOptionsProvided)) {
|
||||
errors.push(`Max Options needs to be greater than 0 and smaller than ${numOptionsProvided}`);
|
||||
}
|
||||
|
||||
const durationDays = parseInt(form.querySelector('input[name=duration_days]').value);
|
||||
const durationHours = parseInt(form.querySelector('input[name=duration_hours]').value);
|
||||
const durationMinutes = parseInt(form.querySelector('input[name=duration_minutes]').value);
|
||||
const durationTotalMinutes = durationDays*60*24 + durationHours * 60 + durationMinutes;
|
||||
// 20160 is the max duration accepted by pnut
|
||||
if (isNaN(durationTotalMinutes) || durationTotalMinutes < 1 || durationTotalMinutes > 20160) {
|
||||
errors.push('Duration must be more than 1 and less than 20160 minutes');
|
||||
}
|
||||
|
||||
const closesAtLabel = document.getElementById('openUntil');
|
||||
if (!isNaN(durationTotalMinutes)) {
|
||||
// Add duration_total_minutes to the curent Date
|
||||
const closes_at = new Date(new Date().getTime() + durationTotalMinutes*60000);
|
||||
closesAtLabel.innerText = `Open until ${closes_at.toLocaleString()}`;
|
||||
} else {
|
||||
closesAtLabel.innerText = '';
|
||||
}
|
||||
|
||||
const errorSpan = form.querySelector('.error');
|
||||
if (errors.length) {
|
||||
errorSpan.innerHTML = `<ul><li>${errors.join('</li><li>')}</li></ul>`;
|
||||
} else {
|
||||
errorSpan.innerText = '';
|
||||
}
|
||||
form.querySelector('button[name=submit]').disabled = !!errors.length;
|
||||
|
||||
}
|
@ -182,6 +182,70 @@ datewrapper time {
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
/* Poll creation */
|
||||
|
||||
.create-poll {
|
||||
display: grid;
|
||||
max-width: 400px;
|
||||
grid-auto-columns: auto 1fr;
|
||||
grid-column-gap: 8px;
|
||||
}
|
||||
.create-poll input[type=text],
|
||||
.create-poll input[type=number],
|
||||
.create-poll input[type=checkbox] {
|
||||
grid-column: 2;
|
||||
}
|
||||
.create-poll input[type=number] {
|
||||
max-width: 3em;
|
||||
background-color: var(--secondary-bg-color);
|
||||
color: var(--main-accent-color);
|
||||
}
|
||||
.create-poll input[type=text] {
|
||||
display: block;
|
||||
width: 100%;
|
||||
background-color: var(--secondary-bg-color);
|
||||
color: var(--main-accent-color);
|
||||
}
|
||||
.create-poll input[type=text]:focus {
|
||||
outline: 1px solid var(--main-accent-color);
|
||||
}
|
||||
.create-poll label {
|
||||
grid-column: 1;
|
||||
}
|
||||
.create-poll label[for=options] {
|
||||
grid-row: 2;
|
||||
}
|
||||
.create-poll #options {
|
||||
grid-row: 2;
|
||||
}
|
||||
.create-poll label[for=anonymous] {
|
||||
grid-row: 3
|
||||
}
|
||||
.create-poll label[for=public] {
|
||||
grid-row: 4
|
||||
}
|
||||
.create-poll label[for=max_options] {
|
||||
grid-row: 5
|
||||
}
|
||||
.create-poll label[for=duration] {
|
||||
grid-row: 6
|
||||
}
|
||||
#duration {
|
||||
grid-row: 6;
|
||||
}
|
||||
.create-poll button[type=submit] {
|
||||
grid-row: 8;
|
||||
}
|
||||
|
||||
.create-poll .error {
|
||||
grid-column: 1/3;
|
||||
grid-row: 7;
|
||||
background-color: rgba(255, 0, 0, 0.3);
|
||||
}
|
||||
.create-poll .error:not(:empty) {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
footer {
|
||||
display: flex;
|
||||
|
Loading…
Reference in New Issue
Block a user