Add tags to book UI

This commit is contained in:
SvyatoslavArtymovych 2023-05-15 23:29:10 +03:00
parent 2556838a77
commit 0d3141deb2
7 changed files with 110 additions and 3167 deletions

View File

@ -13,6 +13,7 @@
"cSpell.words": [
"bookname",
"Btns",
"Divs",
"flowbite",
"jsonify",
"pydantic",

View File

@ -17,6 +17,7 @@ class CreateBookForm(BaseBookForm):
class EditBookForm(BaseBookForm):
book_id = StringField("User ID", [DataRequired()])
tags = StringField("Tags")
submit = SubmitField("Edit book")
def validate_label(self, field):

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -36,7 +36,7 @@
<div id="myTabContent">
<!-- prettier-ignore -->
<div class="hidden pl-4 rounded-lg bg-gray-50 dark:bg-gray-800" id="settings" role="tabpanel" aria-labelledby="settings-tab">
<form action="{{ url_for('book.edit', book_id=book.id) }}" method="post" class="mb-0 flex flex-col space-y-2 w-1/2">
<form action="{{ url_for('book.edit', book_id=book.id) }}" method="post" class="settings-form mb-0 flex flex-col space-y-2 w-1/2">
{{ form_hidden_tag() }}
<input value="{{book.id}}" type="text" name="book_id" id="book_id" class="hidden" placeholder="Book id" required>
<div>
@ -44,15 +44,34 @@
<input value="{{book.label}}" type="text" name="label" id="label" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="My Book" required>
</div>
<div>
<label for="about" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Book about</label>
<textarea type="text" name="about" id="about" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="About my Book">{{book.about if not book.about==None}}</textarea>
<label for="about" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Book about
</label>
<textarea type="text" name="about" id="about" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="About my Book">
{{book.about if not book.about==None}}
</textarea>
</div>
<div class="mb-6">
<label for="tags-input" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Tags
</label>
<input type="text" name="tags" class="hidden tags-to-submit">
<input
type="text"
id="tags-input"
class="multiple-input mb-3 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="e.g. Law (press 'Enter' or Comma to add tag or 'Backspace' to edit last tag)"
>
<div class="multiple-input-items gap-1 flex flex-wrap">
<div class="multiple-input-word bg-sky-500 rounded text-center py-1/2 px-2">Tag</div>
</div>
</div>
<div>
<button type="submit" class="text-center text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Submit</button>
<div class="flex justify-between">
<button type="submit" class="mr-2 mb-2 text-center text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Submit</button>
<button type="button" data-modal-target="delete_book_modal" data-modal-toggle="delete_book_modal" class="text-red-700 hover:text-white border border-red-700 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2 dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:hover:bg-red-600 dark:focus:ring-red-900">Delete Book</button>
</div>
</form>
<button type="button" data-modal-target="delete_book_modal" data-modal-toggle="delete_book_modal" class="mt-3 text-red-700 hover:text-white border border-red-700 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2 dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:hover:bg-red-600 dark:focus:ring-red-900">Delete Book</button>
</div>
<div class="hidden p-4 rounded-lg bg-gray-50 dark:bg-gray-800" id="permissions" role="tabpanel" aria-labelledby="permissions-tab">
<div class="p-5">

View File

@ -8,6 +8,7 @@ import {initVote} from './vote';
import {initTheme} from './theme';
import {initApprove} from './approve';
import {initStar} from './star';
import {initMultipleInput} from './multipleInput';
initBooks();
initContributors();
@ -19,3 +20,4 @@ initVote();
initTheme();
initApprove();
initStar();
initMultipleInput();

69
src/multipleInput.ts Normal file
View File

@ -0,0 +1,69 @@
export function initMultipleInput() {
const settingsForm = document.querySelector('.settings-form');
settingsForm.addEventListener('keypress', (e: any) => {
if (e.keyCode === 13) {
e.preventDefault();
}
});
const tagsToSubmitInput: HTMLInputElement =
document.querySelector('.tags-to-submit');
const multipleInput: any = document.querySelector('.multiple-input');
const wordsBlock: HTMLDivElement = multipleInput.parentElement.querySelector(
'.multiple-input-items',
);
const wordDivs = wordsBlock.querySelectorAll('.multiple-input-word');
const addedWords: string[] = [];
wordDivs.forEach(el => {
addedWords.push(el.innerHTML);
});
tagsToSubmitInput.value = addedWords.join();
multipleInput.addEventListener('keyup', (event: any) => {
if (event.keyCode === 13 || event.keyCode === 188) {
if (!multipleInput.value) {
return;
}
let inputValue = multipleInput.value.trim();
inputValue =
inputValue.charAt(0).toUpperCase() + inputValue.substr(1).toLowerCase();
if (
inputValue.substring(inputValue.length - 1, inputValue.length) == ','
) {
inputValue = inputValue.substring(0, inputValue.length - 1);
event.target.value = inputValue;
}
if (addedWords.includes(inputValue)) {
return;
}
const wordDiv = document.createElement('div');
wordDiv.className =
'multiple-input-word bg-sky-500 rounded text-center py-1/2 px-2';
wordDiv.innerHTML = inputValue;
addedWords.push(inputValue);
wordsBlock.appendChild(wordDiv);
multipleInput.value = '';
tagsToSubmitInput.value = addedWords.join();
} else if (event.keyCode === 8 && multipleInput.value.length === 0) {
const addedWordsDivs = document.querySelectorAll('.multiple-input-word');
const lastAdded = addedWordsDivs[addedWordsDivs.length - 1];
if (!lastAdded) {
return;
}
const word = lastAdded.innerHTML;
if (word || word != '') {
multipleInput.value = word;
lastAdded.remove();
addedWords.slice(0, addedWords.length - 1);
tagsToSubmitInput.value = addedWords.join();
}
}
});
}