├── .travis.yml ├── .gitignore ├── package.json ├── bower.json ├── examples ├── css │ ├── reset.css │ └── main.css └── index.html ├── Gruntfile.js ├── karma.conf.js ├── dist ├── alert.default.min.css ├── alert.lite.min.css ├── src │ ├── alert.lite.css │ ├── alert.default.css │ ├── alert.core.css │ └── alert.js ├── alert.core.min.css └── alert.min.js ├── theme ├── alert.lite.css ├── alert.default.css └── alert.core.css ├── tests └── AlertSpec.js ├── README.md └── lib └── alert.js /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4.2.0" 4 | 5 | before_install: 6 | - "export DISPLAY=:99.0" 7 | - "sh -e /etc/init.d/xvfb start" 8 | 9 | before_script: 10 | - npm install -g grunt-cli 11 | - npm install -g karma-cli 12 | - grunt 13 | 14 | script: 15 | - karma start --single-run 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User specific & automatically generated files # 2 | ################################################# 3 | /node_modules 4 | /npm-debug.log 5 | 6 | # OS generated files # 7 | ###################### 8 | .DS_Store 9 | .DS_Store? 10 | ._* 11 | .Spotlight-V100 12 | .Trashes 13 | Icon? 14 | ehthumbs.db 15 | Thumbs.db 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alert.js", 3 | "version": "0.0.0-beta", 4 | "author": "Ankit Pokhrel", 5 | "description": "Beautifully crafted responsive javascript alert boxes.", 6 | "homepage": "http://ankitpokhrel.com.np/", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/ankitpokhrel/alert.js.git" 10 | }, 11 | "license": "MIT", 12 | "main": "Gruntfile.js", 13 | "directories": { 14 | "test": "tests" 15 | }, 16 | "keywords": [ 17 | "alert", 18 | "javascript", 19 | "fancy alert" 20 | ], 21 | "devDependencies": { 22 | "grunt": "^1.0.1", 23 | "grunt-contrib-copy": "^1.0.0", 24 | "grunt-contrib-cssmin": "^2.2.1", 25 | "grunt-contrib-jshint": "^1.1.0", 26 | "grunt-contrib-uglify": "^3.0.1", 27 | "jasmine-core": "^2.8.0", 28 | "karma": "^1.7.1", 29 | "karma-chrome-launcher": "~2.2.0", 30 | "karma-jasmine": "~1.1.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alert.js", 3 | "version": "0.0.0-beta", 4 | "homepage": "https://github.com/ankitpokhrel/alert.js", 5 | "authors": [ 6 | "Ankit Pokhrel " 7 | ], 8 | "description": "Beautifully crafted responsive javascript alert boxes.", 9 | "main": "['lib/alert.js', 'theme/alert.core.css', 'theme/alert.default.css', 'theme/alert.lite.css']", 10 | "moduleType": [ 11 | "node" 12 | ], 13 | "keywords": [ 14 | "alert", 15 | "fancy", 16 | "dialog", 17 | "alert.js", 18 | "popup" 19 | ], 20 | "license": "MIT", 21 | "ignore": [ 22 | "**/.*", 23 | "node_modules", 24 | "bower_components", 25 | "tests" 26 | ], 27 | "devDependencies": { 28 | "grunt": "^0.4.5", 29 | "grunt-contrib-jshint": "^0.11.0", 30 | "grunt-contrib-uglify": "^0.7.0", 31 | "karma": "~0.12.31", 32 | "karma-firefox-launcher": "~0.1.4", 33 | "jasmine-core": "~2.1.3", 34 | "karma-jasmine": "~0.3.5", 35 | "karma-chrome-launcher": "~0.1.7", 36 | "grunt-contrib-cssmin": "~0.11.0", 37 | "grunt-contrib-copy": "~0.7.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /examples/css/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } -------------------------------------------------------------------------------- /examples/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: arial, helvetica, 'sans serif'; 3 | background-color: #efefef; 4 | } 5 | 6 | .container { 7 | margin: 20px auto; 8 | width: 75%; 9 | text-align: center; 10 | } 11 | 12 | .link, .linkBtn { 13 | padding: 10px; 14 | border: 1px solid #5cb85c; 15 | text-decoration: none; 16 | display: inline-block; 17 | min-width: 80px; 18 | text-align: center; 19 | margin: 10px; 20 | background: #5cb85c; 21 | color: #fff; 22 | } 23 | 24 | .linkBtn { 25 | -webkit-border-radius: 5px; 26 | -moz-border-radius: 5px; 27 | -ms-border-radius: 5px; 28 | -o-border-radius: 5px; 29 | border-radius: 5px; 30 | } 31 | 32 | .countdown { 33 | font-size: 21px; 34 | margin: 50px; 35 | } 36 | 37 | .sec { 38 | margin-top: 0 !important; 39 | font-size: 12px; 40 | } 41 | 42 | .countdown p { 43 | margin: 20px 0; 44 | } 45 | 46 | #counter { 47 | font-family: 'courier new'; 48 | font-size: 48px; 49 | } 50 | 51 | .social { 52 | display: inline-block; 53 | } 54 | 55 | .inp { 56 | padding: 3px; 57 | margin: 3px; 58 | border: 1px solid #ccc; 59 | } 60 | 61 | #alertJS label { 62 | display: inline-block; 63 | width: 100px; 64 | } 65 | 66 | .active { 67 | background: #FFA500; 68 | border: none; 69 | -webkit-border-radius: 5px; 70 | -moz-border-radius: 5px; 71 | -ms-border-radius: 5px; 72 | -o-border-radius: 5px; 73 | border-radius: 5px; 74 | } 75 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | //Project configuration 3 | grunt.initConfig({ 4 | pkg: grunt.file.readJSON('package.json'), 5 | uglify: { 6 | options: { 7 | mangle: { 8 | properties: true 9 | }, 10 | banner: '/*!\n * <%= pkg.name %> v<%= pkg.version %>, <%= grunt.template.today("dd.mm.yyyy") %>\n * <%= pkg.description %>\n * By <%= pkg.author %> (<%= pkg.homepage %>, @ankitpokhrel)\n * Licenced under <%= pkg.license %>\n */\n' 11 | }, 12 | build: { 13 | files: { 14 | 'dist/alert.min.js': ['lib/<%= pkg.name %>'] 15 | } 16 | } 17 | }, 18 | jshint: { 19 | build: ['Gruntfile.js', 'lib/<%= pkg.name %>', 'tests/AlertSpec.js'] 20 | }, 21 | cssmin: { 22 | build: { 23 | files: { 24 | 'dist/alert.core.min.css': ['theme/alert.core.css'], 25 | 'dist/alert.default.min.css': ['theme/alert.default.css'], 26 | 'dist/alert.lite.min.css': ['theme/alert.lite.css'] 27 | } 28 | } 29 | }, 30 | copy: { 31 | main: { 32 | expand: true, 33 | flatten: true, 34 | src: ['lib/*.js', 'theme/*.css'], 35 | dest: 'dist/src/', 36 | filter: 'isFile' 37 | } 38 | } 39 | }); 40 | 41 | //Load required plugins 42 | grunt.loadNpmTasks('grunt-contrib-uglify'); 43 | grunt.loadNpmTasks('grunt-contrib-jshint'); 44 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 45 | grunt.loadNpmTasks('grunt-contrib-copy'); 46 | 47 | //Register tasks 48 | grunt.registerTask('default', ['jshint', 'uglify', 'cssmin', 'copy']); 49 | }; 50 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Sat Jan 24 2015 15:51:39 GMT+0545 (NPT) 3 | module.exports = function(config) { 4 | config.set({ 5 | 6 | // base path that will be used to resolve all patterns (eg. files, exclude) 7 | basePath: '', 8 | 9 | 10 | // frameworks to use 11 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 12 | frameworks: ['jasmine'], 13 | 14 | 15 | plugins: [ 16 | require('karma-chrome-launcher'), 17 | require('karma-jasmine') 18 | ], 19 | 20 | 21 | // list of files / patterns to load in the browser 22 | files: [ 23 | 'lib/alert.js', 24 | 'tests/*.js' 25 | ], 26 | 27 | 28 | // list of files to exclude 29 | exclude: [ 30 | ], 31 | 32 | 33 | // preprocess matching files before serving them to the browser 34 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 35 | preprocessors: { 36 | }, 37 | 38 | 39 | // test results reporter to use 40 | // possible values: 'dots', 'progress' 41 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 42 | reporters: ['progress'], 43 | 44 | 45 | // web server port 46 | port: 9876, 47 | 48 | 49 | // enable / disable colors in the output (reporters and logs) 50 | colors: true, 51 | 52 | 53 | // level of logging 54 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 55 | logLevel: config.LOG_INFO, 56 | 57 | 58 | // enable / disable watching file and executing tests whenever any file changes 59 | autoWatch: true, 60 | 61 | 62 | // start these browsers 63 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 64 | browsers: ['Chrome'], 65 | 66 | 67 | // Continuous Integration mode 68 | // if true, Karma captures browsers, runs the tests and exits 69 | singleRun: true 70 | }); 71 | }; 72 | -------------------------------------------------------------------------------- /dist/alert.default.min.css: -------------------------------------------------------------------------------- 1 | .alert-js-btn-cancel:hover,.alert-js-btn-ok:hover{-o-transition:all 1s ease .3s;transition:all 1s ease .3s;-webkit-transition:all 1s ease .3s;-moz-transition:all 1s ease .3s}.alert-js{font-family:Arial,helvetica,sans-serif;background-color:#fff;-webkit-box-shadow:1px 0 37px -3px rgba(0,0,0,.75);-moz-box-shadow:1px 0 37px -3px rgba(0,0,0,.75);box-shadow:1px 0 37px -3px rgba(0,0,0,.75)}.alert-js-header{border-bottom:1px solid transparent;border-radius:0;padding:4px 14px;background-color:#337ab7;border-color:#337ab7;color:#fff}.alert-js-header h1{font-size:1.3em;line-height:1.5em;color:#fff}.alert-js-header h2{font-size:.9em;line-height:1em;padding-top:2px}.alert-js-body{padding:15px 15px 5px;font-size:1em;line-height:1.125em;width:auto}.alert-js-footer{padding:10px;text-align:right}.alert-js-footer button{margin:5px;min-width:15%}.alert-js-btn{cursor:pointer;display:inline-block;border:none;font-size:.875em;font-weight:400;margin-bottom:0;padding:6px 12px;text-align:center;vertical-align:middle;white-space:nowrap}.alert-js-btn-ok:hover{background:rgba(45,143,3,1)}.alert-js-btn-cancel:hover{background:rgba(245,0,0,1)}.alert-js-btn-ok{background-color:#149414;color:#fff}.alert-js-btn-cancel{background-color:#FF1414;border-color:#d43f3a;color:#fff}.alert-js-action{padding:10px;text-align:right;border-top:1px solid #eee}.alert-js-action a{margin:5px}.alert-js-overlay{background:#000;position:fixed;top:0;left:0;width:100%;height:100%;-moz-opacity:.4;-khtml-opacity:.4;opacity:.4;z-index:9998}.alert-js-input{background-color:#fff;border:1px solid #ccc;box-shadow:0 1px 1px rgba(0,0,0,.075)inset;color:#555;display:block;padding:6px 12px;width:100%;margin-top:5px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;-moz-transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;-o-transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s} -------------------------------------------------------------------------------- /dist/alert.lite.min.css: -------------------------------------------------------------------------------- 1 | .alert-js-btn-cancel:hover,.alert-js-btn-ok:hover{-o-transition:all 1s ease .3s;transition:all 1s ease .3s;-webkit-transition:all 1s ease .3s;-moz-transition:all 1s ease .3s}.alert-js{font-family:Arial,helvetica,sans-serif;background-color:#fff;border-radius:5px;-webkit-box-shadow:1px 0 37px -3px rgba(0,0,0,.75);-moz-box-shadow:1px 0 37px -3px rgba(0,0,0,.75);box-shadow:1px 0 37px -3px rgba(0,0,0,.75)}.alert-js-header{border-bottom:1px solid #dedede;border-radius:0;padding:12px;text-align:center}.alert-js-header h1{font-size:1.5em;color:#222}.alert-js-header h2{font-size:.9em;line-height:1em;padding-top:2px}.alert-js-body{padding:25px;font-size:1em;line-height:1.125em;width:auto}.alert-js-footer{padding:10px;text-align:right;border-top:1px solid #dedede}.alert-js-footer button{margin:5px;min-width:15%}.alert-js-btn{cursor:pointer;display:inline-block;border:none;font-size:.875em;font-weight:400;margin-bottom:0;padding:6px 12px;text-align:center;vertical-align:middle;border-radius:4px}.alert-js-btn-ok:hover{background:rgba(68,127,68,1)}.alert-js-btn-cancel:hover{background:rgba(185,62,62,1)}.alert-js-btn-ok{background-color:#5cb85c;border:1px solid #4cae4c;color:#fff}.alert-js-btn-cancel{background-color:#d9534f;border:1px solid #d43f3a;color:#fff}.alert-js-action{padding:10px;text-align:right;border-top:1px solid #eee}.alert-js-action a{margin:5px}.alert-js-overlay{background:#000;position:fixed;top:0;left:0;width:100%;height:100%;-moz-opacity:.4;-khtml-opacity:.4;opacity:.4;z-index:9998}.alert-js-input{background-color:#fff;border:1px solid #ccc;box-shadow:0 1px 1px rgba(0,0,0,.075)inset;color:#555;display:block;padding:6px 12px;width:100%;margin-top:5px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;-moz-transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;-o-transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s} -------------------------------------------------------------------------------- /dist/src/alert.lite.css: -------------------------------------------------------------------------------- 1 | /** 2 | * alert.js lite theme v0.0.0-beta, 10.01.2014 3 | * @author Ankit Pokhrel (http://ankitpokhrel.com.np, @ankitpokhrel) 4 | */ 5 | 6 | .alert-js { 7 | font-family: 'Arial', 'helvetica', 'sans-serif'; 8 | background-color: #fff; 9 | border-radius: 5px; 10 | -webkit-box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 11 | -moz-box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 12 | box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 13 | } 14 | 15 | .alert-js-header { 16 | border-bottom: 1px solid #dedede; 17 | border-radius: 0; 18 | padding: 12px; 19 | text-align: center; 20 | } 21 | 22 | .alert-js-header h1 { 23 | font-size: 1.5em; 24 | color: #222; 25 | } 26 | 27 | .alert-js-header h2 { 28 | font-size: 0.9em; 29 | line-height: 1em; 30 | padding-top: 2px; 31 | } 32 | 33 | .alert-js-body { 34 | padding: 25px; 35 | font-size: 1em; 36 | line-height: 1.125em; 37 | width: auto; 38 | } 39 | 40 | .alert-js-footer { 41 | padding: 10px; 42 | text-align: right; 43 | border-top: 1px solid #dedede; 44 | } 45 | 46 | .alert-js-footer button { 47 | margin: 5px; 48 | min-width: 15%; 49 | } 50 | 51 | .alert-js-btn { 52 | cursor: pointer; 53 | display: inline-block; 54 | border: none; 55 | font-size: 0.875em; 56 | font-weight: 400; 57 | margin-bottom: 0; 58 | padding: 6px 12px; 59 | text-align: center; 60 | vertical-align: middle; 61 | border-radius: 4px; 62 | } 63 | 64 | .alert-js-btn-ok:hover { 65 | background: rgba(68, 127, 68, 1); 66 | -webkit-transition: all 1s ease 0.3s; 67 | -moz-transition: all 1s ease 0.3s; 68 | -o-transition: all 1s ease 0.3s; 69 | transition: all 1s ease 0.3s; 70 | } 71 | 72 | .alert-js-btn-cancel:hover { 73 | background: rgba(185, 62, 62, 1); 74 | -webkit-transition: all 1s ease 0.3s; 75 | -moz-transition: all 1s ease 0.3s; 76 | -o-transition: all 1s ease 0.3s; 77 | transition: all 1s ease 0.3s; 78 | } 79 | 80 | 81 | .alert-js-btn-ok { 82 | background-color: #5cb85c; 83 | border: 1px solid #4cae4c; 84 | color: #fff; 85 | } 86 | 87 | .alert-js-btn-cancel { 88 | background-color: #d9534f; 89 | border: 1px solid #d43f3a; 90 | color: #fff; 91 | } 92 | 93 | .alert-js-action { 94 | padding: 10px; 95 | text-align: right; 96 | border-top: 1px solid #eee; 97 | } 98 | 99 | .alert-js-action a { 100 | margin: 5px; 101 | } 102 | 103 | .alert-js-overlay { 104 | background: #000; 105 | position: fixed; 106 | top: 0; 107 | left: 0; 108 | width: 100%; 109 | height: 100%; 110 | -moz-opacity: 0.4; /* Netscape */ 111 | -khtml-opacity: 0.4; /* Safari 1.x */ 112 | opacity: 0.4; 113 | z-index: 9998; 114 | } 115 | 116 | .alert-js-input { 117 | background-color: #fff; 118 | border: 1px solid #ccc; 119 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset; 120 | color: #555; 121 | display: block; 122 | padding: 6px 12px; 123 | width: 100%; 124 | margin-top: 5px; 125 | 126 | -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ 127 | -moz-box-sizing: border-box; /* Firefox, other Gecko */ 128 | box-sizing: border-box; /* IE8+ */ 129 | 130 | -webkit-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 131 | -moz-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 132 | -o-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 133 | transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 134 | } 135 | -------------------------------------------------------------------------------- /theme/alert.lite.css: -------------------------------------------------------------------------------- 1 | /** 2 | * alert.js lite theme v0.0.0-beta, 10.01.2014 3 | * @author Ankit Pokhrel (http://ankitpokhrel.com.np, @ankitpokhrel) 4 | */ 5 | 6 | .alert-js { 7 | font-family: 'Arial', 'helvetica', 'sans-serif'; 8 | background-color: #fff; 9 | border-radius: 5px; 10 | -webkit-box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 11 | -moz-box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 12 | box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 13 | } 14 | 15 | .alert-js-header { 16 | border-bottom: 1px solid #dedede; 17 | border-radius: 0; 18 | padding: 12px; 19 | text-align: center; 20 | } 21 | 22 | .alert-js-header h1 { 23 | font-size: 1.5em; 24 | color: #222; 25 | } 26 | 27 | .alert-js-header h2 { 28 | font-size: 0.9em; 29 | line-height: 1em; 30 | padding-top: 2px; 31 | } 32 | 33 | .alert-js-body { 34 | padding: 25px; 35 | font-size: 1em; 36 | line-height: 1.125em; 37 | width: auto; 38 | } 39 | 40 | .alert-js-footer { 41 | padding: 10px; 42 | text-align: right; 43 | border-top: 1px solid #dedede; 44 | } 45 | 46 | .alert-js-footer button { 47 | margin: 5px; 48 | min-width: 15%; 49 | } 50 | 51 | .alert-js-btn { 52 | cursor: pointer; 53 | display: inline-block; 54 | border: none; 55 | font-size: 0.875em; 56 | font-weight: 400; 57 | margin-bottom: 0; 58 | padding: 6px 12px; 59 | text-align: center; 60 | vertical-align: middle; 61 | border-radius: 4px; 62 | } 63 | 64 | .alert-js-btn-ok:hover { 65 | background: rgba(68, 127, 68, 1); 66 | -webkit-transition: all 1s ease 0.3s; 67 | -moz-transition: all 1s ease 0.3s; 68 | -o-transition: all 1s ease 0.3s; 69 | transition: all 1s ease 0.3s; 70 | } 71 | 72 | .alert-js-btn-cancel:hover { 73 | background: rgba(185, 62, 62, 1); 74 | -webkit-transition: all 1s ease 0.3s; 75 | -moz-transition: all 1s ease 0.3s; 76 | -o-transition: all 1s ease 0.3s; 77 | transition: all 1s ease 0.3s; 78 | } 79 | 80 | 81 | .alert-js-btn-ok { 82 | background-color: #5cb85c; 83 | border: 1px solid #4cae4c; 84 | color: #fff; 85 | } 86 | 87 | .alert-js-btn-cancel { 88 | background-color: #d9534f; 89 | border: 1px solid #d43f3a; 90 | color: #fff; 91 | } 92 | 93 | .alert-js-action { 94 | padding: 10px; 95 | text-align: right; 96 | border-top: 1px solid #eee; 97 | } 98 | 99 | .alert-js-action a { 100 | margin: 5px; 101 | } 102 | 103 | .alert-js-overlay { 104 | background: #000; 105 | position: fixed; 106 | top: 0; 107 | left: 0; 108 | width: 100%; 109 | height: 100%; 110 | -moz-opacity: 0.4; /* Netscape */ 111 | -khtml-opacity: 0.4; /* Safari 1.x */ 112 | opacity: 0.4; 113 | z-index: 9998; 114 | } 115 | 116 | .alert-js-input { 117 | background-color: #fff; 118 | border: 1px solid #ccc; 119 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset; 120 | color: #555; 121 | display: block; 122 | padding: 6px 12px; 123 | width: 100%; 124 | margin-top: 5px; 125 | 126 | -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ 127 | -moz-box-sizing: border-box; /* Firefox, other Gecko */ 128 | box-sizing: border-box; /* IE8+ */ 129 | 130 | -webkit-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 131 | -moz-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 132 | -o-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 133 | transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 134 | } 135 | -------------------------------------------------------------------------------- /theme/alert.default.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Default alert.js theme v0.0.0-beta, 10.01.2014 3 | * @author Ankit Pokhrel (http://ankitpokhrel.com.np, @ankitpokhrel) 4 | */ 5 | 6 | .alert-js { 7 | font-family: 'Arial', 'helvetica', 'sans-serif'; 8 | background-color: #fff; 9 | -webkit-box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 10 | -moz-box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 11 | box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 12 | } 13 | 14 | .alert-js-header { 15 | border-bottom: 1px solid transparent; 16 | border-top-left-radius: 3px; 17 | border-top-right-radius: 3px; 18 | border-radius: 0; 19 | padding: 4px 14px; 20 | background-color: #337ab7; 21 | border-color: #337ab7; 22 | color: #fff; 23 | } 24 | 25 | .alert-js-header h1 { 26 | font-size: 1.3em; 27 | line-height: 1.5em; 28 | color: #fff; 29 | } 30 | 31 | .alert-js-header h2 { 32 | font-size: 0.9em; 33 | line-height: 1em; 34 | padding-top: 2px; 35 | } 36 | 37 | .alert-js-body { 38 | padding: 15px 15px 5px; 39 | font-size: 1em; 40 | line-height: 1.125em; 41 | width: auto; 42 | } 43 | 44 | .alert-js-footer { 45 | padding: 10px; 46 | text-align: right; 47 | } 48 | 49 | .alert-js-footer button { 50 | margin: 5px; 51 | min-width: 15%; 52 | } 53 | 54 | .alert-js-btn { 55 | cursor: pointer; 56 | display: inline-block; 57 | border: none; 58 | font-size: 0.875em; 59 | font-weight: 400; 60 | margin-bottom: 0; 61 | padding: 6px 12px; 62 | text-align: center; 63 | vertical-align: middle; 64 | white-space: nowrap; 65 | } 66 | 67 | .alert-js-btn-ok:hover { 68 | background: rgba(45, 143, 3, 1); 69 | -webkit-transition: all 1s ease 0.3s; 70 | -moz-transition: all 1s ease 0.3s; 71 | -o-transition: all 1s ease 0.3s; 72 | transition: all 1s ease 0.3s; 73 | } 74 | 75 | .alert-js-btn-cancel:hover { 76 | background: rgba(245, 0, 0, 1); 77 | -webkit-transition: all 1s ease 0.3s; 78 | -moz-transition: all 1s ease 0.3s; 79 | -o-transition: all 1s ease 0.3s; 80 | transition: all 1s ease 0.3s; 81 | } 82 | 83 | 84 | .alert-js-btn-ok { 85 | background-color: #149414; 86 | color: #fff; 87 | } 88 | 89 | .alert-js-btn-cancel { 90 | background-color: #FF1414; 91 | border-color: #d43f3a; 92 | color: #fff; 93 | } 94 | 95 | .alert-js-action { 96 | padding: 10px; 97 | text-align: right; 98 | border-top: 1px solid #eee; 99 | } 100 | 101 | .alert-js-action a { 102 | margin: 5px; 103 | } 104 | 105 | .alert-js-overlay { 106 | background: #000; 107 | position: fixed; 108 | top: 0; 109 | left: 0; 110 | width: 100%; 111 | height: 100%; 112 | -moz-opacity: 0.4; /* Netscape */ 113 | -khtml-opacity: 0.4; /* Safari 1.x */ 114 | opacity: 0.4; 115 | z-index: 9998; 116 | } 117 | 118 | .alert-js-input { 119 | background-color: #fff; 120 | border: 1px solid #ccc; 121 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset; 122 | color: #555; 123 | display: block; 124 | padding: 6px 12px; 125 | width: 100%; 126 | margin-top: 5px; 127 | 128 | -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ 129 | -moz-box-sizing: border-box; /* Firefox, other Gecko */ 130 | box-sizing: border-box; /* IE8+ */ 131 | 132 | -webkit-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 133 | -moz-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 134 | -o-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 135 | transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 136 | } 137 | -------------------------------------------------------------------------------- /dist/src/alert.default.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Default alert.js theme v0.0.0-beta, 10.01.2014 3 | * @author Ankit Pokhrel (http://ankitpokhrel.com.np, @ankitpokhrel) 4 | */ 5 | 6 | .alert-js { 7 | font-family: 'Arial', 'helvetica', 'sans-serif'; 8 | background-color: #fff; 9 | -webkit-box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 10 | -moz-box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 11 | box-shadow: 1px 0 37px -3px rgba(0,0,0,0.75); 12 | } 13 | 14 | .alert-js-header { 15 | border-bottom: 1px solid transparent; 16 | border-top-left-radius: 3px; 17 | border-top-right-radius: 3px; 18 | border-radius: 0; 19 | padding: 4px 14px; 20 | background-color: #337ab7; 21 | border-color: #337ab7; 22 | color: #fff; 23 | } 24 | 25 | .alert-js-header h1 { 26 | font-size: 1.3em; 27 | line-height: 1.5em; 28 | color: #fff; 29 | } 30 | 31 | .alert-js-header h2 { 32 | font-size: 0.9em; 33 | line-height: 1em; 34 | padding-top: 2px; 35 | } 36 | 37 | .alert-js-body { 38 | padding: 15px 15px 5px; 39 | font-size: 1em; 40 | line-height: 1.125em; 41 | width: auto; 42 | } 43 | 44 | .alert-js-footer { 45 | padding: 10px; 46 | text-align: right; 47 | } 48 | 49 | .alert-js-footer button { 50 | margin: 5px; 51 | min-width: 15%; 52 | } 53 | 54 | .alert-js-btn { 55 | cursor: pointer; 56 | display: inline-block; 57 | border: none; 58 | font-size: 0.875em; 59 | font-weight: 400; 60 | margin-bottom: 0; 61 | padding: 6px 12px; 62 | text-align: center; 63 | vertical-align: middle; 64 | white-space: nowrap; 65 | } 66 | 67 | .alert-js-btn-ok:hover { 68 | background: rgba(45, 143, 3, 1); 69 | -webkit-transition: all 1s ease 0.3s; 70 | -moz-transition: all 1s ease 0.3s; 71 | -o-transition: all 1s ease 0.3s; 72 | transition: all 1s ease 0.3s; 73 | } 74 | 75 | .alert-js-btn-cancel:hover { 76 | background: rgba(245, 0, 0, 1); 77 | -webkit-transition: all 1s ease 0.3s; 78 | -moz-transition: all 1s ease 0.3s; 79 | -o-transition: all 1s ease 0.3s; 80 | transition: all 1s ease 0.3s; 81 | } 82 | 83 | 84 | .alert-js-btn-ok { 85 | background-color: #149414; 86 | color: #fff; 87 | } 88 | 89 | .alert-js-btn-cancel { 90 | background-color: #FF1414; 91 | border-color: #d43f3a; 92 | color: #fff; 93 | } 94 | 95 | .alert-js-action { 96 | padding: 10px; 97 | text-align: right; 98 | border-top: 1px solid #eee; 99 | } 100 | 101 | .alert-js-action a { 102 | margin: 5px; 103 | } 104 | 105 | .alert-js-overlay { 106 | background: #000; 107 | position: fixed; 108 | top: 0; 109 | left: 0; 110 | width: 100%; 111 | height: 100%; 112 | -moz-opacity: 0.4; /* Netscape */ 113 | -khtml-opacity: 0.4; /* Safari 1.x */ 114 | opacity: 0.4; 115 | z-index: 9998; 116 | } 117 | 118 | .alert-js-input { 119 | background-color: #fff; 120 | border: 1px solid #ccc; 121 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset; 122 | color: #555; 123 | display: block; 124 | padding: 6px 12px; 125 | width: 100%; 126 | margin-top: 5px; 127 | 128 | -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ 129 | -moz-box-sizing: border-box; /* Firefox, other Gecko */ 130 | box-sizing: border-box; /* IE8+ */ 131 | 132 | -webkit-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 133 | -moz-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 134 | -o-transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 135 | transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; 136 | } 137 | -------------------------------------------------------------------------------- /dist/alert.core.min.css: -------------------------------------------------------------------------------- 1 | .alert-js,.alert-js-animation-bottom,.alert-js-animation-left,.alert-js-animation-right,.alert-js-animation-top{position:fixed;left:50%;top:50%}.alert-js{min-width:30%;max-width:60%;-webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%);transform:translate(-50%,-50%);display:table;z-index:9999}html:lang(en)>body .alert-js{display:block}.alert-js-ease-in{-webkit-transition:all 500ms cubic-bezier(.42,0,1,1);-moz-transition:all 500ms cubic-bezier(.42,0,1,1);-o-transition:all 500ms cubic-bezier(.42,0,1,1);transition:all 500ms cubic-bezier(.42,0,1,1)}.alert-js-ease-in-bounce{-webkit-transition:all 500ms cubic-bezier(.92,0,.27,1);-webkit-transition:all 500ms cubic-bezier(.92,-.005,.27,1.65);-moz-transition:all 500ms cubic-bezier(.92,-.005,.27,1.65);-o-transition:all 500ms cubic-bezier(.92,-.005,.27,1.65);transition:all 500ms cubic-bezier(.92,-.005,.27,1.65)}.alert-js-animation-top{-webkit-transform:translate(-50%,-500%);-moz-transform:translate(-50%,-500%);-ms-transform:translate(-50%,-500%);-o-transform:translate(-50%,-500%);transform:translate(-50%,-500%)}.alert-js-animation-bottom{-webkit-transform:translate(-50%,500%);-moz-transform:translate(-50%,500%);-ms-transform:translate(-50%,500%);-o-transform:translate(-50%,500%);transform:translate(-50%,500%)}.alert-js-animation-left{-webkit-transform:translate(-300%,-50%);-moz-transform:translate(-300%,-50%);-ms-transform:translate(-300%,-50%);-o-transform:translate(-300%,-50%);transform:translate(-300%,-50%)}.alert-js-animation-right{-webkit-transform:translate(300%,-50%);-moz-transform:translate(300%,-50%);-ms-transform:translate(300%,-50%);-o-transform:translate(300%,-50%);transform:translate(300%,-50%)}.alert-js-animation-middle{-webkit-transition:opacity .4s ease-in-out;-moz-transition:opacity .4s ease-in-out;-o-transition:opacity .4s ease-in-out;transition:opacity .4s ease-in-out;opacity:0}@-webkit-keyframes shake{0%{-webkit-transform:translate(-50%,-50%)rotate(-5deg)}10%{-webkit-transform:translate(-50%,-50%)rotate(-10deg)}20%{-webkit-transform:translate(-50%,-50%)rotate(-15deg)}30%{-webkit-transform:translate(-50%,-50%)rotate(-20deg)}40%{-webkit-transform:translate(-50%,-50%)rotate(-25deg)}50%{-webkit-transform:translate(-50%,-50%)rotate(5deg)}60%{-webkit-transform:translate(-50%,-50%)rotate(10deg)}70%{-webkit-transform:translate(-50%,-50%)rotate(15deg)}80%{-webkit-transform:translate(-50%,-50%)rotate(20deg)}90%{-webkit-transform:translate(-50%,-50%)rotate(25deg)}100%{-webkit-transform:translate(-50%,-50%)rotate(0)}}@-moz-keyframes shake{0%{-moz-transform:translate(-50%,-50%)rotate(-5deg)}10%{-moz-transform:translate(-50%,-50%)rotate(-10deg)}20%{-moz-transform:translate(-50%,-50%)rotate(-15deg)}30%{-moz-transform:translate(-50%,-50%)rotate(-20deg)}40%{-moz-transform:translate(-50%,-50%)rotate(-25deg)}50%{-moz-transform:translate(-50%,-50%)rotate(5deg)}60%{-moz-transform:translate(-50%,-50%)rotate(10deg)}70%{-moz-transform:translate(-50%,-50%)rotate(15deg)}80%{-moz-transform:translate(-50%,-50%)rotate(20deg)}90%{-moz-transform:translate(-50%,-50%)rotate(25deg)}100%{-moz-transform:translate(-50%,-50%)rotate(0)}}@keyframes shake{0%{transform:translate(-50%,-50%)rotate(-5deg)}10%{transform:translate(-50%,-50%)rotate(-10deg)}20%{transform:translate(-50%,-50%)rotate(-15deg)}30%{transform:translate(-50%,-50%)rotate(-20deg)}40%{transform:translate(-50%,-50%)rotate(-25deg)}50%{transform:translate(-50%,-50%)rotate(5deg)}60%{transform:translate(-50%,-50%)rotate(10deg)}70%{transform:translate(-50%,-50%)rotate(15deg)}80%{transform:translate(-50%,-50%)rotate(20deg)}90%{transform:translate(-50%,-50%)rotate(25deg)}100%{transform:translate(-50%,-50%)rotate(0)}}.alert-js-shake{-webkit-animation:shake .5s linear 1;-moz-animation:shake .5s linear 1;-o-animation:shake .5s linear 1;animation:shake .5s linear 1}@media only screen and (max-width :769px){.alert-js-body,.alert-js-btn{font-size:.9em;line-height:1.2em}.alert-js{max-width:80%}}@media only screen and (max-width :450px){.alert-js-header h1{font-size:.8em;line-height:1em}.alert-js-header h2{font-size:.7em;line-height:.9em}.alert-js-body,.alert-js-btn{font-size:.8em;line-height:1.2em}.alert-js{max-width:90%;width:90%}} -------------------------------------------------------------------------------- /theme/alert.core.css: -------------------------------------------------------------------------------- 1 | /** 2 | * alert.js core css file v0.0.0-beta, 10.01.2014 3 | * @author Ankit Pokhrel (http://ankitpokhrel.com.np, @ankitpokhrel) 4 | */ 5 | 6 | .alert-js { 7 | position: fixed; 8 | left: 50%; 9 | top: 50%; 10 | min-width: 30%; 11 | max-width: 60%; 12 | 13 | -webkit-transform: translate(-50%, -50%); 14 | -moz-transform: translate(-50%, -50%); 15 | -ms-transform: translate(-50%, -50%); 16 | -o-transform: translate(-50%, -50%); 17 | transform: translate(-50%, -50%); 18 | 19 | display: table; 20 | z-index: 9999; 21 | } 22 | 23 | /* safari hack */ 24 | html:lang(en)>body .alert-js { 25 | display: block; 26 | } 27 | 28 | /* animation block */ 29 | .alert-js-ease-in { 30 | -webkit-transition: all 500ms cubic-bezier(0.420, 0.000, 1.000, 1.000); 31 | -moz-transition: all 500ms cubic-bezier(0.420, 0.000, 1.000, 1.000); 32 | -o-transition: all 500ms cubic-bezier(0.420, 0.000, 1.000, 1.000); 33 | transition: all 500ms cubic-bezier(0.420, 0.000, 1.000, 1.000); /* ease-in */ 34 | } 35 | 36 | .alert-js-ease-in-bounce { 37 | -webkit-transition: all 500ms cubic-bezier(0.920, 0, 0.270, 1); /* older webkit */ 38 | -webkit-transition: all 500ms cubic-bezier(0.920, -0.005, 0.270, 1.650); 39 | -moz-transition: all 500ms cubic-bezier(0.920, -0.005, 0.270, 1.650); 40 | -o-transition: all 500ms cubic-bezier(0.920, -0.005, 0.270, 1.650); 41 | transition: all 500ms cubic-bezier(0.920, -0.005, 0.270, 1.650); /* ease-in-bounce */ 42 | } 43 | 44 | .alert-js-animation-top, 45 | .alert-js-animation-bottom, 46 | .alert-js-animation-left, 47 | .alert-js-animation-right { 48 | position: fixed; 49 | left: 50%; 50 | top: 50%; 51 | } 52 | 53 | .alert-js-animation-top { 54 | -webkit-transform: translate(-50%, -500%); 55 | -moz-transform: translate(-50%, -500%); 56 | -ms-transform: translate(-50%, -500%); 57 | -o-transform: translate(-50%, -500%); 58 | transform: translate(-50%, -500%); 59 | } 60 | 61 | .alert-js-animation-bottom { 62 | -webkit-transform: translate(-50%, 500%); 63 | -moz-transform: translate(-50%, 500%); 64 | -ms-transform: translate(-50%, 500%); 65 | -o-transform: translate(-50%, 500%); 66 | transform: translate(-50%, 500%); 67 | } 68 | 69 | .alert-js-animation-left { 70 | -webkit-transform: translate(-300%, -50%); 71 | -moz-transform: translate(-300%, -50%); 72 | -ms-transform: translate(-300%, -50%); 73 | -o-transform: translate(-300%, -50%); 74 | transform: translate(-300%, -50%); 75 | } 76 | 77 | .alert-js-animation-right { 78 | -webkit-transform: translate(300%, -50%); 79 | -moz-transform: translate(300%, -50%); 80 | -ms-transform: translate(300%, -50%); 81 | -o-transform: translate(300%, -50%); 82 | transform: translate(300%, -50%); 83 | } 84 | 85 | .alert-js-animation-middle { 86 | -webkit-transition: opacity 0.4s ease-in-out; 87 | -moz-transition: opacity 0.4s ease-in-out; 88 | -o-transition: opacity 0.4s ease-in-out; 89 | transition: opacity 0.4s ease-in-out; 90 | 91 | opacity: 0; 92 | } 93 | 94 | @-webkit-keyframes shake { 95 | 0% { -webkit-transform: translate(-50%, -50%) rotate(-5deg); } 96 | 10% { -webkit-transform: translate(-50%, -50%) rotate(-10deg); } 97 | 20% { -webkit-transform: translate(-50%, -50%) rotate(-15deg); } 98 | 30% { -webkit-transform: translate(-50%, -50%) rotate(-20deg); } 99 | 40% { -webkit-transform: translate(-50%, -50%) rotate(-25deg); } 100 | 50% { -webkit-transform: translate(-50%, -50%) rotate(5deg); } 101 | 60% { -webkit-transform: translate(-50%, -50%) rotate(10deg); } 102 | 70% { -webkit-transform: translate(-50%, -50%) rotate(15deg); } 103 | 80% { -webkit-transform: translate(-50%, -50%) rotate(20deg); } 104 | 90% { -webkit-transform: translate(-50%, -50%) rotate(25deg); } 105 | 100% { -webkit-transform: translate(-50%, -50%) rotate(0deg); } 106 | } 107 | 108 | @-moz-keyframes shake { 109 | 0% { -moz-transform: translate(-50%, -50%) rotate(-5deg); } 110 | 10% { -moz-transform: translate(-50%, -50%) rotate(-10deg); } 111 | 20% { -moz-transform: translate(-50%, -50%) rotate(-15deg); } 112 | 30% { -moz-transform: translate(-50%, -50%) rotate(-20deg); } 113 | 40% { -moz-transform: translate(-50%, -50%) rotate(-25deg); } 114 | 50% { -moz-transform: translate(-50%, -50%) rotate(5deg); } 115 | 60% { -moz-transform: translate(-50%, -50%) rotate(10deg); } 116 | 70% { -moz-transform: translate(-50%, -50%) rotate(15deg); } 117 | 80% { -moz-transform: translate(-50%, -50%) rotate(20deg); } 118 | 90% { -moz-transform: translate(-50%, -50%) rotate(25deg); } 119 | 100% { -moz-transform: translate(-50%, -50%) rotate(0deg); } 120 | } 121 | 122 | @keyframes shake { 123 | 0% { transform: translate(-50%, -50%) rotate(-5deg); } 124 | 10% { transform: translate(-50%, -50%) rotate(-10deg); } 125 | 20% { transform: translate(-50%, -50%) rotate(-15deg); } 126 | 30% { transform: translate(-50%, -50%) rotate(-20deg); } 127 | 40% { transform: translate(-50%, -50%) rotate(-25deg); } 128 | 50% { transform: translate(-50%, -50%) rotate(5deg); } 129 | 60% { transform: translate(-50%, -50%) rotate(10deg); } 130 | 70% { transform: translate(-50%, -50%) rotate(15deg); } 131 | 80% { transform: translate(-50%, -50%) rotate(20deg); } 132 | 90% { transform: translate(-50%, -50%) rotate(25deg); } 133 | 100% { transform: translate(-50%, -50%) rotate(0deg); } 134 | } 135 | 136 | .alert-js-shake { 137 | -webkit-animation: shake 0.5s linear 1; 138 | -moz-animation: shake 0.5s linear 1; 139 | -o-animation: shake 0.5s linear 1; 140 | animation: shake 0.5s linear 1; 141 | 142 | } 143 | 144 | @media only screen 145 | and (max-width : 769px) { 146 | .alert-js-body, .alert-js-btn { 147 | font-size: 0.9em; 148 | line-height: 1.2em; 149 | } 150 | 151 | .alert-js { 152 | max-width: 80%; 153 | } 154 | } 155 | 156 | @media only screen 157 | and (max-width : 450px) { 158 | .alert-js-header h1 { 159 | font-size: 0.8em; 160 | line-height: 1em; 161 | } 162 | 163 | .alert-js-header h2 { 164 | font-size: 0.7em; 165 | line-height: 0.9em; 166 | } 167 | 168 | .alert-js-body, .alert-js-btn { 169 | font-size: 0.8em; 170 | line-height: 1.2em; 171 | } 172 | 173 | .alert-js { 174 | max-width: 90%; 175 | width: 90%; 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /dist/src/alert.core.css: -------------------------------------------------------------------------------- 1 | /** 2 | * alert.js core css file v0.0.0-beta, 10.01.2014 3 | * @author Ankit Pokhrel (http://ankitpokhrel.com.np, @ankitpokhrel) 4 | */ 5 | 6 | .alert-js { 7 | position: fixed; 8 | left: 50%; 9 | top: 50%; 10 | min-width: 30%; 11 | max-width: 60%; 12 | 13 | -webkit-transform: translate(-50%, -50%); 14 | -moz-transform: translate(-50%, -50%); 15 | -ms-transform: translate(-50%, -50%); 16 | -o-transform: translate(-50%, -50%); 17 | transform: translate(-50%, -50%); 18 | 19 | display: table; 20 | z-index: 9999; 21 | } 22 | 23 | /* safari hack */ 24 | html:lang(en)>body .alert-js { 25 | display: block; 26 | } 27 | 28 | /* animation block */ 29 | .alert-js-ease-in { 30 | -webkit-transition: all 500ms cubic-bezier(0.420, 0.000, 1.000, 1.000); 31 | -moz-transition: all 500ms cubic-bezier(0.420, 0.000, 1.000, 1.000); 32 | -o-transition: all 500ms cubic-bezier(0.420, 0.000, 1.000, 1.000); 33 | transition: all 500ms cubic-bezier(0.420, 0.000, 1.000, 1.000); /* ease-in */ 34 | } 35 | 36 | .alert-js-ease-in-bounce { 37 | -webkit-transition: all 500ms cubic-bezier(0.920, 0, 0.270, 1); /* older webkit */ 38 | -webkit-transition: all 500ms cubic-bezier(0.920, -0.005, 0.270, 1.650); 39 | -moz-transition: all 500ms cubic-bezier(0.920, -0.005, 0.270, 1.650); 40 | -o-transition: all 500ms cubic-bezier(0.920, -0.005, 0.270, 1.650); 41 | transition: all 500ms cubic-bezier(0.920, -0.005, 0.270, 1.650); /* ease-in-bounce */ 42 | } 43 | 44 | .alert-js-animation-top, 45 | .alert-js-animation-bottom, 46 | .alert-js-animation-left, 47 | .alert-js-animation-right { 48 | position: fixed; 49 | left: 50%; 50 | top: 50%; 51 | } 52 | 53 | .alert-js-animation-top { 54 | -webkit-transform: translate(-50%, -500%); 55 | -moz-transform: translate(-50%, -500%); 56 | -ms-transform: translate(-50%, -500%); 57 | -o-transform: translate(-50%, -500%); 58 | transform: translate(-50%, -500%); 59 | } 60 | 61 | .alert-js-animation-bottom { 62 | -webkit-transform: translate(-50%, 500%); 63 | -moz-transform: translate(-50%, 500%); 64 | -ms-transform: translate(-50%, 500%); 65 | -o-transform: translate(-50%, 500%); 66 | transform: translate(-50%, 500%); 67 | } 68 | 69 | .alert-js-animation-left { 70 | -webkit-transform: translate(-300%, -50%); 71 | -moz-transform: translate(-300%, -50%); 72 | -ms-transform: translate(-300%, -50%); 73 | -o-transform: translate(-300%, -50%); 74 | transform: translate(-300%, -50%); 75 | } 76 | 77 | .alert-js-animation-right { 78 | -webkit-transform: translate(300%, -50%); 79 | -moz-transform: translate(300%, -50%); 80 | -ms-transform: translate(300%, -50%); 81 | -o-transform: translate(300%, -50%); 82 | transform: translate(300%, -50%); 83 | } 84 | 85 | .alert-js-animation-middle { 86 | -webkit-transition: opacity 0.4s ease-in-out; 87 | -moz-transition: opacity 0.4s ease-in-out; 88 | -o-transition: opacity 0.4s ease-in-out; 89 | transition: opacity 0.4s ease-in-out; 90 | 91 | opacity: 0; 92 | } 93 | 94 | @-webkit-keyframes shake { 95 | 0% { -webkit-transform: translate(-50%, -50%) rotate(-5deg); } 96 | 10% { -webkit-transform: translate(-50%, -50%) rotate(-10deg); } 97 | 20% { -webkit-transform: translate(-50%, -50%) rotate(-15deg); } 98 | 30% { -webkit-transform: translate(-50%, -50%) rotate(-20deg); } 99 | 40% { -webkit-transform: translate(-50%, -50%) rotate(-25deg); } 100 | 50% { -webkit-transform: translate(-50%, -50%) rotate(5deg); } 101 | 60% { -webkit-transform: translate(-50%, -50%) rotate(10deg); } 102 | 70% { -webkit-transform: translate(-50%, -50%) rotate(15deg); } 103 | 80% { -webkit-transform: translate(-50%, -50%) rotate(20deg); } 104 | 90% { -webkit-transform: translate(-50%, -50%) rotate(25deg); } 105 | 100% { -webkit-transform: translate(-50%, -50%) rotate(0deg); } 106 | } 107 | 108 | @-moz-keyframes shake { 109 | 0% { -moz-transform: translate(-50%, -50%) rotate(-5deg); } 110 | 10% { -moz-transform: translate(-50%, -50%) rotate(-10deg); } 111 | 20% { -moz-transform: translate(-50%, -50%) rotate(-15deg); } 112 | 30% { -moz-transform: translate(-50%, -50%) rotate(-20deg); } 113 | 40% { -moz-transform: translate(-50%, -50%) rotate(-25deg); } 114 | 50% { -moz-transform: translate(-50%, -50%) rotate(5deg); } 115 | 60% { -moz-transform: translate(-50%, -50%) rotate(10deg); } 116 | 70% { -moz-transform: translate(-50%, -50%) rotate(15deg); } 117 | 80% { -moz-transform: translate(-50%, -50%) rotate(20deg); } 118 | 90% { -moz-transform: translate(-50%, -50%) rotate(25deg); } 119 | 100% { -moz-transform: translate(-50%, -50%) rotate(0deg); } 120 | } 121 | 122 | @keyframes shake { 123 | 0% { transform: translate(-50%, -50%) rotate(-5deg); } 124 | 10% { transform: translate(-50%, -50%) rotate(-10deg); } 125 | 20% { transform: translate(-50%, -50%) rotate(-15deg); } 126 | 30% { transform: translate(-50%, -50%) rotate(-20deg); } 127 | 40% { transform: translate(-50%, -50%) rotate(-25deg); } 128 | 50% { transform: translate(-50%, -50%) rotate(5deg); } 129 | 60% { transform: translate(-50%, -50%) rotate(10deg); } 130 | 70% { transform: translate(-50%, -50%) rotate(15deg); } 131 | 80% { transform: translate(-50%, -50%) rotate(20deg); } 132 | 90% { transform: translate(-50%, -50%) rotate(25deg); } 133 | 100% { transform: translate(-50%, -50%) rotate(0deg); } 134 | } 135 | 136 | .alert-js-shake { 137 | -webkit-animation: shake 0.5s linear 1; 138 | -moz-animation: shake 0.5s linear 1; 139 | -o-animation: shake 0.5s linear 1; 140 | animation: shake 0.5s linear 1; 141 | 142 | } 143 | 144 | @media only screen 145 | and (max-width : 769px) { 146 | .alert-js-body, .alert-js-btn { 147 | font-size: 0.9em; 148 | line-height: 1.2em; 149 | } 150 | 151 | .alert-js { 152 | max-width: 80%; 153 | } 154 | } 155 | 156 | @media only screen 157 | and (max-width : 450px) { 158 | .alert-js-header h1 { 159 | font-size: 0.8em; 160 | line-height: 1em; 161 | } 162 | 163 | .alert-js-header h2 { 164 | font-size: 0.7em; 165 | line-height: 0.9em; 166 | } 167 | 168 | .alert-js-body, .alert-js-btn { 169 | font-size: 0.8em; 170 | line-height: 1.2em; 171 | } 172 | 173 | .alert-js { 174 | max-width: 90%; 175 | width: 90%; 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /dist/alert.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * alert.js v0.0.0-beta, 22.03.2015 3 | * Beautifully crafted responsive javascript alert boxes. 4 | * By Ankit Pokhrel (http://ankitpokhrel.com.np/, @ankitpokhrel) 5 | * Licenced under MIT 6 | */ 7 | !function(a,b){"use strict";var c=function(){var a={type:"alert",title:"",subtitle:"",text:"",buttons:{OK:{label:"Ok",attrs:{id:"btn_ok","class":"alert-js-btn alert-js-btn-ok"}},CANCEL:{label:"Cancel",attrs:{id:"btn_cancel","class":"alert-js-btn alert-js-btn-cancel"}}},overlay:!0,header:!0,effect:"ease-in",wait:0,from:"middle",x:"50%",y:"80%",hideOnClick:!1,showTime:2e3,success:null,cancelled:null,complete:null},h=function(b){var c=this,d=c.artisan,e=JSON.parse(JSON.stringify(a)),f=g.map(e,b);return d.setOptions(f),"alert"===d.options.type&&(d.options.buttons.CANCEL=!1),k(d,b),d.create("layer"),d.options.header!==!1&&(d.create("header"),d.create("title"),""!==d.options.subtitle&&d.create("subtitle")),d.create("body"),"prompt"===d.options.type&&d.create("input"),d.create("overlay"),b.buttons!==!1&&(d.create("footer"),d.create("okButton"),d.options.buttons.CANCEL!==!1&&d.create("cancelButton")),i(d),d},i=function(a){b.body.appendChild(a.layer),j(a.layer,a.header),a.layer.appendChild(a.body),j(a.header,a.title),j(a.header,a.subtitle),j(a.body,a.input),j(a.layer,a.footer),null!==a.footer&&null!==a.okButton&&(a.footer.appendChild(a.okButton),q(a.okButton,"click",function(){l(!0)})),null!==a.footer&&null!==a.cancelButton&&(a.footer.appendChild(a.cancelButton),q(a.cancelButton,"click",function(){l(!1)})),"flash"===a.options.type&&q(a.layer,"click",function(){l(!0)}),null===a.input||/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)||a.input.focus()},j=function(a,b){null!==b&&a.appendChild(b)},k=function(a,b){"flash"===a.options.type&&(a.options.overlay=!1,a.options.header=!1,a.options.from="middle",b.buttons=!1)},l=function(a){var b=s().ref,c=b.artisan.options;b.hide(),a&&null!==c.success?m(b):a||null===c.cancelled||c.cancelled.apply(this),null!==c.complete&&n(b,a)},m=function(a){var b=a.artisan.options;"prompt"===b.type?b.success.call(this,a.artisan.input.value):"#"===b.text.charAt(0)?b.success.call(this,o(a.artisan.layer)):b.success.apply(this)},n=function(a,b){var c=a.artisan.options;"prompt"===c.type?c.complete.call(this,b,a.artisan.input.value):"#"===c.text.charAt(0)?c.complete.call(this,b,o(a.artisan.layer)):c.complete.call(this,b)},o=function(a){var b,c,d=a.querySelectorAll("input, textarea, select"),e={};if(d.length>0)for(b=0;b0&&(a=a.artisan,setTimeout(function(){b.body.insertBefore(a.overlay,a.layer),a.options.overlay||(a.overlay.style.visibility="hidden"),g.addClass(a.layer,"alert-js-"+a.options.effect,function(){setTimeout(function(){g.removeClass(a.layer,"alert-js-animation-"+a.options.from)},10)}),"flash"===a.options.type&&(a.layer.style.left=a.options.x,a.layer.style.top=a.options.y,setTimeout(function(){s().ref.hide()},a.options.showTime))},a.options.wait))},q=function(a,b,c){"function"==typeof a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,c)},r=function(){if(!e){var a=s(),b=h.call(a.ref,a.opt);return p(a.ref),b}return!1},s=function(){return d.length<=0?{}:d.slice(0,1).pop()};return{artisan:new f,show:function(a){var b=this;return"undefined"!=typeof a.type&&g.inArray(a.type,g.validTypes())||(a.type="alert"),d.push({ref:new c,opt:a}),this.artisan=r(),b},hide:function(){var a=this,c=a.artisan.layer,e=a.artisan.overlay,f=a.artisan.options;g.addClass(c,"alert-js-animation-"+f.from,function(){d.length>0&&setTimeout(function(){b.body.removeChild(e),b.body.removeChild(c),d.splice(0,1),g.release(),d.length>0&&r()},400)})}}},d=[],e=!1,f=function(){var a=function(){var a=b.createElement("section");return a.setAttribute("id","alertJS"),a.className="alert-js alert-js-animation-"+this.options.from+" "+this.options.type,a},c=function(){var a=b.createElement("header");return a.className="alert-js-header",a},d=function(){var a=b.createElement("h1");return a.innerHTML=this.options.title,a},e=function(){var a=b.createElement("h2");return a.innerHTML=this.options.subtitle,a},f=function(){var a=b.createElement("div");return a.className="alert-js-body",a.innerHTML="#"===this.options.text.charAt(0)?g.pick(this.options.text.slice(1),!0).innerHTML:this.options.text,a},h=function(){var a=b.createElement("input");return a.setAttribute("type","text"),a.className="alert-js-input",a},i=function(){var a=b.createElement("footer");return a.className="alert-js-footer",a},j=function(a){var c=b.createElement("button"),d=this.options.buttons[a];if("object"==typeof d&&g.keyExist("attrs",d))for(var e in d.attrs)"function"!=typeof d.attrs[e]&&d.attrs.hasOwnProperty(e)&&c.setAttribute(e,d.attrs[e]);return c.innerHTML="object"==typeof d&&g.keyExist("label",d)?d.label:"string"==typeof d?d:d.toString(),c},k=function(){return j.call(this,"OK")},l=function(){return j.call(this,"CANCEL")},m=function(){var a=b.createElement("div");return a.className="alert-js-overlay",a};return{layer:null,header:null,title:null,subtitle:null,body:null,input:null,footer:null,buttons:null,okButton:null,cancelButton:null,overlay:null,options:null,customHTML:!1,create:function(b){switch(b){case"layer":return this.layer=a.call(this);case"header":return this.header=c.call(this);case"title":return this.title=d.call(this);case"subtitle":return this.subtitle=e.call(this);case"body":return this.body=f.call(this);case"input":return this.input=h.call(this);case"footer":return this.footer=i.call(this);case"okButton":return this.okButton=k.call(this);case"cancelButton":return this.cancelButton=l.call(this);case"overlay":return this.overlay=m.call(this)}return!1},setOptions:function(a){this.options=a}}},g={pick:function(a,c){return"undefined"==typeof c?b.querySelectorAll(a):b.getElementById(a)},wait:function(){e=!0},release:function(){e=!1},validTypes:function(){return["alert","confirm","prompt","flash"]},inArray:function(a,b){return"object"!=typeof b?!1:b.indexOf(a)>=0},keyExist:function(a,b){return null!==b&&"object"==typeof b?a in b:!1},map:function(a,b){if("undefined"==typeof b)return a;for(var c in b)a.hasOwnProperty(c)&&(g.inArray(typeof b[c],["string","number","function","boolean"])?a[c]="class"===c?a[c]+" "+b[c]:b[c]:"object"!=typeof b[c]||g.inArray(c,["success","cancelled","complete"])||g.map(a[c],b[c]));return a},addClass:function(a,b,c){return a.className+="string"!=typeof b?" "+b.join(" "):" "+b,"function"==typeof c&&c.apply(null),a},removeClass:function(a,b){return a.className=(" "+a.className+" ").replace(" "+b+" "," "),a}};"undefined"==typeof alertjs&&(a.alertjs=new c)}(window,document); -------------------------------------------------------------------------------- /tests/AlertSpec.js: -------------------------------------------------------------------------------- 1 | //Tests for alert.js 2 | describe('Alert library', function() { 3 | var a = alertjs.show({ 4 | type: 'prompt', 5 | title: 'Test heading', 6 | subtitle: 'Test subheading', 7 | text: 'Test message', 8 | buttons: { 9 | OK: { 10 | label: 'Continue', 11 | attrs: { 12 | id: 'continue_btn' 13 | } 14 | }, 15 | CANCEL: { 16 | label: 'Back', 17 | attrs: { 18 | 'class': 'btn btn-back' 19 | } 20 | } 21 | }, 22 | wait: 100, 23 | effect: 'ease-in-bounce', 24 | from: 'left', 25 | success: function( val ) { 26 | return true; 27 | } 28 | }); 29 | 30 | //=======================================// 31 | // Options // 32 | //=======================================// 33 | 34 | describe('Options', function() { 35 | it('should have type', function() { 36 | expect(a.artisan.options.type).toEqual('prompt'); 37 | }); 38 | 39 | it('should have title', function() { 40 | expect(a.artisan.options.title).toEqual('Test heading'); 41 | }); 42 | 43 | it('should have subtitle', function() { 44 | expect(a.artisan.options.subtitle).toEqual('Test subheading'); 45 | }); 46 | 47 | it('should have text', function() { 48 | expect(a.artisan.options.text).toEqual('Test message'); 49 | }); 50 | 51 | it('should wait 100ms', function() { 52 | expect(a.artisan.options.wait).toEqual(100); 53 | }); 54 | 55 | it('should have bounce effect', function() { 56 | expect(a.artisan.options.effect).toEqual('ease-in-bounce'); 57 | }); 58 | 59 | it('should slide from left', function() { 60 | expect(a.artisan.options.from).toEqual('left'); 61 | }); 62 | 63 | it('should have OK button', function() { 64 | var ok = { 65 | label: 'Continue', 66 | attrs: { 67 | id: 'continue_btn', 68 | class: 'alert-js-btn alert-js-btn-ok' 69 | } 70 | }; 71 | expect( JSON.stringify(a.artisan.options.buttons.OK) ).toEqual( JSON.stringify(ok) ); 72 | }); 73 | 74 | it('should have Cancel button', function() { 75 | var cancel = { 76 | label: 'Back', 77 | attrs: { 78 | id: 'btn_cancel', 79 | class: 'alert-js-btn alert-js-btn-cancel btn btn-back' 80 | } 81 | }; 82 | expect( JSON.stringify(a.artisan.options.buttons.CANCEL) ).toEqual( JSON.stringify(cancel) ); 83 | }); 84 | 85 | it('should have success callback', function() { 86 | expect(typeof a.artisan.options.success).toBe('function'); 87 | }); 88 | 89 | it('should have cancelled callback', function() { 90 | expect(a.artisan.options.cancelled).toBeNull(); 91 | }); 92 | 93 | it('should have complete callback', function() { 94 | expect(a.artisan.options.complete).toBeNull(); 95 | }); 96 | }); 97 | 98 | //=======================================// 99 | // Creator // 100 | //=======================================// 101 | describe('OK Button', function() { 102 | it('create htmlnode for okButton', function() { 103 | expect(a.artisan.okButton).not.toBeNull(); 104 | 105 | var btn = ''; 106 | expect(a.artisan.okButton.outerHTML).toBe(btn); 107 | }); 108 | }); 109 | 110 | describe('CANCEL Button', function() { 111 | it('create htmlnode for cancelButton', function() { 112 | expect(a.artisan.cancelButton).not.toBeNull(); 113 | 114 | var btn = ''; 115 | expect(a.artisan.cancelButton.outerHTML).toBe(btn); 116 | }); 117 | }); 118 | 119 | describe('Footer', function() { 120 | it('create htmlnode for footer element', function() { 121 | expect(a.artisan.footer).not.toBeNull(); 122 | 123 | var footer = '
' + 124 | '' + 125 | '' + 126 | '
'; 127 | expect(a.artisan.footer.outerHTML).toBe(footer); 128 | }); 129 | }); 130 | 131 | describe('Heading', function() { 132 | it('create htmlnode for heading element', function() { 133 | expect(a.artisan.title).not.toBeNull(); 134 | 135 | var title = '

