Add 'insert' view for inserting ratings on paper
parent
bb7e7b5089
commit
d0694ed38a
@ -1,5 +1,11 @@
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
|
||||
class InsertForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
rating = forms.ChoiceField(choices=settings.RATING_CHOICES, required=False, widget=forms.RadioSelect)
|
||||
|
||||
InsertFormSet = forms.formset_factory(InsertForm)
|
||||
|
||||
class RateArtistForm(forms.Form):
|
||||
rating = forms.ChoiceField(choices=settings.RATING_CHOICES, required=False, widget=forms.RadioSelect)
|
||||
|
@ -0,0 +1,126 @@
|
||||
{% extends "core/base.html" %}
|
||||
|
||||
{% block title %}A/D-Wandler{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
|
||||
{{ formset.management_form }}
|
||||
|
||||
{% for form in formset %}
|
||||
<div class="row">
|
||||
{{ form.name }}
|
||||
|
||||
<div class="rating-container">
|
||||
<div class="rating" style="--num-choices: {{ form.rating | length }}">
|
||||
{% for radio in form.rating %}
|
||||
{{ radio.tag }}
|
||||
<label class="rating-point" for="{{ radio.id_for_label }}"></label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="reset" type="button">Zurücksetzen</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<button id="add" type="button">+</button>
|
||||
|
||||
<button type="submit">Speichern</button>
|
||||
</form>
|
||||
|
||||
{{ playlist | json_script:"playlist" }}
|
||||
<script>
|
||||
const playlist = JSON.parse(document.getElementById('playlist').textContent);
|
||||
|
||||
const findBestMatch = value => playlist.find(name => name.toLowerCase().includes(value) || value.includes(name.toLowerCase())) || '';
|
||||
|
||||
const registerEvents = row => {
|
||||
const input = row.querySelector('input[name$=name]');
|
||||
input.addEventListener('input', () => {
|
||||
const value = (input.dataset.value || '') + input.value.toLowerCase();
|
||||
input.dataset.value = value;
|
||||
|
||||
const bestMatch = findBestMatch(value);
|
||||
input.placeholder = bestMatch;
|
||||
input.value = '';
|
||||
input.dataset.bestMatch = bestMatch;
|
||||
});
|
||||
input.addEventListener('keydown', event => {
|
||||
if (event.key === 'Backspace') {
|
||||
if (input.value !== '') {
|
||||
input.value = '';
|
||||
} else {
|
||||
const value = (input.dataset.value || '').slice(0, -1);
|
||||
input.dataset.value = value;
|
||||
|
||||
if (value === '') {
|
||||
input.placeholder = '';
|
||||
input.dataset.bestMatch = '';
|
||||
} else {
|
||||
const bestMatch = findBestMatch(value);
|
||||
input.placeholder = bestMatch;
|
||||
input.dataset.bestMatch = bestMatch;
|
||||
}
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
} else if (event.key === 'Tab') {
|
||||
input.placeholder = '';
|
||||
input.value = input.dataset.bestMatch || '';
|
||||
input.dataset.bestMatch = '';
|
||||
input.dataset.value = '';
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
row.querySelector('.reset').addEventListener('click', event => {
|
||||
event.target.parentElement.querySelectorAll('.rating-container > .rating > input').forEach(input => {
|
||||
input.checked = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
document.querySelectorAll('.row').forEach(registerEvents);
|
||||
|
||||
const totalForms = document.getElementById('id_form-TOTAL_FORMS');
|
||||
|
||||
let numForms = Number.parseInt(totalForms.value);
|
||||
|
||||
const replace = value => value.replace(/form-\d+-(.+)/, `form-${numForms}-$1`);
|
||||
|
||||
const addBtn = document.getElementById('add');
|
||||
addBtn.addEventListener('click', () => {
|
||||
const row = document.querySelector('.row').cloneNode(true);
|
||||
|
||||
row.querySelectorAll('[name^=form-]').forEach(input => {
|
||||
const label = row.querySelector(`label[for=${input.id}]`);
|
||||
if (label) {
|
||||
label.htmlFor = replace(label.htmlFor);
|
||||
}
|
||||
|
||||
input.id = replace(input.id);
|
||||
input.name = replace(input.name);
|
||||
});
|
||||
|
||||
const input = row.querySelector('input[name$=name]');
|
||||
input.placeholder = '';
|
||||
input.value = '';
|
||||
input.dataset.bestMatch = '';
|
||||
input.dataset.value = '';
|
||||
|
||||
row.querySelectorAll('.rating-container > .rating > input').forEach(input => {
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
registerEvents(row);
|
||||
|
||||
addBtn.before(row);
|
||||
|
||||
numForms += 1;
|
||||
totalForms.value = numForms;
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
Loading…
Reference in New Issue