Selectize working.

This commit is contained in:
Simon Brooke 2018-07-10 15:46:59 +01:00
parent b5f1190c13
commit 54029c2941
3 changed files with 214 additions and 165 deletions

View file

@ -0,0 +1,28 @@
/**
* selectize one select widget. Substitute the actual id of the widget for `{{widget_id}}`.
*/
$('#{{widget_id}}').selectize({
valueField: 'id',
labelField: 'name',
searchField: 'name',
options: [],
create: false,
load: function(query, callback) {
console.log('Desperately seeking ' + query);
if (query === null || !query.length) return callback();
$.ajax({
url: '/json/auto/search-strings-electors?name=' + query,
type: 'GET',
dataType: 'jsonp',
error: function() {
console.log( 'Query ' + query + ' failed.');
callback();
},
success: function(res) {
console.log('Received ' + res + ' records for ' + query);
callback(res);
}
});
}
});

View file

@ -53,6 +53,7 @@
'[clojure.java.io :as io]
'[clojure.set :refer [subset?]]
'[clojure.tools.logging :as log]
'[clojure.walk :refer [keywordize-keys]]
'[compojure.core :refer [defroutes GET POST]]
'[hugsql.core :as hugsql]
'[noir.response :as nresponse]
@ -65,35 +66,57 @@
(defn make-form-handler-content
[f e a n]
(let [warning (str "Error while fetching " (singularise (:name (:attrs e))) " record")]
(let [warning (list 'str (str "Error while fetching " (singularise (:name (:attrs e))) " record ") 'params)]
;; TODO: as yet makes no attempt to save the record
(list 'let
(vector
'record (list
'support/do-or-log-error
(list 'if (list 'subset? (key-names e) (set (list 'keys 'p)))
(list
(symbol
(str "db/get-" (singularise (:name (:attrs e)))))
(symbol "db/*db*")
'p))
:message warning
:error-return {:warnings [warning]}))
'record (list
'support/do-or-log-error
;;(list 'if (list 'subset? (key-names e) (list 'set (list 'keys 'params)))
(list
(symbol
(str "db/get-" (singularise (:name (:attrs e)))))
(symbol "db/*db*")
'params)
;;)
:message warning
:error-return {:warnings [warning]}))
(reduce
merge
{:warnings (list :warnings 'record)
:record (list 'assoc 'record :warnings nil)}
(map
(fn [p]
(hash-map
(keyword (-> p :attrs :entity))
(list 'support/do-or-log-error
(list (symbol (str "db/list-" (:entity (:attrs p)))) (symbol "db/*db*"))
:message (str "Error while fetching "
(singularise (:entity (:attrs p)))
" record"))))
(filter #(#{"entity" "link"} (:type (:attrs %)))
(descendants-with-tag e :property)))))))
merge
{:error (list :warnings 'record)
:record (list 'dissoc 'record :warnings)}
(map
(fn [property]
(hash-map
(keyword (-> property :attrs :name))
(list
'flatten
(list
'remove
'nil?
(list
'list
;; Get the current value of the property, if it's an entity
(if (= (-> property :attrs :type) "entity")
(list 'support/do-or-log-error
(list
(symbol
(str "db/get-" (singularise (:entity (:attrs property)))))
(symbol "db/*db*")
(hash-map (keyword (-> property :attrs :farkey))
(list (keyword (-> property :attrs :name)) 'record)))
:message (str "Error while fetching "
(singularise (:entity (:attrs property)))
" record " (hash-map (keyword (-> property :attrs :farkey))
(list (keyword (-> property :attrs :name)) 'record)))))
;;; and the potential values of the property
(list 'support/do-or-log-error
(list (symbol (str "db/list-" (:entity (:attrs property)))) (symbol "db/*db*"))
:message (str "Error while fetching "
(singularise (:entity (:attrs property)))
" list")))))))
(filter #(:entity (:attrs %))
(descendants-with-tag e :property)))))))
(defn make-page-handler-content
@ -107,7 +130,7 @@
(symbol
(str "db/get-" (singularise (:name (:attrs e)))))
(symbol "db/*db*")
'p))
'params))
:message warning
:error-return {:warnings [warning]}))
{:warnings (list :warnings 'record)
@ -124,17 +147,14 @@
'if
(list
'some
(set (map #(-> % :attrs :name) (all-properties e)))
(list 'keys 'p))
(set (map #(keyword (-> % :attrs :name)) (all-properties e)))
(list 'keys 'params))
(list
'support/do-or-log-error
(list
(symbol
(str
"db/search-strings-"
(singularise (:name (:attrs e)))))
(symbol (str "db/search-strings-" (:name (:attrs e))))
(symbol "db/*db*")
'p)
'params)
:message (str
"Error while searching "
(singularise (:name (:attrs e)))
@ -171,10 +191,13 @@
(list
'defn
(symbol n)
(vector 'r)
(vector 'request)
(list 'let (vector
'p
(list 'support/massage-params (list :params 'r) (list :form-params 'r) (key-names e)))
'params
(list 'support/massage-params
(list 'keywordize-keys (list :params 'request))
(list 'keywordize-keys (list :form-params 'request))
(key-names e true)))
;; TODO: we must take key params out of just params,
;; but we should take all other params out of form-params - because we need the key to
;; load the form in the first place, but just accepting values of other params would
@ -182,71 +205,74 @@
(list
'l/render
(list 'support/resolve-template (str n ".html"))
(list :session 'r)
(list :session 'request)
(list 'merge
{:title (capitalise (:name (:attrs f)))
:params 'p}
:params 'params}
(case (:tag f)
(:form :page)
(list
'reduce
'merge
(list 'merge
(list 'cond (list :save-button 'p)
(list 'try
(list 'if
(list 'some (key-names e) (list 'map 'name (list 'keys 'p)))
(list 'do
(list (symbol
(str "db/update-" (singularise (-> e :attrs :name)) "!"))
'db/*db*
'p)
{:message "Updated record"})
(list 'do
(list (symbol
(str "db/create-" (singularise (-> e :attrs :name)) "!"))
'db/*db*
'p)
{:message "Saved record"}))
`(catch Exception any#
{:error (.getMessage any#)})))
{:record
(list 'if (list 'empty? (list 'remove 'nil? (list 'vals 'p))) []
(list
(symbol
(str "db/get-" (singularise (:name (:attrs e)))))
(symbol "db/*db*")
'p))})
(cons 'list
(map
(fn [p]
(hash-map
(keyword (-> p :attrs :entity))
(list (symbol (str "db/list-" (:entity (:attrs p)))) (symbol "db/*db*"))))
(filter #(#{"entity" "link"} (:type (:attrs %)))
(descendants-with-tag e :property)))))
:list
{:records
(list
'if
(list
'not
(list
'empty?
(list 'remove 'nil? (list 'vals 'p))))
(list
(symbol
(str
"db/search-strings-"
(:name (:attrs e))))
(symbol "db/*db*")
'p)
(list
(symbol
(str
"db/list-"
(:name (:attrs e))))
(symbol "db/*db*") {}))})))))))
:form (make-form-handler-content f e a n)
:page (make-page-handler-content f e a n)
:list (make-list-handler-content f e a n))))))))
;; (:form :page)
;; (list
;; 'reduce
;; 'merge
;; (list 'merge
;; (list 'cond (list :save-button 'p)
;; (list 'try
;; (list 'if
;; (list 'some (key-names e) (list 'map 'name (list 'keys 'p)))
;; (list 'do
;; (list (symbol
;; (str "db/update-" (singularise (-> e :attrs :name)) "!"))
;; 'db/*db*
;; 'p)
;; {:message "Updated record"})
;; (list 'do
;; (list (symbol
;; (str "db/create-" (singularise (-> e :attrs :name)) "!"))
;; 'db/*db*
;; 'p)
;; {:message "Saved record"}))
;; `(catch Exception any#
;; {:error (.getMessage any#)})))
;; {:record
;; (list 'if (list 'empty? (list 'remove 'nil? (list 'vals 'p))) []
;; (list
;; (symbol
;; (str "db/get-" (singularise (:name (:attrs e)))))
;; (symbol "db/*db*")
;; 'p))})
;; (cons 'list
;; (map
;; (fn [p]
;; (hash-map
;; (keyword (-> p :attrs :entity))
;; (list (symbol (str "db/list-" (:entity (:attrs p)))) (symbol "db/*db*"))))
;; (filter #(#{"entity" "link"} (:type (:attrs %)))
;; (descendants-with-tag e :property)))))
;; :list
;; {:records
;; (list
;; 'if
;; (list
;; 'not
;; (list
;; 'empty?
;; (list 'remove 'nil? (list 'vals 'p))))
;; (list
;; (symbol
;; (str
;; "db/search-strings-"
;; (:name (:attrs e))))
;; (symbol "db/*db*")
;; 'p)
;; (list
;; (symbol
;; (str
;; "db/list-"
;; (:name (:attrs e))))
;; (symbol "db/*db*") {}))})))))))
;; (def a (x/parse "../youyesyet/youyesyet.canonical.adl.xml"))
;; (def e (child-with-tag a :entity))

View file

@ -258,12 +258,16 @@
(:farkey (:attrs property))
(first (key-names farside))
"id")]
[(str "{% for r in " farname " %}<option value='{{r."
;; Yes, I know it looks BONKERS generating this as an HTML string. But there is a
;; reason. We don't know whether the `selected` attribute should be present or
;; absent until rendering.
[(str "{% for option in " (-> property :attrs :name)
" %}<option value='{{option."
farkey
"}}' {% ifequal record."
(-> property :attrs :name)
" r." farkey "%}selected{% endifequal %}>"
(s/join " " (map #(str "{{r." (:name (:attrs %)) "}}") fs-distinct))
" option." farkey "%}selected{% endifequal %}>"
(s/join " " (map #(str "{{option." (:name (:attrs %)) "}}") fs-distinct))
"</option>{% endfor %}")]))
@ -292,50 +296,20 @@
(defn select-widget
;; TODO: rewrite for selectize https://github.com/selectize/selectize.js/blob/master/docs/usage.md
;; https://gist.github.com/zabolotnov87/11142887
[property form entity application]
(let [farname (:entity (:attrs property))
farside (first (children application #(= (:name (:attrs %)) farname)))
magnitude (try (read-string (:magnitude (:attrs farside))) (catch Exception _ 7))
async? (and (number? magnitude) (> magnitude 1))
widget-name (safe-name (:name (:attrs property)) :sql)]
{:tag :span
:attrs {:class "select-box" :farside farname :found (if farside "true" "false")}
:content
(apply
vector
(remove
nil?
(flatten
(list
(if
async?
(list
{:tag :input
:attrs
{:name (str widget-name "_search_box")
:onchange (str "$.getJSON(\"/auto/json/seach-strings-"
(-> farside :attrs :name)
"?"
(s/join (str "=\" + " widget-name "_search_box.text + \"&amp;")
(user-distinct-property-names farside))
(str "=\" + " widget-name "_search_box.text")
", null, function (data) {updateMenuOptions(\""
widget-name "\", \""
(first (key-names farside))
"\", [\""
(s/join "\", \"" (user-distinct-property-names farside))
"\"], data);})")}}
{:tag :br}))
{:tag :select
:attrs (merge
{:id widget-name
:name widget-name}
(if
(= (:type (:attrs property)) "link")
{:multiple "multiple"}))
:content (apply vector (get-options property form entity application))}))))}))
{:tag :select
:attrs (merge
{:id widget-name
:name widget-name}
(if
(= (:type (:attrs property)) "link")
{:multiple "multiple"}))
:content (apply vector (get-options property form entity application))}))
(defn compose-readable-or-not-authorised
@ -353,8 +327,7 @@
:name w
:class "pseudo-widget not-authorised"}
:content [(str "You are not permitted to view " w " of " (:name (:attrs e)))]}
"{% endifmemberof %}"
))
"{% endifmemberof %}"))
(defn compose-widget-para
@ -454,7 +427,7 @@
(defn embed-script-fragment
"Return the content of the file at `fielpath`, with these `substitutions`
"Return the content of the file at `filepath`, with these `substitutions`
made into it in order. Substitutions should be pairss [`pattern` `value`],
where `pattern` is a string, a char, or a regular expression."
([filepath substitutions]
@ -603,31 +576,53 @@
(defn compose-form-extra-head
[form entity application]
{:extra-head
(if
(some
#(= "text-area" (widget-type % application)) (properties entity))
"{% script \"js/lib/node_modules/simplemde/dist/simplemde.min.js\" %}
{% style \"js/lib/node_modules/simplemde/dist/simplemde.min.css\" %}")})
(apply
str
(remove
nil?
(list
(if
(some
#(= "text-area" (widget-type % application)) (properties entity))
"
{% script \"js/lib/node_modules/simplemde/dist/simplemde.min.js\" %}
{% style \"js/lib/node_modules/simplemde/dist/simplemde.min.css\" %}")
(if
(some
#(= "select" (widget-type % application)) (properties entity))
"
{% script \"/js/lib/node_modules/selectize/dist/js/standalone/selectize.min.js\" %}
{% style \"/js/lib/node_modules/selectize/dist/css/selectize.css\" %}"))))})
(defn compose-form-extra-tail
[form entity application]
{:extra-tail
{:tag :script :attrs {:type "text/javascript"}
:content
(apply
vector
(remove
nil?
(list
(if
(some
#(= "select" (widget-type % application)) (properties entity))
(embed-script-fragment "resources/js/select-widget-support.js"))
(if
(some
#(= "text-area" (widget-type % application)) (properties entity))
(embed-script-fragment "resources/js/text-area-md-support.js")))))}})
(defn compose-form-extra-tail
[form entity application]
{:extra-tail
{:tag :script :attrs {:type "text/javascript"}
:content
(apply
vector
(remove
nil?
(flatten
(list
(map
(fn [property]
(let
[farname (:entity (:attrs property))
farside (first (children application #(= (:name (:attrs %)) farname)))
magnitude (try (read-string (:magnitude (:attrs farside))) (catch Exception _ 7))]
(if
(> magnitude 2)
(embed-script-fragment
"resources/js/selectize-one.js"
[["{{widget_id}}" (-> property :attrs :name)]]
))))
(children-with-tag entity :property #(= (-> % :attrs :type) "entity")))
(if
(some
#(= "text-area" (widget-type % application)) (properties entity))
(embed-script-fragment "resources/js/text-area-md-support.js"))))))}})
(defn form-to-template