Selectize working.
This commit is contained in:
parent
b5f1190c13
commit
54029c2941
28
resources/js/selectize-one.js
Normal file
28
resources/js/selectize-one.js
Normal 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
|
@ -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))
|
||||
|
|
|
@ -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 + \"&")
|
||||
(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
|
||||
|
|
Loading…
Reference in a new issue