summaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/fatcat_web/forms.py24
-rw-r--r--python/fatcat_web/templates/container_edit.html92
-rw-r--r--python/fatcat_web/templates/entity_macros.html8
3 files changed, 119 insertions, 5 deletions
diff --git a/python/fatcat_web/forms.py b/python/fatcat_web/forms.py
index 776812ae..79365687 100644
--- a/python/fatcat_web/forms.py
+++ b/python/fatcat_web/forms.py
@@ -187,17 +187,24 @@ class ContainerEntityForm(EntityEditForm):
publisher = StringField("Publisher")
issnl = StringField("ISSN-L")
wikidata_qid = StringField('Wikidata QID')
+ urls = FieldList(
+ StringField("Container URLs",
+ [validators.DataRequired(),
+ validators.URL(require_tld=False)]))
@staticmethod
- def from_entity(re):
+ def from_entity(ce):
"""
Initializes form with values from an existing container entity.
"""
- ref = ContainerEntityForm()
+ cef = ContainerEntityForm()
for simple_attr in CONTAINER_SIMPLE_ATTRS:
- a = getattr(ref, simple_attr)
- a.data = getattr(re, simple_attr)
- return ref
+ a = getattr(cef, simple_attr)
+ a.data = getattr(ce, simple_attr)
+ if ce.extra and ce.extra.get('urls'):
+ for url in ce.extra['urls']:
+ cef.urls.append_entry(url)
+ return cef
def to_entity(self):
assert(self.name.data)
@@ -218,6 +225,13 @@ class ContainerEntityForm(EntityEditForm):
if a == '':
a = None
setattr(ce, simple_attr, a)
+ extra_urls = []
+ for url in self.urls:
+ extra_urls.append(url.data)
+ if extra_urls:
+ if not ce.extra:
+ ce.extra = dict()
+ ce.extra['urls'] = extra_urls
if self.edit_description.data:
ce.edit_extra = dict(description=self.edit_description.data)
diff --git a/python/fatcat_web/templates/container_edit.html b/python/fatcat_web/templates/container_edit.html
index 2a3f6f5f..83c00514 100644
--- a/python/fatcat_web/templates/container_edit.html
+++ b/python/fatcat_web/templates/container_edit.html
@@ -22,6 +22,33 @@
{{ edit_macros.form_field_inline(form.wikidata_qid) }}
<br>
+ <h3 class="ui dividing header">Homepage URLs</h3>
+ <i>Landing page or mirror locations of container as a whole.</i>
+ <br><br>
+ <div class="list-group" id="url_list" name="url_list">
+ {% for cfield in form.urls %}
+ <div class="list-group-item ui grid" style="padding-right: 1em;">
+ <div class="one wide column middle aligned center aligned sortable-handle" style="padding-bottom: 0px; padding-right: 0px; padding-left: 0px;">
+ <i class="arrows alternate vertical icon"></i>
+ </div>
+ <div class="thirteen wide column" style="padding-bottom: 0px;">
+ <div class="field {% if cfield.errors %}error{% endif %}">
+ {{ cfield() }}
+ {{ edit_macros.form_field_errors(cfield) }}
+ </div>
+ </div>
+ <div class="one wide column right aligned" style="padding-bottom: 0px; padding-left: 0rem;">
+ <button type="button" class="ui icon red button delete-url-button"><i class="trash icon"></i></button>
+ </div>
+ </div>
+ {% endfor %}
+ </div>
+ <br>
+ <button type="button" id="add-url-button" class="ui right floated icon green button" style="margin-right: 0.3rem;">
+ <i class="plus icon"></i>
+ </button>
+
+ <br>
<h3 class="ui dividing header">Submit</h3>
{{ edit_macros.form_field_basic(form.edit_description) }}
This description will be attached to the individual edit, not to the
@@ -38,12 +65,77 @@
{% endblock %}
{% block postscript %}
+<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
<script>
<!-- Form code -->
$(document).ready(function() {
$('.ui.accordion').accordion();
+ var fixup_url_numbering = function(group_item) {
+ items = Array.from(group_item.querySelectorAll(".list-group-item"))
+ for (var i = 0; i < items.length; i++) {
+ var item_el = items[i];
+ input_el = item_el.querySelectorAll("input")[0];
+ //console.log(input_el.id);
+ input_el.id = "urls-" + i;
+ input_el.name = input_el.id;
+ //console.log(input_el.id);
+ };
+ console.log("re-named url rows up to i=" + i);
+ };
+
+ var url_list = document.getElementById('url_list');
+ var url_sortable = Sortable.create(url_list, {
+ handle: '.sortable-handle',
+ animation: 150,
+ onSort: function(evt) {
+ fixup_url_numbering(url_list);
+ },
+ });
+ fixup_url_numbering(url_list);
+
+ var url_delete_handler = function(ev) {
+ row = ev.target.parentNode.parentNode;
+ // I don't understand why this hack is needed; maybe because of the sortable stuff?
+ if(!row.classList.contains("list-group-item")) {
+ row = row.parentNode;
+ }
+ // console.log(row);
+ console.assert(row.classList.contains("list-group-item"));
+ row.parentNode.removeChild(row);
+ fixup_url_numbering(url_list);
+ };
+
+ var attach_url_delete_handler = function(topthing) {
+ Array.from(topthing.querySelectorAll(".delete-url-button")).forEach((el) => {
+ el.addEventListener("click", url_delete_handler);
+ });
+ };
+ attach_url_delete_handler(document);
+
+ // XXX: really need some way to not duplicate this code from above...
+ var url_template = `
+ <div class="list-group-item ui grid" style="padding-right: 1em;">
+ <div class="one wide column middle aligned center aligned sortable-handle" style="padding-bottom: 0px; padding-right: 0px; padding-left: 0px;">
+ <i class="arrows alternate vertical icon"></i>
+ </div>
+ <div class="fourteen wide column" style="padding-bottom: 0px;">
+ <input id="urls-X" name="urls-X" type="text" value="">
+ </div>
+ <div class="one wide column right aligned" style="padding-bottom: 0px; padding-left: 0rem;">
+ <button type="button" class="ui icon red button delete-url-button"><i class="trash icon"></i></button>
+ </div>
+ </div>
+ `;
+
+ var add_url_button = document.getElementById("add-url-button");
+ add_url_button.addEventListener("click", function(){
+ url_list.insertAdjacentHTML('beforeend', url_template);
+ attach_url_delete_handler(url_list.lastElementChild);
+ fixup_url_numbering(url_list);
+ });
+
});
</script>
{% endblock %}
diff --git a/python/fatcat_web/templates/entity_macros.html b/python/fatcat_web/templates/entity_macros.html
index 3e83b9d4..6d9ceed0 100644
--- a/python/fatcat_web/templates/entity_macros.html
+++ b/python/fatcat_web/templates/entity_macros.html
@@ -35,6 +35,14 @@
<tr><td class="three wide right aligned"><code>{{ key }}.{{ inner_key }}</code></td>
<td class="seven wide"><code>{{ inner_value }}</code>
{% endfor %}
+ {% elif key in ("urls") and value and value is iterable and value is not string %}
+ <tr><td class="three wide right aligned"><code>{{ key }}</code></td>
+ <td class="seven wide">
+ <code>
+ {% for u in value %}
+ <a href="{{ u }}">{{ u }}</a><br>
+ {% endfor %}
+ </code>
{% else %}
<tr><td class="three wide right aligned"><code>{{ key }}</code></td>
<td class="seven wide"><code>{{ value }}</code>