├── .editorconfig ├── .gitignore ├── .prettierrc ├── LICENSE ├── README.md ├── assets └── audio │ ├── LICENCE.txt │ ├── beep1.mp3 │ ├── beep1.ogg │ ├── beep2.mp3 │ ├── beep2.ogg │ ├── beep3.mp3 │ ├── beep3.ogg │ ├── bling1.mp3 │ ├── bling1.ogg │ ├── bling2.mp3 │ ├── bling2.ogg │ ├── bling3.mp3 │ ├── bling3.ogg │ ├── bling4.mp3 │ ├── bling4.ogg │ ├── bling5.mp3 │ ├── bling5.ogg │ ├── blop.mp3 │ ├── blop.ogg │ ├── boop1.mp3 │ ├── boop1.ogg │ ├── boop2.mp3 │ ├── boop2.ogg │ ├── boop3.mp3 │ └── boop3.ogg ├── demo ├── es6 │ ├── css │ │ ├── demo.css │ │ └── normalize.css │ ├── index.html │ ├── index.js │ ├── package-lock.json │ └── package.json └── html │ ├── css │ ├── demo.css │ ├── normalize.css │ ├── playground-avatars.css │ ├── playground-inception.css │ └── playground-login.css │ ├── index.html │ └── js │ ├── demo.js │ ├── playground-avatars.js │ ├── playground-inception.js │ └── playground-login.js ├── dist ├── jBox.all.css ├── jBox.all.js ├── jBox.all.min.css ├── jBox.all.min.js ├── jBox.css ├── jBox.js ├── jBox.min.css ├── jBox.min.js ├── plugins │ ├── jBox.Confirm.css │ ├── jBox.Confirm.js │ ├── jBox.Confirm.min.css │ ├── jBox.Confirm.min.js │ ├── jBox.Image.css │ ├── jBox.Image.js │ ├── jBox.Image.min.css │ ├── jBox.Image.min.js │ ├── jBox.Notice.css │ ├── jBox.Notice.js │ ├── jBox.Notice.min.css │ └── jBox.Notice.min.js └── themes │ ├── jBox.NoticeFancy.css │ ├── jBox.NoticeFancy.min.css │ ├── jBox.TooltipBorder.css │ ├── jBox.TooltipBorder.min.css │ ├── jBox.TooltipBorderThick.css │ ├── jBox.TooltipBorderThick.min.css │ ├── jBox.TooltipDark.css │ ├── jBox.TooltipDark.min.css │ ├── jBox.TooltipError.css │ ├── jBox.TooltipError.min.css │ ├── jBox.TooltipSmall.css │ ├── jBox.TooltipSmall.min.css │ ├── jBox.TooltipSmallGray.css │ └── jBox.TooltipSmallGray.min.css ├── documentation.html ├── gulpfile.js ├── package-lock.json ├── package.json ├── src ├── js │ ├── jBox.d.ts │ ├── jBox.js │ ├── plugins │ │ ├── jBox.Confirm.js │ │ ├── jBox.Image.js │ │ └── jBox.Notice.js │ └── umd.js └── scss │ ├── jBox.scss │ ├── plugins │ ├── jBox.Confirm.scss │ ├── jBox.Image.scss │ └── jBox.Notice.scss │ └── themes │ ├── jBox.NoticeFancy.scss │ ├── jBox.TooltipBorder.scss │ ├── jBox.TooltipBorderThick.scss │ ├── jBox.TooltipDark.scss │ ├── jBox.TooltipError.scss │ ├── jBox.TooltipSmall.scss │ └── jBox.TooltipSmallGray.scss └── test └── assets.test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at http://editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # CSS and JS maps 2 | *.js.map 3 | *.css.map 4 | 5 | # npm 6 | node_modules 7 | 8 | # OS generated files 9 | .DS_Store 10 | .DS_Store? 11 | ._* 12 | .Spotlight-V100 13 | .Trashes 14 | ehthumbs.db 15 | Thumbs.db 16 | 17 | # Tool specific files 18 | # vim 19 | *~ 20 | *.swp 21 | *.swo 22 | # sublime text & textmate 23 | *.sublime-* 24 | *.stTheme.cache 25 | *.tmlanguage.cache 26 | *.tmPreferences.cache 27 | # Eclipse 28 | .settings/* 29 | # JetBrains, aka PHPStorm, IntelliJ IDEA 30 | .idea/* 31 | # NetBeans 32 | nbproject/* 33 | # Visual Studio Code 34 | .vscode 35 | # Sass preprocessor 36 | .sass-cache/ 37 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "jsxSingleQuote": true, 8 | "quoteProps": "consistent", 9 | "trailingComma": "none", 10 | "bracketSpacing": true, 11 | "jsxBracketSameLine": false, 12 | "arrowParens": "always" 13 | } 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Stephan Wagner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jBox 2 | 3 | jBox is a jQuery plugin that makes it easy to create customizable tooltips, modal windows, image galleries and more. 4 | 5 | Demo: https://stephanwagner.me/jBox 6 | 7 | Docs: https://stephanwagner.me/jBox/documentation 8 | 9 | --- 10 | 11 | ## Install 12 | 13 | ### ES6 14 | 15 | ```bash 16 | npm install --save jbox 17 | ``` 18 | 19 | ```javascript 20 | import jBox from 'jbox'; 21 | import 'jbox/dist/jBox.all.css'; 22 | ``` 23 | 24 | ### CDN 25 | 26 | ```html 27 | 28 | 29 | 30 | ``` 31 | 32 | --- 33 | 34 | ## Tooltips 35 | 36 | Create a new instance of jBox Tooltip and attach it to elements: 37 | 38 | ```javascript 39 | new jBox('Tooltip', { 40 | attach: '.tooltip' 41 | }); 42 | ``` 43 | 44 | Now elements with `class="tooltip"` will open tooltips: 45 | 46 | ```html 47 | Hover me! 48 | Hover me! 49 | ``` 50 | 51 | --- 52 | 53 | ## Modal windows 54 | 55 | You can set up modal windows the same way as tooltips. 56 | But most of times you'd want more variety, like a title or HTML content: 57 | 58 | ```javascript 59 | new jBox('Modal', { 60 | width: 300, 61 | height: 200, 62 | attach: '#myModal', 63 | title: 'My Modal Window', 64 | content: 'Hello there!' 65 | }); 66 | ``` 67 | 68 | ```html 69 |
Click me to open a modal window!
70 | ``` 71 | 72 | --- 73 | 74 | ## Confirm windows 75 | 76 | Confirm windows are modal windows which requires the user to confirm a click action on an element. 77 | Give an element the attribute data-confirm to attach it: 78 | 79 | ```javascript 80 | new jBox('Confirm', { 81 | confirmButton: 'Do it!', 82 | cancelButton: 'Nope' 83 | }); 84 | ``` 85 | 86 | ```html 87 |
Click me!
88 | Click me! 89 | ``` 90 | 91 | --- 92 | 93 | ## Notices 94 | 95 | A notice will open automatically and destroy itself after some time: 96 | 97 | ```javascript 98 | new jBox('Notice', { 99 | content: 'Hurray! A notice!' 100 | }); 101 | ``` 102 | 103 | --- 104 | 105 | ## Images 106 | 107 | To create image windows you only need following few lines: 108 | 109 | ```javascript 110 | new jBox('Image'); 111 | ``` 112 | 113 | ```html 114 | 115 | 116 | 117 | ``` 118 | 119 | --- 120 | 121 | ## Learn more 122 | 123 | These few examples are very basic. 124 | The jBox library is quite powerful and offers a vast variety of options to customize appearance and behavior. 125 | Learn more in the documentation: https://stephanwagner.me/jBox/documentation 126 | -------------------------------------------------------------------------------- /assets/audio/LICENCE.txt: -------------------------------------------------------------------------------- 1 | blop.mp3 sound file recorded by Mark DiAngelo 2 | Downloaded from http://soundbible.com/2067-Blop.html 3 | 4 | All other files created by rjsken (http://www.fiverr.com/rjsken) 5 | All files are royalty free (http://en.wikipedia.org/wiki/Royalty-free) -------------------------------------------------------------------------------- /assets/audio/beep1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/beep1.mp3 -------------------------------------------------------------------------------- /assets/audio/beep1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/beep1.ogg -------------------------------------------------------------------------------- /assets/audio/beep2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/beep2.mp3 -------------------------------------------------------------------------------- /assets/audio/beep2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/beep2.ogg -------------------------------------------------------------------------------- /assets/audio/beep3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/beep3.mp3 -------------------------------------------------------------------------------- /assets/audio/beep3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/beep3.ogg -------------------------------------------------------------------------------- /assets/audio/bling1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/bling1.mp3 -------------------------------------------------------------------------------- /assets/audio/bling1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/bling1.ogg -------------------------------------------------------------------------------- /assets/audio/bling2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/bling2.mp3 -------------------------------------------------------------------------------- /assets/audio/bling2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/bling2.ogg -------------------------------------------------------------------------------- /assets/audio/bling3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/bling3.mp3 -------------------------------------------------------------------------------- /assets/audio/bling3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/bling3.ogg -------------------------------------------------------------------------------- /assets/audio/bling4.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/bling4.mp3 -------------------------------------------------------------------------------- /assets/audio/bling4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/bling4.ogg -------------------------------------------------------------------------------- /assets/audio/bling5.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/bling5.mp3 -------------------------------------------------------------------------------- /assets/audio/bling5.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/bling5.ogg -------------------------------------------------------------------------------- /assets/audio/blop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/blop.mp3 -------------------------------------------------------------------------------- /assets/audio/blop.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/blop.ogg -------------------------------------------------------------------------------- /assets/audio/boop1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/boop1.mp3 -------------------------------------------------------------------------------- /assets/audio/boop1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/boop1.ogg -------------------------------------------------------------------------------- /assets/audio/boop2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/boop2.mp3 -------------------------------------------------------------------------------- /assets/audio/boop2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/boop2.ogg -------------------------------------------------------------------------------- /assets/audio/boop3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/boop3.mp3 -------------------------------------------------------------------------------- /assets/audio/boop3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephanWagner/jBox/f64e462da0fd9551f4a45c707411293ca905a220/assets/audio/boop3.ogg -------------------------------------------------------------------------------- /demo/es6/css/demo.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | body { 8 | position: relative; 9 | font-family: Roboto, sans-serif; 10 | font-size: 17px; 11 | line-height: 1.4; 12 | color: #222; 13 | background: #fff; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | -webkit-text-size-adjust: none; 17 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 18 | } 19 | 20 | * { 21 | outline: none; 22 | box-sizing: border-box; 23 | } 24 | 25 | p { 26 | margin: 0 0 15px; 27 | } 28 | 29 | p:last-child { 30 | margin-bottom: 0; 31 | } 32 | 33 | h2 { 34 | margin: 0; 35 | font-size: 22px; 36 | font-weight: normal; 37 | } 38 | 39 | main { 40 | padding: 20px 0; 41 | } 42 | 43 | .container { 44 | position: relative; 45 | width: calc(100% - 60px); 46 | max-width: 1000px; 47 | margin: auto; 48 | } 49 | 50 | @media (max-width: 768px) { 51 | .container { 52 | width: calc(100% - 30px); 53 | } 54 | } 55 | 56 | /* Target elements */ 57 | 58 | .targets-wrapper { 59 | margin: 0 -5px; 60 | padding: 10px 0 20px; 61 | display: flex; 62 | flex-wrap: wrap; 63 | } 64 | 65 | .target, 66 | .target-click, 67 | .target-notice { 68 | cursor: default; 69 | font-size: 14px; 70 | line-height: 50px; 71 | height: 52px; 72 | border-radius: 4px; 73 | overflow: hidden; 74 | border: 2px solid #e2e2e2; 75 | background: #fafafa; 76 | text-align: center; 77 | font-weight: 500; 78 | position: relative; 79 | text-transform: uppercase; 80 | width: calc(25% - 10px); 81 | margin: 5px; 82 | transition: border-color .2s, background-color .2s; 83 | -webkit-user-select: none; 84 | -moz-user-select: none; 85 | -ms-user-select: none; 86 | user-select: none; 87 | } 88 | 89 | .target:hover, 90 | .target-click:hover, 91 | .target-notice:hover { 92 | border-color: #bbb; 93 | background-color: #eee; 94 | } 95 | 96 | .target-click, 97 | .target-notice { 98 | cursor: pointer; 99 | } 100 | 101 | .target.active, 102 | .target-click.active, 103 | .target-notice.active { 104 | color: #49d; 105 | } 106 | 107 | @media (max-width: 768px) { 108 | 109 | .target, 110 | .target-click, 111 | .target-notice { 112 | width: calc(50% - 10px); 113 | } 114 | } 115 | 116 | .demo-img { 117 | width: calc(25% - 10px); 118 | margin: 5px; 119 | } 120 | 121 | @media (max-width: 500px) { 122 | .demo-img { 123 | width: calc(50% - 10px); 124 | } 125 | } 126 | 127 | .demo-img>img { 128 | border: 4px solid #e2e2e2; 129 | border-radius: 4px; 130 | width: 100%; 131 | height: auto; 132 | filter: grayscale(100%); 133 | transition: filter .2s, border-color .2s; 134 | } 135 | 136 | .demo-img:hover>img { 137 | filter: none; 138 | border-color: #bbb; 139 | } 140 | 141 | @media (max-width: 768px) { 142 | .demo-img>img { 143 | border-width: 2px; 144 | } 145 | } 146 | 147 | /* Header */ 148 | 149 | header { 150 | height: 50px; 151 | line-height: 50px; 152 | font-size: 17px; 153 | background: #000; 154 | color: #aaa; 155 | box-shadow: 0 0 3px rgba(0, 0, 0, .6); 156 | } 157 | 158 | header a { 159 | margin-right: 20px; 160 | color: #aaa; 161 | text-decoration: none; 162 | transition: color .2s; 163 | } 164 | 165 | header a:last-child, 166 | header a:nth-child(2) { 167 | margin-right: 0; 168 | } 169 | 170 | header a.active, 171 | header a:hover { 172 | color: #fff; 173 | text-decoration: none; 174 | } 175 | 176 | #stephan { 177 | display: block; 178 | position: absolute; 179 | top: 50%; 180 | right: 0; 181 | width: 40px; 182 | height: 40px; 183 | transform: translateY(-50%); 184 | border-radius: 3px; 185 | background: no-repeat center center url(https://stephanwagner.me/img/stephan.jpg); 186 | background-size: 100%; 187 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, .3); 188 | } 189 | 190 | #stephan>span { 191 | font-size: 0; 192 | line-height: 0; 193 | white-space: nowrap; 194 | position: absolute; 195 | top: 50%; 196 | right: 50%; 197 | pointer-events: none; 198 | transition: font-size .2s, margin .2s, opacity .2s, line-height .2s; 199 | opacity: 0; 200 | } 201 | 202 | #stephan:hover>span { 203 | opacity: 1; 204 | font-size: 17px; 205 | margin-right: 40px; 206 | } 207 | 208 | @media (max-width: 500px) { 209 | #stephan>span { 210 | display: none; 211 | } 212 | } 213 | 214 | /* jBox styles */ 215 | 216 | .ajax-sending { 217 | color: #49d; 218 | } 219 | 220 | .ajax-complete { 221 | color: #390; 222 | } 223 | 224 | .ajax-success tt { 225 | color: #666; 226 | display: block; 227 | padding-top: 10px; 228 | font-size: 14px; 229 | } 230 | 231 | .ajax-error { 232 | color: #d00; 233 | } 234 | -------------------------------------------------------------------------------- /demo/es6/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /* Document 4 | ========================================================================== */ 5 | 6 | /** 7 | * 1. Correct the line height in all browsers. 8 | * 2. Prevent adjustments of font size after orientation changes in iOS. 9 | */ 10 | 11 | html { 12 | line-height: 1.15; /* 1 */ 13 | -webkit-text-size-adjust: 100%; /* 2 */ 14 | } 15 | 16 | /* Sections 17 | ========================================================================== */ 18 | 19 | /** 20 | * Remove the margin in all browsers. 21 | */ 22 | 23 | body { 24 | margin: 0; 25 | } 26 | 27 | /** 28 | * Render the `main` element consistently in IE. 29 | */ 30 | 31 | main { 32 | display: block; 33 | } 34 | 35 | /** 36 | * Correct the font size and margin on `h1` elements within `section` and 37 | * `article` contexts in Chrome, Firefox, and Safari. 38 | */ 39 | 40 | h1 { 41 | font-size: 2em; 42 | margin: 0.67em 0; 43 | } 44 | 45 | /* Grouping content 46 | ========================================================================== */ 47 | 48 | /** 49 | * 1. Add the correct box sizing in Firefox. 50 | * 2. Show the overflow in Edge and IE. 51 | */ 52 | 53 | hr { 54 | box-sizing: content-box; /* 1 */ 55 | height: 0; /* 1 */ 56 | overflow: visible; /* 2 */ 57 | } 58 | 59 | /** 60 | * 1. Correct the inheritance and scaling of font size in all browsers. 61 | * 2. Correct the odd `em` font sizing in all browsers. 62 | */ 63 | 64 | pre { 65 | font-family: monospace, monospace; /* 1 */ 66 | font-size: 1em; /* 2 */ 67 | } 68 | 69 | /* Text-level semantics 70 | ========================================================================== */ 71 | 72 | /** 73 | * Remove the gray background on active links in IE 10. 74 | */ 75 | 76 | a { 77 | background-color: transparent; 78 | } 79 | 80 | /** 81 | * 1. Remove the bottom border in Chrome 57- 82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 83 | */ 84 | 85 | abbr[title] { 86 | border-bottom: none; /* 1 */ 87 | text-decoration: underline; /* 2 */ 88 | text-decoration: underline dotted; /* 2 */ 89 | } 90 | 91 | /** 92 | * Add the correct font weight in Chrome, Edge, and Safari. 93 | */ 94 | 95 | b, 96 | strong { 97 | font-weight: bolder; 98 | } 99 | 100 | /** 101 | * 1. Correct the inheritance and scaling of font size in all browsers. 102 | * 2. Correct the odd `em` font sizing in all browsers. 103 | */ 104 | 105 | code, 106 | kbd, 107 | samp { 108 | font-family: monospace, monospace; /* 1 */ 109 | font-size: 1em; /* 2 */ 110 | } 111 | 112 | /** 113 | * Add the correct font size in all browsers. 114 | */ 115 | 116 | small { 117 | font-size: 80%; 118 | } 119 | 120 | /** 121 | * Prevent `sub` and `sup` elements from affecting the line height in 122 | * all browsers. 123 | */ 124 | 125 | sub, 126 | sup { 127 | font-size: 75%; 128 | line-height: 0; 129 | position: relative; 130 | vertical-align: baseline; 131 | } 132 | 133 | sub { 134 | bottom: -0.25em; 135 | } 136 | 137 | sup { 138 | top: -0.5em; 139 | } 140 | 141 | /* Embedded content 142 | ========================================================================== */ 143 | 144 | /** 145 | * Remove the border on images inside links in IE 10. 146 | */ 147 | 148 | img { 149 | border-style: none; 150 | } 151 | 152 | /* Forms 153 | ========================================================================== */ 154 | 155 | /** 156 | * 1. Change the font styles in all browsers. 157 | * 2. Remove the margin in Firefox and Safari. 158 | */ 159 | 160 | button, 161 | input, 162 | optgroup, 163 | select, 164 | textarea { 165 | font-family: inherit; /* 1 */ 166 | font-size: 100%; /* 1 */ 167 | line-height: 1.15; /* 1 */ 168 | margin: 0; /* 2 */ 169 | } 170 | 171 | /** 172 | * Show the overflow in IE. 173 | * 1. Show the overflow in Edge. 174 | */ 175 | 176 | button, 177 | input { /* 1 */ 178 | overflow: visible; 179 | } 180 | 181 | /** 182 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 183 | * 1. Remove the inheritance of text transform in Firefox. 184 | */ 185 | 186 | button, 187 | select { /* 1 */ 188 | text-transform: none; 189 | } 190 | 191 | /** 192 | * Correct the inability to style clickable types in iOS and Safari. 193 | */ 194 | 195 | button, 196 | [type="button"], 197 | [type="reset"], 198 | [type="submit"] { 199 | -webkit-appearance: button; 200 | } 201 | 202 | /** 203 | * Remove the inner border and padding in Firefox. 204 | */ 205 | 206 | button::-moz-focus-inner, 207 | [type="button"]::-moz-focus-inner, 208 | [type="reset"]::-moz-focus-inner, 209 | [type="submit"]::-moz-focus-inner { 210 | border-style: none; 211 | padding: 0; 212 | } 213 | 214 | /** 215 | * Restore the focus styles unset by the previous rule. 216 | */ 217 | 218 | button:-moz-focusring, 219 | [type="button"]:-moz-focusring, 220 | [type="reset"]:-moz-focusring, 221 | [type="submit"]:-moz-focusring { 222 | outline: 1px dotted ButtonText; 223 | } 224 | 225 | /** 226 | * Correct the padding in Firefox. 227 | */ 228 | 229 | fieldset { 230 | padding: 0.35em 0.75em 0.625em; 231 | } 232 | 233 | /** 234 | * 1. Correct the text wrapping in Edge and IE. 235 | * 2. Correct the color inheritance from `fieldset` elements in IE. 236 | * 3. Remove the padding so developers are not caught out when they zero out 237 | * `fieldset` elements in all browsers. 238 | */ 239 | 240 | legend { 241 | box-sizing: border-box; /* 1 */ 242 | color: inherit; /* 2 */ 243 | display: table; /* 1 */ 244 | max-width: 100%; /* 1 */ 245 | padding: 0; /* 3 */ 246 | white-space: normal; /* 1 */ 247 | } 248 | 249 | /** 250 | * Add the correct vertical alignment in Chrome, Firefox, and Opera. 251 | */ 252 | 253 | progress { 254 | vertical-align: baseline; 255 | } 256 | 257 | /** 258 | * Remove the default vertical scrollbar in IE 10+. 259 | */ 260 | 261 | textarea { 262 | overflow: auto; 263 | } 264 | 265 | /** 266 | * 1. Add the correct box sizing in IE 10. 267 | * 2. Remove the padding in IE 10. 268 | */ 269 | 270 | [type="checkbox"], 271 | [type="radio"] { 272 | box-sizing: border-box; /* 1 */ 273 | padding: 0; /* 2 */ 274 | } 275 | 276 | /** 277 | * Correct the cursor style of increment and decrement buttons in Chrome. 278 | */ 279 | 280 | [type="number"]::-webkit-inner-spin-button, 281 | [type="number"]::-webkit-outer-spin-button { 282 | height: auto; 283 | } 284 | 285 | /** 286 | * 1. Correct the odd appearance in Chrome and Safari. 287 | * 2. Correct the outline style in Safari. 288 | */ 289 | 290 | [type="search"] { 291 | -webkit-appearance: textfield; /* 1 */ 292 | outline-offset: -2px; /* 2 */ 293 | } 294 | 295 | /** 296 | * Remove the inner padding in Chrome and Safari on macOS. 297 | */ 298 | 299 | [type="search"]::-webkit-search-decoration { 300 | -webkit-appearance: none; 301 | } 302 | 303 | /** 304 | * 1. Correct the inability to style clickable types in iOS and Safari. 305 | * 2. Change font properties to `inherit` in Safari. 306 | */ 307 | 308 | ::-webkit-file-upload-button { 309 | -webkit-appearance: button; /* 1 */ 310 | font: inherit; /* 2 */ 311 | } 312 | 313 | /* Interactive 314 | ========================================================================== */ 315 | 316 | /* 317 | * Add the correct display in Edge, IE 10+, and Firefox. 318 | */ 319 | 320 | details { 321 | display: block; 322 | } 323 | 324 | /* 325 | * Add the correct display in all browsers. 326 | */ 327 | 328 | summary { 329 | display: list-item; 330 | } 331 | 332 | /* Misc 333 | ========================================================================== */ 334 | 335 | /** 336 | * Add the correct display in IE 10+. 337 | */ 338 | 339 | template { 340 | display: none; 341 | } 342 | 343 | /** 344 | * Add the correct display in IE 10. 345 | */ 346 | 347 | [hidden] { 348 | display: none; 349 | } 350 | -------------------------------------------------------------------------------- /demo/es6/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jBox ES6 demos 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 23 |
24 | 25 |
26 | 27 |

Tooltip

28 | 29 |
30 |
Hover me
31 |
Hover me
32 |
Hover me
33 |
Hover me
34 |
Hover me
35 |
Hover me
36 |
Click me
37 |
Click me
38 |
39 | 40 |

Modal

41 | 42 |
43 | 44 | 45 | 46 |
Click me
47 |
48 | 49 |

Notice

50 | 51 |
52 |
Click me
53 |
Click me
54 |
Click me
55 |
Click me
56 |
57 | 58 |

Image

59 | 60 |
61 | 62 | 63 | 64 | 65 | 66 |
67 | 68 |
69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /demo/es6/index.js: -------------------------------------------------------------------------------- 1 | import jQuery from 'jquery'; 2 | import jBox from 'jbox'; 3 | import 'jbox/dist/jBox.all.css'; 4 | 5 | // Tooltip 6 | 7 | new jBox('Tooltip', { 8 | attach: '#Tooltip-1', 9 | content: 'This is a basic jBox tooltip' 10 | }); 11 | 12 | new jBox('Tooltip', { 13 | attach: '#Tooltip-2', 14 | theme: 'TooltipBorderThick', 15 | width: 200, 16 | position: { 17 | x: 'left', 18 | y: 'center' 19 | }, 20 | outside: 'x', 21 | pointer: 'top:15', 22 | content: 'You have many options to position and animate your jBoxes', 23 | animation: 'move' 24 | }); 25 | 26 | new jBox('Tooltip', { 27 | attach: '#Tooltip-3', 28 | theme: 'TooltipDark', 29 | animation: 'zoomOut', 30 | content: 'Use themes to change appearance' 31 | }); 32 | 33 | new jBox('Tooltip', { 34 | attach: '#Tooltip-4', 35 | width: 300, 36 | pointer: 'right:80', 37 | animation: 'move', 38 | delayOpen: 1000, 39 | delayClose: 2000, 40 | content: 'This tooltip waits 1 second to open and closes after 2 seconds', 41 | onOpen: function () { 42 | this.source.removeClass('active').html('Hover me'); 43 | }, 44 | onClose: function () { 45 | this.source.removeClass('active').html('Hover me'); 46 | } 47 | }); 48 | 49 | new jBox('Mouse', { 50 | attach: '#Tooltip-5', 51 | position: { 52 | x: 'right', 53 | y: 'bottom' 54 | }, 55 | content: 'I will follow you!' 56 | }); 57 | 58 | new jBox('Tooltip', { 59 | attach: '#Tooltip-6', 60 | width: 280, 61 | closeOnMouseleave: true, 62 | animation: 'zoomIn', 63 | content: "I won't close when you move your mouse over me" 64 | }); 65 | 66 | new jBox('Tooltip', { 67 | attach: '#Tooltip-7', 68 | target: '#Tooltip-1', 69 | theme: 'TooltipBorder', 70 | trigger: 'click', 71 | adjustTracker: true, 72 | closeOnClick: 'body', 73 | closeButton: 'box', 74 | animation: 'move', 75 | position: { 76 | x: 'left', 77 | y: 'top' 78 | }, 79 | outside: 'y', 80 | pointer: 'left:20', 81 | offset: { 82 | x: 25 83 | }, 84 | content: 85 | 'You can position your tooltips at any element.
Scroll up and down to see this tooltip flip position!', 86 | onOpen: function () { 87 | this.source.addClass('active').html('Now scroll'); 88 | }, 89 | onClose: function () { 90 | this.source.removeClass('active').html('Click me'); 91 | } 92 | }); 93 | 94 | new jBox('Tooltip', { 95 | attach: '#Tooltip-8', 96 | theme: 'TooltipBorder', 97 | trigger: 'click', 98 | width: 200, 99 | height: jQuery(window).height() - 160, 100 | adjustTracker: true, 101 | closeOnClick: 'body', 102 | closeOnEsc: true, 103 | animation: 'move', 104 | position: { 105 | x: 'right', 106 | y: 'center' 107 | }, 108 | outside: 'x', 109 | content: 110 | 'Scroll up and down or resize your browser, I will adjust my position!

Press [ESC] or click anywhere to close.', 111 | onOpen: function () { 112 | this.source.addClass('active').html('Now scroll'); 113 | }, 114 | onClose: function () { 115 | this.source.removeClass('active').html('Click me'); 116 | } 117 | }); 118 | 119 | // Modal 120 | 121 | new jBox('Modal', { 122 | attach: '#Modal-1', 123 | height: 200, 124 | title: "I'm a basic jBox modal window", 125 | content: 126 | '
Try to scroll ...it\'s blocked.
Press [ESC] or click anywhere to close.
' 127 | }); 128 | 129 | new jBox('Modal', { 130 | attach: '#Modal-2', 131 | width: 350, 132 | height: 200, 133 | blockScroll: false, 134 | animation: 'zoomIn', 135 | draggable: 'title', 136 | closeButton: true, 137 | content: 'You can move this modal window', 138 | title: 'Click here to drag me around', 139 | overlay: false, 140 | reposition: false, 141 | repositionOnOpen: false 142 | }); 143 | 144 | new jBox('Modal', { 145 | attach: '#Modal-3', 146 | width: 450, 147 | height: 250, 148 | closeButton: 'title', 149 | animation: false, 150 | title: 'AJAX request', 151 | ajax: { 152 | url: 'https://reqres.in/api/users?delay=2', 153 | data: { 154 | id: '1982', 155 | name: 'Stephan Wagner' 156 | }, 157 | method: 'post', 158 | reload: 'strict', 159 | setContent: false, 160 | beforeSend: function () { 161 | this.setContent(''); 162 | this.setTitle('
Sending AJAX request...
'); 163 | }, 164 | complete: function () { 165 | this.setTitle('
AJAX request complete
'); 166 | }, 167 | success: function (response) { 168 | this.setContent( 169 | '
Response:' + 170 | JSON.stringify(response) + 171 | '
' 172 | ); 173 | }, 174 | error: function () { 175 | this.setContent( 176 | '
Oops, something went wrong
' 177 | ); 178 | } 179 | } 180 | }); 181 | 182 | // Confirm 183 | 184 | new jBox('Confirm', { 185 | content: 'Do you really want to do this?', 186 | cancelButton: 'Nope', 187 | confirmButton: 'Sure do!' 188 | }); 189 | 190 | // Notice 191 | 192 | jQuery('#Notice-1').on('click', function () { 193 | new jBox('Notice', { 194 | content: "Hello, I'm a notice", 195 | color: 'black' 196 | }); 197 | }); 198 | 199 | jQuery('#Notice-2').on('click', function () { 200 | new jBox('Notice', { 201 | animation: 'flip', 202 | color: getColor(), 203 | content: 'Oooh! They also come in colors', 204 | delayOnHover: true, 205 | showCountdown: true 206 | }); 207 | }); 208 | 209 | jQuery('#Notice-3').on('click', function () { 210 | new jBox('Notice', { 211 | theme: 'NoticeFancy', 212 | attributes: { 213 | x: 'left', 214 | y: 'bottom' 215 | }, 216 | color: getColor(), 217 | content: "Hello, I'm down here", 218 | audio: 'https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/assets/audio/bling2', 219 | volume: 80, 220 | animation: { 221 | open: 'slide:bottom', 222 | close: 'slide:left' 223 | } 224 | }); 225 | }); 226 | 227 | jQuery('#Notice-4').on('click', function () { 228 | new jBox('Notice', { 229 | attributes: { 230 | x: 'right', 231 | y: 'bottom' 232 | }, 233 | stack: false, 234 | animation: { 235 | open: 'tada', 236 | close: 'zoomIn' 237 | }, 238 | color: getColor(), 239 | title: "Tadaaa! I'm single", 240 | content: "Open another notice, I won't stack" 241 | }); 242 | }); 243 | 244 | // Image 245 | 246 | new jBox('Image', { 247 | imageCounter: true, 248 | imageCounterSeparator: ' of ' 249 | }); 250 | 251 | // Additional JS for demo purposes 252 | 253 | jQuery('#Tooltip-4').on('mouseenter mouseleave', function () { 254 | jQuery('#Tooltip-4').addClass('active').html('Wait...'); 255 | }); 256 | 257 | jQuery('.target-notice') 258 | .on('click', function () { 259 | jQuery(this).addClass('active').html('Click me again'); 260 | }) 261 | .on('mouseleave', function () { 262 | jQuery(this).removeClass('active').html('Click me'); 263 | }); 264 | 265 | var colors = ['red', 'green', 'blue', 'yellow']; 266 | var index = 0; 267 | var getColor = function () { 268 | if (index >= colors.length) { 269 | index = 0; 270 | } 271 | return colors[index++]; 272 | }; 273 | -------------------------------------------------------------------------------- /demo/es6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jbox-es6-demo", 3 | "description": "", 4 | "version": "0.0.1", 5 | "author": "Stephan Wagner (https://stephanwagner.me)", 6 | "license": "ISC", 7 | "main": "index.js", 8 | "dependencies": { 9 | "jbox": "*" 10 | }, 11 | "devDependencies": { 12 | "snowpack": "^3.3.5" 13 | }, 14 | "scripts": { 15 | "start": "snowpack dev" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /demo/html/css/demo.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | body { 8 | position: relative; 9 | font-family: Roboto, sans-serif; 10 | font-size: 17px; 11 | line-height: 1.4; 12 | color: #222; 13 | background: #fff; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | -webkit-text-size-adjust: none; 17 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 18 | } 19 | 20 | * { 21 | outline: none; 22 | box-sizing: border-box; 23 | } 24 | 25 | p { 26 | margin: 0 0 15px; 27 | } 28 | 29 | p:last-child { 30 | margin-bottom: 0; 31 | } 32 | 33 | h2 { 34 | margin: 0; 35 | font-size: 22px; 36 | font-weight: normal; 37 | } 38 | 39 | main { 40 | padding: 20px 0; 41 | } 42 | 43 | .container { 44 | position: relative; 45 | width: calc(100% - 60px); 46 | max-width: 1000px; 47 | margin: auto; 48 | } 49 | 50 | @media (max-width: 768px) { 51 | .container { 52 | width: calc(100% - 30px); 53 | } 54 | } 55 | 56 | /* Target elements */ 57 | 58 | .targets-wrapper { 59 | margin: 0 -5px; 60 | padding: 10px 0 20px; 61 | display: flex; 62 | flex-wrap: wrap; 63 | } 64 | 65 | .target, 66 | .target-click, 67 | .target-notice { 68 | cursor: default; 69 | font-size: 14px; 70 | line-height: 50px; 71 | height: 52px; 72 | border-radius: 4px; 73 | overflow: hidden; 74 | border: 2px solid #e2e2e2; 75 | background: #fafafa; 76 | text-align: center; 77 | font-weight: 500; 78 | position: relative; 79 | text-transform: uppercase; 80 | width: calc(25% - 10px); 81 | margin: 5px; 82 | transition: border-color .2s, background-color .2s; 83 | -webkit-user-select: none; 84 | -moz-user-select: none; 85 | -ms-user-select: none; 86 | user-select: none; 87 | } 88 | 89 | .target:hover, 90 | .target-click:hover, 91 | .target-notice:hover { 92 | border-color: #bbb; 93 | background-color: #eee; 94 | } 95 | 96 | .target-click, 97 | .target-notice { 98 | cursor: pointer; 99 | } 100 | 101 | .target.active, 102 | .target-click.active, 103 | .target-notice.active { 104 | color: #49d; 105 | } 106 | 107 | @media (max-width: 768px) { 108 | 109 | .target, 110 | .target-click, 111 | .target-notice { 112 | width: calc(50% - 10px); 113 | } 114 | } 115 | 116 | .demo-img { 117 | width: calc(25% - 10px); 118 | margin: 5px; 119 | } 120 | 121 | @media (max-width: 500px) { 122 | .demo-img { 123 | width: calc(50% - 10px); 124 | } 125 | } 126 | 127 | .demo-img>img { 128 | border: 4px solid #e2e2e2; 129 | border-radius: 4px; 130 | width: 100%; 131 | height: auto; 132 | filter: grayscale(100%); 133 | transition: filter .2s, border-color .2s; 134 | } 135 | 136 | .demo-img:hover>img { 137 | filter: none; 138 | border-color: #bbb; 139 | } 140 | 141 | @media (max-width: 768px) { 142 | .demo-img>img { 143 | border-width: 2px; 144 | } 145 | } 146 | 147 | /* Header */ 148 | 149 | header { 150 | height: 50px; 151 | line-height: 50px; 152 | font-size: 17px; 153 | background: #000; 154 | color: #aaa; 155 | box-shadow: 0 0 3px rgba(0, 0, 0, .6); 156 | } 157 | 158 | header a { 159 | margin-right: 20px; 160 | color: #aaa; 161 | text-decoration: none; 162 | transition: color .2s; 163 | } 164 | 165 | header a:last-child, 166 | header a:nth-child(2) { 167 | margin-right: 0; 168 | } 169 | 170 | header a.active, 171 | header a:hover { 172 | color: #fff; 173 | text-decoration: none; 174 | } 175 | 176 | #stephan { 177 | display: block; 178 | position: absolute; 179 | top: 50%; 180 | right: 0; 181 | width: 40px; 182 | height: 40px; 183 | transform: translateY(-50%); 184 | border-radius: 3px; 185 | background: no-repeat center center url(https://stephanwagner.me/img/stephan.jpg); 186 | background-size: 100%; 187 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, .3); 188 | } 189 | 190 | #stephan>span { 191 | font-size: 0; 192 | line-height: 0; 193 | white-space: nowrap; 194 | position: absolute; 195 | top: 50%; 196 | right: 50%; 197 | pointer-events: none; 198 | transition: font-size .2s, margin .2s, opacity .2s, line-height .2s; 199 | opacity: 0; 200 | } 201 | 202 | #stephan:hover>span { 203 | opacity: 1; 204 | font-size: 17px; 205 | margin-right: 40px; 206 | } 207 | 208 | @media (max-width: 500px) { 209 | #stephan>span { 210 | display: none; 211 | } 212 | } 213 | 214 | /* jBox styles */ 215 | 216 | .ajax-sending { 217 | color: #49d; 218 | } 219 | 220 | .ajax-complete { 221 | color: #390; 222 | } 223 | 224 | .ajax-success tt { 225 | color: #666; 226 | display: block; 227 | padding-top: 10px; 228 | font-size: 14px; 229 | } 230 | 231 | .ajax-error { 232 | color: #d00; 233 | } 234 | -------------------------------------------------------------------------------- /demo/html/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /* Document 4 | ========================================================================== */ 5 | 6 | /** 7 | * 1. Correct the line height in all browsers. 8 | * 2. Prevent adjustments of font size after orientation changes in iOS. 9 | */ 10 | 11 | html { 12 | line-height: 1.15; /* 1 */ 13 | -webkit-text-size-adjust: 100%; /* 2 */ 14 | } 15 | 16 | /* Sections 17 | ========================================================================== */ 18 | 19 | /** 20 | * Remove the margin in all browsers. 21 | */ 22 | 23 | body { 24 | margin: 0; 25 | } 26 | 27 | /** 28 | * Render the `main` element consistently in IE. 29 | */ 30 | 31 | main { 32 | display: block; 33 | } 34 | 35 | /** 36 | * Correct the font size and margin on `h1` elements within `section` and 37 | * `article` contexts in Chrome, Firefox, and Safari. 38 | */ 39 | 40 | h1 { 41 | font-size: 2em; 42 | margin: 0.67em 0; 43 | } 44 | 45 | /* Grouping content 46 | ========================================================================== */ 47 | 48 | /** 49 | * 1. Add the correct box sizing in Firefox. 50 | * 2. Show the overflow in Edge and IE. 51 | */ 52 | 53 | hr { 54 | box-sizing: content-box; /* 1 */ 55 | height: 0; /* 1 */ 56 | overflow: visible; /* 2 */ 57 | } 58 | 59 | /** 60 | * 1. Correct the inheritance and scaling of font size in all browsers. 61 | * 2. Correct the odd `em` font sizing in all browsers. 62 | */ 63 | 64 | pre { 65 | font-family: monospace, monospace; /* 1 */ 66 | font-size: 1em; /* 2 */ 67 | } 68 | 69 | /* Text-level semantics 70 | ========================================================================== */ 71 | 72 | /** 73 | * Remove the gray background on active links in IE 10. 74 | */ 75 | 76 | a { 77 | background-color: transparent; 78 | } 79 | 80 | /** 81 | * 1. Remove the bottom border in Chrome 57- 82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 83 | */ 84 | 85 | abbr[title] { 86 | border-bottom: none; /* 1 */ 87 | text-decoration: underline; /* 2 */ 88 | text-decoration: underline dotted; /* 2 */ 89 | } 90 | 91 | /** 92 | * Add the correct font weight in Chrome, Edge, and Safari. 93 | */ 94 | 95 | b, 96 | strong { 97 | font-weight: bolder; 98 | } 99 | 100 | /** 101 | * 1. Correct the inheritance and scaling of font size in all browsers. 102 | * 2. Correct the odd `em` font sizing in all browsers. 103 | */ 104 | 105 | code, 106 | kbd, 107 | samp { 108 | font-family: monospace, monospace; /* 1 */ 109 | font-size: 1em; /* 2 */ 110 | } 111 | 112 | /** 113 | * Add the correct font size in all browsers. 114 | */ 115 | 116 | small { 117 | font-size: 80%; 118 | } 119 | 120 | /** 121 | * Prevent `sub` and `sup` elements from affecting the line height in 122 | * all browsers. 123 | */ 124 | 125 | sub, 126 | sup { 127 | font-size: 75%; 128 | line-height: 0; 129 | position: relative; 130 | vertical-align: baseline; 131 | } 132 | 133 | sub { 134 | bottom: -0.25em; 135 | } 136 | 137 | sup { 138 | top: -0.5em; 139 | } 140 | 141 | /* Embedded content 142 | ========================================================================== */ 143 | 144 | /** 145 | * Remove the border on images inside links in IE 10. 146 | */ 147 | 148 | img { 149 | border-style: none; 150 | } 151 | 152 | /* Forms 153 | ========================================================================== */ 154 | 155 | /** 156 | * 1. Change the font styles in all browsers. 157 | * 2. Remove the margin in Firefox and Safari. 158 | */ 159 | 160 | button, 161 | input, 162 | optgroup, 163 | select, 164 | textarea { 165 | font-family: inherit; /* 1 */ 166 | font-size: 100%; /* 1 */ 167 | line-height: 1.15; /* 1 */ 168 | margin: 0; /* 2 */ 169 | } 170 | 171 | /** 172 | * Show the overflow in IE. 173 | * 1. Show the overflow in Edge. 174 | */ 175 | 176 | button, 177 | input { /* 1 */ 178 | overflow: visible; 179 | } 180 | 181 | /** 182 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 183 | * 1. Remove the inheritance of text transform in Firefox. 184 | */ 185 | 186 | button, 187 | select { /* 1 */ 188 | text-transform: none; 189 | } 190 | 191 | /** 192 | * Correct the inability to style clickable types in iOS and Safari. 193 | */ 194 | 195 | button, 196 | [type="button"], 197 | [type="reset"], 198 | [type="submit"] { 199 | -webkit-appearance: button; 200 | } 201 | 202 | /** 203 | * Remove the inner border and padding in Firefox. 204 | */ 205 | 206 | button::-moz-focus-inner, 207 | [type="button"]::-moz-focus-inner, 208 | [type="reset"]::-moz-focus-inner, 209 | [type="submit"]::-moz-focus-inner { 210 | border-style: none; 211 | padding: 0; 212 | } 213 | 214 | /** 215 | * Restore the focus styles unset by the previous rule. 216 | */ 217 | 218 | button:-moz-focusring, 219 | [type="button"]:-moz-focusring, 220 | [type="reset"]:-moz-focusring, 221 | [type="submit"]:-moz-focusring { 222 | outline: 1px dotted ButtonText; 223 | } 224 | 225 | /** 226 | * Correct the padding in Firefox. 227 | */ 228 | 229 | fieldset { 230 | padding: 0.35em 0.75em 0.625em; 231 | } 232 | 233 | /** 234 | * 1. Correct the text wrapping in Edge and IE. 235 | * 2. Correct the color inheritance from `fieldset` elements in IE. 236 | * 3. Remove the padding so developers are not caught out when they zero out 237 | * `fieldset` elements in all browsers. 238 | */ 239 | 240 | legend { 241 | box-sizing: border-box; /* 1 */ 242 | color: inherit; /* 2 */ 243 | display: table; /* 1 */ 244 | max-width: 100%; /* 1 */ 245 | padding: 0; /* 3 */ 246 | white-space: normal; /* 1 */ 247 | } 248 | 249 | /** 250 | * Add the correct vertical alignment in Chrome, Firefox, and Opera. 251 | */ 252 | 253 | progress { 254 | vertical-align: baseline; 255 | } 256 | 257 | /** 258 | * Remove the default vertical scrollbar in IE 10+. 259 | */ 260 | 261 | textarea { 262 | overflow: auto; 263 | } 264 | 265 | /** 266 | * 1. Add the correct box sizing in IE 10. 267 | * 2. Remove the padding in IE 10. 268 | */ 269 | 270 | [type="checkbox"], 271 | [type="radio"] { 272 | box-sizing: border-box; /* 1 */ 273 | padding: 0; /* 2 */ 274 | } 275 | 276 | /** 277 | * Correct the cursor style of increment and decrement buttons in Chrome. 278 | */ 279 | 280 | [type="number"]::-webkit-inner-spin-button, 281 | [type="number"]::-webkit-outer-spin-button { 282 | height: auto; 283 | } 284 | 285 | /** 286 | * 1. Correct the odd appearance in Chrome and Safari. 287 | * 2. Correct the outline style in Safari. 288 | */ 289 | 290 | [type="search"] { 291 | -webkit-appearance: textfield; /* 1 */ 292 | outline-offset: -2px; /* 2 */ 293 | } 294 | 295 | /** 296 | * Remove the inner padding in Chrome and Safari on macOS. 297 | */ 298 | 299 | [type="search"]::-webkit-search-decoration { 300 | -webkit-appearance: none; 301 | } 302 | 303 | /** 304 | * 1. Correct the inability to style clickable types in iOS and Safari. 305 | * 2. Change font properties to `inherit` in Safari. 306 | */ 307 | 308 | ::-webkit-file-upload-button { 309 | -webkit-appearance: button; /* 1 */ 310 | font: inherit; /* 2 */ 311 | } 312 | 313 | /* Interactive 314 | ========================================================================== */ 315 | 316 | /* 317 | * Add the correct display in Edge, IE 10+, and Firefox. 318 | */ 319 | 320 | details { 321 | display: block; 322 | } 323 | 324 | /* 325 | * Add the correct display in all browsers. 326 | */ 327 | 328 | summary { 329 | display: list-item; 330 | } 331 | 332 | /* Misc 333 | ========================================================================== */ 334 | 335 | /** 336 | * Add the correct display in IE 10+. 337 | */ 338 | 339 | template { 340 | display: none; 341 | } 342 | 343 | /** 344 | * Add the correct display in IE 10. 345 | */ 346 | 347 | [hidden] { 348 | display: none; 349 | } 350 | -------------------------------------------------------------------------------- /demo/html/css/playground-avatars.css: -------------------------------------------------------------------------------- 1 | .AvatarsModal .jBox-footer { 2 | display: flex; 3 | } 4 | 5 | .AvatarsModal .jBox-footer button { 6 | width: 50%; 7 | flex-shrink: 0; 8 | height: 50px; 9 | border: 0; 10 | padding: 0; 11 | display: block; 12 | float: left; 13 | background: center center no-repeat; 14 | transition: background-color .2s; 15 | } 16 | 17 | .AvatarsModal .jBox-footer button:active { 18 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2); 19 | } 20 | 21 | #AvatarsComplete.AvatarsModal .jBox-footer button { 22 | width: 100%; 23 | float: none; 24 | } 25 | 26 | .AvatarsModal .jBox-footer .button-cross { 27 | background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTUwNy4zLDQxMS4zQzUwNy4zLDQxMS4zLDUwNy4zLDQxMS4zLDUwNy4zLDQxMS4zTDM1MiwyNTZsMTU1LjMtMTU1LjNjMCwwLDAsMCwwLDBDNTA5LDk5LDUxMC4yLDk3LDUxMSw5NQpjMi4xLTUuNywwLjktMTIuMy0zLjctMTYuOUw0MzQsNC43QzQyOS40LDAuMSw0MjIuNy0xLjEsNDE3LDFjLTIuMSwwLjgtNCwyLTUuNywzLjdjMCwwLDAsMCwwLDBMMjU2LDE2MEwxMDAuNyw0LjdjMCwwLDAsMCwwLDAKQzk5LDMsOTcsMS44LDk1LDFjLTUuNy0yLjEtMTIuMy0wLjktMTYuOSwzLjdMNC43LDc4QzAuMSw4Mi42LTEuMSw4OS4zLDEsOTVjMC44LDIuMSwyLDQsMy43LDUuN2MwLDAsMCwwLDAsMEwxNjAsMjU2TDQuNyw0MTEuMwpjMCwwLDAsMCwwLDBDMyw0MTMsMS44LDQxNSwxLDQxN2MtMi4xLDUuNy0wLjksMTIuMywzLjcsMTYuOWw3My40LDczLjRjNC42LDQuNiwxMS4yLDUuOCwxNi45LDMuN2MyLjEtMC44LDQtMiw1LjctMy43YzAsMCwwLDAsMCwwCkwyNTYsMzUybDE1NS4zLDE1NS4zYzAsMCwwLDAsMCwwYzEuNywxLjcsMy42LDIuOSw1LjcsMy43YzUuNywyLjEsMTIuMywwLjksMTYuOS0zLjdsNzMuNC03My40YzQuNi00LjYsNS44LTExLjIsMy43LTE2LjkKQzUxMC4yLDQxNSw1MDksNDEzLDUwNy4zLDQxMS4zTDUwNy4zLDQxMS4zeiIvPgo8L3N2Zz4K); 28 | background-color: #e33; 29 | background-size: 24px auto; 30 | border-radius: 0 0 0 4px; 31 | } 32 | 33 | .AvatarsModal .jBox-footer .button-cross:hover { 34 | background-color: #f33; 35 | } 36 | 37 | .AvatarsModal .jBox-footer .button-cross:active { 38 | background-color: #e33; 39 | } 40 | 41 | .AvatarsModal .jBox-footer .button-heart { 42 | background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggMzg0Ij4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTIyNCwzODRjLTQsMC04LTEuNS0xMS00LjVMNTcsMjI5Yy0yLTEuOC01Ny01Mi01Ny0xMTJDMCw0My44LDQ0LjgsMCwxMTkuNSwwYzQzLjgsMCw4NC44LDM0LjUsMTA0LjUsNTQKYzE5LjgtMTkuNSw2MC44LTU0LDEwNC41LTU0QzQwMy4yLDAsNDQ4LDQzLjgsNDQ4LDExN2MwLDYwLTU1LDExMC4yLTU3LjIsMTEyLjVMMjM1LDM3OS41QzIzMiwzODIuNSwyMjgsMzg0LDIyNCwzODR6Ii8+Cjwvc3ZnPg==); 43 | background-color: #7d0; 44 | background-size: 30px auto; 45 | border-radius: 0 0 4px 0; 46 | } 47 | 48 | .AvatarsModal .jBox-footer .button-heart:hover { 49 | background-color: #8e0; 50 | } 51 | 52 | .AvatarsModal .jBox-footer .button-heart:active { 53 | background-color: #7d0; 54 | } 55 | 56 | .AvatarsModal .jBox-footer .button-close { 57 | background-color: #ddd; 58 | border-radius: 0 0 4px 4px; 59 | } 60 | 61 | .AvatarsModal .jBox-footer .button-close:hover { 62 | background-color: #eee; 63 | } 64 | 65 | .AvatarsModal .jBox-footer .button-close:active { 66 | background-color: #ddd; 67 | } 68 | 69 | .AvatarsModal .jBox-content { 70 | padding: 0; 71 | background: center -10px no-repeat; 72 | } 73 | 74 | #AvatarsComplete.AvatarsModal .jBox-content { 75 | font-style: italic; 76 | text-align: center; 77 | color: #999; 78 | } 79 | 80 | #AvatarsComplete.AvatarsModal .jBox-content>div { 81 | position: absolute; 82 | top: calc(50% - 23px); 83 | left: 25px; 84 | right: 25px; 85 | } 86 | 87 | .AvatarsModal .jBox-title { 88 | font-size: 26px; 89 | color: #000; 90 | font-weight: 300; 91 | text-align: center; 92 | padding: 0; 93 | line-height: 60px; 94 | } 95 | 96 | .AvatarsModal .jBox-footer { 97 | border-top: 0; 98 | background: none; 99 | padding: 0; 100 | } 101 | 102 | .AvatarsTooltip .jBox-content { 103 | color: #fff; 104 | text-align: center; 105 | } 106 | 107 | .AvatarsTooltip .jBox-container, 108 | .AvatarsTooltip .jBox-pointer:after { 109 | background: #000; 110 | box-shadow: none; 111 | } 112 | 113 | .AvatarsTooltipLike .jBox-container, 114 | .AvatarsTooltipLike .jBox-pointer:after { 115 | border-color: #7d0; 116 | } 117 | 118 | .AvatarsTooltipDislike .jBox-container, 119 | .AvatarsTooltipDislike .jBox-pointer:after { 120 | border-color: #e33; 121 | } 122 | 123 | .AvatarsCollection { 124 | width: 50%; 125 | position: fixed; 126 | bottom: 5px; 127 | z-index: 11000; 128 | } 129 | 130 | .AvatarsCollection#DislikedAvatars { 131 | left: 4px; 132 | } 133 | 134 | .AvatarsCollection#LikedAvatars { 135 | right: 4px; 136 | } 137 | 138 | .AvatarsCollection>div { 139 | width: 47px; 140 | height: 45px; 141 | padding: 0 1px; 142 | } 143 | 144 | .AvatarsCollection#DislikedAvatars>div { 145 | float: left; 146 | } 147 | 148 | .AvatarsCollection#LikedAvatars>div { 149 | float: right; 150 | } 151 | 152 | .AvatarsCollection>div>div { 153 | position: relative; 154 | overflow: hidden; 155 | width: 45px; 156 | height: 45px; 157 | border: 2px solid; 158 | border-radius: 50%; 159 | background: #000; 160 | } 161 | 162 | .AvatarsCollection#DislikedAvatars>div>div { 163 | border-color: #e33; 164 | } 165 | 166 | .AvatarsCollection#LikedAvatars>div>div { 167 | border-color: #7d0; 168 | } 169 | 170 | .AvatarsCollection>div>div>img { 171 | position: absolute; 172 | top: 50%; 173 | left: 50%; 174 | width: 60px; 175 | height: 60px; 176 | margin-top: -27px; 177 | margin-left: -30px; 178 | } 179 | -------------------------------------------------------------------------------- /demo/html/css/playground-inception.css: -------------------------------------------------------------------------------- 1 | .inception-overlay { 2 | background-color: rgba(0, 0, 0, .35); 3 | } 4 | 5 | .inception-modal button { 6 | cursor: pointer; 7 | border: 0; 8 | margin: 0; 9 | display: block; 10 | width: 100%; 11 | color: #fff; 12 | background: #000; 13 | height: 40px; 14 | text-align: center; 15 | border-radius: 4px; 16 | } 17 | -------------------------------------------------------------------------------- /demo/html/css/playground-login.css: -------------------------------------------------------------------------------- 1 | /* Restyle jBoxes */ 2 | 3 | #jBoxLogin .jBox-content { 4 | padding: 0; 5 | } 6 | 7 | #jBoxLogin .jBox-title { 8 | text-align: center; 9 | line-height: 1.6; 10 | padding: 15px 0; 11 | font-size: 20px; 12 | } 13 | 14 | .jBox-TooltipSmall.LoginTooltipSmall .jBox-content, 15 | .jBox-TooltipError.LoginTooltipError .jBox-content { 16 | font-size: 13px; 17 | padding: 5px 10px; 18 | line-height: 18px; 19 | } 20 | 21 | .jBox-TooltipSmall.LoginTooltipSmall .jBox-container, 22 | .jBox-TooltipError.LoginTooltipError .jBox-container { 23 | border-radius: 2px; 24 | font-weight: bold; 25 | color: #fff; 26 | } 27 | 28 | .jBox-TooltipSmall.LoginTooltipError .jBox-container { 29 | background: #d00; 30 | } 31 | 32 | .jBox-TooltipSmall.LoginTooltipSmall .jBox-container { 33 | background: #246bb3; 34 | } 35 | 36 | .jBox-TooltipSmall.LoginTooltipSmall .jBox-pointer:after { 37 | background: #246bb3; 38 | } 39 | 40 | /* Content */ 41 | 42 | .login-container { 43 | display: none; 44 | } 45 | 46 | .login-container.active { 47 | display: block; 48 | } 49 | 50 | .login-body { 51 | padding: 0 25px; 52 | } 53 | 54 | .login-container button { 55 | margin: 25px 0 0; 56 | } 57 | 58 | .login-textfield-wrapper { 59 | position: relative; 60 | } 61 | 62 | .login-remember { 63 | margin: 25px 0 0; 64 | height: 20px; 65 | } 66 | 67 | #LoginWrapper.request-running .login-footer a, 68 | #LoginWrapper.request-running .login-footer span { 69 | cursor: default !important; 70 | text-decoration: none !important; 71 | } 72 | 73 | /* Form elements */ 74 | 75 | .login-textfield { 76 | width: 100%; 77 | border: 0; 78 | border-bottom: 2px solid #ddd; 79 | padding: 6px 2px; 80 | font-size: 18px; 81 | margin-top: 25px; 82 | transition: border-color .2s; 83 | } 84 | 85 | .login-textfield:hover { 86 | border-bottom-color: #ccc; 87 | } 88 | 89 | .login-textfield:focus { 90 | border-bottom-color: #246bb3; 91 | } 92 | 93 | .login-textfield.textfield-error { 94 | border-bottom-color: #d00; 95 | } 96 | 97 | .login-checkbox { 98 | float: left; 99 | position: relative; 100 | cursor: pointer; 101 | width: 20px; 102 | height: 20px; 103 | border-radius: 3px; 104 | background: #eee; 105 | box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .05); 106 | transition: background-color .2s; 107 | } 108 | 109 | .login-checkbox.login-checkbox-active { 110 | box-shadow: none; 111 | background: #7d0; 112 | } 113 | 114 | .login-checkbox-check { 115 | opacity: 0; 116 | background: no-repeat center center; 117 | background-size: 14px; 118 | background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MjQuNTMgMzE1LjczIj4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTQ2NS4wNywxNTMuNmExMC4zMSwxMC4zMSwwLDAsMCwwLTE0LjkzTDQyOC44LDEwMi40YTEwLjMxLDEwLjMxLDAsMCwwLTE0LjkzLDBMMjAwLjUzLDMxNS43Myw5OC4xMywyMTMuMzNhMTAuMzEsMTAuMzEsMCwwLDAtMTQuOTMsMEw0Ni45MywyNDkuNmExMC4zMSwxMC4zMSwwLDAsMCwwLDE0LjkzbDE0Ny4yLDE0Ny4yYTEwLjMxLDEwLjMxLDAsMCwwLDE0LjkzLDBsMjU2LTI1OC4xM1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00My43MyAtOTkuMikiLz4KPC9zdmc+); 119 | width: 20px; 120 | height: 20px; 121 | position: absolute; 122 | top: 50%; 123 | left: 50%; 124 | margin-top: -10px; 125 | margin-left: -10px; 126 | transition: opacity .2s; 127 | } 128 | 129 | .login-checkbox.login-checkbox-active .login-checkbox-check { 130 | opacity: 1; 131 | } 132 | 133 | .login-checkbox-label { 134 | float: left; 135 | cursor: pointer; 136 | width: calc(100% - 20px); 137 | line-height: 20px; 138 | font-size: 17px; 139 | padding: 0 0 0 12px; 140 | -webkit-user-select: none; 141 | -moz-user-select: none; 142 | -ms-user-select: none; 143 | user-select: none; 144 | } 145 | 146 | .login-button { 147 | width: 100%; 148 | border: 0; 149 | color: #fff; 150 | background: #246bb3; 151 | border-radius: 4px; 152 | height: 40px; 153 | line-height: 40px; 154 | font-size: 20px; 155 | padding: 0; 156 | transition: background-color .2s; 157 | } 158 | 159 | .login-button:hover { 160 | background: #3878c1; 161 | } 162 | 163 | .login-button:active { 164 | background: #246bb3; 165 | } 166 | 167 | .login-button[disabled] { 168 | cursor: default !important; 169 | color: #ccc !important; 170 | background: #eee !important; 171 | } 172 | 173 | .loading-bar, 174 | .login-button[disabled].loading-bar { 175 | background-image: linear-gradient(-45deg, rgba(255, 255, 255, .4) 25%, rgba(255, 255, 255, .0) 25%, rgba(255, 255, 255, .0) 50%, rgba(255, 255, 255, .4) 50%, rgba(255, 255, 255, .4) 75%, rgba(255, 255, 255, .0) 75%, rgba(255, 255, 255, .0)) !important; 176 | background-size: 32px 32px !important; 177 | background-repeat: repeat !important; 178 | transition: background-position 60000s linear !important; 179 | background-position: 4000000px !important; 180 | } 181 | 182 | /* Footer */ 183 | 184 | .login-footer { 185 | background: #fafafa; 186 | border-top: 1px solid #eee; 187 | border-radius: 0 0 4px 4px; 188 | font-size: 17px; 189 | line-height: 1.6; 190 | padding: 15px 0 15px 25px; 191 | position: absolute; 192 | bottom: 0; 193 | left: 0; 194 | right: 0; 195 | } 196 | 197 | .login-footer span { 198 | cursor: pointer; 199 | color: #297acc; 200 | } 201 | 202 | .login-footer span:hover { 203 | text-decoration: underline; 204 | } 205 | -------------------------------------------------------------------------------- /demo/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jBox HTML demos 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 27 |
28 | 29 |
30 | 31 |

Tooltip

32 | 33 |
34 |
Hover me
35 |
Hover me
36 |
Hover me
37 |
Hover me
38 |
Hover me
39 |
Hover me
40 |
Click me
41 |
Click me
42 |
43 | 44 |

Modal

45 | 46 |
47 | 48 | 49 | 50 |
Click me
51 |
52 | 53 |

Notice

54 | 55 |
56 |
Click me
57 |
Click me
58 |
Click me
59 |
Click me
60 |
61 | 62 |

Image

63 | 64 |
65 | 66 | 67 | 68 | 69 | 70 |
71 | 72 |

Playground

73 | 74 |
75 |
Inception
76 |
Avatars
77 |
Login
78 |
79 | 80 |
81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /demo/html/js/demo.js: -------------------------------------------------------------------------------- 1 | jQuery(function () { 2 | // Tooltip 3 | 4 | new jBox('Tooltip', { 5 | attach: '#Tooltip-1', 6 | content: 'This is a basic jBox tooltip' 7 | }); 8 | 9 | new jBox('Tooltip', { 10 | attach: '#Tooltip-2', 11 | theme: 'TooltipBorderThick', 12 | width: 200, 13 | position: { 14 | x: 'left', 15 | y: 'center' 16 | }, 17 | outside: 'x', 18 | pointer: 'top:15', 19 | content: 'You have many options to position and animate your jBoxes', 20 | animation: 'move' 21 | }); 22 | 23 | new jBox('Tooltip', { 24 | attach: '#Tooltip-3', 25 | theme: 'TooltipDark', 26 | animation: 'zoomOut', 27 | content: 'Use themes to change appearance' 28 | }); 29 | 30 | new jBox('Tooltip', { 31 | attach: '#Tooltip-4', 32 | width: 300, 33 | pointer: 'right:80', 34 | animation: 'move', 35 | delayOpen: 1000, 36 | delayClose: 2000, 37 | content: 'This tooltip waits 1 second to open and closes after 2 seconds', 38 | onOpen: function () { 39 | this.source.removeClass('active').html('Hover me'); 40 | }, 41 | onClose: function () { 42 | this.source.removeClass('active').html('Hover me'); 43 | } 44 | }); 45 | 46 | new jBox('Mouse', { 47 | attach: '#Tooltip-5', 48 | position: { 49 | x: 'right', 50 | y: 'bottom' 51 | }, 52 | content: 'I will follow you!' 53 | }); 54 | 55 | new jBox('Tooltip', { 56 | attach: '#Tooltip-6', 57 | width: 280, 58 | closeOnMouseleave: true, 59 | animation: 'zoomIn', 60 | content: "I won't close when you move your mouse over me" 61 | }); 62 | 63 | new jBox('Tooltip', { 64 | attach: '#Tooltip-7', 65 | target: '#Tooltip-1', 66 | theme: 'TooltipBorder', 67 | trigger: 'click', 68 | adjustTracker: true, 69 | closeOnClick: 'body', 70 | closeButton: 'box', 71 | animation: 'move', 72 | position: { 73 | x: 'left', 74 | y: 'top' 75 | }, 76 | outside: 'y', 77 | pointer: 'left:20', 78 | offset: { 79 | x: 25 80 | }, 81 | content: 82 | 'You can position your tooltips at any element.
Scroll up and down to see this tooltip flip position!', 83 | onOpen: function () { 84 | this.source.addClass('active').html('Now scroll'); 85 | }, 86 | onClose: function () { 87 | this.source.removeClass('active').html('Click me'); 88 | } 89 | }); 90 | 91 | new jBox('Tooltip', { 92 | attach: '#Tooltip-8', 93 | theme: 'TooltipBorder', 94 | trigger: 'click', 95 | width: 200, 96 | height: jQuery(window).height() - 160, 97 | adjustTracker: true, 98 | closeOnClick: 'body', 99 | closeOnEsc: true, 100 | animation: 'move', 101 | position: { 102 | x: 'right', 103 | y: 'center' 104 | }, 105 | outside: 'x', 106 | content: 107 | 'Scroll up and down or resize your browser, I will adjust my position!

Press [ESC] or click anywhere to close.', 108 | onOpen: function () { 109 | this.source.addClass('active').html('Now scroll'); 110 | }, 111 | onClose: function () { 112 | this.source.removeClass('active').html('Click me'); 113 | } 114 | }); 115 | 116 | // Modal 117 | 118 | new jBox('Modal', { 119 | attach: '#Modal-1', 120 | height: 200, 121 | title: "I'm a basic jBox modal window", 122 | content: 123 | '
Try to scroll ...it\'s blocked.
Press [ESC] or click anywhere to close.
' 124 | }); 125 | 126 | new jBox('Modal', { 127 | attach: '#Modal-2', 128 | width: 350, 129 | height: 200, 130 | blockScroll: false, 131 | animation: 'zoomIn', 132 | draggable: 'title', 133 | closeButton: true, 134 | content: 'You can move this modal window', 135 | title: 'Click here to drag me around', 136 | overlay: false, 137 | reposition: false, 138 | repositionOnOpen: false 139 | }); 140 | 141 | new jBox('Modal', { 142 | attach: '#Modal-3', 143 | width: 450, 144 | height: 250, 145 | closeButton: 'title', 146 | animation: false, 147 | title: 'AJAX request', 148 | ajax: { 149 | url: 'https://reqres.in/api/users?delay=2', 150 | data: { 151 | id: '1982', 152 | name: 'Stephan Wagner' 153 | }, 154 | method: 'post', 155 | reload: 'strict', 156 | setContent: false, 157 | beforeSend: function () { 158 | this.setContent(''); 159 | this.setTitle( 160 | '
Sending AJAX request...
' 161 | ); 162 | }, 163 | complete: function () { 164 | this.setTitle('
AJAX request complete
'); 165 | }, 166 | success: function (response) { 167 | this.setContent( 168 | '
Response:' + 169 | JSON.stringify(response) + 170 | '
' 171 | ); 172 | }, 173 | error: function () { 174 | this.setContent( 175 | '
Oops, something went wrong
' 176 | ); 177 | } 178 | } 179 | }); 180 | 181 | // Confirm 182 | 183 | new jBox('Confirm', { 184 | content: 'Do you really want to do this?', 185 | cancelButton: 'Nope', 186 | confirmButton: 'Sure do!' 187 | }); 188 | 189 | // Notice 190 | 191 | jQuery('#Notice-1').on('click', function () { 192 | new jBox('Notice', { 193 | content: "Hello, I'm a notice", 194 | color: 'black' 195 | }); 196 | }); 197 | 198 | jQuery('#Notice-2').on('click', function () { 199 | new jBox('Notice', { 200 | animation: 'flip', 201 | color: getColor(), 202 | content: 'Oooh! They also come in colors', 203 | delayOnHover: true, 204 | showCountdown: true 205 | }); 206 | }); 207 | 208 | jQuery('#Notice-3').on('click', function () { 209 | new jBox('Notice', { 210 | theme: 'NoticeFancy', 211 | attributes: { 212 | x: 'left', 213 | y: 'bottom' 214 | }, 215 | color: getColor(), 216 | content: "Hello, I'm down here", 217 | audio: '../../assets/audio/bling2', 218 | volume: 80, 219 | animation: { 220 | open: 'slide:bottom', 221 | close: 'slide:left' 222 | } 223 | }); 224 | }); 225 | 226 | jQuery('#Notice-4').on('click', function () { 227 | new jBox('Notice', { 228 | attributes: { 229 | x: 'right', 230 | y: 'bottom' 231 | }, 232 | stack: false, 233 | animation: { 234 | open: 'tada', 235 | close: 'zoomIn' 236 | }, 237 | color: getColor(), 238 | title: "Tadaaa! I'm single", 239 | content: "Open another notice, I won't stack" 240 | }); 241 | }); 242 | 243 | // Image 244 | 245 | new jBox('Image', { 246 | imageCounter: true, 247 | imageCounterSeparator: ' of ' 248 | }); 249 | 250 | // Additional JS for demo purposes 251 | 252 | jQuery('#Tooltip-4').on('mouseenter mouseleave', function () { 253 | jQuery('#Tooltip-4').addClass('active').html('Wait...'); 254 | }); 255 | 256 | jQuery('.target-notice') 257 | .on('click', function () { 258 | jQuery(this).addClass('active').html('Click me again'); 259 | }) 260 | .on('mouseleave', function () { 261 | jQuery(this).removeClass('active').html('Click me'); 262 | }); 263 | 264 | var colors = ['red', 'green', 'blue', 'yellow']; 265 | var index = 0; 266 | var getColor = function () { 267 | if (index >= colors.length) { 268 | index = 0; 269 | } 270 | return colors[index++]; 271 | }; 272 | }); 273 | -------------------------------------------------------------------------------- /demo/html/js/playground-avatars.js: -------------------------------------------------------------------------------- 1 | // Playground Demo: Avatars 2 | 3 | // All data we are using for this demo we will store in the variable DemoAvatars 4 | 5 | var DemoAvatars = { 6 | Avatars: ['Stephan', 'Susan', 'Jack', 'Elizabeth', 'Fungus', 'Donald', 'Gary', 'Trixi', 'Samuel', 'Maria'], 7 | Modals: {} 8 | }; 9 | 10 | // All the magic happens in the function generateAvatarJBox 11 | 12 | function generateAvatarJBox(initial) { 13 | // We only need to initialize the tooltips for the avatar collection once 14 | // We can later refer to this jBox instance with DemoAvatars.AvatarsTooltip 15 | 16 | !DemoAvatars.AvatarsTooltip && (DemoAvatars.AvatarsTooltip = new jBox('Tooltip', { 17 | theme: 'TooltipBorder', // We are using the border theme... 18 | addClass: 'AvatarsTooltip', // ...and add a class so we can adjust the theme with CSS 19 | attach: '[data-avatar-tooltip]', // We attach the tooltip to the elements with the attribute data-avatar-tooltip... 20 | getContent: 'data-avatar-tooltip', // ... and also get the content from the same attribute 21 | zIndex: 12000, // These tooltips have the highest z-index 22 | animation: 'move', 23 | 24 | // Adding the liked or disliked class depending on the container the avatar is in 25 | onOpen: function () { 26 | this.wrapper.removeClass('AvatarsTooltipLike AvatarsTooltipDislike').addClass('AvatarsTooltip' + (this.source.parent().attr('id') == 'LikedAvatars' ? 'Like' : 'Dislike')); 27 | } 28 | })); 29 | 30 | // When we are creating the initial jBox, reset global variables 31 | 32 | if (initial) { 33 | DemoAvatars.clicked = false; 34 | DemoAvatars.current = -1; 35 | } 36 | 37 | // Increase current avatar index 38 | 39 | DemoAvatars.current++; 40 | 41 | // When we looped through all the avatars, show a jBox Modal with a hint that there are no more avatars nearby 42 | 43 | if (DemoAvatars.current >= DemoAvatars.Avatars.length) { 44 | 45 | DemoAvatars.Modals.AvatarsComplete = new jBox('Modal', { 46 | 47 | // We use similar options to our Avatar modal so they look similar 48 | id: 'AvatarsComplete', 49 | addClass: 'AvatarsModal', 50 | width: 300, 51 | height: 250, 52 | animation: 'zoomIn', 53 | overlay: false, 54 | blockScroll: false, 55 | closeButton: false, 56 | closeOnEsc: false, 57 | adjustDistance: { 58 | top: 40, 59 | right: 5, 60 | bottom: 55, 61 | left: 5 62 | }, 63 | footer: '', 64 | title: 'Whoops', 65 | content: '
There are currently no more avatars near you
', 66 | zIndex: 10000, 67 | 68 | // Once this jBox is created, we tel the close button to close the initial avatar modal 69 | onCreated: function () { 70 | this.footer.find('button').on('click', function () { 71 | DemoAvatars.Modals.AvatarsInitial.close(); 72 | }); 73 | } 74 | }).open(); 75 | 76 | // Nothing more to do, abort here 77 | return null; 78 | } 79 | 80 | // We are creating a new jBox Modal with the avatars each time this function gets called 81 | 82 | var jBoxAvatar = new jBox('Modal', { 83 | addClass: 'AvatarsModal', 84 | width: 300, 85 | height: 250, 86 | animation: 'zoomIn', 87 | zIndex: 10000, 88 | 89 | // Adjusting the distance to the viewport so we have space for the avatar collection at the bottom and the close button of the modal at the top 90 | adjustDistance: { 91 | top: 40, 92 | right: 5, 93 | bottom: 55, 94 | left: 5 95 | }, 96 | 97 | // We are setting these options differently for the initial and the following jBoxes 98 | id: initial ? 'AvatarsInitial' : 'AvatarsModal' + DemoAvatars.current, 99 | overlay: initial ? true : false, // Only one overlay is needed 100 | blockScroll: initial ? true : false, // The initial jBox will block scrolling, no need for the others to o the same 101 | closeButton: initial ? 'overlay' : false, // The initial jBox will have the close button in the overlay, the others won't need one 102 | closeOnEsc: initial ? true : false, // Only the initial jBox can be closed with [ESC] button 103 | 104 | // Placing the buttons in the footer area 105 | footer: '', 106 | 107 | // Open this jBox when it is being initialized 108 | onInit: function () { 109 | this.open(); 110 | 111 | // Here we store the index we used for this jBox 112 | this.AvatarIndex = DemoAvatars.current; 113 | }, 114 | 115 | // When the jBox is created, add the click events to the buttons 116 | onCreated: function () { 117 | 118 | // Create the containers for the liked or disliked avatars 119 | if (initial) { 120 | $('
').appendTo($('body')); 121 | $('
').appendTo($('body')); 122 | } 123 | 124 | $.each(this.footer.find('button'), function (index, el) { 125 | 126 | // Adding the click events for the buttons in the footer 127 | $(el).on('click', function () { 128 | 129 | // Storing a global var that the user clicked on a button 130 | DemoAvatars.clicked = true; 131 | 132 | // When a user clicks a button close the tooltips 133 | DemoAvatars.AvatarsTooltipLike && DemoAvatars.AvatarsTooltipLike.close(); 134 | DemoAvatars.AvatarsTooltipDislike && DemoAvatars.AvatarsTooltipDislike.close(); 135 | 136 | // When we click a button, the jBox disappears, let's tell this jBox that we removed it 137 | this.AvatarRemoved = true; 138 | 139 | // Did we like or dislike the avatar? 140 | var liked = $(el).hasClass('button-heart'); 141 | 142 | // Slide the jBox to the left or right depending on which button the user clicked 143 | this.animate('slide' + (liked ? 'Right' : 'Left'), { 144 | 145 | // Once the jBox is removed, hide it and show the avatar in the collection 146 | complete: function () { 147 | this.wrapper.css('display', 'none'); 148 | 149 | // Which container to use 150 | var collectionContainer = liked ? $('#LikedAvatars') : $('#DislikedAvatars'); 151 | 152 | // If there if not enough space for the avatars to show in one line remove the first one 153 | if (collectionContainer.find('div[data-avatar-tooltip]').length && ((collectionContainer.find('div[data-avatar-tooltip]').length + 1) * $(collectionContainer.find('div[data-avatar-tooltip]')[0]).outerWidth(true) > collectionContainer.outerWidth())) { 154 | $(collectionContainer.find('div[data-avatar-tooltip]')[0]).remove(); 155 | } 156 | 157 | // Add the avatar to the collection 158 | this.animate('popIn', { 159 | element: $('
').append($('
').html('')).appendTo(collectionContainer) 160 | }); 161 | 162 | // Attach the avatar tooltip 163 | DemoAvatars.AvatarsTooltip && DemoAvatars.AvatarsTooltip.attach(); 164 | 165 | }.bind(this) 166 | }); 167 | 168 | // Open another Avatar jBox 169 | generateAvatarJBox(); 170 | 171 | }.bind(this)); 172 | }.bind(this)); 173 | }, 174 | 175 | // When we open the jBox, set the new content and show the tooltips if it's the initial jBox 176 | onOpen: function () { 177 | 178 | // Set title and content depending on current index 179 | this.setTitle(DemoAvatars.Avatars[DemoAvatars.current]); 180 | this.content.css({ 181 | backgroundImage: 'url(https://stephanwagner.me/img/jBox/avatar/' + DemoAvatars.Avatars[DemoAvatars.current] + '.svg)' 182 | }); 183 | 184 | // If it's the initial jBox, show the tooltips after a short delay 185 | initial && setTimeout(function () { 186 | 187 | // We are creating the two tooltips in a loop as they are very similar 188 | $.each(['Dislike', 'Like'], function (index, item) { 189 | 190 | // We store the tooltips in the global var so we can refer to them later 191 | DemoAvatars['AvatarsTooltip' + item] = new jBox('Tooltip', { 192 | theme: 'TooltipBorder', 193 | addClass: 'AvatarsTooltip AvatarsTooltip' + item, 194 | minWidth: 110, 195 | content: item, 196 | position: { 197 | y: 'bottom' 198 | }, 199 | offset: { 200 | y: 5 201 | }, 202 | target: '#AvatarsInitial .jBox-footer .button-' + (item == 'Like' ? 'heart' : 'cross'), 203 | animation: 'move', 204 | zIndex: 11000, 205 | 206 | // Abort opening the tooltips when we clicked on a like or dislike button already 207 | onOpen: function () { 208 | DemoAvatars.clicked && this.close(); 209 | } 210 | }).open(); 211 | 212 | }); 213 | 214 | }, 500); 215 | } 216 | }); 217 | 218 | // If it's the initial jBox add onClose events 219 | initial && (jBoxAvatar.options.onClose = function () { 220 | // Loop through all avatar jBoxes and close them if they are not removed yet 221 | $.each(DemoAvatars.Modals, function (index, jBox) { 222 | jBox.id != 'AvatarsInitial' && !jBox.AvatarRemoved && jBox.close(); 223 | }.bind(this)); 224 | 225 | // Remove the collection containers with a sliding animation 226 | $.each(['Liked', 'Disliked'], function (index, item) { 227 | this.animate('slide' + (item == 'Liked' ? 'Right' : 'Left'), { 228 | element: $('#' + item + 'Avatars'), 229 | complete: function () { 230 | $('#' + item + 'Avatars').remove(); 231 | } 232 | }); 233 | }.bind(this)); 234 | 235 | // Close the tooltips 236 | DemoAvatars.AvatarsTooltipLike && DemoAvatars.AvatarsTooltipLike.close(); 237 | DemoAvatars.AvatarsTooltipDislike && DemoAvatars.AvatarsTooltipDislike.close(); 238 | }); 239 | 240 | // If it's the initial jBox add onCloseComplete events 241 | initial && (jBoxAvatar.options.onCloseComplete = function () { 242 | // Loop through all modal jBoxes and remove them from DOM 243 | $.each(DemoAvatars.Modals, function (index, jBox) { 244 | jBox.destroy(); 245 | delete DemoAvatars.Modals[jBox.id]; 246 | }); 247 | 248 | // Remove the tooltips from DOM 249 | DemoAvatars.AvatarsTooltipLike && DemoAvatars.AvatarsTooltipLike.destroy(); 250 | DemoAvatars.AvatarsTooltipDislike && DemoAvatars.AvatarsTooltipDislike.destroy(); 251 | }); 252 | 253 | // Store the jBox in the modal collection 254 | DemoAvatars.Modals[jBoxAvatar.id] = jBoxAvatar; 255 | } 256 | 257 | // On domready, add the click event to the button 258 | 259 | $(function () { 260 | 261 | $('#DemoAvatars').on('click', function () { 262 | generateAvatarJBox(true); 263 | }); 264 | 265 | }); 266 | -------------------------------------------------------------------------------- /demo/html/js/playground-inception.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | $('#DemoInception').on('click', function () { 4 | openInceptionModal(); 5 | }); 6 | 7 | }); 8 | 9 | var inceptionLevel = 1; 10 | var offsetLevel = 0; 11 | 12 | function openInceptionModal() { 13 | if (offsetLevel > 5) { 14 | offsetLevel = 0; 15 | } 16 | 17 | new jBox('Modal', { 18 | width: 360, 19 | addClass: 'inception-modal', 20 | overlayClass: 'inception-overlay', 21 | zIndex: 'auto', 22 | draggable: 'title', 23 | closeOnClick: false, 24 | closeButton: 'title', 25 | title: 'Inception level ' + inceptionLevel++, 26 | offset: { 27 | x: offsetLevel * 15, 28 | y: offsetLevel * 15 29 | }, 30 | content: ( 31 | '

You can open new modal windows within this modal window.

' + 32 | '

' 33 | ), 34 | onCreated: function () { 35 | // Add tooltip 36 | this.tooltip = new jBox('Tooltip', { 37 | theme: 'TooltipBorder', 38 | attach: '[data-inception-tooltip]', 39 | getContent: 'data-inception-tooltip', 40 | zIndex: 'auto', 41 | delayOpen: 600 42 | }); 43 | 44 | // Add button event 45 | this.content.find('.inception-modal-button').on('click', function () { 46 | openInceptionModal(); 47 | }); 48 | }, 49 | // Remove modal from DOM when it's closed 50 | onCloseComplete: function () { 51 | this.destroy(); 52 | this.tooltip && this.tooltip.destroy(); 53 | } 54 | }).open(); 55 | 56 | offsetLevel++; 57 | } 58 | -------------------------------------------------------------------------------- /demo/html/js/playground-login.js: -------------------------------------------------------------------------------- 1 | // Playground Demo: Login 2 | 3 | // We are setting up a global variable where we can adjust html and texts 4 | 5 | var jBoxLogin = { 6 | jBox: null, 7 | 8 | // The html of each of the content containers 9 | 10 | html: { 11 | login: '', 12 | register: '' 13 | }, 14 | 15 | // Corresponding titles for content elements 16 | 17 | title: { 18 | login: 'Login', 19 | register: 'Create new account' 20 | }, 21 | 22 | // These tooltips will show when a textelemet gets focus 23 | 24 | textfieldTooltips: { 25 | loginUsername: 'For this demo the username is "username"', 26 | loginPassword: 'For this demo the password is "password"', 27 | registerUsername: 'Choose a unique username', 28 | registerEmail: 'Your email address', 29 | registerPassword: 'Be tricky, use numbers and special characters' 30 | } 31 | }; 32 | 33 | $(function () { 34 | 35 | if (!$('#DemoLogin').length) { 36 | return; 37 | } 38 | 39 | // On domready create the login modal 40 | 41 | jBoxLogin.jBox = new jBox('Modal', { 42 | 43 | // Unique id for CSS access 44 | id: 'jBoxLogin', 45 | 46 | // Dimensions 47 | width: 320, 48 | height: 350, 49 | 50 | // Attach to elements 51 | attach: '#DemoLogin', 52 | 53 | // Create the content with the html provided in global var 54 | content: '
' + jBoxLogin.html.login + jBoxLogin.html.register + '
', 55 | 56 | // Adjust header when scroll is blocked 57 | blockScrollAdjust: ['header'], 58 | 59 | // When the jBox is being initialized add internal functions 60 | onInit: function () { 61 | 62 | // Internal function to show content 63 | this.showContent = function (id, force) { 64 | 65 | // Abort if an ajax call is loading 66 | if (!force && $('#LoginWrapper').hasClass('request-running')) return null; 67 | 68 | // Set the title depending on id 69 | this.setTitle(jBoxLogin.title[id]); 70 | 71 | // Show content depending on id 72 | $('.login-container.active').removeClass('active'); 73 | $('#LoginContainer-' + id).addClass('active'); 74 | 75 | // Remove error tooltips 76 | $.each(jBoxLogin.textfieldTooltips, function (id, tt) { 77 | $('#' + id).data('jBoxTextfieldError') && $('#' + id).data('jBoxTextfieldError').close(); 78 | }); 79 | 80 | }; 81 | 82 | // Initially show content for login 83 | this.showContent('login', true); 84 | 85 | // Add focus and blur events to textfields 86 | $.each(jBoxLogin.textfieldTooltips, function (id, tt) { 87 | 88 | // Focus an textelement 89 | $('#' + id).on('focus', function () { 90 | 91 | // When there is an error tooltip close it 92 | $(this).data('jBoxTextfieldError') && $(this).data('jBoxTextfieldError').close(); 93 | 94 | // Remove the error state from the textfield 95 | $(this).removeClass('textfield-error'); 96 | 97 | // Store the tooltip jBox in the elements data 98 | if (!$(this).data('jBoxTextfieldTooltip')) { 99 | $(this).data('jBoxTextfieldTooltip', new jBox('Tooltip', { 100 | width: 310, 101 | theme: 'TooltipSmall', 102 | addClass: 'LoginTooltipSmall', 103 | target: $(this), 104 | position: { 105 | x: 'left', 106 | y: 'top' 107 | }, 108 | outside: 'y', 109 | offset: { 110 | y: 6, 111 | x: 8 112 | }, 113 | pointer: 'left:17', 114 | content: tt, 115 | animation: 'move' 116 | })); 117 | } 118 | 119 | $(this).data('jBoxTextfieldTooltip').open(); 120 | 121 | // Loose focus of textelement 122 | }).on('blur', function () { 123 | $(this).data('jBoxTextfieldTooltip').close(); 124 | }); 125 | }); 126 | 127 | // Internal function to show errors 128 | this.showError = function (element, message) { 129 | 130 | if (!element.data('errorTooltip')) { 131 | element.data('errorTooltip', new jBox('Tooltip', { 132 | width: 310, 133 | theme: 'TooltipError', 134 | addClass: 'LoginTooltipError', 135 | target: element, 136 | position: { 137 | x: 'left', 138 | y: 'top' 139 | }, 140 | outside: 'y', 141 | offset: { 142 | y: 6 143 | }, 144 | pointer: 'left:9', 145 | content: message, 146 | animation: 'move' 147 | })); 148 | } 149 | 150 | element.data('errorTooltip').open(); 151 | }; 152 | 153 | // Internal function to change checkbox state 154 | this.toggleCheckbox = function () { 155 | // Abort if an ajax call is loading 156 | if ($('#LoginWrapper').hasClass('request-running')) return null; 157 | 158 | $('.login-checkbox').toggleClass('login-checkbox-active'); 159 | }; 160 | 161 | // Add checkbox events to checkbox and label 162 | $('.login-checkbox, .login-checkbox-label').on('click', function () { 163 | this.toggleCheckbox(); 164 | }.bind(this)); 165 | 166 | // Parse an ajax repsonse 167 | this.parseResponse = function (response) { 168 | try { 169 | response = JSON.parse(response.responseText || response); 170 | } catch (e) {} 171 | return response; 172 | }; 173 | 174 | // Show a global error 175 | this.globalError = function () { 176 | new jBox('Notice', { 177 | color: 'red', 178 | content: 'Oops, something went wrong.', 179 | attributes: { 180 | x: 'right', 181 | y: 'bottom' 182 | } 183 | }); 184 | }; 185 | 186 | // Internal function to disable or enable the form while request is running 187 | this.startRequest = function () { 188 | this.toggleRequest(); 189 | }.bind(this); 190 | 191 | this.completeRequest = function () { 192 | this.toggleRequest(true); 193 | }.bind(this); 194 | 195 | this.toggleRequest = function (enable) { 196 | $('#LoginWrapper')[enable ? 'removeClass' : 'addClass']('request-running'); 197 | $('#LoginWrapper button')[enable ? 'removeClass' : 'addClass']('loading-bar'); 198 | $('#LoginWrapper input, #LoginWrapper button').attr('disabled', enable ? false : 'disabled'); 199 | }.bind(this); 200 | 201 | // Bind ajax login function to login button 202 | $('#LoginContainer-login button').on('click', function () { 203 | $.ajax({ 204 | url: 'https://stephanwagner.me/PlaygroundLogin/login', 205 | data: { 206 | username: $('#loginUsername').val(), 207 | password: $('#loginPassword').val(), 208 | remember: $('.login-checkbox').hasClass('login-checkbox-active') ? 1 : 0 209 | }, 210 | method: 'get', 211 | beforeSend: function () { 212 | this.startRequest(); 213 | }.bind(this), 214 | 215 | // Ajax call successfull 216 | success: function (response) { 217 | this.completeRequest(); 218 | response = this.parseResponse(response); 219 | 220 | // Login successfull 221 | if (response.success) { 222 | this.close(); 223 | new jBox('Notice', { 224 | color: 'green', 225 | content: 'You are now logged in', 226 | attributes: { 227 | x: 'right', 228 | y: 'bottom' 229 | } 230 | }); 231 | // Login failed 232 | } else { 233 | // Shake submit button 234 | this.animate('shake', { 235 | element: $('#LoginContainer-login button') 236 | }); 237 | 238 | if (response.errors) { 239 | // Show error on textfields, for login no error tooltips neccessary, username or password is wrong 240 | $('#loginUsername, #loginPassword').addClass('textfield-error'); 241 | } else { 242 | // Backend error 243 | this.globalError(); 244 | } 245 | } 246 | }.bind(this), 247 | 248 | // Ajax call failed 249 | error: function () { 250 | this.completeRequest(); 251 | this.animate('shake', { 252 | element: $('#LoginContainer-login button') 253 | }); 254 | this.globalError(); 255 | }.bind(this) 256 | }); 257 | 258 | }.bind(this)); 259 | 260 | // Bind ajax register function to register button 261 | $('#LoginContainer-register button').on('click', function () { 262 | $.ajax({ 263 | url: 'https://stephanwagner.me/PlaygroundLogin/register', 264 | data: { 265 | username: $('#registerUsername').val(), 266 | email: $('#registerEmail').val(), 267 | password: $('#registerPassword').val() 268 | }, 269 | method: 'get', 270 | beforeSend: function () { 271 | this.startRequest(); 272 | }.bind(this), 273 | 274 | success: function (response) { 275 | this.completeRequest(); 276 | response = this.parseResponse(response); 277 | 278 | // Registration successfull 279 | if (response.success) { 280 | this.close(); 281 | new jBox('Notice', { 282 | color: 'green', 283 | content: 'Your account was created', 284 | attributes: { 285 | x: 'right', 286 | y: 'bottom' 287 | } 288 | }); 289 | 290 | // Registration failed 291 | } else { 292 | // Shake submit button 293 | this.animate('shake', { 294 | element: $('#LoginContainer-register button') 295 | }); 296 | 297 | if (response.errors) { 298 | // Loop through errors and open tooltips 299 | $.each(response.errors, function (id, error) { 300 | var id_selector = 'register' + (id).substr(0, 1).toUpperCase() + (id).substr(1); 301 | $('#' + id_selector).addClass('textfield-error'); 302 | 303 | if (!$('#' + id_selector).data('jBoxTextfieldError')) { 304 | $('#' + id_selector).data('jBoxTextfieldError', new jBox('Tooltip', { 305 | width: 310, 306 | theme: 'TooltipError', 307 | addClass: 'LoginTooltipError', 308 | target: $('#' + id_selector), 309 | position: { 310 | x: 'left', 311 | y: 'top' 312 | }, 313 | outside: 'y', 314 | offset: { 315 | y: 6, 316 | x: 8 317 | }, 318 | pointer: 'left:17', 319 | //content: error, 320 | animation: 'move' 321 | })); 322 | } 323 | $('#' + id_selector).data('jBoxTextfieldError').setContent(error).open(); 324 | }); 325 | 326 | // Backend error 327 | } else { 328 | this.globalError(); 329 | } 330 | } 331 | }.bind(this), 332 | 333 | // Ajax call failed 334 | error: function () { 335 | this.completeRequest(); 336 | this.animate('shake', { 337 | element: $('#RegisterContainer-login button') 338 | }); 339 | this.globalError(); 340 | }.bind(this) 341 | }); 342 | }.bind(this)); 343 | }, 344 | onOpen: function () { 345 | // Go back to login when we open the modal 346 | this.showContent('login', true); 347 | }, 348 | onClose: function () { 349 | // Remove error tooltips 350 | $.each(jBoxLogin.textfieldTooltips, function (id, tt) { 351 | $('#' + id).data('jBoxTextfieldError') && $('#' + id).data('jBoxTextfieldError').close(); 352 | }); 353 | } 354 | }); 355 | }); 356 | -------------------------------------------------------------------------------- /dist/jBox.css: -------------------------------------------------------------------------------- 1 | .jBox-wrapper { 2 | text-align: left; 3 | box-sizing: border-box; 4 | } 5 | 6 | .jBox-title, 7 | .jBox-content, 8 | .jBox-container { 9 | position: relative; 10 | word-break: break-word; 11 | box-sizing: border-box; 12 | } 13 | 14 | .jBox-container { 15 | background: #fff; 16 | } 17 | 18 | .jBox-content { 19 | padding: 8px 12px; 20 | overflow-x: hidden; 21 | overflow-y: auto; 22 | transition: opacity .2s; 23 | } 24 | 25 | .jBox-footer { 26 | box-sizing: border-box; 27 | } 28 | 29 | .jBox-Tooltip .jBox-container, 30 | .jBox-Mouse .jBox-container { 31 | border-radius: 4px; 32 | box-shadow: 0 0 3px rgba(0, 0, 0, 0.25); 33 | } 34 | 35 | .jBox-Tooltip .jBox-title, 36 | .jBox-Mouse .jBox-title { 37 | padding: 8px 10px 0; 38 | font-weight: bold; 39 | } 40 | 41 | .jBox-Tooltip.jBox-hasTitle .jBox-content, 42 | .jBox-Mouse.jBox-hasTitle .jBox-content { 43 | padding-top: 5px; 44 | } 45 | 46 | .jBox-Mouse { 47 | pointer-events: none; 48 | } 49 | 50 | .jBox-pointer { 51 | position: absolute; 52 | overflow: hidden; 53 | box-sizing: border-box; 54 | } 55 | 56 | .jBox-pointer:after { 57 | content: ''; 58 | width: 20px; 59 | height: 20px; 60 | position: absolute; 61 | background: #fff; 62 | transform: rotate(45deg); 63 | box-sizing: border-box; 64 | } 65 | 66 | .jBox-pointer-top { 67 | top: 0; 68 | } 69 | 70 | .jBox-pointer-top:after { 71 | left: 5px; 72 | top: 6px; 73 | box-shadow: -1px -1px 2px rgba(0, 0, 0, 0.15); 74 | } 75 | 76 | .jBox-pointer-right { 77 | right: 0; 78 | } 79 | 80 | .jBox-pointer-right:after { 81 | top: 5px; 82 | right: 6px; 83 | box-shadow: 1px -1px 2px rgba(0, 0, 0, 0.15); 84 | } 85 | 86 | .jBox-pointer-left { 87 | left: 0; 88 | } 89 | 90 | .jBox-pointer-left:after { 91 | top: 5px; 92 | left: 6px; 93 | box-shadow: -1px 1px 2px rgba(0, 0, 0, 0.15); 94 | } 95 | 96 | .jBox-pointer-bottom { 97 | bottom: 0; 98 | } 99 | 100 | .jBox-pointer-bottom:after { 101 | left: 5px; 102 | bottom: 6px; 103 | box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.15); 104 | } 105 | 106 | .jBox-pointer-top, .jBox-pointer-bottom { 107 | width: 30px; 108 | height: 12px; 109 | } 110 | 111 | .jBox-pointer-left, .jBox-pointer-right { 112 | width: 12px; 113 | height: 30px; 114 | } 115 | 116 | .jBox-Modal .jBox-container { 117 | border-radius: 4px; 118 | } 119 | 120 | .jBox-Modal .jBox-container, .jBox-Modal.jBox-closeButton-box:before { 121 | box-shadow: 0 3px 15px rgba(0, 0, 0, 0.4), 0 0 5px rgba(0, 0, 0, 0.4); 122 | } 123 | 124 | .jBox-Modal .jBox-content { 125 | padding: 15px 20px; 126 | } 127 | 128 | .jBox-Modal .jBox-title { 129 | border-radius: 4px 4px 0 0; 130 | padding: 15px 20px; 131 | background: #fafafa; 132 | border-bottom: 1px solid #eee; 133 | } 134 | 135 | .jBox-Modal.jBox-closeButton-title .jBox-title { 136 | padding-right: 65px; 137 | } 138 | 139 | .jBox-Modal .jBox-footer { 140 | border-radius: 0 0 4px 4px; 141 | } 142 | 143 | .jBox-closeButton { 144 | z-index: 1; 145 | cursor: pointer; 146 | position: absolute; 147 | box-sizing: border-box; 148 | } 149 | 150 | .jBox-closeButton svg { 151 | position: absolute; 152 | top: 50%; 153 | right: 50%; 154 | } 155 | 156 | .jBox-closeButton path { 157 | fill: #aaa; 158 | transition: fill .2s; 159 | } 160 | 161 | .jBox-closeButton:hover path { 162 | fill: #888; 163 | } 164 | 165 | .jBox-overlay .jBox-closeButton { 166 | top: 0; 167 | right: 0; 168 | width: 40px; 169 | height: 40px; 170 | } 171 | 172 | .jBox-overlay .jBox-closeButton svg { 173 | width: 20px; 174 | height: 20px; 175 | margin-top: -10px; 176 | margin-right: -10px; 177 | } 178 | 179 | .jBox-overlay .jBox-closeButton path { 180 | fill: #ddd; 181 | } 182 | 183 | .jBox-overlay .jBox-closeButton:hover path { 184 | fill: #fff; 185 | } 186 | 187 | .jBox-closeButton-title .jBox-closeButton { 188 | top: 0; 189 | right: 0; 190 | bottom: 0; 191 | width: 50px; 192 | } 193 | 194 | .jBox-closeButton-title svg { 195 | width: 12px; 196 | height: 12px; 197 | margin-top: -6px; 198 | margin-right: -6px; 199 | } 200 | 201 | .jBox-closeButton-box { 202 | box-sizing: border-box; 203 | } 204 | 205 | .jBox-closeButton-box .jBox-closeButton { 206 | top: -8px; 207 | right: -10px; 208 | width: 24px; 209 | height: 24px; 210 | background: #fff; 211 | border-radius: 50%; 212 | } 213 | 214 | .jBox-closeButton-box .jBox-closeButton svg { 215 | width: 10px; 216 | height: 10px; 217 | margin-top: -5px; 218 | margin-right: -5px; 219 | } 220 | 221 | .jBox-closeButton-box:before { 222 | content: ''; 223 | position: absolute; 224 | top: -8px; 225 | right: -10px; 226 | width: 24px; 227 | height: 24px; 228 | border-radius: 50%; 229 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); 230 | } 231 | 232 | .jBox-closeButton-box.jBox-pointerPosition-top:before { 233 | top: 5px; 234 | } 235 | 236 | .jBox-closeButton-box.jBox-pointerPosition-right:before { 237 | right: 2px; 238 | } 239 | 240 | .jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton { 241 | background: #fafafa; 242 | } 243 | 244 | .jBox-overlay { 245 | position: fixed; 246 | top: 0; 247 | left: 0; 248 | width: 100%; 249 | height: 100%; 250 | background-color: rgba(0, 0, 0, 0.82); 251 | } 252 | 253 | .jBox-footer { 254 | background: #fafafa; 255 | border-top: 1px solid #eee; 256 | padding: 8px 10px; 257 | border-radius: 0 0 3px 3px; 258 | } 259 | 260 | body[class^="jBox-blockScroll-"], 261 | body[class*=" jBox-blockScroll-"] { 262 | overflow: hidden; 263 | } 264 | 265 | .jBox-draggable { 266 | cursor: move; 267 | } 268 | 269 | @keyframes jBoxLoading { 270 | to { 271 | transform: rotate(360deg); 272 | } 273 | } 274 | 275 | .jBox-loading .jBox-content { 276 | opacity: .2; 277 | } 278 | 279 | .jBox-loading-spinner .jBox-content { 280 | min-height: 38px !important; 281 | min-width: 38px !important; 282 | opacity: 0; 283 | } 284 | 285 | .jBox-spinner { 286 | box-sizing: border-box; 287 | position: absolute; 288 | top: 50%; 289 | left: 50%; 290 | width: 24px; 291 | height: 24px; 292 | margin-top: -12px; 293 | margin-left: -12px; 294 | } 295 | 296 | .jBox-spinner:before { 297 | display: block; 298 | box-sizing: border-box; 299 | content: ''; 300 | width: 24px; 301 | height: 24px; 302 | border-radius: 50%; 303 | border: 2px solid rgba(0, 0, 0, 0.2); 304 | border-top-color: rgba(0, 0, 0, 0.8); 305 | animation: jBoxLoading .6s linear infinite; 306 | } 307 | 308 | .jBox-countdown { 309 | border-radius: 4px 4px 0 0; 310 | z-index: 0; 311 | background: #000; 312 | opacity: .2; 313 | position: absolute; 314 | top: 0; 315 | left: 0; 316 | right: 0; 317 | height: 3px; 318 | overflow: hidden; 319 | } 320 | 321 | .jBox-countdown-inner { 322 | top: 0; 323 | right: 0; 324 | width: 100%; 325 | height: 3px; 326 | position: absolute; 327 | background: #fff; 328 | } 329 | 330 | [class^="jBox-animated-"], 331 | [class*=" jBox-animated-"] { 332 | animation-fill-mode: both; 333 | } 334 | 335 | @keyframes jBox-tada { 336 | 0% { 337 | transform: scale(1); 338 | } 339 | 10%, 340 | 20% { 341 | transform: scale(0.8) rotate(-4deg); 342 | } 343 | 30%, 344 | 50%, 345 | 70%, 346 | 90% { 347 | transform: scale(1.2) rotate(4deg); 348 | } 349 | 40%, 350 | 60%, 351 | 80% { 352 | transform: scale(1.2) rotate(-4deg); 353 | } 354 | 100% { 355 | transform: scale(1) rotate(0); 356 | } 357 | } 358 | 359 | .jBox-animated-tada { 360 | animation: jBox-tada 1s; 361 | } 362 | 363 | @keyframes jBox-tadaSmall { 364 | 0% { 365 | transform: scale(1); 366 | } 367 | 10%, 368 | 20% { 369 | transform: scale(0.9) rotate(-2deg); 370 | } 371 | 30%, 372 | 50%, 373 | 70%, 374 | 90% { 375 | transform: scale(1.1) rotate(2deg); 376 | } 377 | 40%, 378 | 60%, 379 | 80% { 380 | transform: scale(1.1) rotate(-2deg); 381 | } 382 | 100% { 383 | transform: scale(1) rotate(0); 384 | } 385 | } 386 | 387 | .jBox-animated-tadaSmall { 388 | animation: jBox-tadaSmall 1s; 389 | } 390 | 391 | @keyframes jBox-flash { 392 | 0%, 393 | 50%, 394 | 100% { 395 | opacity: 1; 396 | } 397 | 25%, 398 | 75% { 399 | opacity: 0; 400 | } 401 | } 402 | 403 | .jBox-animated-flash { 404 | animation: jBox-flash .5s; 405 | } 406 | 407 | @keyframes jBox-shake { 408 | 0%, 409 | 100% { 410 | transform: translateX(0); 411 | } 412 | 20%, 413 | 60% { 414 | transform: translateX(-6px); 415 | } 416 | 40%, 417 | 80% { 418 | transform: translateX(6px); 419 | } 420 | } 421 | 422 | .jBox-animated-shake { 423 | animation: jBox-shake .4s; 424 | } 425 | 426 | @keyframes jBox-pulseUp { 427 | 0% { 428 | transform: scale(1); 429 | } 430 | 50% { 431 | transform: scale(1.15); 432 | } 433 | 100% { 434 | transform: scale(1); 435 | } 436 | } 437 | 438 | .jBox-animated-pulseUp { 439 | animation: jBox-pulseUp .25s; 440 | } 441 | 442 | @keyframes jBox-pulseDown { 443 | 0% { 444 | transform: scale(1); 445 | } 446 | 50% { 447 | transform: scale(0.85); 448 | } 449 | 100% { 450 | transform: scale(1); 451 | } 452 | } 453 | 454 | .jBox-animated-pulseDown { 455 | animation: jBox-pulseDown .25s; 456 | } 457 | 458 | @keyframes jBox-popIn { 459 | 0% { 460 | transform: scale(0); 461 | } 462 | 50% { 463 | transform: scale(1.1); 464 | } 465 | 100% { 466 | transform: scale(1); 467 | } 468 | } 469 | 470 | .jBox-animated-popIn { 471 | animation: jBox-popIn .25s; 472 | } 473 | 474 | @keyframes jBox-popOut { 475 | 0% { 476 | transform: scale(1); 477 | } 478 | 50% { 479 | transform: scale(1.1); 480 | } 481 | 100% { 482 | transform: scale(0); 483 | } 484 | } 485 | 486 | .jBox-animated-popOut { 487 | animation: jBox-popOut .25s; 488 | } 489 | 490 | @keyframes jBox-fadeIn { 491 | 0% { 492 | opacity: 0; 493 | } 494 | 100% { 495 | opacity: 1; 496 | } 497 | } 498 | 499 | .jBox-animated-fadeIn { 500 | animation: jBox-fadeIn .2s; 501 | } 502 | 503 | @keyframes jBox-fadeOut { 504 | 0% { 505 | opacity: 1; 506 | } 507 | 100% { 508 | opacity: 0; 509 | } 510 | } 511 | 512 | .jBox-animated-fadeOut { 513 | animation: jBox-fadeOut .2s; 514 | } 515 | 516 | @keyframes jBox-slideUp { 517 | 0% { 518 | transform: translateY(0); 519 | } 520 | 100% { 521 | transform: translateY(-300px); 522 | opacity: 0; 523 | } 524 | } 525 | 526 | .jBox-animated-slideUp { 527 | animation: jBox-slideUp .4s; 528 | } 529 | 530 | @keyframes jBox-slideRight { 531 | 0% { 532 | transform: translateX(0); 533 | } 534 | 100% { 535 | transform: translateX(300px); 536 | opacity: 0; 537 | } 538 | } 539 | 540 | .jBox-animated-slideRight { 541 | animation: jBox-slideRight .4s; 542 | } 543 | 544 | @keyframes jBox-slideDown { 545 | 0% { 546 | transform: translateY(0); 547 | } 548 | 100% { 549 | transform: translateY(300px); 550 | opacity: 0; 551 | } 552 | } 553 | 554 | .jBox-animated-slideDown { 555 | animation: jBox-slideDown .4s; 556 | } 557 | 558 | @keyframes jBox-slideLeft { 559 | 0% { 560 | transform: translateX(0); 561 | } 562 | 100% { 563 | transform: translateX(-300px); 564 | opacity: 0; 565 | } 566 | } 567 | 568 | .jBox-animated-slideLeft { 569 | animation: jBox-slideLeft .4s; 570 | } 571 | 572 | /*# sourceMappingURL=jBox.css.map */ 573 | -------------------------------------------------------------------------------- /dist/jBox.min.css: -------------------------------------------------------------------------------- 1 | .jBox-wrapper{text-align:left;box-sizing:border-box}.jBox-container,.jBox-content,.jBox-title{position:relative;word-break:break-word;box-sizing:border-box}.jBox-container{background:#fff}.jBox-content{padding:8px 12px;overflow-x:hidden;overflow-y:auto;transition:opacity .2s}.jBox-footer{box-sizing:border-box}.jBox-Mouse .jBox-container,.jBox-Tooltip .jBox-container{border-radius:4px;box-shadow:0 0 3px rgba(0,0,0,.25)}.jBox-Mouse .jBox-title,.jBox-Tooltip .jBox-title{padding:8px 10px 0;font-weight:700}.jBox-Mouse.jBox-hasTitle .jBox-content,.jBox-Tooltip.jBox-hasTitle .jBox-content{padding-top:5px}.jBox-Mouse{pointer-events:none}.jBox-pointer{position:absolute;overflow:hidden;box-sizing:border-box}.jBox-pointer:after{content:'';width:20px;height:20px;position:absolute;background:#fff;transform:rotate(45deg);box-sizing:border-box}.jBox-pointer-top{top:0}.jBox-pointer-top:after{left:5px;top:6px;box-shadow:-1px -1px 2px rgba(0,0,0,.15)}.jBox-pointer-right{right:0}.jBox-pointer-right:after{top:5px;right:6px;box-shadow:1px -1px 2px rgba(0,0,0,.15)}.jBox-pointer-left{left:0}.jBox-pointer-left:after{top:5px;left:6px;box-shadow:-1px 1px 2px rgba(0,0,0,.15)}.jBox-pointer-bottom{bottom:0}.jBox-pointer-bottom:after{left:5px;bottom:6px;box-shadow:1px 1px 2px rgba(0,0,0,.15)}.jBox-pointer-bottom,.jBox-pointer-top{width:30px;height:12px}.jBox-pointer-left,.jBox-pointer-right{width:12px;height:30px}.jBox-Modal .jBox-container{border-radius:4px}.jBox-Modal .jBox-container,.jBox-Modal.jBox-closeButton-box:before{box-shadow:0 3px 15px rgba(0,0,0,.4),0 0 5px rgba(0,0,0,.4)}.jBox-Modal .jBox-content{padding:15px 20px}.jBox-Modal .jBox-title{border-radius:4px 4px 0 0;padding:15px 20px;background:#fafafa;border-bottom:1px solid #eee}.jBox-Modal.jBox-closeButton-title .jBox-title{padding-right:65px}.jBox-Modal .jBox-footer{border-radius:0 0 4px 4px}.jBox-closeButton{z-index:1;cursor:pointer;position:absolute;box-sizing:border-box}.jBox-closeButton svg{position:absolute;top:50%;right:50%}.jBox-closeButton path{fill:#aaa;transition:fill .2s}.jBox-closeButton:hover path{fill:#888}.jBox-overlay .jBox-closeButton{top:0;right:0;width:40px;height:40px}.jBox-overlay .jBox-closeButton svg{width:20px;height:20px;margin-top:-10px;margin-right:-10px}.jBox-overlay .jBox-closeButton path{fill:#ddd}.jBox-overlay .jBox-closeButton:hover path{fill:#fff}.jBox-closeButton-title .jBox-closeButton{top:0;right:0;bottom:0;width:50px}.jBox-closeButton-title svg{width:12px;height:12px;margin-top:-6px;margin-right:-6px}.jBox-closeButton-box{box-sizing:border-box}.jBox-closeButton-box .jBox-closeButton{top:-8px;right:-10px;width:24px;height:24px;background:#fff;border-radius:50%}.jBox-closeButton-box .jBox-closeButton svg{width:10px;height:10px;margin-top:-5px;margin-right:-5px}.jBox-closeButton-box:before{content:'';position:absolute;top:-8px;right:-10px;width:24px;height:24px;border-radius:50%;box-shadow:0 0 5px rgba(0,0,0,.3)}.jBox-closeButton-box.jBox-pointerPosition-top:before{top:5px}.jBox-closeButton-box.jBox-pointerPosition-right:before{right:2px}.jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton{background:#fafafa}.jBox-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.82)}.jBox-footer{background:#fafafa;border-top:1px solid #eee;padding:8px 10px;border-radius:0 0 3px 3px}body[class*=" jBox-blockScroll-"],body[class^=jBox-blockScroll-]{overflow:hidden}.jBox-draggable{cursor:move}@keyframes jBoxLoading{to{transform:rotate(360deg)}}.jBox-loading .jBox-content{opacity:.2}.jBox-loading-spinner .jBox-content{min-height:38px!important;min-width:38px!important;opacity:0}.jBox-spinner{box-sizing:border-box;position:absolute;top:50%;left:50%;width:24px;height:24px;margin-top:-12px;margin-left:-12px}.jBox-spinner:before{display:block;box-sizing:border-box;content:'';width:24px;height:24px;border-radius:50%;border:2px solid rgba(0,0,0,.2);border-top-color:rgba(0,0,0,.8);animation:jBoxLoading .6s linear infinite}.jBox-countdown{border-radius:4px 4px 0 0;z-index:0;background:#000;opacity:.2;position:absolute;top:0;left:0;right:0;height:3px;overflow:hidden}.jBox-countdown-inner{top:0;right:0;width:100%;height:3px;position:absolute;background:#fff}[class*=" jBox-animated-"],[class^=jBox-animated-]{animation-fill-mode:both}@keyframes jBox-tada{0%{transform:scale(1)}10%,20%{transform:scale(.8) rotate(-4deg)}30%,50%,70%,90%{transform:scale(1.2) rotate(4deg)}40%,60%,80%{transform:scale(1.2) rotate(-4deg)}100%{transform:scale(1) rotate(0)}}.jBox-animated-tada{animation:jBox-tada 1s}@keyframes jBox-tadaSmall{0%{transform:scale(1)}10%,20%{transform:scale(.9) rotate(-2deg)}30%,50%,70%,90%{transform:scale(1.1) rotate(2deg)}40%,60%,80%{transform:scale(1.1) rotate(-2deg)}100%{transform:scale(1) rotate(0)}}.jBox-animated-tadaSmall{animation:jBox-tadaSmall 1s}@keyframes jBox-flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}.jBox-animated-flash{animation:jBox-flash .5s}@keyframes jBox-shake{0%,100%{transform:translateX(0)}20%,60%{transform:translateX(-6px)}40%,80%{transform:translateX(6px)}}.jBox-animated-shake{animation:jBox-shake .4s}@keyframes jBox-pulseUp{0%{transform:scale(1)}50%{transform:scale(1.15)}100%{transform:scale(1)}}.jBox-animated-pulseUp{animation:jBox-pulseUp .25s}@keyframes jBox-pulseDown{0%{transform:scale(1)}50%{transform:scale(.85)}100%{transform:scale(1)}}.jBox-animated-pulseDown{animation:jBox-pulseDown .25s}@keyframes jBox-popIn{0%{transform:scale(0)}50%{transform:scale(1.1)}100%{transform:scale(1)}}.jBox-animated-popIn{animation:jBox-popIn .25s}@keyframes jBox-popOut{0%{transform:scale(1)}50%{transform:scale(1.1)}100%{transform:scale(0)}}.jBox-animated-popOut{animation:jBox-popOut .25s}@keyframes jBox-fadeIn{0%{opacity:0}100%{opacity:1}}.jBox-animated-fadeIn{animation:jBox-fadeIn .2s}@keyframes jBox-fadeOut{0%{opacity:1}100%{opacity:0}}.jBox-animated-fadeOut{animation:jBox-fadeOut .2s}@keyframes jBox-slideUp{0%{transform:translateY(0)}100%{transform:translateY(-300px);opacity:0}}.jBox-animated-slideUp{animation:jBox-slideUp .4s}@keyframes jBox-slideRight{0%{transform:translateX(0)}100%{transform:translateX(300px);opacity:0}}.jBox-animated-slideRight{animation:jBox-slideRight .4s}@keyframes jBox-slideDown{0%{transform:translateY(0)}100%{transform:translateY(300px);opacity:0}}.jBox-animated-slideDown{animation:jBox-slideDown .4s}@keyframes jBox-slideLeft{0%{transform:translateX(0)}100%{transform:translateX(-300px);opacity:0}}.jBox-animated-slideLeft{animation:jBox-slideLeft .4s} -------------------------------------------------------------------------------- /dist/plugins/jBox.Confirm.css: -------------------------------------------------------------------------------- 1 | .jBox-Confirm .jBox-content { 2 | text-align: center; 3 | padding: 46px 35px; 4 | } 5 | 6 | @media (max-width: 500px) { 7 | .jBox-Confirm .jBox-content { 8 | padding: 32px 20px; 9 | } 10 | } 11 | 12 | .jBox-Confirm-footer { 13 | height: 46px; 14 | } 15 | 16 | .jBox-Confirm-button { 17 | display: block; 18 | float: left; 19 | cursor: pointer; 20 | text-align: center; 21 | width: 50%; 22 | line-height: 46px; 23 | height: 46px; 24 | overflow: hidden; 25 | padding: 0 10px; 26 | transition: color .2s, background-color .2s; 27 | box-sizing: border-box; 28 | } 29 | 30 | .jBox-Confirm-button-cancel { 31 | border-bottom-left-radius: 4px; 32 | background: #ddd; 33 | color: #666; 34 | } 35 | 36 | .jBox-Confirm-button-cancel:hover, .jBox-Confirm-button-cancel:active { 37 | background: #ccc; 38 | } 39 | 40 | .jBox-Confirm-button-cancel:active { 41 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2); 42 | } 43 | 44 | .jBox-Confirm-button-submit { 45 | border-bottom-right-radius: 4px; 46 | background: #7d0; 47 | color: #fff; 48 | } 49 | 50 | .jBox-Confirm-button-submit:hover, .jBox-Confirm-button-submit:active { 51 | background: #6c0; 52 | } 53 | 54 | .jBox-Confirm-button-submit:active { 55 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2); 56 | } 57 | 58 | /*# sourceMappingURL=jBox.Confirm.css.map */ 59 | -------------------------------------------------------------------------------- /dist/plugins/jBox.Confirm.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jBox Confirm plugin: Add a confirm dialog to links, buttons, etc. 3 | * 4 | * Author: Stephan Wagner (https://stephanwagner.me) 5 | * 6 | * License: MIT (https://opensource.org/licenses/MIT) 7 | * 8 | * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js) 9 | */ 10 | 11 | function jBoxConfirmWrapper(jBox, jQuery) { 12 | 13 | new jBox.plugin('Confirm', { 14 | 15 | 16 | // Options (https://stephanwagner.me/jBox/options#options-confirm) 17 | 18 | confirmButton: 'Submit', // Text for the submit button 19 | cancelButton: 'Cancel', // Text for the cancel button 20 | confirm: null, // Function to execute when clicking the submit button. By default jBox will use the onclick or href attribute in that order if found 21 | cancel: null, // Function to execute when clicking the cancel button 22 | closeOnConfirm: true, // Close jBox when the user clicks the confirm button 23 | target: window, 24 | fixed: true, 25 | attach: '[data-confirm]', 26 | getContent: 'data-confirm', 27 | content: 'Do you really want to do this?', 28 | minWidth: 360, 29 | maxWidth: 500, 30 | blockScroll: true, 31 | closeOnEsc: true, 32 | closeOnClick: false, 33 | closeButton: false, 34 | overlay: true, 35 | animation: 'zoomIn', 36 | preventDefault: true, 37 | 38 | 39 | // Triggered when jBox is attached to the element 40 | 41 | _onAttach: function (el) 42 | { 43 | // Extract the href or the onclick event if no submit event is passed 44 | if (!this.options.confirm) { 45 | var submit = el.attr('onclick') ? el.attr('onclick') : ( 46 | el.attr('href') ? ( 47 | el.attr('target') ? 'window.open("' + el.attr('href') + '", "' + el.attr('target') + '");' : 'window.location.href = "' + el.attr('href') + '";' 48 | ) : ''); 49 | el.prop('onclick', null).data('jBox-Confirm-submit', submit); 50 | } 51 | }, 52 | 53 | 54 | // Triggered when jBox was created 55 | 56 | _onCreated: function () 57 | { 58 | // Add modal class to mimic jBox modal 59 | this.wrapper.addClass('jBox-Modal'); 60 | 61 | // Add a footer to the jBox container 62 | this.footer = jQuery('