postlispcommon-lisphunchentootcl-who

Hunchentoot Handling Checkbox Post Requests


I am developing a web application in Cl-who, Hunchentoot, and Common Lisp that will need to process customer orders. Since they could obviously order more than one item, I figured a Checkbox would make the most sense. However, the issue is when I define an easy-handler, it doesn't receive the array of results like an array in PHP if you have a series of Checkboxes with the same name and different values. Instead, it treats the variable as a String, so I cannot iterate over each Box that was checked. Here is a snippet of my code:

(:input :type "checkbox" :name "food[]" :value "cheese balls")
(:input :type "checkbox" :name "food[]" :value "fries")
(:input :type "checkbox" :name "food[]" :value "hamburger")

Here is the handler I have set up (maybe I need to use the loop macro here?) This is just a sample because I will obviously process each argument passed to the easy-handler when I figure out this problem:

(define-easy-handler (process-order :uri "/process-order") 
    (customer-name customer-address customer-city customer-phone order-type food[])
       (standard-page (:title "order results"
                       :href "file.css")
           (:h1 (if food[]
                (dolist (x food[])
                   (:li (fmt "We see that you want ~A~%" x)))))))

Those are just three potential inputs that someone could check. So lets assume that a customer checks all three... Only cheese balls would return because Lisp is treating the name "food[]" as an individual string. What I mean by that is that in PHP that variable for name ("food[]") would be processed as if it were an array. So in HTML and PHP it would look something like this:

<input type="checkbox" name="food[]" value="cheese balls" class="check"/>
<input type="checkbox" name="food[]" value="fries" class="check"/>
<input type="checkbox" name="food[]" value="hamburger" class="check"/>

Assuming a customer selected all three Checkboxes, I could do something similar to this in PHP:

if( isset( $_POST['food'])) {
    foreach ( $_POST['food'] as $food){
        echo $food;
    }
 }

It is not clear how you'd achieve similar functionality in Common Lisp with Cl-WHO and Hunchentoot however. The only other alternative I can think of is passing like 30 parameters to the easy-handler, but that sounds like the least efficient way to solve this problem. I know that there is also a CL form processing library, but I was hoping to avoid going down that route, although I will if that's the only possible solution. Giving each checkbox a different name seems like the worst possible way to solve this.


Solution

  • After further reading the documentation, you can alter the parameter type that the easy handler expects to receive. As soon as it sees that it is a list in the parameter definition, it treats it as a List. I simply changed my food parameter to this:

    (food[] :parameter-type 'list)
    

    And it treats it as if it where a list and retrieves multiple results from my CheckBoxes.