#33 Add a JavaScript tag widget with tag autocomplete

Samengevoegd
getty heeft 6 commits samengevoegd van getty/gr/rich-tags naar getty/master 4 jaren geleden
8 gewijzigde bestanden met toevoegingen van 47 en 6 verwijderingen
  1. 2 1
      lc/app.py
  2. 6 4
      lc/model.py
  3. 1 0
      lc/view.py
  4. 25 0
      static/lc.js
  5. 1 0
      static/tagify.css
  6. 7 0
      static/tagify.min.js
  7. 3 1
      templates/edit_link.mustache
  8. 2 0
      templates/main.mustache

+ 2 - 1
lc/app.py

@@ -202,12 +202,13 @@ class GetLink(Endpoint):
 class EditLink(Endpoint):
     def html(self, slug: str, link: str):
         u = self.require_authentication(slug)
+        all_tags = u.get_tags()
         l = u.get_link(int(link))
         return render(
             "main",
             v.Page(
                 title="login",
-                content=render("edit_link", v.SingleLink(l)),
+                content=render("edit_link", v.SingleLink(l, all_tags)),
                 user=self.user,
             ),
         )

+ 6 - 4
lc/model.py

@@ -337,10 +337,12 @@ class Tag(Model):
 
     @staticmethod
     def clean():
-        unused = Tag.select(Tag.id) \
-                    .join(HasTag, peewee.JOIN.LEFT_OUTER) \
-                    .group_by(Tag.name) \
-                    .having(peewee.fn.COUNT(HasTag.id) == 0)
+        unused = (
+            Tag.select(Tag.id)
+            .join(HasTag, peewee.JOIN.LEFT_OUTER)
+            .group_by(Tag.name)
+            .having(peewee.fn.COUNT(HasTag.id) == 0)
+        )
         Tag.delete().where(Tag.id.in_(unused)).execute()
 
 

+ 1 - 0
lc/view.py

@@ -152,6 +152,7 @@ class LinkList(View):
 @dataclass
 class SingleLink(View):
     link: Any
+    all_tags: List[Tag]
 
 
 @dataclass

+ 25 - 0
static/lc.js

@@ -25,3 +25,28 @@ function confirmDelete(url, id) {
 function removeConfirm(id) {
     $(`#confirm_${id}`).remove();
 }
+
+$(document).ready(() => {
+    let input = document.querySelector('.tagtest');
+    if (input) {
+        let tags = new Tagify(input);
+
+        let form = $("form[name=\"edit_link\"]")
+        form.submit(event => {
+            event.preventDefault();
+            let url = form.attr("action");
+            let body = {
+                "url": $('input[name="url"]').val(),
+                "name": $('input[name="name"]').val(),
+                "description": $('input[name="description"]').val(),
+                "private": $('input[name="private"]').is(":checked"),
+                "tags": tags.value.map(o => o.value),
+            };
+            fetch(url, {
+                method: 'POST',
+                headers: {'Content-Type': 'application/json'},
+                body: JSON.stringify(body),
+            }).then(_ => window.location.href = url);
+        });
+    }
+});

File diff suppressed because it is too large
+ 1 - 0
static/tagify.css


File diff suppressed because it is too large
+ 7 - 0
static/tagify.min.js


+ 3 - 1
templates/edit_link.mustache

@@ -19,7 +19,9 @@
     </div>
     <div class="tags">
       <label for="tags">Tags</label>
-      <input name="tags" type="text" value="{{#tags}}{{#tag}}{{name}} {{/tag}}{{/tags}}" />
+      <input class="tagtest" type="text"
+        value="{{#tags}}{{#tag}}{{name}}{{/tag}},{{/tags}}"
+        data-whitelist="{{#all_tags}}{{name}},{{/all_tags}}" />
     </div>
 
     <div class="submit">

+ 2 - 0
templates/main.mustache

@@ -5,7 +5,9 @@
     <link rel="icon" type="image/png" href="/static/lc_64.png" />
     <title>Lament Configuration</title>
     <link rel="stylesheet" type="text/css" href="/static/main.css" />
+    <link rel="stylesheet" type="text/css" href="/static/tagify.css" />
     <script type="text/javascript" src="/static/jquery-3.5.0.min.js"></script>
+    <script type="text/javascript" src="/static/tagify.min.js"></script>
     <script type="text/javascript" src="/static/lc.js"></script>
   </head>
   <body>