summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <code@mail.matthias.benkard.de>2012-02-27 20:18:20 +0100
committerMatthias Andreas Benkard <code@mail.matthias.benkard.de>2012-02-27 20:18:20 +0100
commitcaaef2492e17b397bb2ee3d60edfaf830ead51e5 (patch)
tree2272ae0fac307e24e493c313475867c03b2763b4
parent6606fe505cf23e6f2a98daac851a0336c432888c (diff)
Book Marx: Implement tag auto-completion.
-rw-r--r--src/mulk/benki/book_marx.clj25
-rw-r--r--static/js/bookmarx-submit.js55
2 files changed, 78 insertions, 2 deletions
diff --git a/src/mulk/benki/book_marx.clj b/src/mulk/benki/book_marx.clj
index b18a02f..1ac7b8d 100644
--- a/src/mulk/benki/book_marx.clj
+++ b/src/mulk/benki/book_marx.clj
@@ -13,6 +13,7 @@
[clojure.string :as string]
[clojureql.core :as cq]
[noir.request :as request]
+ [noir.response :as response]
[noir.session :as session]
hiccup.core)
(:import [org.jsoup.Jsoup]))
@@ -25,8 +26,22 @@
(def bookmarx-list-page
{:head (list
- [:link {:rel "stylesheet", "href" (resolve-uri "/style/hammer-and-sickle.css")}])})
-(def bookmarx-submission-page {})
+ [:link {:rel "stylesheet"
+ :href (resolve-uri "/style/hammer-and-sickle.css")
+ :type "text/css"}])})
+(def bookmarx-submission-page
+ {:head (list
+ [:link {:rel "stylesheet"
+ :href (resolve-uri "/style/hammer-and-sickle.css")
+ :type "text/css"}]
+ [:link {:rel "stylesheet"
+ :href (resolve-uri "/3rdparty/jquery-ui/css/ui-lightness/jquery-ui-1.8.18.custom.css")
+ :type "text/css"}])
+ :bottom (list
+ [:script {:type "text/javascript"
+ :src (resolve-uri "/3rdparty/jquery-ui/js/jquery-ui-1.8.18.custom.min.js")}]
+ [:script {:type "text/javascript"
+ :src (resolve-uri "/js/bookmarx-submit.js")}])})
(defn restrict-visibility [table user]
(if user
@@ -68,6 +83,12 @@
[:p {:class "bookmark-description"}
(htmlize-description (:description mark))]])]]))))
+(defpage "/marx/tags" {}
+ (with-auth
+ (with-dbt
+ (sql/with-query-results tags ["SELECT tag FROM bookmark_tags"]
+ (response/json (doall (map :tag tags)))))))
+
(defmacro ignore-errors [& body]
`(try (do ~@body)
(catch java.lang.Exception e#
diff --git a/static/js/bookmarx-submit.js b/static/js/bookmarx-submit.js
new file mode 100644
index 0000000..6e5ad01
--- /dev/null
+++ b/static/js/bookmarx-submit.js
@@ -0,0 +1,55 @@
+// Based on the jQuery UI autocomplete example.
+// http://jqueryui.com/demos/autocomplete/#multiple
+
+$(function() {
+ var availableTags;
+ $.ajax('tags', {
+ success: function(data){
+ availableTags = data;
+ }
+ });
+ function split(val) {
+ return val.split(/,\s*/);
+ }
+ function extractLast(term) {
+ return split(term).pop();
+ }
+
+ $("#bookmark-tags-field")
+ // don't navigate away from the field on tab when selecting an item
+ .bind("keydown", function(event) {
+ if (event.keyCode === $.ui.keyCode.TAB &&
+ $(this).data("autocomplete").menu.active) {
+ event.preventDefault();
+ }
+ })
+ .bind("keyup", function(event) {
+ if (event.keyCode === $.ui.keyCode.TAB &&
+ $(this).data("autocomplete").menu.active) {
+ event.preventDefault();
+ }
+ })
+ .autocomplete({
+ minLength: 0,
+ source: function(request, response) {
+ // delegate back to autocomplete, but extract the last term
+ response($.ui.autocomplete.filter(
+ availableTags, extractLast(request.term)));
+ },
+ focus: function() {
+ // prevent value inserted on focus
+ return false;
+ },
+ select: function(event, ui) {
+ var terms = split(this.value);
+ // remove the current input
+ terms.pop();
+ // add the selected item
+ terms.push(ui.item.value);
+ // add placeholder to get the comma-and-space at the end
+ terms.push("");
+ this.value = terms.join(", ");
+ return false;
+ }
+ });
+});