I worked through creating a html ternary checkbox (a checkbox with a tertiary option) this morning - with labels! Woohoo!
Now that we can create a third option we need to tell the user what it means, so we probably need labels.
Now that we can create a third option we need to tell the user what it means, so we probably need labels.
Given a checkbox like this:
<input id="example" name="example" type="checkbox" class="ternaryCheckbox" value="1" />
We can use the default 'Yes', 'No', 'All' options with this HTML:
<input id="example" name="example" type="checkbox" class="ternaryCheckbox" value="1" />
<span class="ternaryLabelsYesNoAll"></span>
OR, use custom labels:
Show Archived: <input id="example" name="example" type="checkbox" class="ternaryCheckbox" value="1" />
<span class="ternary-option checked">Active Only</span>
<span class="ternary-option unchecked">Archived Only</span>
<span class="ternary-option alternate">All Records</span>
We add this JS to attach the handler and the function to run the ternary checkbox:
$(document).ready(function(){
$(":checkbox.ternaryCheckbox").on("click",ternaryCheckbox);
});
function ternaryCheckbox(e){
var $t = $(this),
that = this,
originalVal = $t.val(),
checkedVal = originalVal,
alternateVal = ($t.data("ternary") != undefined ? $t.data("ternary") : 2);
// This should only be undefined the first time to cache the original value
if ($t.data("primary") == undefined) {
$t.data("primary",checkedVal);
} else {
checkedVal = $t.data("primary");
}
// if 'un-checking', and NOT in tern state, go to tern state, else normal checked or unchecked
if($t.prop("checked")==false && $t.prop("indeterminate")==false && originalVal!=alternateVal) {
$t.val(alternateVal);
$t.prop("checked",true);
$t.prop("indeterminate",true);
} else {
$t.val(checkedVal);
$t.prop("indeterminate",false);
}
};
.ternaryCheckbox ~ .ternaryLabelsYesNoAll {display: inline-block;font-weight: 100;margin-right: 21px;position: relative;width: 1px;}.ternaryCheckbox ~ .ternaryLabelsYesNoAll:after {content: "No";display: inline-block;}.ternaryCheckbox:checked ~ .ternaryLabelsYesNoAll:after {content: "Yes";}.ternaryCheckbox:indeterminate ~ .ternaryLabelsYesNoAll:after {content: "All";}.ternaryCheckbox ~ .ternary-option {display: inline-block;font-weight: 100;min-width: 22px;}.ternaryCheckbox ~ .ternary-option.alternate, .ternaryCheckbox ~ .ternary-option.checked {display: none;}.ternaryCheckbox:checked ~ .ternary-option.checked {display: inline-block;}.ternaryCheckbox:indeterminate ~ .ternary-option.checked, .ternaryCheckbox:checked ~ .ternary-option.alternate, .ternaryCheckbox:checked ~ .ternary-option.unchecked {display: none;}.ternaryCheckbox:indeterminate ~ .ternary-option.alternate {display: inline-block;}
Here is the Sass CSS:
/* Ternary Checkbox and Option Labels */
/* Using default 'No', 'Yes', 'All' default labels:
<input id="example" name="example" type="checkbox" class="ternaryCheckbox" value="1"<? if (local.example != 0)> checked</?><? if (local.example == 2)> indeterminate</?> />
<span class="ternaryLabelsYesNoAll"></span>
// Nothing else is needed, CSS does the rest.
*/
.ternaryCheckbox {
~ .ternaryLabelsYesNoAll {
display: inline-block;
font-weight: 100;
margin-right: 21px;
position: relative;
width: 1px;
&:after {
content: 'No';
display: inline-block;
}
}
&:checked {
~ .ternaryLabelsYesNoAll:after {
content: 'Yes';
}
}
&:indeterminate ~ .ternaryLabelsYesNoAll:after {
content: 'All';
}
}
/* Using custom ternary labels:
<input id="example" name="example" type="checkbox" class="ternaryCheckbox" value="1"<? if (local.example != 0)> checked</?><? if (local.example == 2)> indeterminate</?> />
<span class="ternary-option checked">Checked</span>
<span class="ternary-option unchecked">Unchecked</span>
<span class="ternary-option alternate">Alternate</span>
*/
.ternaryCheckbox {
~ .ternary-option {
display: inline-block;
font-weight: 100;
min-width: 22px; /* Override this if longer values are being used, inline style is fine */
&.checked,
&.alternate {
display: none;
}
}
&:checked {
~ .ternary-option.checked {
display: inline-block;
}
~ .ternary-option {
&.unchecked,
&.alternate {
display: none;
}
}
&:indeterminate ~ .ternary-option {
&.checked {
display: none;
}
&.alternate {
display: inline-block;
}
}
}
}
-GBuilt
[This solution is completely open source, absolutly free to use without any restriction. Please give creative to this blog post URL.