ios-checkboxes 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/.gitignore +12 -6
  2. data/Gemfile +21 -0
  3. data/HISTORY.md +10 -0
  4. data/README.md +136 -0
  5. data/Rakefile +36 -21
  6. data/build/.gitignore +2 -0
  7. data/build/build.sh +7 -0
  8. data/build/output/assets/ios-checkboxes/ios-checkboxes-5d38e09413b47993266b4343b181d2f9.css +1 -0
  9. data/build/output/assets/ios-checkboxes/ios-checkboxes-767fc292f6a04316d3a54b18f4637b57.js +1 -0
  10. data/{vendor/assets/images/ios-style-checkboxes/off.png → build/output/assets/ios-checkboxes/off-32586c60c5c48b7002326fdff55cd42e.png} +0 -0
  11. data/{vendor/assets/images/ios-style-checkboxes/on.png → build/output/assets/ios-checkboxes/on-c1710e0553b5cb2ba6b41a59ace60662.png} +0 -0
  12. data/{vendor/assets/images/ios-style-checkboxes/slider.png → build/output/assets/ios-checkboxes/slider-a8cd833485793750ee72350ac5adb4d4.png} +0 -0
  13. data/{vendor/assets/images/ios-style-checkboxes/slider_center.png → build/output/assets/ios-checkboxes/slider_center-137b6fa2802dc0a9be192b66c5a76815.png} +0 -0
  14. data/{vendor/assets/images/ios-style-checkboxes/slider_left.png → build/output/assets/ios-checkboxes/slider_left-e6930b387dd9c0a424e7c1aedd0b0aea.png} +0 -0
  15. data/{vendor/assets/images/ios-style-checkboxes/slider_right.png → build/output/assets/ios-checkboxes/slider_right-e8654b2a69377361211e57422446c703.png} +0 -0
  16. data/ios-checkboxes.gemspec +18 -12
  17. data/{vendor/assets/images/iphone-style-checkboxes → lib/assets/images/ios-checkboxes}/off.png +0 -0
  18. data/{vendor/assets/images/iphone-style-checkboxes → lib/assets/images/ios-checkboxes}/on.png +0 -0
  19. data/{vendor/assets/images/iphone-style-checkboxes → lib/assets/images/ios-checkboxes}/slider.png +0 -0
  20. data/{vendor/assets/images/iphone-style-checkboxes → lib/assets/images/ios-checkboxes}/slider_center.png +0 -0
  21. data/{vendor/assets/images/iphone-style-checkboxes → lib/assets/images/ios-checkboxes}/slider_left.png +0 -0
  22. data/{vendor/assets/images/iphone-style-checkboxes → lib/assets/images/ios-checkboxes}/slider_right.png +0 -0
  23. data/lib/assets/javascripts/ios-checkboxes.js.coffee +2 -0
  24. data/lib/assets/javascripts/ios-checkboxes/ios-checkboxes.js.coffee +269 -0
  25. data/lib/assets/stylesheets/ios-checkboxes.css.sass +3 -0
  26. data/lib/assets/stylesheets/ios-checkboxes/_mixins.sass +104 -0
  27. data/lib/assets/stylesheets/ios-checkboxes/ios-checkboxes.css.sass +3 -0
  28. data/lib/ios-checkboxes.rb +5 -5
  29. data/lib/ios-checkboxes/engine.rb +4 -0
  30. data/lib/ios-checkboxes/railtie.rb +10 -0
  31. data/lib/ios-checkboxes/version.rb +2 -2
  32. data/lib/ios-style-checkboxes/off.png +0 -0
  33. data/lib/ios-style-checkboxes/on.png +0 -0
  34. data/lib/ios-style-checkboxes/slider.png +0 -0
  35. data/lib/ios-style-checkboxes/slider_center.png +0 -0
  36. data/lib/ios-style-checkboxes/slider_left.png +0 -0
  37. data/lib/ios-style-checkboxes/slider_right.png +0 -0
  38. data/lib/tasks/ios-checkboxes_tasks.rake +4 -0
  39. data/spec/dummy/Rakefile +7 -0
  40. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  41. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  42. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  43. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  44. data/spec/dummy/app/mailers/.gitkeep +0 -0
  45. data/spec/dummy/app/models/.gitkeep +0 -0
  46. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  47. data/spec/dummy/config.ru +4 -0
  48. data/spec/dummy/config/application.rb +57 -0
  49. data/spec/dummy/config/boot.rb +10 -0
  50. data/spec/dummy/config/database.yml +25 -0
  51. data/spec/dummy/config/environment.rb +5 -0
  52. data/spec/dummy/config/environments/development.rb +30 -0
  53. data/spec/dummy/config/environments/production.rb +60 -0
  54. data/spec/dummy/config/environments/test.rb +39 -0
  55. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  56. data/spec/dummy/config/initializers/inflections.rb +10 -0
  57. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  58. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  59. data/spec/dummy/config/initializers/session_store.rb +8 -0
  60. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  61. data/spec/dummy/config/locales/en.yml +5 -0
  62. data/spec/dummy/config/routes.rb +58 -0
  63. data/spec/dummy/lib/assets/.gitkeep +0 -0
  64. data/spec/dummy/log/.gitkeep +0 -0
  65. data/spec/dummy/public/404.html +26 -0
  66. data/spec/dummy/public/422.html +26 -0
  67. data/spec/dummy/public/500.html +26 -0
  68. data/spec/dummy/public/favicon.ico +0 -0
  69. data/spec/dummy/script/rails +6 -0
  70. data/spec/ios-checkboxes_spec.rb +13 -0
  71. data/spec/javascripts/ios-checkboxes_spec.js.coffee +36 -0
  72. data/spec/javascripts/spec.css +4 -0
  73. data/spec/javascripts/spec.js.coffee +2 -0
  74. data/spec/javascripts/support/custom-theme.css.sass +7 -0
  75. data/spec/spec_helper.rb +10 -0
  76. data/spec/support/asset_matchers.rb +37 -0
  77. metadata +171 -28
  78. data/vendor/assets/javascripts/ios-checkboxes.js +0 -283
  79. data/vendor/assets/stylesheets/ios-checkboxes.css.erb +0 -147
