diff options
-rw-r--r-- | src/mulk/benki/book_marx.clj | 25 | ||||
-rw-r--r-- | static/js/bookmarx-submit.js | 55 |
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; + } + }); +}); |