ios-checkboxes 0.1.0 → 0.1.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.
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)