Test heading

'; 136 | expect(a.artisan.title.outerHTML).toBe(title); 137 | }); 138 | }); 139 | 140 | describe('Sub Heading', function() { 141 | it('create htmlnode for subheading element', function() { 142 | expect(a.artisan.subtitle).not.toBeNull(); 143 | 144 | var subtitle = '

Test subheading

'; 145 | expect(a.artisan.subtitle.outerHTML).toBe(subtitle); 146 | }); 147 | }); 148 | 149 | describe('Header', function() { 150 | it('create htmlnode for header element', function() { 151 | expect(a.artisan.header).not.toBeNull(); 152 | 153 | var header = '
' + 154 | '

Test heading

' + 155 | '

Test subheading

' + 156 | '
'; 157 | expect(a.artisan.header.outerHTML).toBe(header); 158 | }); 159 | }); 160 | 161 | describe('Body', function() { 162 | it('create htmlnode for main body element', function() { 163 | expect(a.artisan.body).not.toBeNull(); 164 | 165 | var body = '
' + 166 | 'Test message' + 167 | '' + 168 | '
'; 169 | expect(a.artisan.body.outerHTML).toBe(body); 170 | }); 171 | }); 172 | 173 | describe('Input', function() { 174 | it('create htmlnode for input element', function() { 175 | expect(a.artisan.input).not.toBeNull(); 176 | 177 | var inp = ''; 178 | expect(a.artisan.input.outerHTML).toBe(inp); 179 | }); 180 | }); 181 | 182 | describe('Outer Layer', function() { 183 | it('check entire generated htmlnode', function() { 184 | expect(a.artisan.layer).not.toBeNull(); 185 | 186 | var html = '
' + 187 | '
' + 188 | '

