开发者

jQuery val() and checkboxes

Is there some rationale for val() being useless for checkbox controls, whereas it is useful for getting input data consistently across every other input control?

e.g. for checkboxes, at appears to always return "on" regardless of the checkbox state. For other input controls that don't actually have a "value" attribute, e.g. select and textarea, it behaves as you would expect. See:

http://jsfiddle.net/jamietre/sdF2h/4/

I can't think of a good reason why it wouldn't return true or false. Failing that, at least return "on" only when checked, and an empty string when not. Failing that, at least always return an empty string, given that checkboxes have no value attribute!

Obviously I know how to get the value using attr, but here's the situation. I am developing a simple (so far anyway) C# jQuery implementation to do HTML parsing on the server, and I am trying to be completely faithful to jQuery's implementation so it behaves consistently on either the client or server against the same DOM. But this just seems stupid and I'm having a hard time getting myself to actually code "value" to return "ON" for a checkbox no matter what. But if I don't, it won't be consistent. So I'm trying to understand, is there some reason for doing this? Does it serve some purpose, or is it simply an artifact of some kind? Would anyone ever use the val() method against a checkbox, if so, why? If not, why did the开发者_JAVA百科 jQuery architects decide on this approach to make it not useful?


I can't think of a good reason why it wouldn't return true or false. Failing that, at least return "on" only when checked, and an empty string when not. Failing that, at least always return an empty string, given that checkboxes have no value attribute!

Checkboxes do have a value attribute. It's quite common to use it in eg. multi-checkboxes in forms, for example:

<input type="checkbox" name="foo[]" value="1" />
<input type="checkbox" name="foo[]" value="2" />

Then when user submits the form, the server can parse which of the checkboxes were checked by checking the values of the foo[] array. The value of the checkbox does not change whether it is checked or not; the browser simply does not send the values of unchecked checkboxes to the server. If you do eg. $('#your-form').serialize()in jQuery, it should work similarly; it shouldn't include values of unchecked checkboxes. If you omit the value from checkbox, it simply defaults to on.

If you want to check whether an individual checkbox is checked or not in jQuery, the best most descriptive way is to do $(this).is(':checked')


You say that "checkboxes have no value attribute". On the contrary: the value attribute is optional except on checkboxes and radio boxes.

From the W3C specifications:

[the value attribute] is optional except when the type attribute has the value "radio" or "checkbox"

on is the default value that your browser gives the element when you ignore the specification and don't set a value attribute.

You need to remember what the value means: it is sent with the name of the element to the server when the form is submitted. If it is not checked, the value is not sent. The value on is therefore only sent when the checkbox is checked.


Perhaps this should help

$(document).ready(function() {
    $('input[type=checkbox]').click(function() {
      alert("val="+$(this).val()+",checked="+$(this).attr('checked'));
    });

});

Use input[type=checkbox] to select input type="checkbox" since checkbox is and input with type="checkbox"

And also put value attribute to checkbox.

On jsfiddle

UPDATE

<form method="post" action="#">
    PHP<input type="checkbox" name="ch[]" value="PHP"><br/>
    JS<input type="checkbox" name="ch[]" value="JS"><br/>
    JAVA<input type="checkbox" name="ch[]" value="JAVA"><br/>
    PYTHON<input type="checkbox" name="ch[]" value="PYTHON"><br/>
    <input type="submit" name="submit"/>
</form>

And php

if($_POST){
foreach($_POST['ch'] as $post => $value){
    echo "$post -> $value <br/>";
}
}

They all share same name as they are a common group of button. You you know which was checked and which was not through their values.

The other way is

if($_POST){
    foreach($_POST as $post => $value){
        echo "$post -> $value <br/>";
    }
}

<form method="post" action="#">
    PHP<input type="checkbox" name="PHP"><br/>
    JS<input type="checkbox" name="JS"><br/>
    JAVA<input type="checkbox" name="JAVA"><br/>
    PYTHON<input type="checkbox" name="PYTHON"><br/>
    <input type="submit" name="submit"/>
</form>

But the previous seems to add more dynamic and less tedious(I would believe).

And as to @Capsule's question

alert("val="+$(this).val()+",checked="+$(this).attr('checked'));
<input type="checkbox"> Check me.

returns the value on i believe that's the default value of the check-box.

And the second experiment also give the on value.

I hope I am not wrong.


If you pass an array to val function, it will set the checkbox as checked if the checkbox's value matches the value in the array. Source: http://api.jquery.com/val/#val-value

<input id="checkbox" type="checkbox" value="remember">    

$("#checkbox").val(["remember"]);


Checkbox has value just like text box and this value is being sent to the server when the form is submitted only if the checkbox was selected at the time of submission.

Unlike text box, checkbox has default value which is on - this is sent to the server when the checkbox is selected but has no value of its own, so that the processing code can know it was selected.

So the .val() method is working just fine, returning the value of the element.

You're correct that jQuery is missing simple way to see if a specific checkbox/radio button is selected, something like $("#mycheckbox").checked() but that's what we have plugins for. :)


A checkbox is not always alone and its value is passed when submitting the form (otherwise, the name/value is not passed at all).

It's very useful when making arrays out of checkboxes, you can use name="test[]" as their name, and set different values in each. When parsing the submitted result, you end up with an array containing all the checked values


You can do some surgery to jquerys val function to act like that. Return true or false whether theres no value attr.

(function (){
    var jval = $.fn.val
    function superval(value){
        if (value === undefined){
            if (this.is("input") && this.attr("type") == "checkbox"){
                if (this.attr("value")===undefined){
                    return this[0].checked
                }
            }
            return jval.call(this)
        } else {
            return jval.call(this, value)
        }
    }
    $.fn.val = superval
})()

console.log($('<input type="checkbox"/>').val()); // false
console.log($('<input type="checkbox" checked="whatever"/>').val()); // true
console.log($('<input type="checkbox" checked="whatever" value="yes"/>').val()); // yes
console.log($('<input type="text" value="heya"/>').val()); // heya
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


You may consider using hidden input, containing value you want to retreive, along with checkbox, which will change input's value on "input" and "change" events with any value you want.

something
 .append( $("<INPUT/>")
   .prop("type", "hidden")
   .addClass("mycheckboxvalue")
   .val("initial value")
 )
 .append( $("<INPUT/>")
   .prop("type", "checkbox")
   .prop("checked", initial_state)
   .on("input change", function() {
     $(".mycheckboxvalue").val(
       $(this).is(":checked")?
         "checked value":
         "unchecked value"
     )
   })
 )
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