Merge pull request #2020 from bookwyrm-social/multi-input
Array input field for forms
This commit is contained in:
commit
13b82c2740
|
@ -14,6 +14,14 @@ class CoverForm(CustomForm):
|
||||||
help_texts = {f: None for f in fields}
|
help_texts = {f: None for f in fields}
|
||||||
|
|
||||||
|
|
||||||
|
class ArrayWidget(forms.widgets.TextInput):
|
||||||
|
# pylint: disable=unused-argument
|
||||||
|
# pylint: disable=no-self-use
|
||||||
|
def value_from_datadict(self, data, files, name):
|
||||||
|
"""get all values for this name"""
|
||||||
|
return [i for i in data.getlist(name) if i]
|
||||||
|
|
||||||
|
|
||||||
class EditionForm(CustomForm):
|
class EditionForm(CustomForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Edition
|
model = models.Edition
|
||||||
|
@ -41,12 +49,10 @@ class EditionForm(CustomForm):
|
||||||
"series_number": forms.TextInput(
|
"series_number": forms.TextInput(
|
||||||
attrs={"aria-describedby": "desc_series_number"}
|
attrs={"aria-describedby": "desc_series_number"}
|
||||||
),
|
),
|
||||||
|
"subjects": ArrayWidget(),
|
||||||
"languages": forms.TextInput(
|
"languages": forms.TextInput(
|
||||||
attrs={"aria-describedby": "desc_languages_help desc_languages"}
|
attrs={"aria-describedby": "desc_languages_help desc_languages"}
|
||||||
),
|
),
|
||||||
"subjects": forms.TextInput(
|
|
||||||
attrs={"aria-describedby": "desc_subjects_help desc_subjects"}
|
|
||||||
),
|
|
||||||
"publishers": forms.TextInput(
|
"publishers": forms.TextInput(
|
||||||
attrs={"aria-describedby": "desc_publishers_help desc_publishers"}
|
attrs={"aria-describedby": "desc_publishers_help desc_publishers"}
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,6 +1,19 @@
|
||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remoev input field
|
||||||
|
*
|
||||||
|
* @param {event} the button click event
|
||||||
|
*/
|
||||||
|
function removeInput(event) {
|
||||||
|
const trigger = event.currentTarget;
|
||||||
|
const input_id = trigger.dataset.remove;
|
||||||
|
const input = document.getElementById(input_id);
|
||||||
|
|
||||||
|
input.remove();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duplicate an input field
|
* Duplicate an input field
|
||||||
*
|
*
|
||||||
|
@ -29,4 +42,8 @@
|
||||||
document
|
document
|
||||||
.querySelectorAll("[data-duplicate]")
|
.querySelectorAll("[data-duplicate]")
|
||||||
.forEach((node) => node.addEventListener("click", duplicateInput));
|
.forEach((node) => node.addEventListener("click", duplicateInput));
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelectorAll("[data-remove]")
|
||||||
|
.forEach((node) => node.addEventListener("click", removeInput));
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
{% trans "Title:" %}
|
{% trans "Title:" %}
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="title" value="{{ form.title.value|default:'' }}" maxlength="255" class="input" required="" id="id_title" aria-describedby="desc_title">
|
<input type="text" name="title" value="{{ form.title.value|default:'' }}" maxlength="255" class="input" required="" id="id_title" aria-describedby="desc_title">
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.title.errors id="desc_title" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.title.errors id="desc_title" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
{% trans "Subtitle:" %}
|
{% trans "Subtitle:" %}
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="subtitle" value="{{ form.subtitle.value|default:'' }}" maxlength="255" class="input" id="id_subtitle" aria-describedby="desc_subtitle">
|
<input type="text" name="subtitle" value="{{ form.subtitle.value|default:'' }}" maxlength="255" class="input" id="id_subtitle" aria-describedby="desc_subtitle">
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.subtitle.errors id="desc_subtitle" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.subtitle.errors id="desc_subtitle" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
{% trans "Description:" %}
|
{% trans "Description:" %}
|
||||||
</label>
|
</label>
|
||||||
{{ form.description }}
|
{{ form.description }}
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.description.errors id="desc_description" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.description.errors id="desc_description" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
{% trans "Series:" %}
|
{% trans "Series:" %}
|
||||||
</label>
|
</label>
|
||||||
<input type="text" class="input" name="series" id="id_series" value="{{ form.series.value|default:'' }}" aria-describedby="desc_series">
|
<input type="text" class="input" name="series" id="id_series" value="{{ form.series.value|default:'' }}" aria-describedby="desc_series">
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.series.errors id="desc_series" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.series.errors id="desc_series" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
{% trans "Series number:" %}
|
{% trans "Series number:" %}
|
||||||
</label>
|
</label>
|
||||||
{{ form.series_number }}
|
{{ form.series_number }}
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.series_number.errors id="desc_series_number" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.series_number.errors id="desc_series_number" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,21 +75,60 @@
|
||||||
<span class="help" id="desc_languages_help">
|
<span class="help" id="desc_languages_help">
|
||||||
{% trans "Separate multiple values with commas." %}
|
{% trans "Separate multiple values with commas." %}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.languages.errors id="desc_languages" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.languages.errors id="desc_languages" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div>
|
||||||
<label class="label" for="id_subjects">
|
<label class="label" for="id_add_subjects">
|
||||||
{% trans "Subjects:" %}
|
{% trans "Subjects:" %}
|
||||||
</label>
|
</label>
|
||||||
{{ form.subjects }}
|
{% for subject in book.subjects %}
|
||||||
<span class="help" id="desc_subjects_help">
|
<label class="label is-sr-only" for="id_add_subject={% if not forloop.first %}-{{forloop.counter}}{% endif %}">
|
||||||
{% trans "Separate multiple values with commas." %}
|
{% trans "Add subject" %}
|
||||||
</span>
|
</label>
|
||||||
|
<div class="field has-addons" id="subject_field_wrapper_{{ forloop.counter }}">
|
||||||
|
<div class="control is-expanded">
|
||||||
|
<input
|
||||||
|
id="id_add_subject-{{ forloop.counter }}"
|
||||||
|
type="text"
|
||||||
|
name="subjects"
|
||||||
|
value="{{ subject }}"
|
||||||
|
class="input"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button
|
||||||
|
class="button is-danger is-light"
|
||||||
|
type="button"
|
||||||
|
data-remove="subject_field_wrapper_{{ forloop.counter }}"
|
||||||
|
>
|
||||||
|
{% trans "Remove subject" as text %}
|
||||||
|
<span class="icon icon-x" title="{{ text }}">
|
||||||
|
<span class="is-sr-only">{{ text }}</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<input
|
||||||
|
class="input"
|
||||||
|
type="text"
|
||||||
|
name="subjects"
|
||||||
|
id="id_add_subject"
|
||||||
|
value="{{ subject }}"
|
||||||
|
{% if confirm_mode %}readonly{% endif %}
|
||||||
|
>
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.subjects.errors id="desc_subjects" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.subjects.errors id="desc_subjects" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<span class="help">
|
||||||
|
<button class="button is-small" type="button" data-duplicate="id_add_subject" id="another_subject_field">
|
||||||
|
<span class="icon icon-plus" aria-hidden="true"></span>
|
||||||
|
<span>{% trans "Add Another Subject" %}</span>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -106,7 +145,7 @@
|
||||||
<span class="help" id="desc_publishers_help">
|
<span class="help" id="desc_publishers_help">
|
||||||
{% trans "Separate multiple values with commas." %}
|
{% trans "Separate multiple values with commas." %}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.publishers.errors id="desc_publishers" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.publishers.errors id="desc_publishers" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -115,7 +154,7 @@
|
||||||
{% trans "First published date:" %}
|
{% trans "First published date:" %}
|
||||||
</label>
|
</label>
|
||||||
<input type="date" name="first_published_date" class="input" id="id_first_published_date"{% if form.first_published_date.value %} value="{{ form.first_published_date.value|date:'Y-m-d' }}"{% endif %} aria-describedby="desc_first_published_date">
|
<input type="date" name="first_published_date" class="input" id="id_first_published_date"{% if form.first_published_date.value %} value="{{ form.first_published_date.value|date:'Y-m-d' }}"{% endif %} aria-describedby="desc_first_published_date">
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.first_published_date.errors id="desc_first_published_date" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.first_published_date.errors id="desc_first_published_date" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -124,7 +163,7 @@
|
||||||
{% trans "Published date:" %}
|
{% trans "Published date:" %}
|
||||||
</label>
|
</label>
|
||||||
<input type="date" name="published_date" class="input" id="id_published_date"{% if form.published_date.value %} value="{{ form.published_date.value|date:'Y-m-d'}}"{% endif %} aria-describedby="desc_published_date">
|
<input type="date" name="published_date" class="input" id="id_published_date"{% if form.published_date.value %} value="{{ form.published_date.value|date:'Y-m-d'}}"{% endif %} aria-describedby="desc_published_date">
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.published_date.errors id="desc_published_date" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.published_date.errors id="desc_published_date" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -162,7 +201,12 @@
|
||||||
<input class="input" type="text" name="add_author" id="id_add_author" placeholder="{% trans 'Jane Doe' %}" value="{{ author }}" {% if confirm_mode %}readonly{% endif %}>
|
<input class="input" type="text" name="add_author" id="id_add_author" placeholder="{% trans 'Jane Doe' %}" value="{{ author }}" {% if confirm_mode %}readonly{% endif %}>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<span class="help"><button class="button is-small" type="button" data-duplicate="id_add_author" id="another_author_field">{% trans "Add Another Author" %}</button></span>
|
<span class="help">
|
||||||
|
<button class="button is-small" type="button" data-duplicate="id_add_author" id="another_author_field">
|
||||||
|
<span class="icon icon-plus" aria-hidden="true"></span>
|
||||||
|
<span>{% trans "Add Another Author" %}</span>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
@ -193,7 +237,7 @@
|
||||||
</label>
|
</label>
|
||||||
<input class="input" name="cover-url" id="id_cover_url" type="url" value="{{ cover_url|default:'' }}" aria-describedby="desc_cover">
|
<input class="input" name="cover-url" id="id_cover_url" type="url" value="{{ cover_url|default:'' }}" aria-describedby="desc_cover">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.cover.errors id="desc_cover" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.cover.errors id="desc_cover" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -214,7 +258,7 @@
|
||||||
<div class="select">
|
<div class="select">
|
||||||
{{ form.physical_format }}
|
{{ form.physical_format }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.physical_format.errors id="desc_physical_format" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.physical_format.errors id="desc_physical_format" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -224,7 +268,7 @@
|
||||||
{% trans "Format details:" %}
|
{% trans "Format details:" %}
|
||||||
</label>
|
</label>
|
||||||
{{ form.physical_format_detail }}
|
{{ form.physical_format_detail }}
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.physical_format_detail.errors id="desc_physical_format_detail" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.physical_format_detail.errors id="desc_physical_format_detail" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -235,7 +279,7 @@
|
||||||
{% trans "Pages:" %}
|
{% trans "Pages:" %}
|
||||||
</label>
|
</label>
|
||||||
{{ form.pages }}
|
{{ form.pages }}
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.pages.errors id="desc_pages" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.pages.errors id="desc_pages" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -251,7 +295,7 @@
|
||||||
{% trans "ISBN 13:" %}
|
{% trans "ISBN 13:" %}
|
||||||
</label>
|
</label>
|
||||||
{{ form.isbn_13 }}
|
{{ form.isbn_13 }}
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.isbn_13.errors id="desc_isbn_13" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.isbn_13.errors id="desc_isbn_13" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -260,7 +304,7 @@
|
||||||
{% trans "ISBN 10:" %}
|
{% trans "ISBN 10:" %}
|
||||||
</label>
|
</label>
|
||||||
{{ form.isbn_10 }}
|
{{ form.isbn_10 }}
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.isbn_10.errors id="desc_isbn_10" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.isbn_10.errors id="desc_isbn_10" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -269,7 +313,7 @@
|
||||||
{% trans "Openlibrary ID:" %}
|
{% trans "Openlibrary ID:" %}
|
||||||
</label>
|
</label>
|
||||||
{{ form.openlibrary_key }}
|
{{ form.openlibrary_key }}
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.openlibrary_key.errors id="desc_openlibrary_key" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.openlibrary_key.errors id="desc_openlibrary_key" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -278,7 +322,7 @@
|
||||||
{% trans "Inventaire ID:" %}
|
{% trans "Inventaire ID:" %}
|
||||||
</label>
|
</label>
|
||||||
{{ form.inventaire_id }}
|
{{ form.inventaire_id }}
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.inventaire_id.errors id="desc_inventaire_id" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.inventaire_id.errors id="desc_inventaire_id" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -287,7 +331,7 @@
|
||||||
{% trans "OCLC Number:" %}
|
{% trans "OCLC Number:" %}
|
||||||
</label>
|
</label>
|
||||||
{{ form.oclc_number }}
|
{{ form.oclc_number }}
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.oclc_number.errors id="desc_oclc_number" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.oclc_number.errors id="desc_oclc_number" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -296,7 +340,7 @@
|
||||||
{% trans "ASIN:" %}
|
{% trans "ASIN:" %}
|
||||||
</label>
|
</label>
|
||||||
{{ form.asin }}
|
{{ form.asin }}
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=form.ASIN.errors id="desc_ASIN" %}
|
{% include 'snippets/form_errors.html' with errors_list=form.ASIN.errors id="desc_ASIN" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue