Tri-state Check box in HTML?

匿名 (未验证) 提交于 2019-12-03 02:08:02

问题:

There is no way to have a tri-state check button (yes, no, null) in HTML, right?

Are there any simple tricks or work-arounds without having to render the whole thing by oneself?

回答1:

Edit

Thanks to Janus Troelsen's comment, I found a better solution.

HTML5 defines a property for checkboxes called indeterminate

See w3c reference guide. To make checkbox appear visually indeterminate set it to true:

element.indeterminate = true; 

Here is Janus Troelsen's fiddle. Note, however, that:

  • The indeterminate state cannot be set in the HTML markup, it can only be done via Javascript (see this JSfiddle test and this detailed article in CSS tricks)

  • This state doesn't change the value of the checkbox, it is only a visual cue that masks the input's real state.

  • Browser test: Worked for me in Chrome 22, Firefox 15, Opera 12 and back to IE7. Regarding mobile browsers, Android 2.0 browser and Safari mobile on iOS 3.1 don't have support for it.

Previous answer

Another alternative would be to play with the checkbox transparency for the "some selected" state (as Gmail does used to do in previous versions). It will require some javascript and a CSS class. Here I put a particular example that handles a list with checkable items and a checkbox that allows to select all/none of them. This checkbox shows a "some selected" state when some of the list items are selected.

Given a checkbox with an ID #select_all and several checkboxes with a class .select_one,

The CSS class that fades the "select all" checkbox would be the following:

.some_selected {     opacity: 0.5;     filter: alpha(opacity=50); } 

And the JS code that handles the tri-state of the select all checkbox is the following:

$('#select_all').change (function () {     //Check/uncheck all the list's checkboxes     $('.select_one').attr('checked', $(this).is(':checked'));     //Remove the faded state     $(this).removeClass('some_selected'); });  $('.select_one').change (function () {     if ($('.select_one:checked').length == 0)         $('#select_all').removeClass('some_selected').attr('checked', false);     else if ($('.select_one:not(:checked)').length == 0)         $('#select_all').removeClass('some_selected').attr('checked', true);     else         $('#select_all').addClass('some_selected').attr('checked', true); }); 

You can try it here: http://jsfiddle.net/98BMK/

Hope that helps!



回答2:

You could use HTML's indeterminate IDL attribute on input elements.



回答3:

My proposal would be using

  • a plain text input field (size=1)
  • no border
  • read only
  • display no cursor
  • onclick handler to toggle thru the three states

See examples at:

HTML source:

<input type='text'         style='border: none;'         onfocus='this.blur()'         readonly='true'         size='1'         value='&#x2753;' onclick='tristate_Marks(this)' /> 

or as in-line javascript:

<input style="border: none;"        id="tristate"         type="text"          readonly="true"         size="1"         value="&#x2753;"          onclick="switch(this.form.tristate.value.charAt(0)) {           case '&#x2753': this.form.tristate.value='&#x2705;'; break;            case '&#x2705': this.form.tristate.value='&#x274C;'; break;           case '&#x274C': this.form.tristate.value='&#x2753;'; break;         };" /> 

Javascript source code:

<script type="text/javascript" charset="utf-8">   /**    *  loops thru the given 3 values for the given control    */   function tristate(control, value1, value2, value3) {     switch (control.value.charAt(0)) {       case value1:         control.value = value2;       break;       case value2:         control.value = value3;       break;       case value3:         control.value = value1;       break;       default:         // display the current value if it's unexpected         alert(control.value);     }   }   function tristate_Marks(control) {     tristate(control,'\u2753', '\u2705', '\u274C');   }   function tristate_Circles(control) {     tristate(control,'\u25EF', '\u25CE', '\u25C9');   }   function tristate_Ballot(control) {     tristate(control,'\u2610', '\u2611', '\u2612');   }   function tristate_Check(control) {     tristate(control,'\u25A1', '\u2754', '\u2714');   }  </script> 


回答4:

You can use an indeterminate state: http://css-tricks.com/indeterminate-checkboxes/. It's supported by the browsers out of the box and don't require any external js libraries.



回答5:

You can use radio groups to achieve that functionality:

<input type="radio" name="choice" value="yes" />Yes <input type="radio" name="choice" value="No" />No <input type="radio" name="choice" value="null" />null 


回答6:

Like @Franz answer you can also do it with a select. For example:

<select>   <option></option>   <option value="Yes">Yes</option>   <option value="No">No</option> </select> 

With this you can also give a concrete value that will be send with the form, I think that with javascript indeterminate version of checkbox, it will send the underline value of the checkbox.

At least, you can use it as a callback when javascript is disabled. For example, give it an id and in the load event change it to the javascript version of the checkbox with indeterminate status.



回答7:

I think that the most semantic way is using readonly attribute that checkbox inputs can have. No css, no images, etc; a built-in HTML property!

See Fiddle:
http://jsfiddle.net/chriscoyier/mGg85/2/

As described here in last trick: http://css-tricks.com/indeterminate-checkboxes/



回答8:

Refering to @BoltClock answer, here is my solution for a more complex recursive method:

http://jsfiddle.net/gx7so2tq/2/

It might not be the most pretty solution but it works fine for me and is quite flexible.

I use two data objects defining the container:

data-select-all="chapter1" 

and the elements itself:

data-select-some="chapter1" 

Both having the same value. The combination of both data-objects within one checkbox allows sublevels, which are scanned recursively. Therefore two "helper" functions are needed to prevent the change-trigger.



回答9:

Besides all cited above, there are jQuery plugins that may help too:

for individual checkboxes:

for tree-like behavior checkboxes:

EDIT Both libraries uses the 'indeterminate' checkbox attribute, since this attribute in Html5 is just for styling (https://www.w3.org/TR/2011/WD-html5-20110113/number-state.html#checkbox-state), the null value is never sent to the server (checkboxes can only have two values).

To be able to submit this value to the server, I've create hidden counterpart fields which are populated on form submission using some javascript. On the server side, you'd need to check those counterpart fields instead of original checkboxes, of course.

I've used the first library (standalone checkboxes) where it's important to:

  • Initialize the checked, unchecked, indeterminate values
  • use .val() function to get the actual value
  • Cannot make work .state (probably my mistake)

Hope that helps.



回答10:

You'll need to use javascript/css to fake it.

Try here for an example: http://www.dynamicdrive.com/forums/archive/index.php/t-26322.html



回答11:

It's possible to have HTML form elements disabled -- wouldn't that do? Your users would see it in one of three states, i.e. checked, unchecked, and disabled, which would be greyed out and not clickable. To me, that seems similar to "null" or "not applicable" or whatever you're looking for in that third state.



回答12:

There's a simple JavaScript tri-state input field implementation at https://github.com/supernifty/tristate-checkbox



回答13:

The jQuery plugin "jstree" with the checkbox plugin can do this.

http://www.jstree.com/documentation/checkbox

-Matt



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!