I am making a Clojure web-app to process numeric input data. I have set up the main page and am working on having the inputed data processed and displayed after submission via a button.
key bits of code with comments:
(defn process-grades
"Takes user input from home's form-to function and processes it into the final grades list"
[weights grades]
(->> grades
(map (partial percentify-vector weights)) ;; <- The functions being called here are omitted but defined in the same name space.
(mapv #(apply + %))))
(defn home [& [weights grades error]]
(html
[:head
[:title "Home | Clojuregrade"]]
[:body
[:h1 "Welcome to Clojuregrade"]
[:p error]
[:hr]
(form-to [:post "/"]
[:h3 "Enter the weights for each of the grades below. Of course, all of the numbers should add up to 100%. Be sure to include the brackets"
[:br]
(text-area {:cols 30 :placeholder "[40 10 50] <- adds up to 100%"} "weights" weights)]
[:h3 "Enter ALL of the grades for EACH STUDENT in your class.
Make sure that each of the grades is ordered such that the grade corresponds
to its matching weight above."
[:br]
(text-area {:rows 15 :cols 30 :placeholder
"[89 78 63]
[78 91 60]
[87 65 79]
... " } "grades" grades)]
(submit-button "process"))]))
(defn processed [weights grades]
(cond
(empty? weights)
(home weights grades "You forgot to add the weights!")
(empty? grades)
(home weights grades "You forgot to add the grades!")
:else
(do
(html
[:h2 "These are your final grades."]
[:hr]
[:p "test"])))) ;; <- I would like to call process-grades here. "test" renders fine.
(defroutes app
(GET "/" []
{:status 200
:headers {"Content-Type" "text/html"}
:body (home)})
(POST "/" [weights grades] (processed weights grades))
(ANY "*" []
(route/not-found (slurp (io/resource "404.html")))))
;; ...
My Assumption was right. I was taking your code and put it into a barebone luminus project. The html your code produces looks like this:
<h3>
Enter the weights for each of the grades below. Of…
<br></br>
<textarea id="weights" placeholder="[40 10 50] <- adds up to 100%" name="weights" cols="30"></textarea>
</h3>
<h3>
Enter ALL of the grades for EACH STUDENT in your c…
<br></br>
<textarea id="grades" rows="15" placeholder="bla" name="grades" cols="30"></textarea>
</h3>
And here comes the error:
<form method="POST" action="/">
<input type="submit" value="process"></input>
</form>
The form element has to wrap the input elements, otherwise it wont submit them as part of the request.
So if you take your hiccup code and change it to this:
(defn home [ & [weights grades error]]
(html
[:h1 "Welcome to Clojure-grade"]
[:p error]
[:hr]
(form-to [:post "/"]
[:h3 "Enter the weights for each of the grades below. Of course, all of the numbers should add up to 100%. Be sure to include the brackets"
[:br]
(text-area {:cols 30 :placeholder "[40 10 50] <- adds up to 100%"} "weights" weights)
]
[:h3 "Enter ALL of the grades for EACH STUDENT in your class.
Make sure that each of the grades is ordered such that the grade corresponds
to its matching weight above."
[:br]
(text-area {:rows 15 :cols 30 :placeholder "bla"} "grades" grades)]
;...
;
; (Each grade corresponds to one of the weights above,
; so order is important. You can copy and paste directly from your excel file but don't forget
; the brackets!)" } "grades" grades)]
(submit-button "process")))) ;; <- when I hit this in the browser I get a 404, with or without input.
It works. Take precise look at: "(form-to [:post "/"]". I moved it a few lines up so that it wraps the input elements.
Just a side note, spend some time working with the browser developer tools and read at least a small html tutorial. Especially knowing how to use the developert tools will give you a big edge while debugging such problems.