iphone-style-checkboxes 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +4 -10
- data/VERSION +1 -1
- data/iphone-style-checkboxes.gemspec +63 -0
- data/templates/project/iphone-style-checkboxes.js +219 -0
- data/templates/project/manifest.rb +1 -0
- metadata +4 -2
data/README.rdoc
CHANGED
@@ -1,16 +1,10 @@
|
|
1
1
|
= compass-iphone-style-checkboxes
|
2
2
|
|
3
|
-
|
3
|
+
Install Gem:
|
4
|
+
gem install iphone-style-checkboxes
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
* Fork the project.
|
8
|
-
* Make your feature addition or bug fix.
|
9
|
-
* Add tests for it. This is important so I don't break it in a
|
10
|
-
future version unintentionally.
|
11
|
-
* Commit, do not mess with rakefile, version, or history.
|
12
|
-
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
-
* Send me a pull request. Bonus points for topic branches.
|
6
|
+
Install into Compass:
|
7
|
+
compass install iphone-style-checkboxes
|
14
8
|
|
15
9
|
== Copyright
|
16
10
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{iphone-style-checkboxes}
|
8
|
+
s.version = "0.0.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Thomas Reynolds"]
|
12
|
+
s.date = %q{2010-08-17}
|
13
|
+
s.email = %q{tdreyno@gmail.com}
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"LICENSE",
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".document",
|
20
|
+
".gitignore",
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"iphone-style-checkboxes.gemspec",
|
26
|
+
"lib/iphone-style-checkboxes.rb",
|
27
|
+
"stylesheets/_iphone-style-checkboxes.sass",
|
28
|
+
"templates/project/iphone-style-checkboxes.js",
|
29
|
+
"templates/project/iphone-style-checkboxes/off.png",
|
30
|
+
"templates/project/iphone-style-checkboxes/on.png",
|
31
|
+
"templates/project/iphone-style-checkboxes/slider.png",
|
32
|
+
"templates/project/iphone-style-checkboxes/slider_center.png",
|
33
|
+
"templates/project/iphone-style-checkboxes/slider_left.png",
|
34
|
+
"templates/project/iphone-style-checkboxes/slider_right.png",
|
35
|
+
"templates/project/iphone-style-example.sass",
|
36
|
+
"templates/project/manifest.rb",
|
37
|
+
"test/helper.rb",
|
38
|
+
"test/test_compass-iphone-style-checkboxes.rb"
|
39
|
+
]
|
40
|
+
s.homepage = %q{http://github.com/tdreyno/compass-iphone-style-checkboxes}
|
41
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
42
|
+
s.require_paths = ["lib"]
|
43
|
+
s.rubygems_version = %q{1.3.6}
|
44
|
+
s.summary = %q{Compass plugin for the iPhone-style checkboxes}
|
45
|
+
s.test_files = [
|
46
|
+
"test/helper.rb",
|
47
|
+
"test/test_compass-iphone-style-checkboxes.rb"
|
48
|
+
]
|
49
|
+
|
50
|
+
if s.respond_to? :specification_version then
|
51
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
52
|
+
s.specification_version = 3
|
53
|
+
|
54
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
55
|
+
s.add_runtime_dependency(%q<compass>, [">= 0.10"])
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<compass>, [">= 0.10"])
|
58
|
+
end
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<compass>, [">= 0.10"])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,219 @@
|
|
1
|
+
/*!
|
2
|
+
// iPhone-style Checkboxes jQuery plugin
|
3
|
+
// Copyright Thomas Reynolds, licensed GPL & MIT
|
4
|
+
*/
|
5
|
+
;(function($, iphoneStyle) {
|
6
|
+
|
7
|
+
// Constructor
|
8
|
+
$[iphoneStyle] = function(elem, options) {
|
9
|
+
this.$elem = $(elem);
|
10
|
+
|
11
|
+
// Import options into instance variables
|
12
|
+
var obj = this;
|
13
|
+
$.each(options, function(key, value) {
|
14
|
+
obj[key] = value;
|
15
|
+
});
|
16
|
+
|
17
|
+
// Initialize the control
|
18
|
+
this.wrapCheckboxWithDivs();
|
19
|
+
this.attachEvents();
|
20
|
+
this.disableTextSelection();
|
21
|
+
|
22
|
+
if (this.resizeHandle) { this.optionallyResize('handle'); }
|
23
|
+
if (this.resizeContainer) { this.optionallyResize('container'); }
|
24
|
+
|
25
|
+
this.initialPosition();
|
26
|
+
};
|
27
|
+
|
28
|
+
$.extend($[iphoneStyle].prototype, {
|
29
|
+
// Wrap the existing input[type=checkbox] with divs for styling and grab DOM references to the created nodes
|
30
|
+
wrapCheckboxWithDivs: function() {
|
31
|
+
this.$elem.wrap('<div class="' + this.containerClass + '" />');
|
32
|
+
this.container = this.$elem.parent();
|
33
|
+
|
34
|
+
this.offLabel = $('<label class="'+ this.labelOffClass +'">' +
|
35
|
+
'<span>'+ this.uncheckedLabel +'</span>' +
|
36
|
+
'</label>').appendTo(this.container);
|
37
|
+
this.offSpan = this.offLabel.children('span');
|
38
|
+
|
39
|
+
this.onLabel = $('<label class="'+ this.labelOnClass +'">' +
|
40
|
+
'<span>'+ this.checkedLabel +'</span>' +
|
41
|
+
'</label>').appendTo(this.container);
|
42
|
+
this.onSpan = this.onLabel.children('span');
|
43
|
+
|
44
|
+
this.handle = $('<div class="' + this.handleClass + '">' +
|
45
|
+
'<div class="' + this.handleRightClass + '">' +
|
46
|
+
'<div class="' + this.handleCenterClass + '" />' +
|
47
|
+
'</div>' +
|
48
|
+
'</div>').appendTo(this.container);
|
49
|
+
},
|
50
|
+
|
51
|
+
// Disable IE text selection, other browsers are handled in CSS
|
52
|
+
disableTextSelection: function() {
|
53
|
+
if (!$.browser.msie) { return; }
|
54
|
+
|
55
|
+
// Elements containing text should be unselectable
|
56
|
+
$.each([this.handle, this.offLabel, this.onLabel, this.container], function(el) {
|
57
|
+
$(el).attr("unselectable", "on");
|
58
|
+
});
|
59
|
+
},
|
60
|
+
|
61
|
+
// Automatically resize the handle or container
|
62
|
+
optionallyResize: function(mode) {
|
63
|
+
var onLabelWidth = this.onLabel.width(),
|
64
|
+
offLabelWidth = this.offLabel.width(),
|
65
|
+
newWidth = (onLabelWidth < offLabelWidth) ? onLabelWidth : offLabelWidth;
|
66
|
+
|
67
|
+
if (mode == 'container') { newWidth += this.handle.width() + 15; }
|
68
|
+
this[mode].css({ width: newWidth });
|
69
|
+
},
|
70
|
+
|
71
|
+
attachEvents: function() {
|
72
|
+
var obj = this;
|
73
|
+
|
74
|
+
// A mousedown anywhere in the control will start tracking for dragging
|
75
|
+
this.container
|
76
|
+
.bind('mousedown touchstart', function(event) {
|
77
|
+
event.preventDefault();
|
78
|
+
|
79
|
+
if (obj.$elem.is(':disabled')) { return; }
|
80
|
+
|
81
|
+
var x = event.pageX || event.originalEvent.changedTouches[0].pageX;
|
82
|
+
$[iphoneStyle].currentlyClicking = obj.handle;
|
83
|
+
$[iphoneStyle].dragStartPosition = x;
|
84
|
+
$[iphoneStyle].handleLeftOffset = parseInt(obj.handle.css('left'), 10) || 0;
|
85
|
+
})
|
86
|
+
|
87
|
+
// Utilize event bubbling to handle drag on any element beneath the container
|
88
|
+
.bind('iPhoneDrag', function(event, x) {
|
89
|
+
event.preventDefault();
|
90
|
+
|
91
|
+
if (obj.$elem.is(':disabled')) { return; }
|
92
|
+
|
93
|
+
var p = (x + $[iphoneStyle].handleLeftOffset - $[iphoneStyle].dragStartPosition) / obj.rightSide;
|
94
|
+
if (p < 0) { p = 0; }
|
95
|
+
if (p > 1) { p = 1; }
|
96
|
+
obj.handle.css({ left: p * obj.rightSide });
|
97
|
+
obj.onLabel.css({ width: p * obj.rightSide + 4 });
|
98
|
+
obj.offSpan.css({ marginRight: -p * obj.rightSide });
|
99
|
+
obj.onSpan.css({ marginLeft: -(1 - p) * obj.rightSide });
|
100
|
+
})
|
101
|
+
|
102
|
+
// Utilize event bubbling to handle drag end on any element beneath the container
|
103
|
+
.bind('iPhoneDragEnd', function(event, x) {
|
104
|
+
if (obj.$elem.is(':disabled')) { return; }
|
105
|
+
|
106
|
+
if ($[iphoneStyle].dragging) {
|
107
|
+
var p = (x - $[iphoneStyle].dragStartPosition) / obj.rightSide;
|
108
|
+
obj.$elem.attr('checked', (p >= 0.5));
|
109
|
+
} else {
|
110
|
+
obj.$elem.attr('checked', !obj.$elem.attr('checked'));
|
111
|
+
}
|
112
|
+
|
113
|
+
$[iphoneStyle].currentlyClicking = null;
|
114
|
+
$[iphoneStyle].dragging = null;
|
115
|
+
obj.$elem.change();
|
116
|
+
});
|
117
|
+
|
118
|
+
// Animate when we get a change event
|
119
|
+
this.$elem.change(function() {
|
120
|
+
if (obj.$elem.is(':disabled')) {
|
121
|
+
obj.container.addClass(obj.disabledClass);
|
122
|
+
return false;
|
123
|
+
} else {
|
124
|
+
obj.container.removeClass(obj.disabledClass);
|
125
|
+
}
|
126
|
+
|
127
|
+
var new_left = obj.$elem.attr('checked') ? obj.rightSide : 0;
|
128
|
+
|
129
|
+
obj.handle.animate({ left: new_left }, obj.duration);
|
130
|
+
obj.onLabel.animate({ width: new_left + 4 }, obj.duration);
|
131
|
+
obj.offSpan.animate({ marginRight: -new_left }, obj.duration);
|
132
|
+
obj.onSpan.animate({ marginLeft: new_left - obj.rightSide }, obj.duration);
|
133
|
+
});
|
134
|
+
},
|
135
|
+
|
136
|
+
// Setup the control's inital position
|
137
|
+
initialPosition: function() {
|
138
|
+
this.offLabel.css({ width: this.container.width() - 5 });
|
139
|
+
|
140
|
+
var offset = ($.browser.msie && $.browser.version < 7) ? 3 : 6;
|
141
|
+
this.rightSide = this.container.width() - this.handle.width() - offset;
|
142
|
+
|
143
|
+
if (this.$elem.is(':checked')) {
|
144
|
+
this.handle.css({ left: this.rightSide });
|
145
|
+
this.onLabel.css({ width: this.rightSide + 4 });
|
146
|
+
this.offSpan.css({ marginRight: -this.rightSide });
|
147
|
+
} else {
|
148
|
+
this.onLabel.css({ width: 0 });
|
149
|
+
this.onSpan.css({ marginLeft: -this.rightSide });
|
150
|
+
}
|
151
|
+
|
152
|
+
if (this.$elem.is(':disabled')) {
|
153
|
+
this.container.addClass(this.disabledClass);
|
154
|
+
}
|
155
|
+
}
|
156
|
+
});
|
157
|
+
|
158
|
+
// jQuery-specific code
|
159
|
+
$.fn[iphoneStyle] = function(options) {
|
160
|
+
var checkboxes = this.filter(':checkbox');
|
161
|
+
|
162
|
+
// Fail early if we don't have any checkboxes passed in
|
163
|
+
if (!checkboxes.length) { return this; }
|
164
|
+
|
165
|
+
// Merge options passed in with global defaults
|
166
|
+
var opt = $.extend({}, $[iphoneStyle].defaults, options);
|
167
|
+
|
168
|
+
checkboxes.each(function() {
|
169
|
+
$(this).data(iphoneStyle, new $[iphoneStyle](this, opt));
|
170
|
+
});
|
171
|
+
|
172
|
+
if (!$[iphoneStyle].initComplete) {
|
173
|
+
// As the mouse moves on the page, animate if we are in a drag state
|
174
|
+
$(document)
|
175
|
+
.bind('mousemove touchmove', function(event) {
|
176
|
+
if (!$[iphoneStyle].currentlyClicking) { return; }
|
177
|
+
event.preventDefault();
|
178
|
+
|
179
|
+
var x = event.pageX || event.originalEvent.changedTouches[0].pageX;
|
180
|
+
if (!$[iphoneStyle].dragging &&
|
181
|
+
(Math.abs($[iphoneStyle].dragStartPosition - x) > opt.dragThreshold)) {
|
182
|
+
$[iphoneStyle].dragging = true;
|
183
|
+
}
|
184
|
+
|
185
|
+
$(event.target).trigger('iPhoneDrag', [x]);
|
186
|
+
})
|
187
|
+
|
188
|
+
// When the mouse comes up, leave drag state
|
189
|
+
.bind('mouseup touchend', function(event) {
|
190
|
+
if (!$[iphoneStyle].currentlyClicking) { return; }
|
191
|
+
event.preventDefault();
|
192
|
+
|
193
|
+
var x = event.pageX || event.originalEvent.changedTouches[0].pageX;
|
194
|
+
$($[iphoneStyle].currentlyClicking).trigger('iPhoneDragEnd', [x]);
|
195
|
+
});
|
196
|
+
|
197
|
+
$[iphoneStyle].initComplete = true;
|
198
|
+
}
|
199
|
+
|
200
|
+
return this;
|
201
|
+
}; // End of $.fn[iphoneStyle]
|
202
|
+
|
203
|
+
$[iphoneStyle].defaults = {
|
204
|
+
duration: 200, // Time spent during slide animation
|
205
|
+
checkedLabel: 'ON', // Text content of "on" state
|
206
|
+
uncheckedLabel: 'OFF', // Text content of "off" state
|
207
|
+
resizeHandle: true, // Automatically resize the handle to cover either label
|
208
|
+
resizeContainer: true, // Automatically resize the widget to contain the labels
|
209
|
+
disabledClass: 'iPhoneCheckDisabled',
|
210
|
+
containerClass: 'iPhoneCheckContainer',
|
211
|
+
labelOnClass: 'iPhoneCheckLabelOn',
|
212
|
+
labelOffClass: 'iPhoneCheckLabelOff',
|
213
|
+
handleClass: 'iPhoneCheckHandle',
|
214
|
+
handleCenterClass: 'iPhoneCheckHandleCenter',
|
215
|
+
handleRightClass: 'iPhoneCheckHandleRight',
|
216
|
+
dragThreshold: 5 // Pixels that must be dragged for a click to be ignored
|
217
|
+
};
|
218
|
+
|
219
|
+
})(jQuery, 'iphoneStyle');
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# Make sure you list all the project template files here in the manifest.
|
2
2
|
stylesheet 'iphone-style-example.sass', :media => 'screen, projection'
|
3
|
+
javascript 'iphone-style-checkboxes.js'
|
3
4
|
image 'iphone-style-checkboxes/off.png'
|
4
5
|
image 'iphone-style-checkboxes/on.png'
|
5
6
|
image 'iphone-style-checkboxes/slider.png'
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Thomas Reynolds
|
@@ -46,8 +46,10 @@ files:
|
|
46
46
|
- README.rdoc
|
47
47
|
- Rakefile
|
48
48
|
- VERSION
|
49
|
+
- iphone-style-checkboxes.gemspec
|
49
50
|
- lib/iphone-style-checkboxes.rb
|
50
51
|
- stylesheets/_iphone-style-checkboxes.sass
|
52
|
+
- templates/project/iphone-style-checkboxes.js
|
51
53
|
- templates/project/iphone-style-checkboxes/off.png
|
52
54
|
- templates/project/iphone-style-checkboxes/on.png
|
53
55
|
- templates/project/iphone-style-checkboxes/slider.png
|