I want to open a dialog, and work with the data after the the dialog returns ok. The problem is that :success-fn is not called after the dialog is submitted. That has something to do with the listener from the button. If the connectDialog is called without listener, the function of :success-fn is called.
Code:
(def dbConnectionForm
(grid-panel :columns 2
:items ["Database Driver" (combobox :id :dbdriver :model ["postgresql" "mysql"])
"Database" (text :id :dbname :text "postgres")
"Port" (text :id :dbport :text "32768")
"Username" (text :id :username :text "postgres")
"Password" (text :id :password :text "postgres")]))
(defn connectionDialog []
(print (-> (dialog
:content dbConnectionForm
:option-type :ok-cancel
:type :plain
:success-fn (fn [e] (print (value dbConnectionForm)))
)pack! show!))
)
(def connectButton (button :text "Connect"
:listen [:action (fn [e] (connectionDialog))]))
This is probably because you're using print. Change it to println or add a call to flush inside the callback after the print.
If (value dbConnectionForm) returns a small value (as in something that when turned into a String has only a few characters), and doesn't contain newlines, it might not prompt the outstream to automatically flush, so the text gets stuck in the buffer.
Related
I am new to clojure and reagent. I was trying to generate dynamic number of checkboxes, the state of which is stored in the app state which is a list of dicts like this
[{:checked false, :text "Sample text 1"} {:checked false, :text "Sample text 2"} {:checked false, :text "Sample text 3"}]
The function below is expected to generate a checkbox corresponding to the specified index of app's db (db). The function does it jobs and the checkboxes are clickable.
(defn gen-checkbox [index db]
[re-com/checkbox
:label (:text (#db index))
:model (:checked (#db index))
:on-change #(swap! db assoc-in [index :checked] (not(:checked (#db index))))
])
However, I get this error in the browser console when I click on any checkbox.
Uncaught Error: Assert failed: Reaction is read only; on-set is not allowed
The error occurs at swap!. Can some one point out what I am doing wrong?
The db initialization part is as below:
(re-frame/reg-event-db ::initialize-db
(fn [_ _]
(atom [{:checked false :text "Sample text"}, {:checked false :text "Sample text"}, {:checked false :text "Sample text"}])
))
I also have a function to retreive the db. I am currently getting
(re-frame/reg-sub ::getdb
(fn [db]
#db
))
Based on the tags of your question, I presume that you are using re-frame.
You can't update the database in re-frame directly. Instead, you should register an event handler that updates the database, like the below (the exact code depends on the structure of your DB):
;; (require '[re-frame.core :as rf])
(rf/reg-event-db
:toggle-checkbox
(fn [db [_ index]]
(update-in db [index :checked] not)))
And then dispatch the event in the code of your checkbox's renderer:
...
:on-change #(rf/dispatch [:toggle-checkbox index])
...
I'm working with Reagent and CLJS, familiar with React and Clojure, less so CLJS. I'd like to make a simple form, but it's not obvious to me in CLJS.
(defn form []
[:div
[:input {:type "text" :name "first-name" :id "first-name"}]
[:button {:on-click (fn [e] (test-func "hello"))}
"Click me!"]
])
I want to grab the value of that input, and pass it to a function when the button is clicked. How do I get that input's value into my on-click function?
The idiomatic and technically correct way is to avoid keeping any state in DOM and accessing it directly. You shouldn't rely on the input's value. Keep the state as Reagent's atom. Then you can do anything with it.
(def first-name (r/atom ""))
(defn form []
[:div
[:input {:type "text"
:value #first-name
:on-change #(reset! first-name (.-value (.-target %)))
}]
[:button {:on-click #(test-func #first-name)} "Click me!"]])
You can grab the element's value like this: (.-value (.getElementById js/document "first-name"))
(defn form []
[:div
[:input {:type "text" :name "first-name" :id "first-name"}]
[:button {:on-click (fn [e] (test-func (.-value (.getElementById js/document "first-name"))))}
"Click me!"]
])
If there is a better answer out there, please share. :)
I am trying to display a group of radio buttons in a reagent/cljs app. I have followed the same process from http://yogthos.github.io/reagent-forms-example.html but the radio buttons I am displaying are showing up as textfield input boxes.
(def ^:private options (atom nil))
(defn set-options []
(reset! options
[{:name "label name"}
{:name "label name"}
{:name "label name"}]))
(defn set-radio-buttons []
(set-options)
(for [option #options]
[:div.radio
[:label
[:input {:field :radio}]
(option :name)]]))
(defn response-box []
[:div#response
(set-radio-buttons)])
I am then placing response-box in the ui layer of the app.
Thanks
Field is not a correct input element attribute.
[:input {:field :radio}]
(option :name)]]))
Should probably be
[:input {:type :radio}]
(option :name)]]))
I am creating a GUI using seesaw for the first time and I am stuck on how to add buttons to button groups and display them(buttons) on the same frame. This is what I have so far.
(def b (button :text "Start a new Project"))
(def c (button :text "Continue an Existing Project"))
(def groups (button-group))
(flow-panel :items [(b :group groups)
(c :group groups)])
(display groups)
(button) returns a button (a component) which is not a function. If you later use it as (b :group groups), it actually tries to invoke b as if it was a function, passing it two arguments: :group and groups. That's why it fails, because it can't cast button to function.
Secondly, I believe (button) creates a regular JButton, for which the group makes little sense. Did you mean radio buttons, like (radio)?
One of these two should probably do what you expect.
Radio buttons:
(def groups (button-group))
(def b (radio :text "Start a new Project" :group groups))
(def c (radio :text "Continue an Existing Project" :group groups))
(def panel
(flow-panel :items [b c]))
(invoke-later
(-> (frame :content panel :on-close :dispose) pack! show!))
Regular buttons:
(def b (button :text "Start a new Project"))
(def c (button :text "Continue an Existing Project"))
(def panel
(flow-panel :items [b c]))
(invoke-later
(-> (frame :content panel :on-close :dispose) pack! show!))
You probably can use your (display) function instead of this (invoke-later) snippet here, but this works end-to-end for me.
I have a list of files like so ("File1" "File2" "File3")
I want to turn this into a of radio-menu-items
like this
(menu :text "Lists" :items [(radio-menu-item :text "File 1")(radio-menu-item :text "File 2")(radio-menu-item :text "File 3")])
I have tried looping like this
(def Radios (for [ item '("File1" "File2" "File3")] (radio-menu-item :text item)))
but this does not work.
How can this be accomplished?
your use of a for expression looks correct, if I change the expression slightly so it returns the list it would run instead of running it we can verify this:
core> (list 'menu :text "Lists" :items
(vec (for [ item '("File1" "File2" "File3")]
(list 'radio-menu-item :text item))))
(menu :text "Lists" :items [(radio-menu-item :text "File1")
(radio-menu-item :text "File2")
(radio-menu-item :text "File3")])
so the finished expression becomes:
core> (menu :text "Lists" :items
(vec (for [ item '("File1" "File2" "File3")]
(radio-menu-item :text item))))
provided that menu and radio-menu-item resolve to the proper values.