-1

I am playing with node.js and jade and currently have this simple template:

extends layout

block content
  h1 #{title}
  br

  form(action="/updateingredient", method="post")
    table.table.table-striped.table-bordered
      tr
        td Name
        td Category
        td Available
      if (typeof ingredients === "undefined")
        tr
          td
      else
        each ingredient in ingredients
          tr
            td #{ingredient.name}
            td #{ingredient.category}
            td
              input(type="checkbox", name="#{ingredient.id}", 
                value="#{ingredient.available}", checked=ingredient.available)
    button.btn(type="submit") Update Ingredients

When submitting this I get hit in upgradeIngredients as expected:

updateIngredient: function (req, res) {
    console.log(req.body);
}

My problem lies in. That the Post only includes the checkboxes that are checked, also the value of checked boxes always seem to be false. I presume that is because that was the value before the form Post.

What I preferably would like is to get all checkbox values in the form, checked or not. Is this possible?

The current output from the updateIngredient method gives me the following when a checkbox is checked (currently just testing with one item):

{ 'b56a5f79-b074-4815-e7e0-4b746b2f65d8': 'false' }

and when unchecked:

{}

Edit

Looking at the constructed HTML I see this for an item:

<tr>
    <td>Ost</td>
    <td>Mælkeprodukt</td>
    <td>
        <input 
            type="checkbox" 
            name="b56a5f79-b074-4815-e7e0-4b746b2f65d8" 
            value="false" 
            checked="false">
    </td>
 </tr>
Community
  • 1
  • 1
Cheesebaron
  • 24,131
  • 15
  • 66
  • 118

2 Answers2

0

Verify that the checkbox HTML is correctly constructed

  • look in console for errors and warnings
  • ensure that the boxes all have either "true" or "false" for the checked value.

This example contains working syntax:

Node Express Jade - Checkbox boolean value

Community
  • 1
  • 1
  • Hmm, reading more, there seem to be some odd standards on this. E.g. XHTML requires the attribute in full or not at all (equates to 'false') and there is no supported usage as in: checked="false". So if that is the problem, you'll need to conditionally either emit checked="checked" or nothing at all as the case may be. – RobertB Sep 16 '16 at 13:35
0

After searching some more here on SO, I found this answer: Post the checkboxes that are unchecked

It seems like checkboxes, which are not checked are not part of a form when posting HTML. This is exactly what I am seeing.

I did change my checked code to the following before going down another path.

checked=ingredient.available?"checked":undefined

This did not change anything, and did not give me any data in my form post when unchecked.

So I used the JavaScript approach, adding a submit event handler to my form. I added a new checkbox.js file in my javascripts folder, this code is taken from this answer:

// Add an event listener on #form's submit action...
$("#updateform").submit(
    function() {

        // For each unchecked checkbox on the form...
        $(this).find($("input:checkbox:not(:checked)")).each(
            // Create a hidden field with the same name as the checkbox and a value of 0
            // You could just as easily use "off", "false", or whatever you want to get
            // when the checkbox is empty.
            function() {
                console.log("hello");

                var input = $('<input />');
                input.attr('type', 'hidden');
                input.attr('name', $(this).attr("name")); // Same name as the checkbox

                // append it to the form the checkbox is in just as it's being submitted
                var form = $(this)[0].form;
                $(form).append(input);

            }   // end function inside each()
        );      // end each() argument list

        return true;    // Don't abort the form submit

    }   // end function inside submit()
);      // end submit() argument list

Then I added the script to the end of my layout.jade file:

script(src='/javascripts/checkbox.js')

And I modified my form to include an ID:

form#updateform(action="/updateingredient", method="post")

And removed the value from the checkbox:

input(type="checkbox", name="#{ingredient.id}",
    checked=ingredient.available?"checked":undefined)

Now I get the following when value is unchecked:

{ 'b2a4b035-8371-e620-4626-5eb8959a36b0': '' }

And when checked:

{ 'b2a4b035-8371-e620-4626-5eb8959a36b0': 'on' }

Now in my method I can find out whether it was checked or not with:

var available = req.body[ingredient] === "on" ? true : false;

Where ingredient is the key.

Community
  • 1
  • 1
Cheesebaron
  • 24,131
  • 15
  • 66
  • 118