fukamachi / caveman

Lightweight web application framework for Common Lisp.
http://8arrow.org/caveman/
775 stars 63 forks source link

How to get multiple values in params #97

Closed azzamsa closed 6 years ago

azzamsa commented 6 years ago

@fukamachi Hi, Fukamachi.

I am sorry for disturbing your time and calmness.

I have tried this for more than 3 days, but I still can't solve this problem. I Have asked this qestion in Stackoverflow, but also no workaround.

I have tried this caveman1 readme but no luck.

thank you very much.

azzamsa commented 6 years ago

Stil there is no solution for this problem, but my dirty hack is:

@route GET "/cbdua"
(lambda (&key _parsed)
  (let ((result (remove "name" (alexandria:flatten 
                                (loop for (vehicle . value)
                                      in _parsed collect value)) :test #'equal)))

    (render #P"cbdua.html"
            `(:result ,result))))
azzamsa commented 6 years ago

This is my complete code to yield the result


(defvar *answers* nil)

(defun parse-params (input)
  (remove "name" (alexandria:flatten 
                  (loop for (vehicle . value)
                     in input collect value)) :test #'equal))

(defun get-result (input)
  (cond
    ((equal input '("car")) (setf *answers* "kamu punya car"))
    ((equal input '("bike")) (setf *answers* "kamu punya bike"))
    ((equal input '("bike" "car")) (setf *answers* "kamu punya car dan bike"))))
@route GET "/cbdua"
(defun cari-jawaban (&key _parsed)
  (render #P"cbdua.html" `(:jawaban ,(get-result (parse-params _parsed)))))
       <form action="/cbdua">
            <input type="checkbox" name="items[][name]" value="bike"> I have a bike<br>
            <input type="checkbox" name="items[][name]" value="car"> I have a car<br>
            <input type="submit" value="Checkbox 2!">
        </form>

you can look at complete code in this repo

aarvid commented 6 years ago

This is value of _parsed

(("items" (("name" . "bike")) (("name" . "car"))))

to get the value of parameter items do

(cdr (assoc "items" _parsed :test #'string=))

to get result

((("name" . "bike")) (("name" . "car")))

which is a list of associated lists.

This is because your html asks for a matrix of values items[][name]

if you change the html to items[], you will get an array of values.

with both checked, _parsed will be:

(("items" "bike" "car"))

now

(cdr (assoc "items" _parsed :test #'string=))

returns

("bike" "car")

azzamsa commented 6 years ago

Hi, Aarvid.

It's long story to tell, I spent two days to find out the answer. I thought I was have wrong code, because the caveman1 readme tell to use getf-all for multiple value in params. I try to play with the result and no luck.

So, I think I have to use the "dirty hack" because in Caveman2 Readme, it does not tell how to get value in multiple params (eg. ?foo=1&foo=2). so instead of using &key I try to use _parsed and manipulate the result.

I play with _parsed more than 7 hours (as I am lisp newbie) to extract the result as it is associated list, so what I do is: 1. loop over items, get the value instead of key, and 2. remove the car value. so the result was ("bike" "car")

Even tough it was tedious, it's worth and it works :).

2017-11-19-10 54 45 - dr kucing

Unfortunately, I only focus to items[][name] and I though caveman does not supposed to use items[]

Thanks for pointing out.

I hope we will have good docs on caveman soon :)


Do you use caveman2 on your production?

aarvid commented 6 years ago

I have used caveman2 on a bunch toy/proof of concept systems and on one production system which is proprietary which is your basic data entry and data display site with some peculiar requirements but accessible only to my client and their clients. So I can't show you the code or the website. I used caveman2 because it combines djula templates (my client was supposed to provide a css web designer but never did), a postgres database, internationalization (the site is in 3 languages and would be easy to add more. in fact I contributed to the Djula so it can generate cl-locale files and created translate_client to get google translations. )

azzamsa commented 6 years ago

Wow, sounds great that caveman2 used in your production stack. Thanks for that.

Happy Hacking.

azzamsa commented 6 years ago

Since we have solution above,

I will close this issue.