├── .gitignore ├── Gruntfile.coffee ├── README.md ├── bower.json ├── dist ├── starrr.css └── starrr.js ├── index.html ├── package.json └── src ├── starrr.coffee └── starrr.scss /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .sass-cache -------------------------------------------------------------------------------- /Gruntfile.coffee: -------------------------------------------------------------------------------- 1 | module.exports = (grunt) -> 2 | 3 | grunt.loadNpmTasks('grunt-contrib-coffee') 4 | grunt.loadNpmTasks('grunt-contrib-sass') 5 | grunt.loadNpmTasks('grunt-contrib-watch') 6 | grunt.loadNpmTasks('grunt-release') 7 | 8 | grunt.initConfig 9 | pkg: '' 10 | 11 | coffee: 12 | all: 13 | src: 'src/starrr.coffee' 14 | dest: 'dist/starrr.js' 15 | options: 16 | bare: true 17 | 18 | sass: 19 | all: 20 | files: 21 | 'dist/starrr.css': 'src/starrr.scss' 22 | options: 23 | sourcemap: 'none' 24 | 25 | watch: 26 | all: 27 | files: ['src/starrr.coffee', 'src/starrr.scss'] 28 | tasks: 'default' 29 | 30 | grunt.registerTask 'default', ['coffee:all', 'sass:all'] 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | starrr 2 | ====== 3 | 4 | 1-5 (or 1-`n`) star rating in < 75 lines of code. 5 | 6 | ## Requirements 7 | 8 | - jQuery 9 | 10 | ## Usage 11 | 12 | ### Create the stars 13 | 14 | ```html 15 |
16 | ``` 17 | 18 | ```js 19 | $('.starrr').starrr() 20 | ``` 21 | 22 | ### With an existing rating 23 | 24 | ```js 25 | $('.starrr').starrr({ 26 | rating: 4 27 | }) 28 | ``` 29 | 30 | ### With more than 5 stars 31 | 32 | ```js 33 | $('.starrr').starrr({ 34 | max: 10 35 | }) 36 | ``` 37 | 38 | ### Read-only 39 | 40 | ```js 41 | $('.starrr').starrr({ 42 | readOnly: true 43 | }) 44 | ``` 45 | 46 | ### Do something with the rating... 47 | 48 | ```js 49 | $('.starrr').starrr({ 50 | change: function(e, value){ 51 | alert('new rating is ' + value) 52 | } 53 | }) 54 | ``` 55 | 56 | Or if you prefer events: 57 | 58 | ```js 59 | $('.starrr').on('starrr:change', function(e, value){ 60 | alert('new rating is ' + value) 61 | }) 62 | ``` 63 | 64 | ## Developing 65 | 66 | - `npm install` 67 | - `npm install -g grunt-cli` 68 | - Make changes in `src/` 69 | - Run `grunt` to compile them 70 | 71 | ## License 72 | 73 | MIT 74 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "starrr", 3 | "authors": [ 4 | "ajb " 5 | ], 6 | "description": "1-5 star rating with jQuery.", 7 | "license": "MIT", 8 | "ignore": [ 9 | "**/.*", 10 | "node_modules", 11 | "bower_components" 12 | ], 13 | "main": [ 14 | "dist/starrr.js", 15 | "dist/starrr.css" 16 | ], 17 | "dependencies": {} 18 | } 19 | -------------------------------------------------------------------------------- /dist/starrr.css: -------------------------------------------------------------------------------- 1 | .starrr { 2 | display: inline-block; } 3 | .starrr a { 4 | font-size: 16px; 5 | padding: 0 1px; 6 | cursor: pointer; 7 | color: #FFD119; 8 | text-decoration: none; } 9 | -------------------------------------------------------------------------------- /dist/starrr.js: -------------------------------------------------------------------------------- 1 | var slice = [].slice; 2 | 3 | (function($, window) { 4 | var Starrr; 5 | window.Starrr = Starrr = (function() { 6 | Starrr.prototype.defaults = { 7 | rating: void 0, 8 | max: 5, 9 | readOnly: false, 10 | emptyClass: 'fa fa-star-o', 11 | fullClass: 'fa fa-star', 12 | change: function(e, value) {} 13 | }; 14 | 15 | function Starrr($el, options) { 16 | this.options = $.extend({}, this.defaults, options); 17 | this.$el = $el; 18 | this.createStars(); 19 | this.syncRating(); 20 | if (this.options.readOnly) { 21 | return; 22 | } 23 | this.$el.on('mouseover.starrr', 'a', (function(_this) { 24 | return function(e) { 25 | return _this.syncRating(_this.getStars().index(e.currentTarget) + 1); 26 | }; 27 | })(this)); 28 | this.$el.on('mouseout.starrr', (function(_this) { 29 | return function() { 30 | return _this.syncRating(); 31 | }; 32 | })(this)); 33 | this.$el.on('click.starrr', 'a', (function(_this) { 34 | return function(e) { 35 | e.preventDefault(); 36 | return _this.setRating(_this.getStars().index(e.currentTarget) + 1); 37 | }; 38 | })(this)); 39 | this.$el.on('starrr:change', this.options.change); 40 | } 41 | 42 | Starrr.prototype.getStars = function() { 43 | return this.$el.find('a'); 44 | }; 45 | 46 | Starrr.prototype.createStars = function() { 47 | var j, ref, results; 48 | results = []; 49 | for (j = 1, ref = this.options.max; 1 <= ref ? j <= ref : j >= ref; 1 <= ref ? j++ : j--) { 50 | results.push(this.$el.append("")); 51 | } 52 | return results; 53 | }; 54 | 55 | Starrr.prototype.setRating = function(rating) { 56 | if (this.options.rating === rating) { 57 | rating = void 0; 58 | } 59 | this.options.rating = rating; 60 | this.syncRating(); 61 | return this.$el.trigger('starrr:change', rating); 62 | }; 63 | 64 | Starrr.prototype.getRating = function() { 65 | return this.options.rating; 66 | }; 67 | 68 | Starrr.prototype.syncRating = function(rating) { 69 | var $stars, i, j, ref, results; 70 | rating || (rating = this.options.rating); 71 | $stars = this.getStars(); 72 | results = []; 73 | for (i = j = 1, ref = this.options.max; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) { 74 | results.push($stars.eq(i - 1).removeClass(rating >= i ? this.options.emptyClass : this.options.fullClass).addClass(rating >= i ? this.options.fullClass : this.options.emptyClass)); 75 | } 76 | return results; 77 | }; 78 | 79 | return Starrr; 80 | 81 | })(); 82 | return $.fn.extend({ 83 | starrr: function() { 84 | var args, option; 85 | option = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; 86 | return this.each(function() { 87 | var data; 88 | data = $(this).data('starrr'); 89 | if (!data) { 90 | $(this).data('starrr', (data = new Starrr($(this), option))); 91 | } 92 | if (typeof option === 'string') { 93 | return data[option].apply(data, args); 94 | } 95 | }); 96 | } 97 | }); 98 | })(window.jQuery, window); 99 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Starrr, for jQuery 4 | 5 | 6 | 7 | 8 | 27 | 28 | 29 | 30 | Fork me on GitHub 31 | 32 | 33 |
34 |

Starrr

35 | 36 |
Click to rate:
37 |
38 |
  39 | 42 |
43 | 44 |
Advanced:
45 |
46 |
47 | 48 | 49 |
Why?
50 |

There are other libraries out there, but none that approach the level clarity and conciseness that I wanted. Starrr is less than 75 lines of code -- you can understand the entirety of its source code in about a minute.

51 | 52 |
Dependencies
53 |

jQuery.

54 |

I'm using Bootstrap + Font Awesome to render the stars, but you're more than welcome to use something else.

55 |
56 | 57 | 58 | 59 | 80 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "starrr", 3 | "version": "2.0.0", 4 | "main": "Gruntfile.coffee", 5 | "author": "ajb ", 6 | "license": "MIT", 7 | "devDependencies": { 8 | "grunt-contrib-sass": "^0.9.2", 9 | "grunt-contrib-coffee": "^0.13.0", 10 | "grunt-contrib-watch": "^0.6.1", 11 | "grunt": "^0.4.5" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/starrr.coffee: -------------------------------------------------------------------------------- 1 | (($, window) -> 2 | 3 | window.Starrr = class Starrr 4 | defaults: 5 | rating: undefined 6 | max: 5 7 | readOnly: false 8 | emptyClass: 'fa fa-star-o' 9 | fullClass: 'fa fa-star' 10 | change: (e, value) -> 11 | 12 | constructor: ($el, options) -> 13 | @options = $.extend({}, @defaults, options) 14 | @$el = $el 15 | @createStars() 16 | @syncRating() 17 | 18 | return if @options.readOnly 19 | 20 | @$el.on 'mouseover.starrr', 'a', (e) => 21 | @syncRating(@getStars().index(e.currentTarget) + 1) 22 | 23 | @$el.on 'mouseout.starrr', => 24 | @syncRating() 25 | 26 | @$el.on 'click.starrr', 'a', (e) => 27 | e.preventDefault() 28 | @setRating(@getStars().index(e.currentTarget) + 1) 29 | 30 | @$el.on 'starrr:change', @options.change 31 | 32 | getStars: -> 33 | @$el.find('a') 34 | 35 | createStars: -> 36 | @$el.append("") for [1..@options.max] 37 | 38 | setRating: (rating) -> 39 | rating = undefined if @options.rating == rating 40 | @options.rating = rating 41 | @syncRating() 42 | @$el.trigger('starrr:change', rating) 43 | 44 | getRating: -> 45 | @options.rating 46 | 47 | syncRating: (rating) -> 48 | rating ||= @options.rating 49 | $stars = @getStars() 50 | for i in [1..@options.max] 51 | $stars. 52 | eq(i - 1). 53 | removeClass(if rating >= i then @options.emptyClass else @options.fullClass). 54 | addClass(if rating >= i then @options.fullClass else @options.emptyClass) 55 | 56 | # Define the plugin 57 | $.fn.extend starrr: (option, args...) -> 58 | @each -> 59 | data = $(@).data('starrr') 60 | 61 | if !data 62 | $(@).data 'starrr', (data = new Starrr($(@), option)) 63 | if typeof option == 'string' 64 | data[option].apply(data, args) 65 | 66 | ) window.jQuery, window 67 | -------------------------------------------------------------------------------- /src/starrr.scss: -------------------------------------------------------------------------------- 1 | $starrrColor: #FFD119 !default; 2 | 3 | .starrr { 4 | display: inline-block; 5 | 6 | a { 7 | font-size: 16px; 8 | padding: 0 1px; 9 | cursor: pointer; 10 | color: $starrrColor; 11 | text-decoration: none; 12 | } 13 | } 14 | --------------------------------------------------------------------------------