Add the search for articles on the index page.
This commit is contained in:
@@ -46,6 +46,24 @@
|
||||
(catch js/Error err (js/console.log (ex-cause err)))))
|
||||
channel)
|
||||
|
||||
(defn search-articles-briefly
|
||||
"Search all articles by titles and contents and returns via channel. It gets and returns the same channel. The content will be brief (<=60 characters)."
|
||||
[client search channel]
|
||||
(go
|
||||
(try
|
||||
(let [res (<p! (.query client
|
||||
(str "select id, title, "
|
||||
"substr(content, 0, 60) content, "
|
||||
"length(content) content_length, "
|
||||
"created from articles "
|
||||
"where title like $1 "
|
||||
"or content like $1 "
|
||||
"order by created desc")
|
||||
(clj->js [(str "%" search "%")])))]
|
||||
(>! channel (.-rows res)))
|
||||
(catch js/Error err (js/console.log (ex-cause err)))))
|
||||
channel)
|
||||
|
||||
(defn get-article
|
||||
"Reads an article with the id and returns via channel. It gets and returns the same channel. Empty collection if not found."
|
||||
[client id channel]
|
||||
|
||||
@@ -112,6 +112,23 @@
|
||||
(res/status 500)
|
||||
(res/send (ex-message err))))))))
|
||||
|
||||
(defn htmx-search-articles-handler-factory
|
||||
[client]
|
||||
(fn [req res]
|
||||
(let [channel (chan)
|
||||
search (.-search (.-body req))]
|
||||
(go
|
||||
(try
|
||||
(let [articles (<! (db/search-articles-briefly client search channel))]
|
||||
(res/status 200)
|
||||
(.render res "articles_briefly"
|
||||
(-> {:articles articles
|
||||
:layout false}
|
||||
(cljs.core/clj->js))))
|
||||
(catch js/Error err
|
||||
(res/status 500)
|
||||
(res/send (ex-message err))))))))
|
||||
|
||||
(defn htmx-create-article-handler-factory
|
||||
[client]
|
||||
(fn [req res]
|
||||
|
||||
@@ -70,6 +70,9 @@
|
||||
(. app get "/admin"
|
||||
(handlers/admin-panel-handler-factory client))
|
||||
|
||||
(. app post "/htmx/search/articles/"
|
||||
(handlers/htmx-search-articles-handler-factory client))
|
||||
|
||||
(. app post "/htmx/articles/"
|
||||
(handlers/htmx-create-article-handler-factory client))
|
||||
|
||||
|
||||
+10
-6
@@ -1,11 +1,15 @@
|
||||
<main class="bg-white dark:bg-gray-800 py-4 grow">
|
||||
<h1 class="mb-4 text-5xl tracking-tight font-extrabold text-gray-900 dark:text-white text-center">Articles</h1>
|
||||
|
||||
{{#each articles as |article|}}
|
||||
{{> article_briefly article=article }}
|
||||
{{> search_articles }}
|
||||
|
||||
{{#unless @last}}
|
||||
<hr class="w-48 h-1 mx-auto my-4 bg-gray-100 border-0 rounded md:my-10 dark:bg-gray-700">
|
||||
{{/unless}}
|
||||
{{/each}}
|
||||
<div id="articles">
|
||||
{{#each articles as |article|}}
|
||||
{{> article_briefly article=article }}
|
||||
|
||||
{{#unless @last}}
|
||||
<hr class="w-48 h-1 mx-auto my-4 bg-gray-100 border-0 rounded md:my-10 dark:bg-gray-700">
|
||||
{{/unless}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<div id="articles">
|
||||
{{#each articles as |article|}}
|
||||
{{> article_briefly article=article }}
|
||||
|
||||
{{#unless @last}}
|
||||
<hr class="w-48 h-1 mx-auto my-4 bg-gray-100 border-0 rounded md:my-10 dark:bg-gray-700">
|
||||
{{/unless}}
|
||||
{{/each}}
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
<form class="max-w-md mx-auto" method="POST">
|
||||
<label for="default-search" class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 start-0 flex items-center ps-3 pointer-events-none">
|
||||
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<input type="search"
|
||||
id="search"
|
||||
name="search"
|
||||
hx-post="/htmx/search/articles/"
|
||||
hx-trigger="input changed delay:500ms, search"
|
||||
hx-target="#articles"
|
||||
hx-swap="outerHTML"
|
||||
class="block w-full p-4 ps-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 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="Search articles by title or content" required />
|
||||
</div>
|
||||
</form>
|
||||
Reference in New Issue
Block a user