Test heading

' + 189 | '

Test subheading

' + 190 | '
' + 191 | '
' + 192 | 'Test message' + 193 | '' + 194 | '
' + 195 | '
' + 196 | '' + 197 | '' + 198 | '
' + 199 | '
'; 200 | expect(a.artisan.layer.outerHTML).toBe(html); 201 | }); 202 | }); 203 | 204 | describe('Overlay', function() { 205 | it('create htmlnode for overlay element', function() { 206 | expect(a.artisan.overlay).not.toBeNull(); 207 | 208 | var overlay = '
'; 209 | expect(a.artisan.overlay.outerHTML).toBe(overlay); 210 | }); 211 | }); 212 | 213 | }); 214 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Travis CI Build](https://travis-ci.org/ankitpokhrel/alert.js.svg?branch=master)](https://travis-ci.org/ankitpokhrel/alert.js) 2 | [![devDependency Status](https://david-dm.org/ankitpokhrel/alert.js/dev-status.svg)](https://david-dm.org/ankitpokhrel/alert.js#info=devDependencies) 3 | [![Codacy Badge](https://www.codacy.com/project/badge/de58b013d63b4756a87d417d323ba9da)](https://www.codacy.com/public/ankitpokhrel/alert.js) 4 | [![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](http://gruntjs.com/) 5 | 6 | # Alert.js 7 | Beautifully crafted responsive javascript alert boxes. 8 | 9 | ![Alert.js](http://ankitpokhrel.com.np/alert.js/img/alertjs.gif) 10 | > This project is written in plain javascript and has no dependencies. 11 | 12 | ## Version 13 | Current version is v0.0.0 (~6.5KB minified) 14 | 15 | ## Browser Support 16 | All modern browsers and Internet Explorer 9+ 17 | 18 | ## Installation 19 | ``` 20 | bower install alert.js 21 | ``` 22 | 23 | ## Getting Started 24 | 1. Include script 25 | ``` 26 | 27 | ``` 28 | 29 | 2. Include style 30 | ``` 31 | /* core css */ 32 | 33 | 34 | /* theme: default or lite */ 35 | 36 | ``` 37 | 38 | ## Basic Usage 39 | **Alert box** 40 | ``` 41 | alertjs.show({ 42 | title: 'Error!', 43 | text: 'You must fill all fields to continue', 44 | from: 'top', //drop from top, 45 | effect: 'ease-in-bounce', 46 | wait: 500, 47 | success: function() { 48 | //user clicked OK button 49 | }, 50 | cancelled: function() { 51 | //user clicked cancel button 52 | }, 53 | complete: function( val ) { 54 | //this callback is available everytime. 55 | //val determines what user clicked. 56 | } 57 | }); 58 | ``` 59 | ![Alert](http://ankitpokhrel.com.np/alert.js/img/alertt.gif) 60 | 61 | **Confirm dialog** 62 | ``` 63 | alertjs.show({ 64 | type: 'confirm', 65 | title: 'Confirm', 66 | text: 'Are you sure you want to perform this action?', 67 | from: 'left', //slide from left 68 | complete: function( val ) { 69 | if( val ) { 70 | //clicked ok 71 | } else { 72 | //clicked cancel 73 | } 74 | } 75 | }); 76 | ``` 77 | ![Confirm](http://ankitpokhrel.com.np/alert.js/img/confirm.gif) 78 | 79 | **Prompt dialog** 80 | ``` 81 | alertjs.show({ 82 | type: 'prompt', 83 | title: 'Please enter your name to continue', 84 | text: 'Enter your name here:', 85 | from: 'right', //slide from left 86 | success: function( val ) { 87 | //user clicked OK button 88 | //input box value will be available here 89 | var value = 'Your name is ' + val; 90 | if( val === '' ) { 91 | value = 'You didn\'t type anything!'; 92 | } 93 | alertjs.show({ 94 | title: 'Alert.js', 95 | from: 'top', 96 | effect: 'ease-in-bounce', 97 | text: value 98 | }); 99 | }, 100 | cancelled: function() { 101 | //user clicked cancel button 102 | }, 103 | complete: function( status, val ) { 104 | console.log(status, val); 105 | } 106 | }); 107 | ``` 108 | ![Prompt](http://ankitpokhrel.com.np/alert.js/img/prompt.gif) 109 | 110 | **Using custom HTML for message** 111 | HTML can be in any format but it should be wrapped with an ID 112 | ``` 113 | 119 | ``` 120 | 121 | Call alert box as follow 122 | ``` 123 | alertjs.show({ 124 | title: 'Error!', 125 | text: '#myCustomDialog', //must be an id 126 | from: 'top' 127 | }); 128 | ``` 129 | 130 | **Custom form** 131 | You can also use custom form in alert box. Data from evey input fields will be available in name value pairs in success and complete callback. If the name attribute is not provided, numeric index is used. 132 | 133 | ``` 134 | //For example in success callback 135 | //you can do something like this 136 | success: function( val ) { 137 | var str = ''; 138 | for( var prop in val ) { 139 | str += " " + val[prop] + "
"; 140 | } 141 | 142 | alertjs.show({ 143 | title: 'You entered following values:', 144 | text: str 145 | }); 146 | } 147 | ``` 148 | ![Custom Form](http://ankitpokhrel.com.np/alert.js/img/form.gif) 149 | 150 | **Using custom attribute for buttons** 151 | You can provide label and attributes for button as shown below. 152 | ``` 153 | alertjs.show({ 154 | type: 'confirm', 155 | title: 'Delete Permanently', 156 | text: 'Are you sure you want to delete the file permanently?', 157 | buttons: { 158 | OK: { 159 | label: 'Continue', 160 | attrs: { 161 | 'class': 'continue btn', 162 | id: 'continueBtn' 163 | } 164 | }, 165 | CANCEL: { 166 | label: 'Go back', 167 | attrs: { 168 | 'class': 'btn btn-back' 169 | } 170 | } 171 | }, 172 | wait: 500 173 | }); 174 | ``` 175 | 176 | **Display alert 10sec after site loads** 177 | ``` 178 | //Demo: Like the one displayed at the very beginning of this page 179 | window.onload = function() { 180 | setTimeout(function() { 181 | alertjs.show({ 182 | title: 'Welcome to our site!', 183 | text: 'Thank you for visiting our site.', 184 | buttons: { 185 | OK: { 186 | label: 'Continue' 187 | } 188 | }, 189 | effect: 'shake', 190 | overlay: false, 191 | }); 192 | }, 10000); 193 | } 194 | ``` 195 | 196 | ## Available Options 197 | Option | Description | Default 198 | ------------|------------------------------------------------------------------------------------------------------------------|-------------- 199 | type | Alert box type: `alert`, `confirm` or `prompt` | alert 200 | title | Main heading | 201 | subtitle | Displayed below main heading | 202 | text | Message to display in body section. `string` or `#elementId`. You can provide id of an element to get html data. | 203 | buttons | Lists button settings. Can be `false`. | 204 | OK | Used with buttons and provides settings for `OK` button. | `{label: 'Ok', attrs: {id: 'btn_ok', 'class': 'alert-js-btn alert-js-btn-ok'}}` 205 | CANCEL | Used with buttons and provides settings for `CANCEL` button. | `{label: 'Ok', attrs: {id: 'btn_ok', 'class': 'alert-js-btn alert-js-btn-ok'}}` 206 | overlay | Show/hide overlay. `true` or `false`. | true 207 | header | Show/hide header element. `true` or `false`. | true 208 | effect | Animation effect to show. `ease-in`, `ease-in-bounce` or `shake` | ease-in 209 | from | Determines where to start effect from. `top`, `left`, `right`, `bottom`, `middle`. | top 210 | wait | Delay in milliseconds. Wait for certain time before showing alert. | 0 211 | 212 | ## Callbacks 213 | | Callback | Description 214 | |--------------|------------------------------------------------------------ 215 | | success | Available when user clicks OK button. Gets input value when type is prompt. 216 | | cancelled | Available when user clicks CANCEL button. Gets input value when type is prompt. 217 | | complete | This callback is available both when user clicks OK and CANCEL button. Gets a value to determine what user clicked. Also gets input value when type is prompt. 218 | 219 | ## Platforms we are testing on 220 | 221 | * Ubuntu 14.04 LTS 222 | - Mozilla Firefox 34+, Chrome & Chromium 38+, Opera 25+ 223 | 224 | * Windows 7 & 8 225 | - Internet Explorer 9+, Firefox 34+, Chrome 38+, Opera 25+, Safari 5.1.7 226 | 227 | * iPhone 4 & 5 228 | * Android (Samsung & Nexus) 229 | 230 | ### Setting up entire project locally 231 | 1. Clone the repo 232 | ``` 233 | git clone git@github.com:ankitpokhrel/alert.js.git 234 | ``` 235 | 236 | 2. Install dev dependencies 237 | ``` 238 | npm install 239 | npm update 240 | ``` 241 | 242 | 3. Make changes. jshint and uglify using grunt. 243 | ``` 244 | grunt 245 | ``` 246 | 247 | 4. Run jasmine tests using karma 248 | ``` 249 | karma start 250 | ``` 251 | 252 | ## Contribution 253 | Feel free to fork, try and report any bug found. Pull requests, issues, and plugin recommendations are more than welcome! 254 | 255 | ## Known bugs 256 | 1. Animation is not smooth sometimes. 257 | 258 | ## License 259 | 260 | alert.js is licensed under MIT http://www.opensource.org/licenses/MIT 261 | 262 | ## Copyright 263 | 264 | Copyright ©, Ankit Pokhrel (http://ankitpokhrel.com.np, @ankitpokhrel) 265 | [![Analytics](https://ga-beacon.appspot.com/UA-59482306-1/ankitpokhrel/readme?pixel)](https://github.com/igrigorik/ga-beacon) 266 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Alert.js - Beautifully crafted responsive javascript alert boxes. 7 | 8 | 9 | 10 | 11 | 12 | 30 | 31 | 32 |
33 | 44 | 45 |
46 |
47 | Lite theme 48 | Default theme 49 |
50 | Alert 51 | Confirm 52 | Prompt 53 | Bottom 54 | Register 55 | No Header 56 |
57 |

58 | New popup in 59 |

60 | 10 61 |

Sec

62 |
63 | 77 | 92 |
93 | 94 | 304 | 305 | 306 | -------------------------------------------------------------------------------- /lib/alert.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * alert.js v0.0.0, 03.22.2015 3 | * Beautifully crafted javascript alert boxes. 4 | * By Ankit Pokhrel (http://ankitpokhrel.com.np, @ankitpokhrel) 5 | * Licensed under MIT 6 | */ 7 | ;(function (window, document, undefined) { 8 | 'use strict'; 9 | 10 | /** 11 | * Main alert class. 12 | * @constructor 13 | */ 14 | var Alert = function() { 15 | 16 | /** @private */ 17 | var 18 | 19 | //default options 20 | defaults = { 21 | type: 'alert', 22 | title: '', 23 | subtitle: '', 24 | text: '', 25 | buttons: { 26 | OK: { 27 | label: 'Ok', 28 | attrs: { 29 | id: 'btn_ok', 30 | 'class': 'alert-js-btn alert-js-btn-ok' 31 | } 32 | }, 33 | CANCEL: { 34 | label: 'Cancel', 35 | attrs: { 36 | id: 'btn_cancel', 37 | 'class': 'alert-js-btn alert-js-btn-cancel' 38 | } 39 | } 40 | }, 41 | overlay: true, 42 | header: true, 43 | effect: 'ease-in', 44 | wait: 0, 45 | from: 'middle', 46 | x: '50%', 47 | y: '80%', 48 | hideOnClick: false, 49 | showTime: 2000, 50 | success: null, 51 | cancelled: null, 52 | complete: null 53 | }, 54 | 55 | /* 56 | Create and assemble different component of alert boxes 57 | @param {Object} options user provided settings 58 | @return {Object} this object 59 | */ 60 | make = function( options ) { 61 | var me = this, 62 | a = me.artisan, 63 | s = ( JSON.parse( JSON.stringify(defaults) ) ), //quick clone 64 | opt = _.map(s, options); 65 | 66 | //set mapped options 67 | a.setOptions(opt); 68 | 69 | //we don't need cancel button for alert box 70 | if( a.options.type === 'alert' ) { 71 | a.options.buttons.CANCEL = false; 72 | } 73 | 74 | flashSettings(a, options); 75 | 76 | //create elements 77 | a.create('layer'); 78 | 79 | if( a.options.header !== false ) { 80 | a.create('header'); 81 | a.create('title'); 82 | 83 | if( a.options.subtitle !== '' ) { 84 | a.create('subtitle'); 85 | } 86 | } 87 | 88 | a.create('body'); 89 | 90 | if( a.options.type === 'prompt' ) { 91 | a.create('input'); 92 | } 93 | 94 | a.create('overlay'); 95 | 96 | //we might want to check user provided options here 97 | //not the mapped one as the mapper will add default 98 | //values for buttons 99 | if( options.buttons !== false ) { 100 | a.create('footer'); 101 | a.create('okButton'); 102 | 103 | if( a.options.buttons.CANCEL !== false ) { 104 | a.create('cancelButton'); 105 | } 106 | } 107 | 108 | assemble(a); 109 | return a; //return creator 110 | }, 111 | 112 | /* Assemble elements */ 113 | assemble = function( a ) { 114 | document.body.appendChild(a.layer); 115 | //a.layer.appendChild(a.header); 116 | put(a.layer, a.header); 117 | a.layer.appendChild(a.body); 118 | put(a.header, a.title); 119 | put(a.header, a.subtitle); 120 | put(a.body, a.input); 121 | put(a.layer, a.footer); 122 | 123 | //append buttons if any 124 | if( a.footer !== null && a.okButton !== null ) { 125 | a.footer.appendChild(a.okButton); 126 | 127 | //attach listener 128 | listen(a.okButton, 'click', function() { 129 | addEvent(true); 130 | }); 131 | } 132 | 133 | if( a.footer !== null && a.cancelButton !== null ) { 134 | a.footer.appendChild(a.cancelButton); 135 | 136 | //attach listener 137 | listen(a.cancelButton, 'click', function() { 138 | addEvent(false); 139 | }); 140 | } 141 | 142 | if( a.options.type === 'flash' ) { 143 | listen(a.layer, 'click', function() { 144 | addEvent(true); 145 | }); 146 | } 147 | 148 | if( a.input !== null && !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) { 149 | a.input.focus(); 150 | } 151 | }, 152 | 153 | /* Append element to DOM if it exists */ 154 | put = function( elm, prop ) { 155 | if( prop !== null ) { 156 | elm.appendChild(prop); 157 | } 158 | }, 159 | 160 | //general settings for flash alert type 161 | flashSettings = function( a, options ) { 162 | if( a.options.type === 'flash' ) { 163 | a.options.overlay = false; 164 | a.options.header = false; 165 | a.options.from = 'middle'; 166 | options.buttons = false; 167 | } 168 | }, 169 | 170 | //attach different events 171 | addEvent = function( status ) { 172 | var a = fn().ref, 173 | o = a.artisan.options; 174 | 175 | a.hide(); 176 | 177 | if( status && o.success !== null ) { 178 | successCb(a); 179 | } else if( !status && o.cancelled !== null ) { 180 | o.cancelled.apply(this); 181 | } 182 | 183 | if( o.complete !== null ) { 184 | completeCb(a, status); 185 | } 186 | }, 187 | 188 | successCb = function(a) { 189 | var o = a.artisan.options; 190 | if(o.type === 'prompt') { 191 | o.success.call(this, a.artisan.input.value); 192 | } else if( o.text.charAt(0) === '#' ) { 193 | o.success.call(this, getCustomData(a.artisan.layer)); 194 | } else { 195 | o.success.apply(this); 196 | } 197 | }, 198 | 199 | completeCb = function(a, status) { 200 | var o = a.artisan.options; 201 | if( o.type === 'prompt' ) { 202 | o.complete.call(this, status, a.artisan.input.value); 203 | } else if( o.text.charAt(0) === '#' ) { 204 | o.complete.call(this, status, getCustomData(a.artisan.layer)); 205 | } else { 206 | o.complete.call(this, status); 207 | } 208 | }, 209 | 210 | //fetch data from user defined inputs 211 | getCustomData = function( wrapper ) { 212 | var inp = wrapper.querySelectorAll('input, textarea, select'), 213 | data = {}, i, name; 214 | 215 | if( inp.length > 0 ) { 216 | for( i = 0; i < inp.length; i++ ) { 217 | name = inp[i].getAttribute('name'); 218 | if( name !== null ) { 219 | data[name] = inp[i].value; 220 | } else { 221 | data[i] = inp[i].value; 222 | } 223 | } 224 | } 225 | 226 | return data; 227 | }, 228 | 229 | /* Animate and show alert box */ 230 | animate = function( a ) { 231 | _.wait(); 232 | if( Object.keys(a).length > 0 ){ 233 | a = a.artisan; 234 | 235 | setTimeout(function() { 236 | 237 | //add overlay 238 | document.body.insertBefore(a.overlay, a.layer); 239 | if( !a.options.overlay ) { 240 | a.overlay.style.visibility = 'hidden'; 241 | } 242 | 243 | //start animation by switching classes 244 | _.addClass(a.layer, 'alert-js-' + a.options.effect, function() { 245 | //wait sometime for smooth animation 246 | setTimeout(function() { 247 | _.removeClass(a.layer, 'alert-js-animation-' + a.options.from); 248 | }, 10); 249 | }); 250 | 251 | if( a.options.type === 'flash' ) { 252 | a.layer.style.left = a.options.x; 253 | a.layer.style.top = a.options.y; 254 | setTimeout(function() { 255 | fn().ref.hide(); 256 | }, a.options.showTime); 257 | } 258 | 259 | }, a.options.wait); 260 | } 261 | }, 262 | 263 | /* 264 | Binds event listener to an element 265 | @param {Object} el Element to bind event to 266 | @param {Event} evt Event to bind 267 | @param {Function} cb Callback 268 | */ 269 | listen = function( el, evt, cb ) { 270 | 271 | if( typeof el.addEventListener === 'function' ) { 272 | el.addEventListener(evt, cb, false); 273 | } else if( el.attachEvent ) { 274 | el.attachEvent("on" + evt, cb); 275 | } 276 | 277 | }, 278 | 279 | //fire animation, if any 280 | fire = function() { 281 | if( !_lock ) { 282 | var o = fn(), 283 | t = make.call(o.ref, o.opt); 284 | 285 | animate(o.ref); 286 | return t; 287 | } 288 | 289 | return false; 290 | }, 291 | 292 | /* 293 | provide access of public methods to 294 | private functions via current object 295 | */ 296 | fn = function() { 297 | if( _pool.length <= 0 ) { 298 | return {}; 299 | } 300 | 301 | return _pool.slice(0, 1).pop(); 302 | }; 303 | 304 | return { 305 | /** @public */ 306 | artisan: new Creator(), 307 | 308 | /** 309 | * Show different type of alerts 310 | * @param {Object} options User defined options 311 | * @return {Object} Alert object 312 | */ 313 | show: function( options ) { 314 | var self = this; 315 | 316 | if( typeof options.type === 'undefined' || !_.inArray(options.type, _.validTypes()) ) { 317 | options.type = 'alert'; //default type 318 | } 319 | 320 | //push a local copy of Alert to queue 321 | _pool.push({ref: new Alert(), opt: options}); 322 | 323 | this.artisan = fire(); 324 | return self; 325 | }, 326 | 327 | /* Hides alert box */ 328 | hide: function() { 329 | var me = this, 330 | elm = me.artisan.layer, 331 | overlay = me.artisan.overlay, 332 | opt = me.artisan.options; 333 | 334 | _.addClass(elm, 'alert-js-animation-' + opt.from, function() { 335 | if( _pool.length > 0 ) { 336 | setTimeout(function() { 337 | document.body.removeChild(overlay); 338 | document.body.removeChild(elm); 339 | _pool.splice(0, 1); 340 | _.release(); 341 | if( _pool.length > 0 ) { 342 | fire(); 343 | } 344 | }, 400); 345 | } 346 | 347 | }); 348 | } 349 | 350 | }; 351 | }; 352 | 353 | var _pool = [], //container 354 | _lock = false; //mutex 355 | 356 | /** 357 | * Creator class 358 | * Creates all html elements required for the app 359 | * @constructor 360 | */ 361 | var Creator = function() { 362 | /** @private */ 363 | var 364 | 365 | //Creates outer element that wraps alert dialog. 366 | createOuterLayer = function() { 367 | var layer = document.createElement('section'); 368 | layer.setAttribute('id', 'alertJS'); 369 | layer.className = 'alert-js alert-js-animation-' + this.options.from + ' ' + this.options.type; 370 | 371 | return layer; 372 | }, 373 | 374 | //Creates header element. 375 | createHeader = function() { 376 | var header = document.createElement('header'); 377 | header.className = 'alert-js-header'; 378 | 379 | return header; 380 | }, 381 | 382 | //Creates title element. 383 | createTitle = function() { 384 | var h1 = document.createElement('h1'); 385 | h1.innerHTML = this.options.title; 386 | 387 | return h1; 388 | }, 389 | 390 | //Creates sub header element. 391 | createSubtitle = function() { 392 | var h2 = document.createElement('h2'); 393 | h2.innerHTML = this.options.subtitle; 394 | 395 | return h2; 396 | }, 397 | 398 | //Creates body. 399 | createBody = function() { 400 | var body = document.createElement('div'); 401 | body.className = 'alert-js-body'; 402 | if( this.options.text.charAt(0) === '#' ) { 403 | body.innerHTML = _.pick(this.options.text.slice(1), true).innerHTML; 404 | } else { 405 | body.innerHTML = this.options.text; 406 | } 407 | 408 | return body; 409 | }, 410 | 411 | //Creates input field for prompt 412 | createInput = function() { 413 | var input = document.createElement('input'); 414 | input.setAttribute('type', 'text'); 415 | input.className = 'alert-js-input'; 416 | 417 | return input; 418 | }, 419 | 420 | //Creates footer element. 421 | createFooter = function() { 422 | var footer = document.createElement('footer'); 423 | footer.className = 'alert-js-footer'; 424 | 425 | return footer; 426 | }, 427 | 428 | //Creates OK and CANCEL button element. 429 | createButton = function( type ) { 430 | var btn = document.createElement('button'), 431 | scope = this.options.buttons[type]; 432 | 433 | //set attributes 434 | if( typeof scope === 'object' && _.keyExist('attrs', scope) ) { 435 | for( var attr in scope.attrs ) { 436 | if( typeof scope.attrs[attr] !== 'function' && scope.attrs.hasOwnProperty(attr) ) { 437 | btn.setAttribute(attr, scope.attrs[attr]); 438 | } 439 | } 440 | } 441 | 442 | //set button text 443 | if( typeof scope === 'object' && _.keyExist('label', scope) ) { 444 | btn.innerHTML = scope.label; 445 | } else if( typeof scope === 'string' ) { 446 | btn.innerHTML = scope; 447 | } else { 448 | btn.innerHTML = scope.toString(); 449 | } 450 | 451 | return btn; 452 | }, 453 | 454 | //Creates OK button. 455 | createOKbutton = function() { 456 | return createButton.call(this, 'OK'); 457 | }, 458 | 459 | //Creates CANCEL button. 460 | createCancelButton = function() { 461 | return createButton.call(this, 'CANCEL'); 462 | }, 463 | 464 | //Creates overlay element. 465 | createOverlay = function() { 466 | var overlay = document.createElement('div'); 467 | overlay.className = 'alert-js-overlay'; 468 | 469 | return overlay; 470 | }; 471 | 472 | 473 | return { 474 | /** @public */ 475 | layer: null, 476 | header: null, 477 | title: null, 478 | subtitle: null, 479 | body: null, 480 | input: null, 481 | footer: null, 482 | buttons: null, 483 | okButton: null, 484 | cancelButton: null, 485 | overlay: null, 486 | options: null, 487 | customHTML: false, 488 | 489 | /** 490 | * Builder 491 | * @param {string} type Determines what to build and builds 492 | * it by calling appropriate builder. 493 | * @return {Object | boolean} 494 | */ 495 | create: function( type ) { 496 | switch(type) { 497 | case 'layer': 498 | return (this.layer = createOuterLayer.call(this)); 499 | 500 | case 'header': 501 | return (this.header = createHeader.call(this)); 502 | 503 | case 'title': 504 | return (this.title = createTitle.call(this)); 505 | 506 | case 'subtitle': 507 | return (this.subtitle = createSubtitle.call(this)); 508 | 509 | case 'body': 510 | return (this.body = createBody.call(this)); 511 | 512 | case 'input': 513 | return (this.input = createInput.call(this)); 514 | 515 | case 'footer': 516 | return (this.footer = createFooter.call(this)); 517 | 518 | case 'okButton': 519 | return (this.okButton = createOKbutton.call(this)); 520 | 521 | case 'cancelButton': 522 | return (this.cancelButton = createCancelButton.call(this)); 523 | 524 | case 'overlay': 525 | return (this.overlay = createOverlay.call(this)); 526 | } 527 | 528 | return false; 529 | }, 530 | 531 | setOptions: function( opt ) { 532 | this.options = opt; 533 | } 534 | }; 535 | }; 536 | 537 | /* Helpers */ 538 | var _ = { 539 | 540 | /* Simple DOM selector */ 541 | pick: function( elm, id ) { 542 | if( typeof id === 'undefined' ) { 543 | return document.querySelectorAll(elm); 544 | } else { 545 | return document.getElementById(elm); 546 | } 547 | }, 548 | 549 | /* lock mutex */ 550 | wait: function() { 551 | _lock = true; 552 | }, 553 | 554 | /* release mutex */ 555 | release: function() { 556 | _lock = false; 557 | }, 558 | 559 | /* All valid alert boxes */ 560 | validTypes: function() { 561 | return ['alert', 'confirm', 'prompt', 'flash']; 562 | }, 563 | 564 | /* Checks if value exists in an array */ 565 | inArray: function( needle, haystack ) { 566 | if( typeof haystack !== 'object' ) { 567 | return false; 568 | } 569 | 570 | return haystack.indexOf(needle) >= 0; 571 | }, 572 | 573 | /* Checks if key exist in a single dimensional object literal */ 574 | keyExist: function( key, obj ) { 575 | if( obj !== null && typeof obj === 'object') { 576 | return (key in obj); 577 | } 578 | 579 | return false; 580 | }, 581 | 582 | /** 583 | * Maps user and default settings for application to use. 584 | * @param {Object} dSet Default settings 585 | * @param {Object} uSet User defined settings 586 | * @return {Object} Mapped/merged settings 587 | */ 588 | map: function( dSet, uSet ) { 589 | if( typeof uSet === 'undefined' ) { 590 | return dSet; 591 | } 592 | 593 | for( var prop in uSet ) { 594 | if( dSet.hasOwnProperty(prop) ) { 595 | if( _.inArray(typeof uSet[prop], ['string', 'number', 'function', 'boolean']) ) { 596 | if( prop === 'class' ) { 597 | dSet[prop] = dSet[prop] + ' ' + uSet[prop]; 598 | } else { 599 | dSet[prop] = uSet[prop]; 600 | } 601 | } else if( typeof uSet[prop] === 'object' && !_.inArray(prop, ['success', 'cancelled', 'complete']) ) { 602 | _.map(dSet[prop], uSet[prop]); 603 | } 604 | } 605 | } 606 | 607 | return dSet; 608 | }, 609 | 610 | /* Adds a class to an element */ 611 | addClass: function( elm, classes, cb ) { 612 | elm.className += (typeof classes !== 'string') ? ' ' + classes.join(' ') : ' ' + classes; 613 | 614 | if( typeof cb === 'function' ) { 615 | cb.apply(null); 616 | } 617 | 618 | return elm; 619 | }, 620 | 621 | /* Removes class from given element */ 622 | removeClass: function( elm, klass ) { 623 | elm.className = (' ' + elm.className + ' ').replace(' ' + klass + ' ', ' '); 624 | 625 | return elm; 626 | } 627 | 628 | }; 629 | 630 | //Provide access of alerts object to the global 631 | //window object if it isn't already available. 632 | if( typeof alertjs === 'undefined' ) { 633 | window.alertjs = new Alert(); 634 | } 635 | 636 | })(window, document); 637 | -------------------------------------------------------------------------------- /dist/src/alert.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * alert.js v0.0.0, 03.22.2015 3 | * Beautifully crafted javascript alert boxes. 4 | * By Ankit Pokhrel (http://ankitpokhrel.com.np, @ankitpokhrel) 5 | * Licensed under MIT 6 | */ 7 | ;(function (window, document, undefined) { 8 | 'use strict'; 9 | 10 | /** 11 | * Main alert class. 12 | * @constructor 13 | */ 14 | var Alert = function() { 15 | 16 | /** @private */ 17 | var 18 | 19 | //default options 20 | defaults = { 21 | type: 'alert', 22 | title: '', 23 | subtitle: '', 24 | text: '', 25 | buttons: { 26 | OK: { 27 | label: 'Ok', 28 | attrs: { 29 | id: 'btn_ok', 30 | 'class': 'alert-js-btn alert-js-btn-ok' 31 | } 32 | }, 33 | CANCEL: { 34 | label: 'Cancel', 35 | attrs: { 36 | id: 'btn_cancel', 37 | 'class': 'alert-js-btn alert-js-btn-cancel' 38 | } 39 | } 40 | }, 41 | overlay: true, 42 | header: true, 43 | effect: 'ease-in', 44 | wait: 0, 45 | from: 'middle', 46 | x: '50%', 47 | y: '80%', 48 | hideOnClick: false, 49 | showTime: 2000, 50 | success: null, 51 | cancelled: null, 52 | complete: null 53 | }, 54 | 55 | /* 56 | Create and assemble different component of alert boxes 57 | @param {Object} options user provided settings 58 | @return {Object} this object 59 | */ 60 | make = function( options ) { 61 | var me = this, 62 | a = me.artisan, 63 | s = ( JSON.parse( JSON.stringify(defaults) ) ), //quick clone 64 | opt = _.map(s, options); 65 | 66 | //set mapped options 67 | a.setOptions(opt); 68 | 69 | //we don't need cancel button for alert box 70 | if( a.options.type === 'alert' ) { 71 | a.options.buttons.CANCEL = false; 72 | } 73 | 74 | flashSettings(a, options); 75 | 76 | //create elements 77 | a.create('layer'); 78 | 79 | if( a.options.header !== false ) { 80 | a.create('header'); 81 | a.create('title'); 82 | 83 | if( a.options.subtitle !== '' ) { 84 | a.create('subtitle'); 85 | } 86 | } 87 | 88 | a.create('body'); 89 | 90 | if( a.options.type === 'prompt' ) { 91 | a.create('input'); 92 | } 93 | 94 | a.create('overlay'); 95 | 96 | //we might want to check user provided options here 97 | //not the mapped one as the mapper will add default 98 | //values for buttons 99 | if( options.buttons !== false ) { 100 | a.create('footer'); 101 | a.create('okButton'); 102 | 103 | if( a.options.buttons.CANCEL !== false ) { 104 | a.create('cancelButton'); 105 | } 106 | } 107 | 108 | assemble(a); 109 | return a; //return creator 110 | }, 111 | 112 | /* Assemble elements */ 113 | assemble = function( a ) { 114 | document.body.appendChild(a.layer); 115 | //a.layer.appendChild(a.header); 116 | put(a.layer, a.header); 117 | a.layer.appendChild(a.body); 118 | put(a.header, a.title); 119 | put(a.header, a.subtitle); 120 | put(a.body, a.input); 121 | put(a.layer, a.footer); 122 | 123 | //append buttons if any 124 | if( a.footer !== null && a.okButton !== null ) { 125 | a.footer.appendChild(a.okButton); 126 | 127 | //attach listener 128 | listen(a.okButton, 'click', function() { 129 | addEvent(true); 130 | }); 131 | } 132 | 133 | if( a.footer !== null && a.cancelButton !== null ) { 134 | a.footer.appendChild(a.cancelButton); 135 | 136 | //attach listener 137 | listen(a.cancelButton, 'click', function() { 138 | addEvent(false); 139 | }); 140 | } 141 | 142 | if( a.options.type === 'flash' ) { 143 | listen(a.layer, 'click', function() { 144 | addEvent(true); 145 | }); 146 | } 147 | 148 | if( a.input !== null && !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) { 149 | a.input.focus(); 150 | } 151 | }, 152 | 153 | /* Append element to DOM if it exists */ 154 | put = function( elm, prop ) { 155 | if( prop !== null ) { 156 | elm.appendChild(prop); 157 | } 158 | }, 159 | 160 | //general settings for flash alert type 161 | flashSettings = function( a, options ) { 162 | if( a.options.type === 'flash' ) { 163 | a.options.overlay = false; 164 | a.options.header = false; 165 | a.options.from = 'middle'; 166 | options.buttons = false; 167 | } 168 | }, 169 | 170 | //attach different events 171 | addEvent = function( status ) { 172 | var a = fn().ref, 173 | o = a.artisan.options; 174 | 175 | a.hide(); 176 | 177 | if( status && o.success !== null ) { 178 | successCb(a); 179 | } else if( !status && o.cancelled !== null ) { 180 | o.cancelled.apply(this); 181 | } 182 | 183 | if( o.complete !== null ) { 184 | completeCb(a, status); 185 | } 186 | }, 187 | 188 | successCb = function(a) { 189 | var o = a.artisan.options; 190 | if(o.type === 'prompt') { 191 | o.success.call(this, a.artisan.input.value); 192 | } else if( o.text.charAt(0) === '#' ) { 193 | o.success.call(this, getCustomData(a.artisan.layer)); 194 | } else { 195 | o.success.apply(this); 196 | } 197 | }, 198 | 199 | completeCb = function(a, status) { 200 | var o = a.artisan.options; 201 | if( o.type === 'prompt' ) { 202 | o.complete.call(this, status, a.artisan.input.value); 203 | } else if( o.text.charAt(0) === '#' ) { 204 | o.complete.call(this, status, getCustomData(a.artisan.layer)); 205 | } else { 206 | o.complete.call(this, status); 207 | } 208 | }, 209 | 210 | //fetch data from user defined inputs 211 | getCustomData = function( wrapper ) { 212 | var inp = wrapper.querySelectorAll('input, textarea, select'), 213 | data = {}, i, name; 214 | 215 | if( inp.length > 0 ) { 216 | for( i = 0; i < inp.length; i++ ) { 217 | name = inp[i].getAttribute('name'); 218 | if( name !== null ) { 219 | data[name] = inp[i].value; 220 | } else { 221 | data[i] = inp[i].value; 222 | } 223 | } 224 | } 225 | 226 | return data; 227 | }, 228 | 229 | /* Animate and show alert box */ 230 | animate = function( a ) { 231 | _.wait(); 232 | if( Object.keys(a).length > 0 ){ 233 | a = a.artisan; 234 | 235 | setTimeout(function() { 236 | 237 | //add overlay 238 | document.body.insertBefore(a.overlay, a.layer); 239 | if( !a.options.overlay ) { 240 | a.overlay.style.visibility = 'hidden'; 241 | } 242 | 243 | //start animation by switching classes 244 | _.addClass(a.layer, 'alert-js-' + a.options.effect, function() { 245 | //wait sometime for smooth animation 246 | setTimeout(function() { 247 | _.removeClass(a.layer, 'alert-js-animation-' + a.options.from); 248 | }, 10); 249 | }); 250 | 251 | if( a.options.type === 'flash' ) { 252 | a.layer.style.left = a.options.x; 253 | a.layer.style.top = a.options.y; 254 | setTimeout(function() { 255 | fn().ref.hide(); 256 | }, a.options.showTime); 257 | } 258 | 259 | }, a.options.wait); 260 | } 261 | }, 262 | 263 | /* 264 | Binds event listener to an element 265 | @param {Object} el Element to bind event to 266 | @param {Event} evt Event to bind 267 | @param {Function} cb Callback 268 | */ 269 | listen = function( el, evt, cb ) { 270 | 271 | if( typeof el.addEventListener === 'function' ) { 272 | el.addEventListener(evt, cb, false); 273 | } else if( el.attachEvent ) { 274 | el.attachEvent("on" + evt, cb); 275 | } 276 | 277 | }, 278 | 279 | //fire animation, if any 280 | fire = function() { 281 | if( !_lock ) { 282 | var o = fn(), 283 | t = make.call(o.ref, o.opt); 284 | 285 | animate(o.ref); 286 | return t; 287 | } 288 | 289 | return false; 290 | }, 291 | 292 | /* 293 | provide access of public methods to 294 | private functions via current object 295 | */ 296 | fn = function() { 297 | if( _pool.length <= 0 ) { 298 | return {}; 299 | } 300 | 301 | return _pool.slice(0, 1).pop(); 302 | }; 303 | 304 | return { 305 | /** @public */ 306 | artisan: new Creator(), 307 | 308 | /** 309 | * Show different type of alerts 310 | * @param {Object} options User defined options 311 | * @return {Object} Alert object 312 | */ 313 | show: function( options ) { 314 | var self = this; 315 | 316 | if( typeof options.type === 'undefined' || !_.inArray(options.type, _.validTypes()) ) { 317 | options.type = 'alert'; //default type 318 | } 319 | 320 | //push a local copy of Alert to queue 321 | _pool.push({ref: new Alert(), opt: options}); 322 | 323 | this.artisan = fire(); 324 | return self; 325 | }, 326 | 327 | /* Hides alert box */ 328 | hide: function() { 329 | var me = this, 330 | elm = me.artisan.layer, 331 | overlay = me.artisan.overlay, 332 | opt = me.artisan.options; 333 | 334 | _.addClass(elm, 'alert-js-animation-' + opt.from, function() { 335 | if( _pool.length > 0 ) { 336 | setTimeout(function() { 337 | document.body.removeChild(overlay); 338 | document.body.removeChild(elm); 339 | _pool.splice(0, 1); 340 | _.release(); 341 | if( _pool.length > 0 ) { 342 | fire(); 343 | } 344 | }, 400); 345 | } 346 | 347 | }); 348 | } 349 | 350 | }; 351 | }; 352 | 353 | var _pool = [], //container 354 | _lock = false; //mutex 355 | 356 | /** 357 | * Creator class 358 | * Creates all html elements required for the app 359 | * @constructor 360 | */ 361 | var Creator = function() { 362 | /** @private */ 363 | var 364 | 365 | //Creates outer element that wraps alert dialog. 366 | createOuterLayer = function() { 367 | var layer = document.createElement('section'); 368 | layer.setAttribute('id', 'alertJS'); 369 | layer.className = 'alert-js alert-js-animation-' + this.options.from + ' ' + this.options.type; 370 | 371 | return layer; 372 | }, 373 | 374 | //Creates header element. 375 | createHeader = function() { 376 | var header = document.createElement('header'); 377 | header.className = 'alert-js-header'; 378 | 379 | return header; 380 | }, 381 | 382 | //Creates title element. 383 | createTitle = function() { 384 | var h1 = document.createElement('h1'); 385 | h1.innerHTML = this.options.title; 386 | 387 | return h1; 388 | }, 389 | 390 | //Creates sub header element. 391 | createSubtitle = function() { 392 | var h2 = document.createElement('h2'); 393 | h2.innerHTML = this.options.subtitle; 394 | 395 | return h2; 396 | }, 397 | 398 | //Creates body. 399 | createBody = function() { 400 | var body = document.createElement('div'); 401 | body.className = 'alert-js-body'; 402 | if( this.options.text.charAt(0) === '#' ) { 403 | body.innerHTML = _.pick(this.options.text.slice(1), true).innerHTML; 404 | } else { 405 | body.innerHTML = this.options.text; 406 | } 407 | 408 | return body; 409 | }, 410 | 411 | //Creates input field for prompt 412 | createInput = function() { 413 | var input = document.createElement('input'); 414 | input.setAttribute('type', 'text'); 415 | input.className = 'alert-js-input'; 416 | 417 | return input; 418 | }, 419 | 420 | //Creates footer element. 421 | createFooter = function() { 422 | var footer = document.createElement('footer'); 423 | footer.className = 'alert-js-footer'; 424 | 425 | return footer; 426 | }, 427 | 428 | //Creates OK and CANCEL button element. 429 | createButton = function( type ) { 430 | var btn = document.createElement('button'), 431 | scope = this.options.buttons[type]; 432 | 433 | //set attributes 434 | if( typeof scope === 'object' && _.keyExist('attrs', scope) ) { 435 | for( var attr in scope.attrs ) { 436 | if( typeof scope.attrs[attr] !== 'function' && scope.attrs.hasOwnProperty(attr) ) { 437 | btn.setAttribute(attr, scope.attrs[attr]); 438 | } 439 | } 440 | } 441 | 442 | //set button text 443 | if( typeof scope === 'object' && _.keyExist('label', scope) ) { 444 | btn.innerHTML = scope.label; 445 | } else if( typeof scope === 'string' ) { 446 | btn.innerHTML = scope; 447 | } else { 448 | btn.innerHTML = scope.toString(); 449 | } 450 | 451 | return btn; 452 | }, 453 | 454 | //Creates OK button. 455 | createOKbutton = function() { 456 | return createButton.call(this, 'OK'); 457 | }, 458 | 459 | //Creates CANCEL button. 460 | createCancelButton = function() { 461 | return createButton.call(this, 'CANCEL'); 462 | }, 463 | 464 | //Creates overlay element. 465 | createOverlay = function() { 466 | var overlay = document.createElement('div'); 467 | overlay.className = 'alert-js-overlay'; 468 | 469 | return overlay; 470 | }; 471 | 472 | 473 | return { 474 | /** @public */ 475 | layer: null, 476 | header: null, 477 | title: null, 478 | subtitle: null, 479 | body: null, 480 | input: null, 481 | footer: null, 482 | buttons: null, 483 | okButton: null, 484 | cancelButton: null, 485 | overlay: null, 486 | options: null, 487 | customHTML: false, 488 | 489 | /** 490 | * Builder 491 | * @param {string} type Determines what to build and builds 492 | * it by calling appropriate builder. 493 | * @return {Object | boolean} 494 | */ 495 | create: function( type ) { 496 | switch(type) { 497 | case 'layer': 498 | return (this.layer = createOuterLayer.call(this)); 499 | 500 | case 'header': 501 | return (this.header = createHeader.call(this)); 502 | 503 | case 'title': 504 | return (this.title = createTitle.call(this)); 505 | 506 | case 'subtitle': 507 | return (this.subtitle = createSubtitle.call(this)); 508 | 509 | case 'body': 510 | return (this.body = createBody.call(this)); 511 | 512 | case 'input': 513 | return (this.input = createInput.call(this)); 514 | 515 | case 'footer': 516 | return (this.footer = createFooter.call(this)); 517 | 518 | case 'okButton': 519 | return (this.okButton = createOKbutton.call(this)); 520 | 521 | case 'cancelButton': 522 | return (this.cancelButton = createCancelButton.call(this)); 523 | 524 | case 'overlay': 525 | return (this.overlay = createOverlay.call(this)); 526 | } 527 | 528 | return false; 529 | }, 530 | 531 | setOptions: function( opt ) { 532 | this.options = opt; 533 | } 534 | }; 535 | }; 536 | 537 | /* Helpers */ 538 | var _ = { 539 | 540 | /* Simple DOM selector */ 541 | pick: function( elm, id ) { 542 | if( typeof id === 'undefined' ) { 543 | return document.querySelectorAll(elm); 544 | } else { 545 | return document.getElementById(elm); 546 | } 547 | }, 548 | 549 | /* lock mutex */ 550 | wait: function() { 551 | _lock = true; 552 | }, 553 | 554 | /* release mutex */ 555 | release: function() { 556 | _lock = false; 557 | }, 558 | 559 | /* All valid alert boxes */ 560 | validTypes: function() { 561 | return ['alert', 'confirm', 'prompt', 'flash']; 562 | }, 563 | 564 | /* Checks if value exists in an array */ 565 | inArray: function( needle, haystack ) { 566 | if( typeof haystack !== 'object' ) { 567 | return false; 568 | } 569 | 570 | return haystack.indexOf(needle) >= 0; 571 | }, 572 | 573 | /* Checks if key exist in a single dimensional object literal */ 574 | keyExist: function( key, obj ) { 575 | if( obj !== null && typeof obj === 'object') { 576 | return (key in obj); 577 | } 578 | 579 | return false; 580 | }, 581 | 582 | /** 583 | * Maps user and default settings for application to use. 584 | * @param {Object} dSet Default settings 585 | * @param {Object} uSet User defined settings 586 | * @return {Object} Mapped/merged settings 587 | */ 588 | map: function( dSet, uSet ) { 589 | if( typeof uSet === 'undefined' ) { 590 | return dSet; 591 | } 592 | 593 | for( var prop in uSet ) { 594 | if( dSet.hasOwnProperty(prop) ) { 595 | if( _.inArray(typeof uSet[prop], ['string', 'number', 'function', 'boolean']) ) { 596 | if( prop === 'class' ) { 597 | dSet[prop] = dSet[prop] + ' ' + uSet[prop]; 598 | } else { 599 | dSet[prop] = uSet[prop]; 600 | } 601 | } else if( typeof uSet[prop] === 'object' && !_.inArray(prop, ['success', 'cancelled', 'complete']) ) { 602 | _.map(dSet[prop], uSet[prop]); 603 | } 604 | } 605 | } 606 | 607 | return dSet; 608 | }, 609 | 610 | /* Adds a class to an element */ 611 | addClass: function( elm, classes, cb ) { 612 | elm.className += (typeof classes !== 'string') ? ' ' + classes.join(' ') : ' ' + classes; 613 | 614 | if( typeof cb === 'function' ) { 615 | cb.apply(null); 616 | } 617 | 618 | return elm; 619 | }, 620 | 621 | /* Removes class from given element */ 622 | removeClass: function( elm, klass ) { 623 | elm.className = (' ' + elm.className + ' ').replace(' ' + klass + ' ', ' '); 624 | 625 | return elm; 626 | } 627 | 628 | }; 629 | 630 | //Provide access of alerts object to the global 631 | //window object if it isn't already available. 632 | if( typeof alertjs === 'undefined' ) { 633 | window.alertjs = new Alert(); 634 | } 635 | 636 | })(window, document); 637 | --------------------------------------------------------------------------------