data/.gitignore CHANGED
@@ -1,7 +1,13 @@
1
- .DS_Store
2
- pkg/*
3
- *.gem
4
- *.rbc
5
- *.swp
6
- .bundle
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
7
4
  Gemfile.lock
5
+ spec/dummy/db/*.sqlite3
6
+ spec/dummy/log/*.log
7
+ spec/dummy/tmp/
8
+ spec/dummy/public/assets
9
+ db/*.sqlite3
10
+ log/*.log
11
+ tmp/
12
+ .sass-cache/
13
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Declare your gem's dependencies in ios-checkboxes.gemspec.
4
+ # Bundler will treat runtime dependencies like base dependencies, and
5
+ # development dependencies will be added by default to the :development group.
6
+ gemspec
7
+
8
+ # jquery-rails is used by the dummy application
9
+ gem "jquery-rails"
10
+ gem 'jasminerice'
11
+ gem 'coffee-script'
12
+ gem 'pry'
13
+ gem 'uglifier'
14
+
15
+ # Declare any dependencies that are still in development here instead of in
16
+ # your gemspec. These might include edge Rails or gems from your path or
17
+ # Git. Remember to move these dependencies to your gemspec before releasing
18
+ # your gem to rubygems.org.
19
+
20
+ # To use debugger
21
+ # gem 'ruby-debug19', :require => 'ruby-debug'
@@ -0,0 +1,10 @@
1
+ 0.1.2 - Mon 21 Nov 2011
2
+ ========================================
3
+ - Customise the images, sizes etc via SASS
4
+ - Provide precompiled assets for standalone use
5
+
6
+ 0.1.1 - Fri 18 Nov 2011
7
+ ========================================
8
+ - Provides jQuery iphoneStyle function in JavaScript and the JavaScript file itself.
9
+ - Provides default styling.
10
+ - Compatible with Rails Assets Pipeline (include images referenced from the CSS).
@@ -0,0 +1,136 @@
1
+ ios-checkboxes
2
+ ========================================
3
+
4
+ This project allows you to easily use iPhone style checkboxes in a Rails 3.1 application.
5
+
6
+ Install
7
+ ========================================
8
+
9
+ Add `gem 'ios-checkboxes'` to your Gemfile and run `bundle install`
10
+
11
+
12
+ Usage
13
+ ========================================
14
+
15
+ Add `//=require ios-checkboxes` to your `app/assets/javascripts/application.js`.
16
+ This will require `jquery` automaticaly.
17
+
18
+ Also make sure you add the stylesheets to your `application.css`.
19
+ Just `require ios-checkboxes` to get the default styling.
20
+
21
+ You may choose not to use it and write the styling from scratch. In that case just don't add the iox-checkboxes to the stylesheet manifest.
22
+
23
+
24
+ After you have all the ingridients in place you can convert your checkboxes into "On/Off" buttons
25
+ with this JavaScript snippet:
26
+
27
+ ```javascript
28
+ $(function(){
29
+ $("input:checkbox").iphoneStyle();
30
+ });
31
+ ```
32
+
33
+ Using as a standalone
34
+ ========================================
35
+
36
+ Go to the `build/output` directory and download its content.
37
+ Put it content under your server root.
38
+ Make sure you reference the JavaScript and CSS files properly.
39
+
40
+ Don't reference it as 'assets/ios-checkboxes.js', instead use the full file name from the download
41
+ (it will change with time): `assets/ios-checkboxes-d0bbaf0b834d61ddccf7510739596dd2.js`
42
+
43
+ The same applies to CSS, but you don't need to do anything for images.
44
+
45
+ The use of the "digest" appended to the end of file ensures that your users will have the most recent version of the files (cashe buster).
46
+
47
+
48
+ Customisation
49
+ ========================================
50
+
51
+ If the defaut stylesheet doesn't fit your design, you can customize it.
52
+
53
+ First, add a `.css.sass` file to your application:
54
+
55
+ ```sass
56
+ // app/assets/stylesheets/iphone.css.sass
57
+ @import "./ios-checkboxes/mixins"
58
+
59
+ // This will change the default for everything
60
+ $iphone-style-height: 33px // Default = 27px
61
+ $iphone-style-font-size: 30px // Default = 17px
62
+ $iphone-style-images-path: 'custom-path-to-images' // Default = ios-checkboxes
63
+
64
+ +iphone-style // This includes the actual styles with customised values
65
+
66
+ // You can also override the styles for sub-selectors
67
+ .huge
68
+ $iphone-style-height: 60px
69
+ $iphone-style-font-size: 40px
70
+ $iphone-style-images-path: 'hude-images'
71
+ +iphone-style
72
+ ```
73
+
74
+ If you modify the `$iphone-style-images-path` then you have to provide a (Sprockets) directory with the following files:
75
+
76
+ ```
77
+ off.png
78
+ on.png
79
+ slider.png
80
+ slider_center.png
81
+ slider_left.png
82
+ slider_right.png
83
+ ```
84
+
85
+
86
+
87
+ Development
88
+ ========================================
89
+
90
+ ```bash
91
+ git clone git@github.com:dnagir/ios-checkboxes.git
92
+ cd ios-checkboxes
93
+ bundle install
94
+ bundle rspec spec
95
+ (cd spec/dummy/ && bundle exec rails s)
96
+ # Now go to http://localhost:3000/jasmine to run the specs
97
+ ```
98
+
99
+ To build the standalone assets: `sh build/build.sh`.
100
+
101
+ Help
102
+ ========================================
103
+
104
+ - Report issues on [Github](https://github.com/dnagir/ios-checkboxes/issues).
105
+ - Shout at me in Twitter - [@dnagir](http://twitter.com/dnagir)
106
+
107
+
108
+ Credits
109
+ ========================================
110
+
111
+ [Thomas Reynolds](https://github.com/tdreyno) for the original [implementation](https://github.com/tdreyno/iphone-style-checkboxes).
112
+
113
+
114
+ License (MIT)
115
+ ========================================
116
+
117
+ Copyright 2011 Thomas Reynolds, Dmytrii Nagirniak
118
+
119
+ Permission is hereby granted, free of charge, to any person obtaining
120
+ a copy of this software and associated documentation files (the
121
+ "Software"), to deal in the Software without restriction, including
122
+ without limitation the rights to use, copy, modify, merge, publish,
123
+ distribute, sublicense, and/or sell copies of the Software, and to
124
+ permit persons to whom the Software is furnished to do so, subject to
125
+ the following conditions:
126
+
127
+ The above copyright notice and this permission notice shall be
128
+ included in all copies or substantial portions of the Software.
129
+
130
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
131
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
132
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
133
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
134
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
135
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
136
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,22 +1,37 @@
1
- require 'rake'
2
- require 'bundler/gem_tasks'
3
-
4
- desc "Update the gem with the latest files"
5
- task :update do
6
- # Copy the js file and require jQuery
7
- js_content = File.read "../jquery/iphone-style-checkboxes.js"
8
- f = File.new("vendor/assets/javascripts/ios-checkboxes.js", "w")
9
- f.write("//= require jquery\n\n#{js_content}")
10
- f.close
11
-
12
- # Copy the images
13
- cp_r "../images/", "vendor/assets/"
14
-
15
- # Copy CSS and make sure it references the images via assets pipeline
16
- css_content = File.read "../style.css"
17
- pattern = /url\('images\/([^']+)'\)/
18
- css_processed = css_content.gsub(pattern) {|m| "url('<%= image_path \"#{$1.sub(/\?.*/, '')}\" %>')" }
19
- f2 = File.new("vendor/assets/stylesheets/ios-checkboxes.css.erb", "w")
20
- f2.write(css_processed)
21
- f2.close
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
22
6
  end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'IosCheckboxes'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+
