├── .gitignore ├── .travis.yml ├── Gruntfile.js ├── LICENSE ├── README.md ├── bower.json ├── composer.json ├── demo ├── css │ ├── static.css │ └── static.min.css ├── demo.css ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── index.html └── js │ ├── static.js │ └── static.min.js ├── dist ├── css │ ├── jquery.progresstimer.css │ └── jquery.progresstimer.min.css └── js │ ├── jquery.progresstimer.js │ └── jquery.progresstimer.min.js ├── package.json └── src ├── css └── jquery.progressTimer.css └── js └── jquery.progressTimer.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.11" 4 | - "0.10" 5 | before_install: 6 | - npm install -g grunt-cli 7 | - npm install -g bower 8 | install: 9 | - npm install 10 | before_script: 11 | - bower install 12 | script: 13 | - grunt dist -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by thomas.c.norberg on 4/24/14. 3 | */ 4 | module.exports = function (grunt) { 5 | "use strict"; 6 | 7 | // Force use of Unix newlines 8 | grunt.util.linefeed = "\n"; 9 | 10 | RegExp.quote = function (string) { 11 | return string.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&"); 12 | }; 13 | // If you want to add the grunt css/js to another view change it here 14 | var distDir = "dist/", 15 | demoDir = "demo/", 16 | srcDir = "src/", 17 | bowerDir = "bower_components/", 18 | staticJsFile = demoDir + "js/static.js", 19 | staticMinJsFile = demoDir + "js/static.min.js", 20 | staticCssFile = demoDir + "css/static.css", 21 | staticMinCssFile = demoDir + "css/static.min.css"; 22 | // 1. All configuration goes here 23 | grunt.initConfig({ 24 | pkg: grunt.file.readJSON("package.json"), 25 | pkgName: "<%= pkg.name.replace(/-/, \".\") %>", 26 | banner: "/**!\n" + 27 | " * <%= pkg.title || pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today(\"m/d/yyyy\") %>\n" + 28 | " * <%= pkg.homepage %>\n" + 29 | " * Copyright (c) <%= grunt.template.today(\"yyyy\") %> <%= pkg.author.name %>;\n" + 30 | " * Licensed <%= _.pluck(pkg.licenses, \"type\").join(\", \") %>\n" + 31 | " */\n", 32 | concat: { 33 | options: { 34 | //banner: "<%= banner %>\n", 35 | stripBanners: false 36 | }, 37 | // 2. Configuration for concatenating files goes here. 38 | staticjs: { 39 | src: [ 40 | bowerDir + "jquery/dist/jquery.js", 41 | bowerDir + "bootstrap/dist/js/bootstrap.js" 42 | ], 43 | dest: staticJsFile 44 | }, 45 | staticcss: { 46 | src: [ 47 | bowerDir + "bootstrap/dist/css/bootstrap.css", 48 | bowerDir + "bootstrap/dist/css/bootstrap-theme.css" 49 | ], 50 | dest: staticCssFile 51 | }, 52 | css: { 53 | src: [ 54 | [srcDir + "css/*.css"] 55 | ], 56 | dest: distDir + "css/<%= pkgName %>.css" 57 | }, 58 | js: { 59 | src: [ 60 | [srcDir + "js/*.js"] 61 | ], 62 | dest: distDir + "js/<%= pkgName %>.js" 63 | } 64 | }, 65 | cssmin: { 66 | css: { 67 | files: [ 68 | { 69 | src: "<%= concat.css.dest %>", 70 | dest: distDir + "css/<%= pkgName %>.min.css" 71 | }, 72 | { 73 | src: "<%= concat.staticcss.dest %>", 74 | dest: staticMinCssFile 75 | } 76 | ] 77 | } 78 | }, 79 | uglify: { 80 | js: { 81 | files: [ 82 | { 83 | src: "<%= concat.js.dest %>", 84 | dest: distDir + "js/<%= pkgName %>.min.js" 85 | }, 86 | { 87 | src: "<%= concat.staticjs.dest %>", 88 | dest: staticMinJsFile 89 | } 90 | ] 91 | } 92 | }, 93 | copy: { 94 | main: { 95 | files: [ 96 | // includes files within path 97 | { 98 | expand: true, 99 | src: [ bowerDir + "bootstrap/dist/fonts/*"], 100 | dest: demoDir + "fonts/", 101 | filter: "isFile", 102 | flatten: true 103 | }, 104 | { 105 | expand: true, 106 | src: [ srcDir + "img/*"], 107 | dest: demoDir + "img/", 108 | filter: "isFile", 109 | flatten: true 110 | }, 111 | { 112 | expand: true, 113 | src: bowerDir + "respond/dest/respond.min.js", 114 | dest: demoDir + "js/", 115 | filter: "isFile", 116 | flatten: true 117 | } 118 | ] 119 | } 120 | }, 121 | usebanner: { 122 | dist: { 123 | options: { 124 | position: "top", 125 | banner: "<%= banner %>" 126 | }, 127 | files: { 128 | src: [ 129 | "<%= concat.js.dest %>", 130 | "<%= concat.css.dest %>", 131 | "<%= uglify.js.files[0].dest %>", 132 | "<%= uglify.js.files[1].dest %>", 133 | "<%= cssmin.css.files[0].dest %>", 134 | "<%= cssmin.css.files[1].dest %>" 135 | ] 136 | } 137 | } 138 | }, 139 | clean: [distDir + "*", demoDir + "/css/*", demoDir + "/js/*", demoDir + "/fonts/*"], 140 | jshint: { 141 | // You get to make the name 142 | // The paths tell JSHint which files to validate 143 | myFiles: ["src/js/**/*.js"] 144 | }, 145 | bump: { 146 | options: { 147 | files: ["package.json", "bower.json"] 148 | }, 149 | scripts: { 150 | files: ["dist/*", "src/*", "demo/*", "package.json", "bower.json", "GruntFile.js"], 151 | updateConfigs: ["pkg"], 152 | commitFiles: ["-a"], 153 | push: true, 154 | pushTo: "<%= pkg.respository.url =>" 155 | } 156 | }, 157 | jsdox: { 158 | generate: { 159 | options: { 160 | contentsEnabled: true, 161 | contentsTitle: "Example Documentation", 162 | contentsFile: "readme.md"//, 163 | ///pathFilter: /^example/ 164 | }, 165 | src: ["src/js/*"], 166 | dest: "md" 167 | }//, 168 | // [optional additional "generation" task like generate above, can be targed with jsdox:generate-other-docs], 169 | /*publish: { 170 | enabled: true, 171 | path: "<%= jsdox.generate.dest %>", 172 | message: "Markdown Auto-Generated for version <%= pkg.version %>", 173 | remoteName: "upstream", 174 | remoteBranch: "master" 175 | }*/ 176 | }/* Need to install grunt-sed but current version does not support exclude, 177 | sed: { 178 | versionNumber: { 179 | pattern: (function () { 180 | var old = grunt.option("oldver"); 181 | return old ? RegExp.quote(old) : old; 182 | })(), 183 | replacement: grunt.option("newver"), 184 | recursive: true, 185 | exclude:["node_modules","bower_components"] 186 | } 187 | }*/ 188 | }); 189 | 190 | // 3. Where we tell Grunt we plan to use this plug-in. 191 | // measures the time each task takes 192 | require("time-grunt")(grunt); 193 | 194 | // load grunt config 195 | require("load-grunt-tasks")(grunt, {scope: "devDependencies"}); 196 | 197 | grunt.registerTask("dev-js", ["newer:jshint:myFiles", "newer:concat:staticjs", "newer:concat:js", "newer:uglify:js"]); 198 | 199 | grunt.registerTask("dist-js", ["jshint:myFiles", "concat:staticjs", "concat:js", "uglify:js"]); 200 | 201 | grunt.registerTask("dev-css", ["newer:concat:staticcss", "newer:concat:css", "newer:cssmin:css"]); 202 | 203 | grunt.registerTask("dist-css", ["concat:staticcss", "concat:css", "cssmin:css"]); 204 | 205 | // 4. Where we tell Grunt what to do when we type "grunt" into the terminal. 206 | grunt.registerTask("default", ["dev-js", "dev-css", "newer:copy:main"]); 207 | 208 | grunt.registerTask("dist", ["clean", "dist-js", "dist-css", "copy:main", "usebanner:dist"]); 209 | 210 | // Version numbering task. 211 | // grunt change-version-number --oldver=A.B.C --newver=X.Y.Z 212 | // This can be overzealous, so its changes should always be manually reviewed! 213 | //grunt.registerTask("change-version-number", "sed"); 214 | }; 215 | 216 | 217 | 218 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2014 Twitter, Inc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Bower version](https://badge.fury.io/bo/jquery-progresstimer.svg)](http://badge.fury.io/bo/jquery-progresstimer) 2 | [![devDependency Status](https://david-dm.org/tnory56/jquery-progressTimer/dev-status.svg)](https://david-dm.org/tnory56/jquery-progressTimer/#info=devDependencies) 3 | [![Dependency Status](https://david-dm.org/tnory56/jquery-progressTimer/status.svg)](https://david-dm.org/tnory56/jquery-progressTimer/) 4 | [![Build Status](https://travis-ci.org/tnory56/jquery-progressTimer.svg?branch=master)](https://travis-ci.org/tnory56/jquery-progressTimer) 5 | [![Codacy Badge](https://www.codacy.com/project/badge/92bc754497b64930aeaef6b0f0632320)](https://www.codacy.com/public/tnory56/jqueryprogressTimer) 6 | 7 | jQuery Progress timer is a jquery extension that extends the functionality of the Bootstrap progress [bar component](http://getbootstrap.com/components/#progress) 8 | 9 | - REQUIRES Bootstrap 3.2.0 or greater. 10 | 11 | ## Table of contents 12 | 13 | - [Quick start](#quick-start) 14 | - [What's Included](#whats-included) 15 | - [Simple Example](#simple-example) 16 | 17 | ## Quick start 18 | 19 | Three quick start options are available: 20 | 21 | - Clone the repo: `git clone https://github.com/tnory56/jquery-progressTimer.git`. 22 | - Install with [Bower](http://bower.io): `bower install jquery-progresstimer`. 23 | - See the demo page [Demo](http://tnory56.github.io/jquery-progressTimer/) for usage and possibilities 24 | 25 | 26 | ## What's included 27 | 28 | Within the download you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations. You'll see something like this: 29 | 30 | ``` 31 | jquery-progresstimer/ 32 | ├── demo/ 33 | │ ├── css/ 34 | │ │ ├── static.css 35 | │ │ └── static.min.css 36 | │ ├── fonts/ 37 | │ │ ├── glyphicons-halflings-regular.eot 38 | │ │ ├── glyphicons-halflings-regular.svg 39 | │ │ ├── glyphicons-halflings-regular.ttf 40 | │ │ └── glyphicons-halflings-regular.woff 41 | │ ├── js/ 42 | │ │ ├── static.js 43 | │ │ └── static.min.js 44 | │ ├── demo.css 45 | │ └── index.html 46 | ├── dist/ 47 | │ ├── css/ 48 | │ │ └── jquery.progresstimer.css 49 | │ └── js/ 50 | │ ├── jquery.progresstimer.js 51 | │ └── jquery.progresstimer.min.js 52 | ├── src/ 53 | │ ├── css/ 54 | │ └── js/ 55 | ├── bower.json 56 | ├── Gruntfile.js 57 | ├── LICENSE 58 | ├── package.json 59 | └── README.md 60 | ``` 61 | 62 | ## Simple Example 63 | 64 | ```html 65 |
66 |
67 |
68 | 69 | 70 | 90 | ``` -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-progresstimer", 3 | "version": "1.0.5", 4 | "authors": [ 5 | "Thomas Norberg " 6 | ], 7 | "description": "The jquery progresstimer is a plugin that extends the ability of the bootstrap progress bar.", 8 | "main": [ 9 | "/dist/jquery.progresstimer.js", 10 | "/dist/jquery.progresstimer.min.js" 11 | ], 12 | "keywords": [ 13 | "progress", 14 | "bootstrap", 15 | "timer" 16 | ], 17 | "license": "MIT", 18 | "homepage": "http://thomasnorberg.com", 19 | "ignore": [ 20 | "**/.*", 21 | "node_modules", 22 | "bower_components", 23 | "test", 24 | "tests" 25 | ], 26 | "devDependencies": {}, 27 | "dependencies": { 28 | "jquery": ">= 1.9.0", 29 | "bootstrap": ">=3.2.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tnory56/jquery-progress-timer", 3 | "description": "The jquery progresstimer is a plugin that extends the ability of the bootstrap progress bar." 4 | } -------------------------------------------------------------------------------- /demo/demo.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin:0 auto; 3 | padding:0; 4 | } 5 | .loading-progress{ 6 | width:100%; 7 | } 8 | 9 | .container { 10 | border: 6px solid black; 11 | border-radius: 8px; 12 | margin-top: 20px; 13 | padding-top: 20px; 14 | } -------------------------------------------------------------------------------- /demo/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnory56/jquery-progressTimer/68cd91e504d43d91342bbb950fb44035b1bf07d6/demo/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /demo/fonts/glyphicons-halflings-regular.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | -------------------------------------------------------------------------------- /demo/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnory56/jquery-progressTimer/68cd91e504d43d91342bbb950fb44035b1bf07d6/demo/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /demo/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnory56/jquery-progressTimer/68cd91e504d43d91342bbb950fb44035b1bf07d6/demo/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /demo/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnory56/jquery-progressTimer/68cd91e504d43d91342bbb950fb44035b1bf07d6/demo/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | jQuery Progress Timer DEMO 7 | 8 | 9 |
10 |
11 |
12 | 13 | 14 | 34 | 35 | -------------------------------------------------------------------------------- /dist/css/jquery.progresstimer.css: -------------------------------------------------------------------------------- 1 | /**! 2 | * jQuery Progress Timer - v1.0.5 - 6/8/2015 3 | * http://www.thomasnorberg.com 4 | * Copyright (c) 2015 Thomas Norberg; 5 | * Licensed MIT 6 | */ 7 | 8 | -------------------------------------------------------------------------------- /dist/css/jquery.progresstimer.min.css: -------------------------------------------------------------------------------- 1 | /**! 2 | * jQuery Progress Timer - v1.0.5 - 6/8/2015 3 | * http://www.thomasnorberg.com 4 | * Copyright (c) 2015 Thomas Norberg; 5 | * Licensed MIT 6 | */ 7 | 8 | -------------------------------------------------------------------------------- /dist/js/jquery.progresstimer.js: -------------------------------------------------------------------------------- 1 | /**! 2 | * jQuery Progress Timer - v1.0.5 - 6/8/2015 3 | * http://www.thomasnorberg.com 4 | * Copyright (c) 2015 Thomas Norberg; 5 | * Licensed MIT 6 | */ 7 | 8 | /* 9 |
10 |
13 | 40% Complete (success) 14 |
15 |
16 | */ 17 | if (typeof jQuery === "undefined") { 18 | throw new Error("jQuery progress timer requires jQuery"); 19 | } 20 | /*! 21 | * jQuery lightweight plugin boilerplate 22 | * Original author: @ajpiano 23 | * Further changes, comments: @addyosmani 24 | * Licensed under the MIT license 25 | */ 26 | 27 | (function ($, window, document, undefined) { 28 | "use strict"; 29 | // undefined is used here as the undefined global 30 | // variable in ECMAScript 3 and is mutable (i.e. it can 31 | // be changed by someone else). undefined isn't really 32 | // being passed in so we can ensure that its value is 33 | // truly undefined. In ES5, undefined can no longer be 34 | // modified. 35 | 36 | // window and document are passed through as local 37 | // variables rather than as globals, because this (slightly) 38 | // quickens the resolution process and can be more 39 | // efficiently minified (especially when both are 40 | // regularly referenced in your plugin). 41 | 42 | // Create the defaults once 43 | var pluginName = "progressTimer", 44 | defaults = { 45 | //total number of seconds 46 | timeLimit: 60, 47 | //seconds remaining triggering switch to warning color 48 | warningThreshold: 5, 49 | //invoked once the timer expires 50 | onFinish: function () { 51 | }, 52 | //bootstrap progress bar style at the beginning of the timer 53 | baseStyle: "", 54 | //bootstrap progress bar style in the warning phase 55 | warningStyle: "progress-bar-danger", 56 | //bootstrap progress bar style at completion of timer 57 | completeStyle: "progress-bar-success", 58 | //show html on progress bar div area 59 | showHtmlSpan: true, 60 | //set the error text when error occurs 61 | errorText: "ERROR!", 62 | //set the success text when succes occurs 63 | successText: "100%" 64 | }; 65 | 66 | // The actual plugin constructor 67 | var Plugin = function (element, options) { 68 | this.element = element; 69 | this.$elem = $(element); 70 | this.options = $.extend({}, defaults, options); 71 | this._defaults = defaults; 72 | this._name = pluginName; 73 | this.metadata = this.$elem.data("plugin-options"); 74 | this.init(); 75 | }; 76 | 77 | Plugin.prototype.constructor = Plugin; 78 | 79 | Plugin.prototype.init = function () { 80 | var t = this; 81 | $(t.element).empty(); 82 | t.span = $(""); 83 | t.barContainer = $("
").addClass("progress"); 84 | t.bar = $("
").addClass("progress-bar active progress-bar-striped").addClass(t.options.baseStyle) 85 | .attr("role", "progressbar") 86 | .attr("aria-valuenow", "0") 87 | .attr("aria-valuemin", "0") 88 | .attr("aria-valuemax", t.options.timeLimit); 89 | t.span.appendTo(t.bar); 90 | if (!t.options.showHtmlSpan) { 91 | t.span.addClass("sr-only"); 92 | } 93 | t.bar.appendTo(t.barContainer); 94 | t.barContainer.appendTo(t.element); 95 | t.start = new Date(); 96 | t.limit = t.options.timeLimit * 1000; 97 | t.warningThreshold = t.options.warningThreshold * 1000; 98 | t.interval = window.setInterval(function () { 99 | t._run.call(t); 100 | }, 250); 101 | t.bar.data("progress-interval", t.interval); 102 | return true; 103 | }; 104 | 105 | Plugin.prototype.destroy = function(){ 106 | this.$elem.removeData(); 107 | }; 108 | 109 | Plugin.prototype._run = function () { 110 | var t = this; 111 | var elapsed = new Date() - t.start, 112 | width = ((elapsed / t.limit) * 100); 113 | t.bar.attr("aria-valuenow", width); 114 | t.bar.width(width + "%"); 115 | var percentage = width.toFixed(2); 116 | if (percentage >= 100) { 117 | percentage = 100; 118 | } 119 | if (t.options.showHtmlSpan) { 120 | t.span.html(percentage + "%"); 121 | } 122 | if (elapsed >= t.warningThreshold) { 123 | t.bar.removeClass(this.options.baseStyle) 124 | .removeClass(this.options.completeStyle) 125 | .addClass(this.options.warningStyle); 126 | } 127 | if (elapsed >= t.limit) { 128 | t.complete.call(t); 129 | } 130 | return true; 131 | }; 132 | 133 | Plugin.prototype.removeInterval = function () { 134 | var t = this, 135 | bar = $(".progress-bar", t.element); 136 | if (typeof bar.data("progress-interval") !== "undefined") { 137 | var interval = bar.data("progress-interval"); 138 | window.clearInterval(interval); 139 | } 140 | return bar; 141 | }; 142 | 143 | Plugin.prototype.complete = function () { 144 | var t = this, 145 | bar = t.removeInterval.call(t), 146 | args = arguments; 147 | if(args.length !== 0 && typeof args[0] === "object"){ 148 | t.options = $.extend({}, t.options, args[0]); 149 | } 150 | bar.removeClass(t.options.baseStyle) 151 | .removeClass(t.options.warningStyle) 152 | .addClass(t.options.completeStyle); 153 | bar.width("100%"); 154 | if (t.options.showHtmlSpan) { 155 | $("span", bar).html(t.options.successText); 156 | } 157 | bar.attr("aria-valuenow", 100); 158 | setTimeout(function () { 159 | t.options.onFinish.call(bar); 160 | }, 500); 161 | t.destroy.call(t); 162 | }; 163 | 164 | Plugin.prototype.error = function () { 165 | var t = this, 166 | bar = t.removeInterval.call(t), 167 | args = arguments; 168 | if(args.length !== 0 && typeof args[0] === "object"){ 169 | t.options = $.extend({}, t.options, args[0]); 170 | } 171 | bar.removeClass(t.options.baseStyle) 172 | .addClass(t.options.warningStyle); 173 | bar.width("100%"); 174 | if (t.options.showHtmlSpan) { 175 | $("span", bar).html(t.options.errorText); 176 | } 177 | bar.attr("aria-valuenow", 100); 178 | setTimeout(function () { 179 | t.options.onFinish.call(bar); 180 | }, 500); 181 | t.destroy.call(t); 182 | }; 183 | 184 | // A really lightweight plugin wrapper around the constructor, 185 | // preventing against multiple instantiations 186 | $.fn[pluginName] = function (options) { 187 | var args = arguments; 188 | if (options === undefined || typeof options === "object") { 189 | // Creates a new plugin instance 190 | return this.each(function () { 191 | if (!$.data(this, "plugin_" + pluginName)) { 192 | $.data(this, "plugin_" + pluginName, new Plugin(this, options)); 193 | } 194 | }); 195 | } else if (typeof options === "string" && options[0] !== "_" && options !== "init") { 196 | // Call a public plugin method (not starting with an underscore) and different 197 | // from the "init" one 198 | if (Array.prototype.slice.call(args, 1).length === 0 && $.inArray(options, $.fn[pluginName].getters) !== -1) { 199 | // If the user does not pass any arguments and the method allows to 200 | // work as a getter then break the chainability so we can return a value 201 | // instead the element reference. 202 | var instance = $.data(this[0], "plugin_" + pluginName); 203 | return instance[options].apply(instance, Array.prototype.slice.call(args, 1)); 204 | } else { 205 | // Invoke the specified method on each selected element 206 | return this.each(function() { 207 | var instance = $.data(this, "plugin_" + pluginName); 208 | if (instance instanceof Plugin && typeof instance[options] === "function") { 209 | instance[options].apply(instance, Array.prototype.slice.call(args, 1)); 210 | } 211 | }); 212 | } 213 | } 214 | }; 215 | 216 | $.fn[pluginName].getters = ["complete", "error"]; 217 | 218 | })(jQuery, window, document, undefined); 219 | -------------------------------------------------------------------------------- /dist/js/jquery.progresstimer.min.js: -------------------------------------------------------------------------------- 1 | /**! 2 | * jQuery Progress Timer - v1.0.5 - 6/8/2015 3 | * http://www.thomasnorberg.com 4 | * Copyright (c) 2015 Thomas Norberg; 5 | * Licensed MIT 6 | */ 7 | 8 | if("undefined"==typeof jQuery)throw new Error("jQuery progress timer requires jQuery");!function(a,b,c,d){"use strict";var e="progressTimer",f={timeLimit:60,warningThreshold:5,onFinish:function(){},baseStyle:"",warningStyle:"progress-bar-danger",completeStyle:"progress-bar-success",showHtmlSpan:!0,errorText:"ERROR!",successText:"100%"},g=function(b,c){this.element=b,this.$elem=a(b),this.options=a.extend({},f,c),this._defaults=f,this._name=e,this.metadata=this.$elem.data("plugin-options"),this.init()};g.prototype.constructor=g,g.prototype.init=function(){var c=this;return a(c.element).empty(),c.span=a(""),c.barContainer=a("
").addClass("progress"),c.bar=a("
").addClass("progress-bar active progress-bar-striped").addClass(c.options.baseStyle).attr("role","progressbar").attr("aria-valuenow","0").attr("aria-valuemin","0").attr("aria-valuemax",c.options.timeLimit),c.span.appendTo(c.bar),c.options.showHtmlSpan||c.span.addClass("sr-only"),c.bar.appendTo(c.barContainer),c.barContainer.appendTo(c.element),c.start=new Date,c.limit=1e3*c.options.timeLimit,c.warningThreshold=1e3*c.options.warningThreshold,c.interval=b.setInterval(function(){c._run.call(c)},250),c.bar.data("progress-interval",c.interval),!0},g.prototype.destroy=function(){this.$elem.removeData()},g.prototype._run=function(){var a=this,b=new Date-a.start,c=b/a.limit*100;a.bar.attr("aria-valuenow",c),a.bar.width(c+"%");var d=c.toFixed(2);return d>=100&&(d=100),a.options.showHtmlSpan&&a.span.html(d+"%"),b>=a.warningThreshold&&a.bar.removeClass(this.options.baseStyle).removeClass(this.options.completeStyle).addClass(this.options.warningStyle),b>=a.limit&&a.complete.call(a),!0},g.prototype.removeInterval=function(){var c=this,d=a(".progress-bar",c.element);if("undefined"!=typeof d.data("progress-interval")){var e=d.data("progress-interval");b.clearInterval(e)}return d},g.prototype.complete=function(){var b=this,c=b.removeInterval.call(b),d=arguments;0!==d.length&&"object"==typeof d[0]&&(b.options=a.extend({},b.options,d[0])),c.removeClass(b.options.baseStyle).removeClass(b.options.warningStyle).addClass(b.options.completeStyle),c.width("100%"),b.options.showHtmlSpan&&a("span",c).html(b.options.successText),c.attr("aria-valuenow",100),setTimeout(function(){b.options.onFinish.call(c)},500),b.destroy.call(b)},g.prototype.error=function(){var b=this,c=b.removeInterval.call(b),d=arguments;0!==d.length&&"object"==typeof d[0]&&(b.options=a.extend({},b.options,d[0])),c.removeClass(b.options.baseStyle).addClass(b.options.warningStyle),c.width("100%"),b.options.showHtmlSpan&&a("span",c).html(b.options.errorText),c.attr("aria-valuenow",100),setTimeout(function(){b.options.onFinish.call(c)},500),b.destroy.call(b)},a.fn[e]=function(b){var c=arguments;if(b===d||"object"==typeof b)return this.each(function(){a.data(this,"plugin_"+e)||a.data(this,"plugin_"+e,new g(this,b))});if("string"==typeof b&&"_"!==b[0]&&"init"!==b){if(0===Array.prototype.slice.call(c,1).length&&-1!==a.inArray(b,a.fn[e].getters)){var f=a.data(this[0],"plugin_"+e);return f[b].apply(f,Array.prototype.slice.call(c,1))}return this.each(function(){var d=a.data(this,"plugin_"+e);d instanceof g&&"function"==typeof d[b]&&d[b].apply(d,Array.prototype.slice.call(c,1))})}},a.fn[e].getters=["complete","error"]}(jQuery,window,document,void 0); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-progresstimer", 3 | "title": "jQuery Progress Timer", 4 | "version": "1.0.5", 5 | "author": { 6 | "name": "Thomas Norberg", 7 | "email": "tnorberg@thomasnorberg.com", 8 | "url": "http://www.thomasnorberg.com" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/tnory56/jquery-progressTimer.git" 13 | }, 14 | "description": "The jquery progresstimer is a plugin that extends the ability of the bootstrap progress bar.", 15 | "homepage": "http://www.thomasnorberg.com", 16 | "devDependencies": { 17 | "bower": "^1.3.12", 18 | "grunt": "~0.4.1", 19 | "grunt-banner": "*", 20 | "grunt-bump": "0.3.1", 21 | "grunt-contrib-clean": "~0.6.0", 22 | "grunt-contrib-concat": "~0.5.0", 23 | "grunt-contrib-copy": "~0.8.0", 24 | "grunt-contrib-cssmin": "~0.12.3", 25 | "grunt-contrib-jshint": "~0.11.2", 26 | "grunt-contrib-uglify": "~0.9.1", 27 | "grunt-contrib-watch": "~0.6.1", 28 | "grunt-jsdox": "~0.1.5", 29 | "grunt-newer": "~1.1.0", 30 | "load-grunt-tasks": "~3.2.0", 31 | "time-grunt": "~1.2.1" 32 | }, 33 | "dependencies": { 34 | "jquery": ">= 1.9.0", 35 | "bootstrap": ">=3.2.0" 36 | }, 37 | "licenses": [ 38 | { 39 | "type": "MIT", 40 | "url": "http://www.opensource.org/licenses/MIT" 41 | } 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /src/css/jquery.progressTimer.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnory56/jquery-progressTimer/68cd91e504d43d91342bbb950fb44035b1bf07d6/src/css/jquery.progressTimer.css -------------------------------------------------------------------------------- /src/js/jquery.progressTimer.js: -------------------------------------------------------------------------------- 1 | /* 2 |
3 |
6 | 40% Complete (success) 7 |
8 |
9 | */ 10 | if (typeof jQuery === "undefined") { 11 | throw new Error("jQuery progress timer requires jQuery"); 12 | } 13 | /*! 14 | * jQuery lightweight plugin boilerplate 15 | * Original author: @ajpiano 16 | * Further changes, comments: @addyosmani 17 | * Licensed under the MIT license 18 | */ 19 | 20 | (function ($, window, document, undefined) { 21 | "use strict"; 22 | // undefined is used here as the undefined global 23 | // variable in ECMAScript 3 and is mutable (i.e. it can 24 | // be changed by someone else). undefined isn't really 25 | // being passed in so we can ensure that its value is 26 | // truly undefined. In ES5, undefined can no longer be 27 | // modified. 28 | 29 | // window and document are passed through as local 30 | // variables rather than as globals, because this (slightly) 31 | // quickens the resolution process and can be more 32 | // efficiently minified (especially when both are 33 | // regularly referenced in your plugin). 34 | 35 | // Create the defaults once 36 | var pluginName = "progressTimer", 37 | defaults = { 38 | //total number of seconds 39 | timeLimit: 60, 40 | //seconds remaining triggering switch to warning color 41 | warningThreshold: 5, 42 | //invoked once the timer expires 43 | onFinish: function () { 44 | }, 45 | //bootstrap progress bar style at the beginning of the timer 46 | baseStyle: "", 47 | //bootstrap progress bar style in the warning phase 48 | warningStyle: "progress-bar-danger", 49 | //bootstrap progress bar style at completion of timer 50 | completeStyle: "progress-bar-success", 51 | //show html on progress bar div area 52 | showHtmlSpan: true, 53 | //set the error text when error occurs 54 | errorText: "ERROR!", 55 | //set the success text when succes occurs 56 | successText: "100%" 57 | }; 58 | 59 | // The actual plugin constructor 60 | var Plugin = function (element, options) { 61 | this.element = element; 62 | this.$elem = $(element); 63 | this.options = $.extend({}, defaults, options); 64 | this._defaults = defaults; 65 | this._name = pluginName; 66 | this.metadata = this.$elem.data("plugin-options"); 67 | this.init(); 68 | }; 69 | 70 | Plugin.prototype.constructor = Plugin; 71 | 72 | Plugin.prototype.init = function () { 73 | var t = this; 74 | $(t.element).empty(); 75 | t.span = $(""); 76 | t.barContainer = $("
").addClass("progress"); 77 | t.bar = $("
").addClass("progress-bar active progress-bar-striped").addClass(t.options.baseStyle) 78 | .attr("role", "progressbar") 79 | .attr("aria-valuenow", "0") 80 | .attr("aria-valuemin", "0") 81 | .attr("aria-valuemax", t.options.timeLimit); 82 | t.span.appendTo(t.bar); 83 | if (!t.options.showHtmlSpan) { 84 | t.span.addClass("sr-only"); 85 | } 86 | t.bar.appendTo(t.barContainer); 87 | t.barContainer.appendTo(t.element); 88 | t.start = new Date(); 89 | t.limit = t.options.timeLimit * 1000; 90 | t.warningThreshold = t.options.warningThreshold * 1000; 91 | t.interval = window.setInterval(function () { 92 | t._run.call(t); 93 | }, 250); 94 | t.bar.data("progress-interval", t.interval); 95 | return true; 96 | }; 97 | 98 | Plugin.prototype.destroy = function(){ 99 | this.$elem.removeData(); 100 | }; 101 | 102 | Plugin.prototype._run = function () { 103 | var t = this; 104 | var elapsed = new Date() - t.start, 105 | width = ((elapsed / t.limit) * 100); 106 | t.bar.attr("aria-valuenow", width); 107 | t.bar.width(width + "%"); 108 | var percentage = width.toFixed(2); 109 | if (percentage >= 100) { 110 | percentage = 100; 111 | } 112 | if (t.options.showHtmlSpan) { 113 | t.span.html(percentage + "%"); 114 | } 115 | if (elapsed >= t.warningThreshold) { 116 | t.bar.removeClass(this.options.baseStyle) 117 | .removeClass(this.options.completeStyle) 118 | .addClass(this.options.warningStyle); 119 | } 120 | if (elapsed >= t.limit) { 121 | t.complete.call(t); 122 | } 123 | return true; 124 | }; 125 | 126 | Plugin.prototype.removeInterval = function () { 127 | var t = this, 128 | bar = $(".progress-bar", t.element); 129 | if (typeof bar.data("progress-interval") !== "undefined") { 130 | var interval = bar.data("progress-interval"); 131 | window.clearInterval(interval); 132 | } 133 | return bar; 134 | }; 135 | 136 | Plugin.prototype.complete = function () { 137 | var t = this, 138 | bar = t.removeInterval.call(t), 139 | args = arguments; 140 | if(args.length !== 0 && typeof args[0] === "object"){ 141 | t.options = $.extend({}, t.options, args[0]); 142 | } 143 | bar.removeClass(t.options.baseStyle) 144 | .removeClass(t.options.warningStyle) 145 | .addClass(t.options.completeStyle); 146 | bar.width("100%"); 147 | if (t.options.showHtmlSpan) { 148 | $("span", bar).html(t.options.successText); 149 | } 150 | bar.attr("aria-valuenow", 100); 151 | setTimeout(function () { 152 | t.options.onFinish.call(bar); 153 | }, 500); 154 | t.destroy.call(t); 155 | }; 156 | 157 | Plugin.prototype.error = function () { 158 | var t = this, 159 | bar = t.removeInterval.call(t), 160 | args = arguments; 161 | if(args.length !== 0 && typeof args[0] === "object"){ 162 | t.options = $.extend({}, t.options, args[0]); 163 | } 164 | bar.removeClass(t.options.baseStyle) 165 | .addClass(t.options.warningStyle); 166 | bar.width("100%"); 167 | if (t.options.showHtmlSpan) { 168 | $("span", bar).html(t.options.errorText); 169 | } 170 | bar.attr("aria-valuenow", 100); 171 | setTimeout(function () { 172 | t.options.onFinish.call(bar); 173 | }, 500); 174 | t.destroy.call(t); 175 | }; 176 | 177 | // A really lightweight plugin wrapper around the constructor, 178 | // preventing against multiple instantiations 179 | $.fn[pluginName] = function (options) { 180 | var args = arguments; 181 | if (options === undefined || typeof options === "object") { 182 | // Creates a new plugin instance 183 | return this.each(function () { 184 | if (!$.data(this, "plugin_" + pluginName)) { 185 | $.data(this, "plugin_" + pluginName, new Plugin(this, options)); 186 | } 187 | }); 188 | } else if (typeof options === "string" && options[0] !== "_" && options !== "init") { 189 | // Call a public plugin method (not starting with an underscore) and different 190 | // from the "init" one 191 | if (Array.prototype.slice.call(args, 1).length === 0 && $.inArray(options, $.fn[pluginName].getters) !== -1) { 192 | // If the user does not pass any arguments and the method allows to 193 | // work as a getter then break the chainability so we can return a value 194 | // instead the element reference. 195 | var instance = $.data(this[0], "plugin_" + pluginName); 196 | return instance[options].apply(instance, Array.prototype.slice.call(args, 1)); 197 | } else { 198 | // Invoke the specified method on each selected element 199 | return this.each(function() { 200 | var instance = $.data(this, "plugin_" + pluginName); 201 | if (instance instanceof Plugin && typeof instance[options] === "function") { 202 | instance[options].apply(instance, Array.prototype.slice.call(args, 1)); 203 | } 204 | }); 205 | } 206 | } 207 | }; 208 | 209 | $.fn[pluginName].getters = ["complete", "error"]; 210 | 211 | })(jQuery, window, document, undefined); 212 | --------------------------------------------------------------------------------