开发者

HTML checkbox elements are only submitted if they're checked?

开发者 https://www.devze.com 2023-01-25 10:02 出处:网络
I\'m trying to work on an existing website and I\'ve found a bug, but I\'m not sure why it\'s a bug or how to work around it.

I'm trying to work on an existing website and I've found a bug, but I'm not sure why it's a bug or how to work around it.

The website basically lists some commercial properties that are for lease in one city. There's a class which grabs the listings from the database and creates an object out of each. In each object is an array of images which are associated with that property.

When the user edits a listing, they get an edit page which has a list of the images, and a "delete" checkbox next to them. The checkboxes all have the same name, so that when they are submitted back to the server, the app gets an array of the images to be deleted.

What's supposed to happen, is that the app has this array of on/off values (where on = delete), and the index of each value in the array corresponds to the index of an image in the listing object -- when one of the values is "on", the filename in the images array corresponding to that "on" value is deleted from the filesystem, and that image is removed from the database.

However, when the form is submitted, the app gets a 0-indexed array of only the checked checkboxes. So if I set three arbitrary images for deletion, the app would get

Array {
   [0] => "on",
   [1] => "on",
 开发者_如何转开发  [2] => "on"
}

This obviously doesn't work, the first 3 images in the listing will be deleted regardless of which checkboxes are set.

How can I fix this? I would like to avoid naming each checkbox (delete_1, delete_2, delete_3, etc) as the system is already built to work with all the checkboxes having the same name. Is there a way I can force all of the checkboxes to be submitted with either "on" or "off?"


There is no way to force, but you could just add a hidden right before checkbox with the same name and needed value:

<input type="hidden" name="delete[42]" value="off" />
<input type="checkbox" name="delete[42]" value="on" />


No, you cannot force unchecked checkboxes to be submitted, but you can give them unique values (instead of "on" for all) to determine which ones are checked without changing the names.


You could solve this by adding the following jQuery:

$(function () {
  $("#myform").submit(function(){
    $("input[name='delete']:not(:checked)").attr("checked","checked").val("off");  
  });
}); 

myform being the ID of your form and delete being the name of the checkboxes.


If you really want to return an array on ons and offs, then you'll need to attach a function to the form submit that will scan for all the check boxes with the given name, and put their values in the array.

In jQuery this would look something like...

$('#yourForm').submit(function(){
    var array = new Array();
    $('input[name="nameOfCheckboxes"]').each(function(index){
        array[index] = $(this).value();
    }
    var r = $.param(array);
    $('#someHiddenFieldInForm').value(r);
 }

(code is untested, of course)


Fred Nurk's solution is good and I upvoted it. Personally when I've had this situation, I've always given the fields different names. I use a common prefix, followed by an underscore so it's easy to recognize, and then some sort of id. I'll often make a set of fields all with the same pattern, like "name_1", "amount_1", "foobar_1", "name_2", "amount_2", etc. It's fairly easy to loop through the fields and take these names apart. (In Java, just indexOf('_').)


The other way around this problem is to accept an oddity of HTML Forms and catch it with a local variable that employs ternary operators during declaration.

For example, given a checkbox

<input type="checkbox" name="notify_users" id="notify_cb">

You can process the post like this regardless of the inclusion of the checkbox value:

// normal boolean value    
$notify_users = ((!empty($_POST['notify_users']) and $_POST['notify_users'] == 'on' );    
// explicitly set a 1 or 0
$notify_users = ((!empty($_POST['notify_users']) and $_POST['notify_users'] == 'on' )? 1 : 0);
// explicitly set 'yes' or 'no'
$notify_users = ((!empty($_POST['notify_users']) and $_POST['notify_users'] == 'on' )? 'yes' : 'no');

In my mind this is preferable to adding additional Javascript to the client, if only because it's a tiny bit less to maintain (and arguably clearer for a successor/other dev to grok what's going on)

0

精彩评论

暂无评论...
验证码 换一张
取 消