iphone-style-checkboxes 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|