3

I am implementing a simple drop-down using hiccup:

;DATASET/CREATE
(defn get-cols-nms [table] 
      "This function gets the list of columns of a specific table".
  (do (db/cols-list table)))

(defpartial form-dataset [cols-list]
  (text-field "dataset_nm" "Input here dataset name")[:br]
  (drop-down "table" tables-n)
  (submit-button "Refresh")[:br]
  (mapcat #(vector (check-box %) % [:br]) cols-list) 
  )

(defpage "/dataset/create" []
  (common/layout
    (form-to [:post "/dataset/create"]
      (form-dataset (get-cols-nms (first tables-n))))))

(defpage [:post "/dataset/create"] {:as ks}
  (common/layout
    (let [table (ks :table)]
      (form-to [:post "/dataset/create"] 
    (form-dataset (get-cols-nms table))))))

What I need is to issue a post request (as I think this the only way to do it, but I am open to suggestions) when the drop-down is selected on a specific table (so that "get-cols-nms" gets called with the selected table). In this way, when a table of the database is selected in the drop-down, the table columns will be automatically showed.

So, ultimately, the main point is for me to understand better this function:

 (drop-down "table" tables-n) 

I think that to do what I want I need the tag to have an "onchange" attribute that calls a javascript function. But I don't know: 1) if I can do this using the hiccup form-helper drop-down; 2) how can I issue (if this is the only solution, maybe there is an hiccup way?) a post request with javascript.

==EDIT==

Following the answer to this question, I rewrote the code above.It should be pretty straightforward. As I think there are not so many examples of hiccup out there, I will post my code here for reference.

Please, bear in mind that there is still a problem with this code: the drop-down won't stay on the selected item, but it will return at the default. This is because it submits "onchange". I still could not find a solution for that, maybe somebody could help...

;DATASET/CREATE
(defn get-cols-nms [table] 
  (do (db/cols-list table)))

(defpartial form-dataset [cols-list]
  (text-field "dataset_nm" "Input here dataset name")[:br]
  (assoc-in (drop-down "table" tables-n) [1 :onclick] "this.form.submit()")[:br]
  [:input {:type "submit" :value "Submit" :name "name"}][:br]
  (mapcat #(vector (check-box %) % [:br]) cols-list) 
  )

(defpage "/dataset/create" []
  (common/layout
    (form-to [:post "/dataset/create"]
      (form-dataset(get-cols-nms (first tables-n))))))

(defpage [:post "/dataset/create"] {:as ks}
  (common/layout
    (prn ks)
    (let [table (ks :table)]
      (form-to [:post "/dataset/create"] 
    (if (= (:name ks) nil)
    (form-dataset (get-cols-nms table))
    [:p "It works!"])))))
kfk
  • 831
  • 2
  • 12
  • 25

1 Answers1

5

hiccup.form-helpers/drop-down doesn't directly support adding attributes to its select element, but it does guarantee there is a standard hiccup attribute map in its return value - meaning the attributes are a map at index 1 (the second element) of the returned vector.

That means you can do something like

(assoc-in (drop-down ....) [1 :onchange] "this.form.submit()")

to generate a select tag with an onchange property.

Joost Diepenmaat
  • 17,633
  • 3
  • 44
  • 53
  • Thanks. Is it possible to send a parameter too? So that I can have 2 submit "buttons" (one for the "onchange" and one for the real submit)? – kfk Nov 15 '11 at 19:57
  • You can add more javascript or add a name+value to the submit button (those get send on when you press that button) but in this case I don't get why you'd want to. If you had to press the submit button you didn't select anything, and if you did select something you didn't press the submit. Or, maybe, you want to use 2 separate forms instead... – Joost Diepenmaat Nov 15 '11 at 20:05
  • Hello, super thanks for the help. I rewrote the code above, I think from that my use case should be clear. Please, shoot if that kind of implementation is not really clojurian... – kfk Nov 15 '11 at 20:44