Skip to content

Commit

Permalink
Minimal implementation and scaffolding for the checkbox widget. Marku…
Browse files Browse the repository at this point in the history
…p and CSS based on Filament Group's awesome book 'Designing with Progressive Enhancement' Ch. 15
  • Loading branch information
rdworth committed Apr 8, 2010
1 parent cad3fd7 commit 1f0710d
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 0 deletions.
43 changes: 43 additions & 0 deletions tests/static/checkbox/default.html
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Checkbox Static Test : Default</title>
<link rel="stylesheet" href="../static.css" type="text/css" />
<link rel="stylesheet" href="../../../themes/base/jquery.ui.base.css" type="text/css" />
<link rel="stylesheet" href="../../../themes/base/jquery.ui.theme.css" type="text/css" title="ui-theme" />
<script type="text/javascript" src="../../../jquery-1.4.2.js"></script>
<script type="text/javascript" src="../static.js"></script>
</head>
<body>

<div class="ui-checkbox">
<input type="checkbox" id="check1">
<label for="check1">Unchecked</label>
</div>

<div class="ui-checkbox">
<input type="checkbox" id="check2" checked="checked">
<label for="check2">Checked</label>
</div>

<div class="ui-checkbox">
<input type="checkbox" id="check3" disabled="disabled">
<label for="check3">Disabled</label>
</div>

<div class="ui-checkbox">
<input type="checkbox" id="check4" checked="checked" disabled="disabled">
<label for="check4">Checked and disabled</label>
</div>

<script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script>
<script>
$('<div/>').css({
position: "absolute",
right: 10,
top: 10
}).appendTo(document.body).themeswitcher();
</script>
</body>
</html>
32 changes: 32 additions & 0 deletions tests/visual/checkbox/default.html
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Checkbox Visual Test : Default</title>
<link rel="stylesheet" href="../visual.css" type="text/css" />
<link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css" type="text/css" />
<script type="text/javascript" src="../../../jquery-1.4.2.js"></script>
<script type="text/javascript" src="../../../ui/jquery.ui.core.js"></script>
<script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script>
<script type="text/javascript" src="../../../ui/jquery.ui.checkbox.js"></script>
<script type="text/javascript">
$(function() {
$("#check1, #check2, #check3").checkbox();

});
</script>
</head>
<body>

<form>

<input type="checkbox" id="check1" /><label for="check1">Check 1</label>

<input type="checkbox" id="check2" /><label for="check2">Check 2</label>

<input type="checkbox" id="check3" /><label for="check3">Check 3</label>

</form>

</body>
</html>
1 change: 1 addition & 0 deletions themes/base/jquery.ui.base.css
Expand Up @@ -3,6 +3,7 @@
@import url("jquery.ui.accordion.css");
@import url("jquery.ui.autocomplete.css");
@import url("jquery.ui.button.css");
@import url("jquery.ui.checkbox.css");
@import url("jquery.ui.datepicker.css");
@import url("jquery.ui.dialog.css");
@import url("jquery.ui.progressbar.css");
Expand Down
5 changes: 5 additions & 0 deletions themes/base/jquery.ui.checkbox.css
@@ -0,0 +1,5 @@
/* Checkbox
----------------------------------*/
.ui-checkbox { position: relative; }
.ui-checkbox input { position: absolute; left: 2px; top: 2px; margin: 0; }
.ui-checkbox label { display: block; position: relative; padding-right: 1em; line-height: 1; padding: .5em 0 .5em 30px; margin: 0 0 .3em; cursor: pointer; z-index: 1; }
59 changes: 59 additions & 0 deletions ui/jquery.ui.checkbox.js
@@ -0,0 +1,59 @@
/*
* jQuery UI Checkbox @VERSION
*
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* {{TODO replace with docs link once plugin is released}}
* http://wiki.jqueryui.com/Checkbox
* {{/TODO}}
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
*/
(function( $ ) {

$.widget( "ui.checkbox", {

_create: function() {

this.labelElement = $( this.element[0].ownerDocument ).find( "label[for=" + this.element.attr("id") + "]" );

This comment has been minimized.

Copy link
@StevenBlack

StevenBlack Apr 8, 2010

Thinking: .siblings() is probably fine here. The danger exposed here is, say, a tab interface with the same control on more than one panel. .siblings() protects from that.

This comment has been minimized.

Copy link
@scottgonzalez

scottgonzalez Apr 8, 2010

Member

Steven: Why would you have multiple tabs that with labels that point to the same checkbox?

This comment has been minimized.

Copy link
@StevenBlack

StevenBlack Apr 8, 2010

Just a (weak) example on my part (sorry). Another brain-fart: -- it's that kind of day -- is .siblings() would be too restrictive of course.

The real point being: the label is surely proximate to the control, especially a checkbox control. Going-up to the .ownerDocument and then filtering for a label's attribute is grossly inefficient in terms of finding a label that is likely proximate, no?

I see jQuery uses .closest() internally so maybe that would be a better route here?

This comment has been minimized.

Copy link
@rdworth

rdworth Apr 8, 2010

Author Contributor

We can't really assume anything about the proximity of the checkbox and its label, though in many common scenarios they won't be too far away from one another. But they might be in different cells in a table, each wrapped in their own div or span or one on its own and the other wrapped in some sibling element. What we know is the user asked us to turn the input[type=checkbox] into a jQuery UI checkbox, so that element will stay where it is and be wrapped in the necessary generated div and the label moved from wherever it might be into the same.

I'm not sure how .closest() would help us here since it wouldn't find the nearest label, .closest() walks up the parent tree starting with the current element. So that would only work if the checkbox were inside the label (which is sometimes done but not a rule). But we can't do .closest("fieldset") nor .closest("form") to find some common container since we don't know for sure that the the checkbox is in either. We know it's in its document and we know the label is in the same document and the for of one matches the id of the other.

This comment has been minimized.

Copy link
@rdworth

rdworth Apr 8, 2010

Author Contributor

Ok, turns out .closest( "label" ) was useful in the case that the checkbox is inside the label. Otherwise we search the document. Fixed up in 93c3e89


this.checkboxElement = this.element.wrap( "<div></div>" ).parent()
.addClass("ui-checkbox")
.append(this.labelElement);

},

widget: function() {
return this.checkboxElement;
},

destroy: function() {
this.checkboxElement
.after( this.labelElement ).end()
.unwrap( "<div></div>" );

$.Widget.prototype.destroy.apply( this, arguments );
},

_setOption: function( key, value ) {
if ( key === "disabled" ) {
this.element
.attr( "disabled", value );
this.checkboxElement
[ value ? "addClass" : "removeClass" ]( "ui-checkbox-disabled" );
}

$.Widget.prototype._setOption.apply( this, arguments );
},

});

$.extend( $.ui.checkbox, {
version: "@VERSION"
});

}( jQuery ));

0 comments on commit 1f0710d

Please sign in to comment.