From 2d19e97212aabb993ebde4f26e937992479e1276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20I=C3=9Fbr=C3=BCcker?= Date: Sun, 4 Apr 2021 10:16:40 +0200 Subject: [PATCH] Allow editing of scraped values (#80) * Allow editing scraped title + description (#80) * Fix edit button hijacking form submit --- bookmarks/styles/bookmarks.scss | 32 +++++++++- bookmarks/templates/bookmarks/form.html | 82 ++++++++++++++++++------- 2 files changed, 92 insertions(+), 22 deletions(-) diff --git a/bookmarks/styles/bookmarks.scss b/bookmarks/styles/bookmarks.scss index 1614546..0ebc101 100644 --- a/bookmarks/styles/bookmarks.scss +++ b/bookmarks/styles/bookmarks.scss @@ -97,12 +97,41 @@ ul.bookmark-list { .bookmarks-form { + .btn.form-icon { + padding: 0; + width: 20px; + height: 20px; + visibility: hidden; + color: $gray-color; + + &:focus, + &:hover, + &:active, + &.active { + color: $gray-color-dark; + } + + > svg { + width: 20px; + height: 20px; + } + } + + .has-icon-right > input, .has-icon-right > textarea { + padding-right: 30px; + } + + .has-icon-right > input:placeholder-shown ~ .btn.form-icon, + .has-icon-right > textarea:placeholder-shown ~ .btn.form-icon { + visibility: visible; + } + .form-icon.loading { visibility: hidden; } .form-input-hint.bookmark-exists { - visibility: hidden; + display: none; color: $warning-color; a { @@ -163,6 +192,7 @@ $bulk-edit-transition-duration: 400ms; span.confirmation { display: flex; } + span.confirmation button { padding: 0; } diff --git a/bookmarks/templates/bookmarks/form.html b/bookmarks/templates/bookmarks/form.html index 954bb57..9e4ac78 100644 --- a/bookmarks/templates/bookmarks/form.html +++ b/bookmarks/templates/bookmarks/form.html @@ -14,12 +14,13 @@ {% endif %}
- This URL is already bookmarked. You can edit it or you can overwrite the existing bookmark by saving this form. + This URL is already bookmarked. You can edit it or you can overwrite the existing bookmark + by saving this form.
- {{ form.tag_string|add_class:"form-input" }} + {{ form.tag_string|add_class:"form-input"|attr:"autocomplete:off" }}
Enter any number of tags separated by space and without the hash (#). If a tag does not exist it will be @@ -30,8 +31,16 @@
- {{ form.title|add_class:"form-input" }} + {{ form.title|add_class:"form-input"|attr:"autocomplete:off" }} + + + + + +
Optional, leave empty to use title from website. @@ -43,6 +52,14 @@
{{ form.description|add_class:"form-input"|attr:"rows:4" }} + + + + + +
Optional, leave empty to use description from website. @@ -82,49 +99,72 @@ /** * - Pre-fill title and description placeholders with metadata from website as soon as URL changes * - Show hint if URL is already bookmarked + * - Setup buttons that allow editing of scraped website values */ (function init() { const urlInput = document.getElementById('{{ form.url.id_for_label }}'); const titleInput = document.getElementById('{{ form.title.id_for_label }}'); const descriptionInput = document.getElementById('{{ form.description.id_for_label }}'); - const editedBookmarkId = {{ bookmark_id }} + const editedBookmarkId = {{ bookmark_id }}; - urlInput.addEventListener('input', checkUrl); + function toggleLoadingIcon(input, show) { + const icon = input.parentNode.querySelector('i.form-icon'); + icon.style['visibility'] = show ? 'visible' : 'hidden'; + } + + function updatePlaceholder(input, value) { + if (value) { + input.setAttribute('placeholder', value); + } else { + input.removeAttribute('placeholder'); + } + } function checkUrl() { - toggleIcon(titleInput, true); - toggleIcon(descriptionInput, true); + toggleLoadingIcon(titleInput, true); + toggleLoadingIcon(descriptionInput, true); + updatePlaceholder(titleInput, null); + updatePlaceholder(descriptionInput, null); const websiteUrl = encodeURIComponent(urlInput.value); const requestUrl = `{% url 'bookmarks:api-root' %}bookmarks/check?url=${websiteUrl}`; fetch(requestUrl) .then(response => response.json()) .then(data => { - const metadata = data.metadata - titleInput.setAttribute('placeholder', metadata.title || ''); - descriptionInput.setAttribute('placeholder', metadata.description || ''); - toggleIcon(titleInput, false); - toggleIcon(descriptionInput, false); + const metadata = data.metadata; + updatePlaceholder(titleInput, metadata.title); + updatePlaceholder(descriptionInput, metadata.description); + toggleLoadingIcon(titleInput, false); + toggleLoadingIcon(descriptionInput, false); // Display hint if URL is already bookmarked - const bookmarkExistsHint = document.querySelector('.form-input-hint.bookmark-exists') - const editExistingBookmarkLink = bookmarkExistsHint.querySelector('a') + const bookmarkExistsHint = document.querySelector('.form-input-hint.bookmark-exists'); + const editExistingBookmarkLink = bookmarkExistsHint.querySelector('a'); - if(data.bookmark && data.bookmark.id !== editedBookmarkId) { - bookmarkExistsHint.style['visibility'] = 'visible' - editExistingBookmarkLink.href = data.bookmark.edit_url + if (data.bookmark && data.bookmark.id !== editedBookmarkId) { + bookmarkExistsHint.style['display'] = 'block'; + editExistingBookmarkLink.href = data.bookmark.edit_url; } else { - bookmarkExistsHint.style['visibility'] = 'hidden' + bookmarkExistsHint.style['display'] = 'none'; } }); } - function toggleIcon(input, show) { - const icon = input.parentNode.querySelector('i.form-icon'); - icon.style['visibility'] = show ? 'visible' : 'hidden'; + function setupEditAutoValueButton(input) { + const editAutoValueButton = input.parentNode.querySelector('.btn.form-icon'); + if (!editAutoValueButton) return; + editAutoValueButton.addEventListener('click', function (event) { + event.preventDefault(); + input.value = input.getAttribute('placeholder'); + input.focus(); + input.select(); + }); } if (urlInput.value) checkUrl(); + urlInput.addEventListener('input', checkUrl); + setupEditAutoValueButton(titleInput); + setupEditAutoValueButton(descriptionInput); })();