25
+ Bundler::GemHelper.install_tasks
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
35
+
36
+
37
+ task :default => :test
@@ -0,0 +1,2 @@
1
+ *.yml
2
+ *.gz
@@ -0,0 +1,7 @@
1
+
2
+ pushd spec/dummy &&
3
+ bundle exec rake assets:clean RAILS_ENV=production &&
4
+ bundle exec rake assets:precompile:primary RAILS_ENV=production &&
5
+ popd &&
6
+ rm -rf build/output/* &&
7
+ cp -rf spec/dummy/public/assets build/output
@@ -0,0 +1 @@
1
+ .iPhoneCheckContainer{position:relative;height:27px;cursor:pointer;overflow:hidden}.iPhoneCheckContainer input{position:absolute;top:5px;left:30px;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);opacity:0}.iPhoneCheckContainer label{white-space:nowrap;font-size:17x;line-height:17x;font-weight:bold;font-family:"Helvetica Neue",Arial,Helvetica,sans-serif;cursor:pointer;display:block;height:27px;position:absolute;width:auto;top:0;padding-top:5px;overflow:hidden}.iPhoneCheckContainer,.iPhoneCheckContainer label{user-select:none;-moz-user-select:none;-khtml-user-select:none}.iPhoneCheckDisabled{filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=50);opacity:0.5}label.iPhoneCheckLabelOn{color:#fff;background:url(/assets/ios-checkboxes/on-c1710e0553b5cb2ba6b41a59ace60662.png) no-repeat;text-shadow:0px 0px 2px rgba(0,0,0,0.6);left:0;padding-top:5px}label.iPhoneCheckLabelOn span{padding-left:8px}label.iPhoneCheckLabelOff{color:#8b8b8b;background:url(/assets/ios-checkboxes/off-32586c60c5c48b7002326fdff55cd42e.png) no-repeat right 0;text-shadow:0px 0px 2px rgba(255,255,255,0.6);text-align:right;right:0}label.iPhoneCheckLabelOff span{padding-right:8px}.iPhoneCheckHandle{display:block;height:27px;cursor:pointer;position:absolute;top:0;left:0;width:0;background:url(/assets/ios-checkboxes/slider_left-e6930b387dd9c0a424e7c1aedd0b0aea.png) no-repeat;padding-left:3px}.iPhoneCheckHandleRight{height:100%;width:100%;padding-right:3px;background:url(/assets/ios-checkboxes/slider_right-e8654b2a69377361211e57422446c703.png) no-repeat right 0}.iPhoneCheckHandleCenter{height:100%;width:100%;background:url(/assets/ios-checkboxes/slider_center-137b6fa2802dc0a9be192b66c5a76815.png)}
@@ -0,0 +1 @@
1
+ ((function(){var a,b=Array.prototype.slice;a=function(){function a(b,c){var d,e,f;this.elem=$(b),e=$.extend({},a.defaults,c);for(d in e)f=e[d],this[d]=f;this.elem.data(this.dataName,this),this.wrapCheckboxWithDivs(),this.attachEvents(),this.disableTextSelection(),this.resizeHandle&&this.optionallyResize("handle"),this.resizeContainer&&this.optionallyResize("container"),this.initialPosition()}return a.prototype.isDisabled=function(){return this.elem.is(":disabled")},a.prototype.wrapCheckboxWithDivs=function(){return this.elem.wrap("<div class='"+this.containerClass+"' />"),this.container=this.elem.parent(),this.offLabel=$("<label class='"+this.labelOffClass+"'>\n <span>"+this.uncheckedLabel+"</span>\n</label>").appendTo(this.container),this.offSpan=this.offLabel.children("span"),this.onLabel=$("<label class='"+this.labelOnClass+"'>\n <span>"+this.checkedLabel+"</span>\n</label>").appendTo(this.container),this.onSpan=this.onLabel.children("span"),this.handle=$("<div class='"+this.handleClass+"'>\n <div class='"+this.handleRightClass+"'>\n <div class='"+this.handleCenterClass+"' />\n </div>\n</div>").appendTo(this.container)},a.prototype.disableTextSelection=function(){if($.browser.msie)return $([this.handle,this.offLabel,this.onLabel,this.container]).attr("unselectable","on")},a.prototype._getDimension=function(a,b){return $.fn.actual!=null?a.actual(b):a[b]()},a.prototype.optionallyResize=function(a){var b,c,d;return d=this._getDimension(this.onLabel,"width"),c=this._getDimension(this.offLabel,"width"),a==="container"?(b=d>c?d:c,b+=this._getDimension(this.handle,"width")+this.handleMargin,this.container.css({width:b})):(b=d>c?d:c,this.handle.css({width:b}))},a.prototype.onMouseDown=function(b){var c;b.preventDefault();if(this.isDisabled())return;return c=b.pageX||b.originalEvent.changedTouches[0].pageX,a.currentlyClicking=this.handle,a.dragStartPosition=c,a.handleLeftOffset=parseInt(this.handle.css("left"),10)||0},a.prototype.onDragMove=function(b,c){var d,e;if(a.currentlyClicking!==this.handle)return;return e=(c+a.handleLeftOffset-a.dragStartPosition)/this.rightSide,e<0&&(e=0),e>1&&(e=1),d=e*this.rightSide,this.handle.css({left:d}),this.onLabel.css({width:d+this.handleRadius}),this.offSpan.css({marginRight:-d}),this.onSpan.css({marginLeft:-(1-e)*this.rightSide})},a.prototype.onDragEnd=function(b,c){var d;if(a.currentlyClicking!==this.handle)return;if(this.isDisabled())return;return a.dragging?(d=(c-a.dragStartPosition)/this.rightSide,this.elem.prop("checked",d>=.5)):this.elem.prop("checked",!this.elem.prop("checked")),a.currentlyClicking=null,a.dragging=null,this.didChange()},a.prototype.refresh=function(){return this.didChange()},a.prototype.didChange=function(){var a;return typeof this.onChange=="function"&&this.onChange(this.elem,this.elem.prop("checked")),this.isDisabled()?(this.container.addClass(this.disabledClass),!1):(this.container.removeClass(this.disabledClass),a=this.elem.prop("checked")?this.rightSide:0,this.handle.animate({left:a},this.duration),this.onLabel.animate({width:a+this.handleRadius},this.duration),this.offSpan.animate({marginRight:-a},this.duration),this.onSpan.animate({marginLeft:a-this.rightSide},this.duration))},a.prototype.attachEvents=function(){var a,b,c;return c=this,a=function(a){return c.onGlobalMove.apply(c,arguments)},b=function(d){return c.onGlobalUp.apply(c,arguments),$(document).unbind("mousemove touchmove",a),$(document).unbind("mouseup touchend",b)},this.elem.change(function(){return c.refresh()}),this.container.bind("mousedown touchstart",function(d){return c.onMouseDown.apply(c,arguments),$(document).bind("mousemove touchmove",a),$(document).bind("mouseup touchend",b)})},a.prototype.initialPosition=function(){var a,b;a=this._getDimension(this.container,"width"),this.offLabel.css({width:a-this.containerRadius}),b=this.containerRadius+1,$.browser.msie&&$.browser.version<7&&(b-=3),this.rightSide=a-this._getDimension(this.handle,"width")-b,this.elem.is(":checked")?(this.handle.css({left:this.rightSide}),this.onLabel.css({width:this.rightSide+this.handleRadius}),this.offSpan.css({marginRight:-this.rightSide})):(this.onLabel.css({width:0}),this.onSpan.css({marginLeft:-this.rightSide}));if(this.isDisabled())return this.container.addClass(this.disabledClass)},a.prototype.onGlobalMove=function(b){var c;if(!!this.isDisabled()||!a.currentlyClicking)return;return b.preventDefault(),c=b.pageX||b.originalEvent.changedTouches[0].pageX,!a.dragging&&Math.abs(a.dragStartPosition-c)>this.dragThreshold&&(a.dragging=!0),this.onDragMove(b,c)},a.prototype.onGlobalUp=function(b){var c;if(!a.currentlyClicking)return;return b.preventDefault(),c=b.pageX||b.originalEvent.changedTouches[0].pageX,this.onDragEnd(b,c),!1},a.defaults={duration:200,checkedLabel:"ON",uncheckedLabel:"OFF",resizeHandle:!0,resizeContainer:!0,disabledClass:"iPhoneCheckDisabled",containerClass:"iPhoneCheckContainer",labelOnClass:"iPhoneCheckLabelOn",labelOffClass:"iPhoneCheckLabelOff",handleClass:"iPhoneCheckHandle",handleCenterClass:"iPhoneCheckHandleCenter",handleRightClass:"iPhoneCheckHandleRight",dragThreshold:5,handleMargin:15,handleRadius:4,containerRadius:5,dataName:"iphoneStyle",onChange:function(){}},a}(),$.iphoneStyle=this.iOSCheckbox=a,$.fn.iphoneStyle=function(){var c,d,e,f,g,h,i,j,k,l,m,n;c=1<=arguments.length?b.call(arguments,0):[],e=(k=(l=c[0])!=null?l.dataName:void 0)!=null?k:a.defaults.dataName,m=this.filter(":checkbox");for(i=0,j=m.length;i<j;i++)d=m[i],f=$(d).data(e),f!=null?(g=c[0],h=2<=c.length?b.call(c,1):[],(n=f[g])!=null&&n.apply(f,h)):new a(d,c[0]);return this},$.fn.iOSCheckbox=function(a){var b;return a==null&&(a={}),b=$.extend({},a,{resizeHandle:!1,disabledClass:"iOSCheckDisabled",containerClass:"iOSCheckContainer",labelOnClass:"iOSCheckLabelOn",labelOffClass:"iOSCheckLabelOff",handleClass:"iOSCheckHandle",handleCenterClass:"iOSCheckHandleCenter",handleRightClass:"iOSCheckHandleRight",dataName:"iOSCheckbox"}),this.iphoneStyle(b)}})).call(this)
@@ -1,19 +1,25 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/ios-checkboxes/version', __FILE__)
1
+ $:.push File.expand_path("../lib", __FILE__)
3
2
 
3
+ # Maintain your gem's version:
4
+ require "ios-checkboxes/version"
5
+
6
+ # Describe your gem and declare its dependencies:
4
7
  Gem::Specification.new do |s|
5
8
  s.name = "ios-checkboxes"
6
- s.version = IOSCheckboxes::VERSION
7
- s.authors = ["Thomas Reynolds"]
8
- s.email = ["me@tdreyno.com"]
9
- s.homepage = "https://github.com/tdreyno/iphone-style-checkboxes"
10
- s.summary = %q{iOS-style Checkboxes}
11
- s.description = %q{iOS-style Checkboxes for Rails asset pipeline.}
9
+ s.version = IosCheckboxes::VERSION
10
+ s.authors = ["Dmytrii Nagirniak, Thomas Reynolds"]
11
+ s.email = ["dnagir@gmail.com"]
12
+ s.homepage = "https://github.com/dnagir/ios-checkboxes"
13
+ s.summary = "iOS checkboxes for Rails"
14
+ s.description = "Easily convert your checkboxes into iPhone style On/Off buttons. Use with Rails 3.1 Assets Pipeline."
12
15
 
13
- s.rubyforge_project = "ios-checkboxes"
14
- s.add_dependency "railties", "~> 3.1"
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features,build}/*`.split("\n")
18
+ s.require_paths = ["lib"]
15
19
 
16
- s.files = `git ls-files`.split("\n")
20
+ s.add_dependency "rails", "~> 3.1.2"
21
+ s.add_dependency "sass-rails"
22
+ s.add_dependency "compass", ">= 0.12.alpha.1"
17
23
 
18
- s.require_paths = ["lib"]
24
+ s.add_development_dependency "rspec-rails"
19
25
  end
@@ -0,0 +1,2 @@
1
+ #= require jquery
2
+ #= require ios-checkboxes/ios-checkboxes
@@ -0,0 +1,269 @@
1
+ # iPhone-style Checkboxes Coffee plugin
2
+ # Copyright Thomas Reynolds, licensed GPL & MIT
3
+
4
+ class iOSCheckbox
5
+ constructor: (elem, options) ->
6
+ @elem = $(elem)
7
+
8
+ opts = $.extend({}, iOSCheckbox.defaults, options)
9
+
10
+ # Import options into instance variables
11
+ for key, value of opts
12
+ @[key] = value
13
+
14
+ @elem.data(@dataName, this)
15
+
16
+ # Initialize the control
17
+ @wrapCheckboxWithDivs()
18
+ @attachEvents()
19
+ @disableTextSelection()
20
+
21
+ @optionallyResize('handle') if @resizeHandle
22
+ @optionallyResize('container') if @resizeContainer
23
+
24
+ @initialPosition()
25
+
26
+ isDisabled: -> @elem.is(':disabled')
27
+
28
+ # Wrap the existing input[type=checkbox] with divs for styling and grab
29
+ # DOM references to the created nodes
30
+ wrapCheckboxWithDivs: ->
31
+ @elem.wrap("<div class='#{@containerClass}' />")
32
+
33
+ @container = @elem.parent()
34
+
35
+ @offLabel = $("""<label class='#{@labelOffClass}'>
36
+ <span>#{@uncheckedLabel}</span>
37
+ </label>""").appendTo(@container)
38
+
39
+ @offSpan = @offLabel.children('span')
40
+
41
+ @onLabel = $("""<label class='#{@labelOnClass}'>
42
+ <span>#{@checkedLabel}</span>
43
+ </label>""").appendTo(@container)
44
+
45
+ @onSpan = @onLabel.children('span')
46
+
47
+ @handle = $("""<div class='#{@handleClass}'>
48
+ <div class='#{@handleRightClass}'>
49
+ <div class='#{@handleCenterClass}' />
50
+ </div>
51
+ </div>""").appendTo(this.container)
52
+
53
+ # Disable IE text selection, other browsers are handled in CSS
54
+ disableTextSelection: ->
55
+ # Elements containing text should be unselectable
56
+ if $.browser.msie
57
+ $([@handle, @offLabel, @onLabel, @container]).attr("unselectable", "on")
58
+
59
+ _getDimension: (elem, dimension) ->
60
+ if $.fn.actual?
61
+ elem.actual(dimension)
62
+ else
63
+ elem[dimension]()
64
+
65
+ # Automatically resize the handle or container
66
+ optionallyResize: (mode) ->
67
+ onLabelWidth = @_getDimension(@onLabel, "width")
68
+ offLabelWidth = @_getDimension(@offLabel, "width")
69
+
70
+ if mode == "container"
71
+ newWidth = if (onLabelWidth > offLabelWidth)
72
+ onLabelWidth
73
+ else
74
+ offLabelWidth
75
+
76
+ newWidth += @_getDimension(@handle, "width") + @handleMargin
77
+ @container.css(width: newWidth)
78
+ else
79
+ newWidth = if (onLabelWidth > offLabelWidth)
80
+ onLabelWidth
81
+ else
82
+ offLabelWidth
83
+ @handle.css(width: newWidth)
84
+
85
+ onMouseDown: (event) ->
86
+ event.preventDefault()
87
+
88
+ return if @isDisabled()
89
+
90
+ x = event.pageX || event.originalEvent.changedTouches[0].pageX
91
+ iOSCheckbox.currentlyClicking = @handle
92
+ iOSCheckbox.dragStartPosition = x
93
+ iOSCheckbox.handleLeftOffset = parseInt(@handle.css('left'), 10) || 0
94
+
95
+ onDragMove: (event, x) ->
96
+ return unless iOSCheckbox.currentlyClicking == @handle
97
+
98
+ p = (x + iOSCheckbox.handleLeftOffset - iOSCheckbox.dragStartPosition) / @rightSide
99
+ p = 0 if p < 0
100
+ p = 1 if p > 1
101
+
102
+ newWidth = p * @rightSide
103
+ @handle.css(left: newWidth)
104
+ @onLabel.css(width: newWidth + @handleRadius)
105
+ @offSpan.css(marginRight: -newWidth)
106
+ @onSpan.css(marginLeft: -(1 - p) * @rightSide)
107
+
108
+ onDragEnd: (event, x) ->
109
+ return unless iOSCheckbox.currentlyClicking == @handle
110
+ return if @isDisabled()
111
+
112
+ if iOSCheckbox.dragging
113
+ p = (x - iOSCheckbox.dragStartPosition) / @rightSide
114
+ @elem.prop('checked', (p >= 0.5))
115
+ else
116
+ @elem.prop('checked', !@elem.prop('checked'))
117
+
118
+ iOSCheckbox.currentlyClicking = null
119
+ iOSCheckbox.dragging = null
120
+ @didChange()
121
+
122
+ refresh: -> @didChange() #TODO: Verify - this might fire event unnecessarily
123
+
124
+ didChange: ->
125
+ @onChange?(@elem, @elem.prop('checked'))
126
+
127
+ if @isDisabled()
128
+ @container.addClass(@disabledClass)
129
+ return false
130
+ else
131
+ @container.removeClass(@disabledClass)
132
+
133
+ new_left = if @elem.prop('checked') then @rightSide else 0
134
+
135
+ @handle.animate(left: new_left, @duration)
136
+ @onLabel.animate(width: new_left + @handleRadius, @duration)
137
+ @offSpan.animate(marginRight: -new_left, @duration)
138
+ @onSpan.animate(marginLeft: new_left - @rightSide, @duration)
139
+
140
+ attachEvents: ->
141
+ self = this
142
+
143
+ localMouseMove = (event) ->
144
+ self.onGlobalMove.apply(self, arguments)
145
+
146
+ localMouseUp = (event) ->
147
+ self.onGlobalUp.apply(self, arguments)
148
+ $(document).unbind 'mousemove touchmove', localMouseMove
149
+ $(document).unbind 'mouseup touchend', localMouseUp
150
+
151
+ # The original checkbox value might be changed by clickig on the associated label or other means
152
+ # To make sure we are in sync:
153
+ @elem.change -> self.refresh()
154
+
155
+ # A mousedown anywhere in the control will start tracking for dragging
156
+ @container.bind 'mousedown touchstart', (event) ->
157
+ self.onMouseDown.apply(self, arguments)
158
+
159
+ # As the mouse moves on the page, animate if we are in a drag state
160
+ $(document).bind 'mousemove touchmove', localMouseMove
161
+
162
+ # When the mouse comes up, leave drag state
163
+ $(document).bind 'mouseup touchend', localMouseUp
164
+
165
+ # Setup the control's inital position
166
+ initialPosition: ->
167
+ containerWidth = @_getDimension(@container, "width")
168
+ @offLabel.css(width: containerWidth - @containerRadius)
169
+
170
+ offset = @containerRadius + 1
171
+ offset -= 3 if $.browser.msie and $.browser.version < 7
172
+ @rightSide = containerWidth - @_getDimension(@handle, "width") - offset
173
+
174
+ if @elem.is(':checked')
175
+ @handle.css(left: @rightSide)
176
+ @onLabel.css(width: @rightSide + @handleRadius)
177
+ @offSpan.css(marginRight: -@rightSide)
178
+ else
179
+ @onLabel.css(width: 0)
180
+ @onSpan.css(marginLeft: -@rightSide)
181
+
182
+ @container.addClass(@disabledClass) if @isDisabled()
183
+
184
+ onGlobalMove: (event) ->
185
+ return unless !@isDisabled() && iOSCheckbox.currentlyClicking
186
+ event.preventDefault()
187
+
188
+ x = event.pageX || event.originalEvent.changedTouches[0].pageX
189
+
190
+ if (!iOSCheckbox.dragging &&
191
+ (Math.abs(iOSCheckbox.dragStartPosition - x) > @dragThreshold))
192
+ iOSCheckbox.dragging = true
193
+
194
+ @onDragMove(event, x)
195
+
196
+ onGlobalUp: (event) ->
197
+ return unless iOSCheckbox.currentlyClicking
198
+ event.preventDefault()
199
+
200
+ x = event.pageX || event.originalEvent.changedTouches[0].pageX
201
+
202
+ @onDragEnd(event, x)
203
+ false
204
+
205
+ @defaults:
206
+ # Time spent during slide animation
207
+ duration: 200
208
+
209
+ # Text content of "on" state
210
+ checkedLabel: 'ON'
211
+
212
+ # Text content of "off" state
213
+ uncheckedLabel: 'OFF'
214
+
215
+ # Automatically resize the handle to cover either label
216
+ resizeHandle: true
217
+
218
+ # Automatically resize the widget to contain the labels
219
+ resizeContainer: true
220
+
221
+ disabledClass: 'iPhoneCheckDisabled'
222
+ containerClass: 'iPhoneCheckContainer'
223
+ labelOnClass: 'iPhoneCheckLabelOn'
224
+ labelOffClass: 'iPhoneCheckLabelOff'
225
+ handleClass: 'iPhoneCheckHandle'
226
+ handleCenterClass: 'iPhoneCheckHandleCenter'
227
+ handleRightClass: 'iPhoneCheckHandleRight'
228
+
229
+ # Pixels that must be dragged for a click to be ignored
230
+ dragThreshold: 5
231
+
232
+ handleMargin: 15
233
+ handleRadius: 4
234
+ containerRadius: 5
235
+
236
+ dataName: "iphoneStyle"
237
+
238
+ onChange: ->
239
+
240
+ $.iphoneStyle = @iOSCheckbox = iOSCheckbox
241
+
242
+ $.fn.iphoneStyle = (args...) ->
243
+ dataName = args[0]?.dataName ? iOSCheckbox.defaults.dataName
244
+
245
+ for checkbox in @filter(':checkbox')
246
+ existingControl = $(checkbox).data(dataName)
247
+ if existingControl?
248
+ [method, params...] = args
249
+ existingControl[method]?.apply(existingControl, params)
250
+ else
251
+ new iOSCheckbox(checkbox, args[0])
252
+
253
+ this
254
+
255
+ $.fn.iOSCheckbox = (options={}) ->
256
+ # iOS5 style only supports circular handle
257
+ opts = $.extend({}, options, {
258
+ resizeHandle: false
259
+ disabledClass: 'iOSCheckDisabled'
260
+ containerClass: 'iOSCheckContainer'
261
+ labelOnClass: 'iOSCheckLabelOn'
262
+ labelOffClass: 'iOSCheckLabelOff'
263
+ handleClass: 'iOSCheckHandle'
264
+ handleCenterClass: 'iOSCheckHandleCenter'
265
+ handleRightClass: 'iOSCheckHandleRight'
266
+ dataName: 'iOSCheckbox'
267
+ })
268
+
269
+ this.iphoneStyle(opts)