Open jkk opened 11 years ago
Perhaps related to this, I can not get a datetime to render correctly. I posted some screenshots of the problem on my blog:
http://www.smashcompany.com/technology/trying-to-use-the-formative-library
Is that a bug, or do I need to reformat the datetime to get it to work?
Might be a bug. Could you verify the class of the date before passing it to Formative? E.g. with (class some-date-object)
Okay, this:
(println (str (class (:created-at item))))
gives me:
class org.joda.time.DateTime
Do I need to coerce this to a different type?
This value is probably coming back to me straight from the driver that connects to MongoDb, though elsewhere in my code I rely on https://github.com/clj-time/clj-time for handling of dates.
Apparently, I was able to fix this problem by adding the special keys "year-start" and "year-end". Perhaps the documentation could make clear that these keys are mandatory?
I ended up with this field definition:
{ :name :created-at :type :datetime-select :note "When was this item first created?" :year-start 2000 :year-end 2020 }
My thanks to you for the work you've done on Formative. It is a good library.
Actually I can not get this to work. I am using (wrap-keyword-params) so most of the form inputs are keywords, but not the datetime-select inputs, which for some reason remain strings. If I use pprint on the form input I see data like:
"created-at[month]" "11", :top-winner-bio "", :mailing-address "", :country "", :cash-total "0.2659130096435547", :subscribe-to-questions-via-email "true", :previous-item-name "", "created-at[day]" "21", :email "zach@gmail.com", "updated-at[m]" "", "updated-at[year]" "", "updated-at[h]" "",
All of the field names are correctly transformed to keywords, except for the datetime-select forms. More so, when I validate the form:
(fp/parse-params the-form (:params request))
The datetime-select fields simply vanish from the item.
I looked here:
https://github.com/jkk/formative/blob/master/src/formative/parse.cljx
and it seems like the code can parse datetime-select. What do I need to do to enable this? Is there a :datatype that I need to set? Or is there specific Ring middleware I should use? Or does (wrap-keyword-params) actually block the workings of Formative?
Huh. This is strange. Even if I manually create a datetime and put it into the (:params request) Formative still removes it when it validates the data.
Right now I have this clunky bit of code, with a pprint at top and pprint at bottom:
(println " these values will be validated by formative: ") (pp/pprint (:params request)) (let item-type-as-keyword (keyword (get-in request [:params :item-type])) the-form (secretary/get-from-interactions [:schema item-type-as-keyword]) item (:params request) item (if (:item-name item) item (assoc item :item-name (in/make-item-name item))) created-at (tyme/make-created-at item) updated-at (tyme/make-updated-at item) start-at (tyme/make-start-at item) end-at (tyme/make-end-at item) item (if created-at (assoc item :created-at created-at) item) item (if updated-at (assoc item :updated-at updated-at) item) item (if start-at (assoc item :start-at start-at) item) item (if end-at (assoc item :end-at end-at) item) item (fp/parse-params the-form item) (pp/pprint item)
And this:
(tyme/make-created-at item)
is a clunky way to force a datetime:
(defn make-created-at [item](if %28get-in item) (tyme/date-time (Integer/parseInt (get-in item "created-at[year]")) (Integer/parseInt (get-in item "created-at[month]")) (Integer/parseInt (get-in item "created-at[day]")) (Integer/parseInt (get-in item "created-at[h]")) (Integer/parseInt (get-in item "created-at[m]")))))
"tyme" is just a refer to clj-time.
The pprint shows the datetime-select input with string keys like this:
"updated-at[year]" "", "updated-at[h]" "",
The bottom pprint surprises me: the datetimes have been removed. Formative gives no error, no exception, Formative simply removes the datetime.
I am trying to figure out why this is.
Looking here:
https://github.com/jkk/formative/blob/master/src/formative/parse.cljx
I see:
(fu/to-date
(fu/from-timezone
(fu/with-time date
(fu/hour time)
(fu/minute time)
(fu/sec time))
So I added a "timezone" as string:
{
:name :start-at
:note " :start-at "
:year-start 1950
:year-end 2030
:important-to-show-in-lists true
:datatype :date
:ampm false
:seconds false
:timezone "US/Eastern"
}
This did not help.
Could you try (fp/parse-params the-form (:form-params req))
or (fp/parse-request the-form req)
and see if that does what you expect?
This:
(pprint request)
shows me (among other things):
:form-params {},
all data is in:
:multipart-params
and:
:params
These last 2, :multipart-params and :params, have similar content, but :multipart-params have keys that are strings. (wrap-keyword-params) gives me keyword keys in :params, but not in :multipart-params.
I do not know why :form-params is empty. Maybe I have wrap-params in the wrong place? I have my Ring middleware set up as:
(def app (-> app-routes (friend/authenticate {:workflows [(workflows/interactive-form)] :credential-fn (partial creds/bcrypt-credential-fn users)}) (wrap-session {:cookie-name "tma-admin-session" :cookie-attrs {:max-age 90000000}}) (wrap-cookies) (wrap-keyword-params) (wrap-multipart-params) (wrap-nested-params) (wrap-params)))
I just tried:
(def app (-> app-routes (wrap-params) (friend/authenticate {:workflows [(workflows/interactive-form)] :credential-fn (partial creds/bcrypt-credential-fn users)}) (wrap-session {:cookie-name "tma-admin-session" :cookie-attrs {:max-age 90000000}}) (wrap-cookies) (wrap-keyword-params) (wrap-multipart-params) (wrap-nested-params)))
but then I am unable to log in, so I moved wrap-params back to the end.
Am I missing any middleware that is necessary to work with Formative? I didn't see anything special in the demo app you've set up.
If I access :multipart-params and send that to parse-params, like this:
item (:multipart-params request)
item (do
(println " now we will parse this item: ")
(pp/pprint item)
(fp/parse-params the-form item))
I get:
java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.CharSequence at clojure.string$blankQMARK.invoke(string.clj:279) at formative.parse$parse_date.invoke(parse.clj:98) at formative.parse$fn9329.invoke(parse.clj:105) at clojure.lang.MultiFn.invoke(MultiFn.java:231) at formative.parse$parse_nested_params$fn9410.invoke(parse.clj:251)
I am guessing that the clojure.lang.PersistentArrayMap causing the problems is the file maps being uploaded, such as:
"file-1" {:size 0, :tempfile
:content-type "application/octet-stream", :filename ""},
In this case I did not upload a file, but the map is still there in :multipart-params.
Must account for this in validations, too - does Verily need to be updated?