I have a search-form that searches some text for me. When I type in the input box I have to manually press a button for it to search. Is there a way for me to hit enter on the keyboard and have that search, as well as the button?
(defn search-form
[]
[:div
[:p "What are you searching for? "
[:input
{:type :text
:name :search
:on-change #(swap! fields assoc :search (-> % .-target .-value))
:value (:search #fields)}]]
[:input
{:type :submit
:value :Search
:on-click #(do
(search-function (:search #fields)))}]
[#search-results]])
This is the code I currently have. As you can see, to call the search-function I have to click on the button. I would like to be able to press enter and also have the ability to press the button and both will call search-function
Any help would be much appreciated. Thanks
You might try something like :on-key-down for the event, and I think you are looking for the number 13. Ran across it when I was reading the source code for reagent-forms though I am not sure where the documentation would be.
Closest documentation that I could find is here, though React tests for the Enter key explicitly here.
Related
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.
I have a series of checkbox inputs and I'd like to uncheck all the boxes when the user clicks a button. Checking the inputs doesn't seem to set an attr, so I'm unsure if/how to reset the "checked" prop. I'd like to do this in pure CLJS, no extra DOM manipulation libraries, please. If there is a smarter way to do this within the Reagent framework, that would also be an acceptable/helpful answer.
(defn clear-order []
(map #(set! (.-checked %) false) (.getElementsByTagName js/document "input")))
This gets all my inputs, and maybe does what it's supposed to, but doesn't actually uncheck my inputs.
Like someone said in a comment, you need to use something eager and not map, which is lazy. run! is like an eager map. Also HTMLCollections aren't seqable, so you can use goog.array/toArray to get something that is.
Putting that together:
(ns foo.core
(:require
[goog.array :as garray]))
(defn clear-order []
(run! #(set! (.-checked %) false)
(garray/toArray (.getElementsByTagName js/document "input"))))
Try this:
(doseq [something (goog.array.toArray (.getElementsByTagName js/document "input"))]
(js/console.log something))
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'm trying to listen to the :key-pressed and :key-released events on my Seesaw frame, but the events aren't firing. I've narrowed the problem down to a listbox -- when the listbox is present, the frame no longer captures the key events. Here's a simplified version of my code that shows the behavior:
(ns ainur.example
(:use seesaw.core))
(let [lst (listbox :model ["Chiptune" "Sinewave"])
f (frame :title "Ainur"
:on-close :exit
:size [1024 :by 768]
:content (border-panel :hgap 10 :vgap 10
:center (label "Center")
:north (label "North")
:south (label "South")
:west lst))]
(listen lst :selection (fn [e]
(let [active-inst (selection e)]
(println active-inst))))
(listen f
:key-pressed (fn [e]
(println "Key pressed"))
:key-released (fn [e]
(println "Key released")))
(invoke-later
(native!)
(show! f)))
Can anyone help me figure out why the key events aren't triggered? Any help would be really appreciated. Thanks in advance!
I posted this question in seesaw's Google Group, and received an excellent answer from Seesaw's creator, Dave Ray, himself. I'm posting it here in case anyone else runs into this issue:
"Hi. Once there's another widget in the hierarchy like a listbox, it grabs keyboard focus so the events never get to the frame. I think the best bet would be to put the key listener on a nested widget like a panel and then give it keyboard focus. A kind of similar example can be seen here:
https://github.com/daveray/regenemies/blob/master/src/regenemies/ui.clj#L163
The :key-typed event is bound to the canvas and then .requestFocusInWindow is used to give it keyboard focus."
Many thanks, Dave!
I would like to be able to make inserts in a tree data structure (like the one doing comments on Disqus, Hacker News etc). And it would be nice to do it in a clever functional way.
Example
(def cmts [{:name "Abi" :id 1 :text "Great question" :children nil}
{:name "Bib" :id 2 :text "What about zippers?" :children
[{:name "Linus" :id 3
:text "I don't understand how to and insert
children at a certain id with them"
:children nil}]}])
The problem is how to insert a comment like this
(add-comment cmts :name "Iba" :text "I think so too!" :in-reply-to 1)
in a somehow concise/elegant way.
Or: what would be a simpler way to solve the problem?
If you are looking to do functional tree editing (editing neste data structures) then perhaps
the zipper library is the right tool.
I realize that there are very good functionality in the clojure.walk library that could do the trick. http://clojuredocs.org/clojure_core/clojure.walk