├── example ├── pattern.png ├── script.js └── script.css ├── .prettierrc ├── .travis.yml ├── .gitattributes ├── package.json ├── .gitignore ├── LICENSE ├── src ├── toastify.css └── toastify.js ├── CHANGELOG.md ├── index.html └── README.md /example/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skjnldsv/toastify-js/master/example/pattern.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "printWidth": 80, 4 | "tabWidth": 2, 5 | "singleQuote": false, 6 | "trailingComma": "es5", 7 | "parser": "babylon", 8 | "noSemi": false 9 | } 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | script: 5 | - echo "skipping tests" 6 | deploy: 7 | skip_cleanup: true 8 | provider: npm 9 | email: $NPM_USERNAME 10 | api_key: $NPM_TOKEN 11 | on: 12 | branch: master -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "toastify-js", 3 | "version": "1.7.0", 4 | "description": 5 | "Toastify is a lightweight, vanilla JS toast notification library.", 6 | "main": "./src/toastify.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/apvarun/toastify-js.git" 10 | }, 11 | "keywords": ["toastify", "javascript", "notifications", "toast"], 12 | "author": "Varun A P", 13 | "license": "MIT", 14 | "bugs": { 15 | "url": "https://github.com/apvarun/toastify-js/issues" 16 | }, 17 | "homepage": "https://github.com/apvarun/toastify-js#readme" 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 apvarun 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 | -------------------------------------------------------------------------------- /example/script.js: -------------------------------------------------------------------------------- 1 | var bgColors = [ 2 | "linear-gradient(to right, #00b09b, #96c93d)", 3 | "linear-gradient(to right, #ff5f6d, #ffc371)", 4 | ], 5 | i = 0; 6 | 7 | Toastify({ 8 | text: "Hi", 9 | duration: 4500, 10 | destination: "https://github.com/apvarun/toastify-js", 11 | newWindow: true, 12 | gravity: "top", 13 | position: 'left', 14 | }).showToast(); 15 | 16 | setTimeout(function() { 17 | Toastify({ 18 | text: "Simple JavaScript Toasts", 19 | gravity: "top", 20 | position: 'center', 21 | backgroundColor: "#0f3443", 22 | }).showToast(); 23 | }, 1000); 24 | 25 | // Options for the toast 26 | var options = { 27 | text: "Happy toasting!", 28 | duration: 2500, 29 | callback: function() { 30 | console.log("Toast hidden"); 31 | Toastify.reposition(); 32 | }, 33 | close: true, 34 | backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", 35 | }; 36 | 37 | // Initializing the toast 38 | var myToast = Toastify(options); 39 | 40 | // Toast after delay 41 | setTimeout(function() { 42 | myToast.showToast(); 43 | }, 4500); 44 | 45 | setTimeout(function() { 46 | Toastify({ 47 | text: "Highly customizable", 48 | gravity: "bottom", 49 | position: 'left', 50 | close: true, 51 | backgroundColor: "linear-gradient(to right, #ff5f6d, #ffc371)", 52 | }).showToast(); 53 | }, 3000); 54 | 55 | // Displaying toast on manual action `Try` 56 | document.getElementById("new-toast").addEventListener("click", function() { 57 | Toastify({ 58 | text: "I am a toast", 59 | duration: 3000, 60 | close: i % 3 ? true : false, 61 | backgroundColor: bgColors[i % 2], 62 | }).showToast(); 63 | i++; 64 | }); 65 | -------------------------------------------------------------------------------- /src/toastify.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Toastify js 1.7.0 3 | * https://github.com/apvarun/toastify-js 4 | * @license MIT licensed 5 | * 6 | * Copyright (C) 2018 Varun A P 7 | */ 8 | 9 | .toastify { 10 | padding: 12px 20px; 11 | color: #ffffff; 12 | display: inline-block; 13 | box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3); 14 | background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5); 15 | background: linear-gradient(135deg, #73a5ff, #5477f5); 16 | position: fixed; 17 | opacity: 0; 18 | transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1); 19 | border-radius: 2px; 20 | cursor: pointer; 21 | text-decoration: none; 22 | max-width: calc(50% - 20px); 23 | z-index: 2147483647; 24 | } 25 | 26 | .toastify.on { 27 | opacity: 1; 28 | } 29 | 30 | .toast-close { 31 | opacity: 0.4; 32 | padding: 0 5px; 33 | } 34 | 35 | .toastify-right { 36 | right: 15px; 37 | } 38 | 39 | .toastify-left { 40 | left: 15px; 41 | } 42 | 43 | .toastify-top { 44 | top: -150px; 45 | } 46 | 47 | .toastify-bottom { 48 | bottom: -150px; 49 | } 50 | 51 | .toastify-rounded { 52 | border-radius: 25px; 53 | } 54 | 55 | .toastify-avatar { 56 | width: 1.5em; 57 | height: 1.5em; 58 | margin: 0 5px; 59 | border-radius: 2px; 60 | } 61 | 62 | .toastify-center { 63 | margin-left: auto; 64 | margin-right: auto; 65 | left: 0; 66 | right: 0; 67 | max-width: fit-content; 68 | } 69 | 70 | @media only screen and (max-width: 360px) { 71 | .toastify-right, .toastify-left { 72 | margin-left: auto; 73 | margin-right: auto; 74 | left: 0; 75 | right: 0; 76 | max-width: fit-content; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /example/script.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | html, body { 6 | height: 100%; 7 | } 8 | 9 | body { 10 | font-family: Helvetica, Arial, sans-serif; 11 | background-size: 100%; 12 | margin: 0; 13 | padding: 0; 14 | color: #424242; 15 | } 16 | 17 | .container { 18 | overflow: hidden; 19 | display: flex; 20 | height: 100%; 21 | justify-content: center; 22 | flex-direction: column; 23 | align-items: center; 24 | background-color: whitesmoke; 25 | background-image: url("./pattern.png"); 26 | } 27 | 28 | .hidden { 29 | display: none; 30 | } 31 | 32 | .docs { 33 | display: flex; 34 | justify-content: center; 35 | flex-direction: column; 36 | align-items: center; 37 | background-color: white; 38 | border: 1px solid #e3e3e3; 39 | padding: 20px 20px; 40 | width: 60%; 41 | border-radius: 4px; 42 | } 43 | 44 | .docs h2 { 45 | margin-top: 0px; 46 | } 47 | 48 | code p { 49 | margin: 2px; 50 | } 51 | 52 | .pad-left { 53 | padding-left: 20px; 54 | } 55 | 56 | .buttons { 57 | margin: 20px; 58 | display: flex; 59 | flex-wrap: wrap; 60 | justify-content: center; 61 | } 62 | 63 | .button { 64 | overflow: hidden; 65 | margin: 10px; 66 | padding: 12px 12px; 67 | cursor: pointer; 68 | -webkit-transition: all 200ms ease-in-out; 69 | transition: all 200ms ease-in-out; 70 | text-align: center; 71 | white-space: nowrap; 72 | text-decoration: none; 73 | text-transform: none; 74 | text-transform: capitalize; 75 | border-radius: 4px; 76 | font-size: 13px; 77 | font-weight: 500; 78 | line-height: 1.3; 79 | min-width: 100px; 80 | display: inline-block; 81 | box-shadow: 0 5px 20px rgba(22, 22, 22, 0.15); 82 | color: #5477f5; 83 | background-color: Snow; 84 | border: 1px solid #5477f5; 85 | } 86 | 87 | .button:hover { 88 | color: #FFFFFF; 89 | background: linear-gradient(135deg, #73a5ff, #5477f5); 90 | border: 1px solid transparent; 91 | } 92 | 93 | .repo { 94 | margin: 10px; 95 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All the changes made to toastify-js library. 4 | 5 | ## [1.7.0] - 2020-03-01 6 | 7 | * To be able to set `stopOnFocus` for toasts without close icon 8 | * Bugfix: `duration` can be infinite by setting as `0` 9 | * Bugfix: Prevent errors when parent node is removed from DOM while using frameworks 10 | * Bugfix: IE 9/10 compatibility fix 11 | 12 | ## [1.6.2] - 2020-01-03 13 | 14 | * Bugfix: Closing the toast when custom close icon from icon fonts are used 15 | 16 | ## [1.6.1] - 2019-06-29 17 | 18 | * Bugfix: Disabling `stopOnFocus` 19 | 20 | ## [1.6.0] - 2019-06-29 21 | 22 | * **Deprecation Warning**: Migrating from `positionLeft` property to `position` 23 | * Property `position` to support `center` as a value along with `left` and `right` - Useful for centering toast messages in the page 24 | 25 | ## [1.5.0] - 2019-05-30 26 | 27 | * Added persistant toast option with ability to programatically close it 28 | 29 | ## [1.4.0] - 2019-05-12 30 | 31 | * **Breaking Change**: Manually import CSS while using as module in your modern JavaScript applications 32 | * Ability to pause the toast dismiss timer on hover (Using `stopOnFocus` property) 33 | 34 | ## [1.3.2] - 2018-12-6 35 | 36 | * Added z-index attribute 37 | 38 | ## [1.2.1] - 2018-05-31 39 | 40 | * Added support for Classes. Now custom classes can be added to the toast while creating it 41 | 42 | ## [1.2.0] - 2018-03-05 43 | 44 | * Fix issue when `destination` and `close` options is used at the same time 45 | 46 | ## [1.1.0] - 2018-02-18 47 | 48 | * Browser support extended to IE10+ without any polyfills 49 | 50 | ## [1.0.0] - 2018-02-17 51 | 52 | * Support for modules 53 | 54 | ## [0.0.6] - 2017-09-09 55 | 56 | * Support for changing background [Options] 57 | * Optimized toast positioning logic 58 | * Added changelog for library update tracking 59 | 60 | ## [0.0.5] - 2017-09-06 61 | 62 | * Support for toast messages on mobile screens 63 | * Tweaked close icon 64 | 65 | ## [0.0.4] - 2017-09-05 66 | 67 | * Support for positioning of toasts on the page 68 | 69 | ## [0.0.3] - 2017-09-05 70 | 71 | * Close buton for toasts [Options] 72 | 73 | ## [0.0.2] - 2017-09-04 74 | 75 | * Option to add on-click link for toasts 76 | * Updated comments for code readability 77 | 78 | ## [0.0.1] - 2017-09-02 79 | 80 | * Initial Release 81 | * Added Preview page 82 | * Optimized function structure 83 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Toastify JS - Pure JavaScript Toast Notificaton Library 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |

Toastify JS

20 |
21 |

Better notification messages

22 |
23 | Try 24 | Docs 25 | Tweet 27 |
28 |
29 |

Usage

30 | 31 |

Toastify({

32 |

text: "This is a toast",

33 |

duration: 3000

34 |

}).showToast();

35 |
36 |
37 |
38 | 40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 | 58 | 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Toastify 2 | 3 | ![forthebadge](https://forthebadge.com/images/badges/made-with-javascript.svg) 4 | ![forthebadge](https://forthebadge.com/images/badges/built-with-love.svg) 5 | 6 | [![toastify-js](https://img.shields.io/badge/toastify--js-1.7.0-brightgreen.svg)](https://www.npmjs.com/package/toastify-js) 7 | 8 | Toastify is a lightweight, vanilla JS toast notification library. 9 | 10 | ## Demo 11 | 12 | [Click here](https://apvarun.github.io/toastify-js/) 13 | 14 | ## Features 15 | 16 | * Multiple stacked notifications 17 | * Customizable 18 | * No blocking of execution thread 19 | 20 | ### Customization options 21 | 22 | * Notification Text 23 | * Duration 24 | * Toast background color 25 | * Close icon display 26 | * Display position 27 | 28 | ## Installation 29 | 30 | #### Toastify now supports installation via NPM 31 | 32 | * Run the below command to add toastify-js to your exisitng or new project. 33 | 34 | ``` 35 | npm install --save toastify-js 36 | ``` 37 | 38 | or 39 | 40 | ``` 41 | yarn add toastify-js -S 42 | ``` 43 | 44 | * Import toastify-js into your module to start using it. 45 | 46 | ``` 47 | import Toastify from 'toastify-js' 48 | ``` 49 | 50 | You can use the default CSS from Toastify as below and later override it or choose to write your own CSS. 51 | 52 | ``` 53 | import "toastify-js/src/toastify.css" 54 | ``` 55 | 56 | #### Adding ToastifyJs to HTML page using the traditional method 57 | 58 | To start using **Toastify**, add the following CSS on to your page. 59 | 60 | ```html 61 | 62 | ``` 63 | 64 | And the script at the bottom of the page 65 | 66 | ```html 67 | 68 | ``` 69 | 70 | > Files are delivered via the CDN service provided by [jsdeliver](https://www.jsdelivr.com/) 71 | 72 | ## Documentation 73 | 74 | ```javascript 75 | Toastify({ 76 | text: "This is a toast", 77 | duration: 3000, 78 | destination: "https://github.com/apvarun/toastify-js", 79 | newWindow: true, 80 | close: true, 81 | gravity: "top", // `top` or `bottom` 82 | position: 'left', // `left`, `center` or `right` 83 | backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", 84 | stopOnFocus: true, // Prevents dismissing of toast on hover 85 | onClick: function(){} // Callback after click 86 | }).showToast(); 87 | ``` 88 | 89 | > Toast messages will be centered on devices with screen width less than 360px. 90 | 91 | * See the [changelog](https://github.com/apvarun/toastify-js/blob/master/CHANGELOG.md) 92 | 93 | ### Add own custom classes 94 | 95 | If you want to use custom classes on the toast for customizing (like info or warning for example), you can do that as follows: 96 | 97 | ```javascript 98 | Toastify({ 99 | text: "This is a toast", 100 | backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", 101 | className: "info", 102 | }).showToast(); 103 | ``` 104 | 105 | Multiple classes also can be assigned as a string, with spaces between class names. 106 | 107 | ## API 108 | 109 | | Option Key | type | Usage | Defaults | 110 | |-----------------|----------------------|----------------------------------------------------------------------------|-------------| 111 | | text | string | Message to be displayed in the toast | "Hi there!" | 112 | | duration | number | Duration for which the toast should be displayed.
0 for permanent toast | 3000 | 113 | | selector | string | CSS Selector on which the toast should be added | body | 114 | | destination | URL string | URL to which the browser should be navigated on click of the toast | | 115 | | newWindow | boolean | Decides whether the `destination` should be opened in a new window or not | false | 116 | | close | boolean | To show the close icon or not | false | 117 | | gravity | "top" or "bottom" | To show the toast from top or bottom | "top" | 118 | | position | "left" or "right" | To show the toast on left or right | "right" | 119 | | backgroundColor | CSS background value | Sets the background color of the toast | | 120 | | avatar | URL string | Image/icon to be shown before text | | 121 | | className | string | Ability to provide custom class name for further customization | | 122 | | stopOnFocus | boolean | To stop timer when hovered over the toast (Only if duration is set) | true | 123 | | callback | Function | Invoked when the toast is dismissed | | 124 | | onClick | Function | Invoked when the toast is clicked | | 125 | 126 | ## Browsers support 127 | 128 | | ![][ie]
IE / Edge | ![][firefox]
Firefox | ![][chrome]
Chrome | ![][safari]
Safari | ![][opera]
Opera | 129 | | ---------------------- | ------------------------- | ----------------------- | ----------------------- | --------------------- | 130 | | IE10, IE11, Edge | last 10 versions | last 10 versions | last 10 versions | last 10 versions | 131 | 132 | ## Contributors 133 | 134 | 135 | 136 | 137 | 138 | 139 | 144 | 149 | 154 | 159 | 164 | 169 | 174 | 175 | 176 | 181 | 186 | 191 | 196 | 201 | 206 | 211 | 212 | 213 | 218 | 223 | 224 |
140 | haydster7 142 |
haydster7
143 |
145 | fiatjaf 147 |
fiatjaf
148 |
150 | victorfeijo 152 |
victorfeijo
153 |
155 | t12ung 157 |
t12ung
158 |
160 | Tadaz 162 |
Tadaz
163 |
165 | mort3za 167 |
mort3za
168 |
170 | Wachiwi 172 |
Wachiwi
173 |
177 | gavinhungry 179 |
gavinhungry
180 |
182 | juliushaertl 184 |
juliushaertl
185 |
187 | skjnldsv 189 |
skjnldsv
190 |
192 | danielkaiser80 194 |
danielkaiser80
195 |
197 | d4rn0k 199 |
d4rn0k
200 |
202 | GodzzZZZ 204 |
GodzzZZZ
205 |
207 | caiomoura1994 209 |
caiomoura1994
210 |
214 | rndevfx 216 |
rndevfx
217 |
219 | apvarun 221 |
apvarun
222 |
225 | 226 | 227 | 228 | ## License 229 | 230 | MIT © [Varun A P](https://github.com/apvarun) 231 | 232 | [ie]: https://raw.githubusercontent.com/godban/browsers-support-badges/master/src/images/edge.png 233 | [firefox]: https://raw.githubusercontent.com/godban/browsers-support-badges/master/src/images/firefox.png 234 | [chrome]: https://raw.githubusercontent.com/godban/browsers-support-badges/master/src/images/chrome.png 235 | [safari]: https://raw.githubusercontent.com/godban/browsers-support-badges/master/src/images/safari.png 236 | [opera]: https://raw.githubusercontent.com/godban/browsers-support-badges/master/src/images/opera.png 237 | -------------------------------------------------------------------------------- /src/toastify.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Toastify js 1.7.0 3 | * https://github.com/apvarun/toastify-js 4 | * @license MIT licensed 5 | * 6 | * Copyright (C) 2018 Varun A P 7 | */ 8 | (function(root, factory) { 9 | if (typeof module === "object" && module.exports) { 10 | module.exports = factory(); 11 | } else { 12 | root.Toastify = factory(); 13 | } 14 | })(this, function(global) { 15 | // Object initialization 16 | var Toastify = function(options) { 17 | // Returning a new init object 18 | return new Toastify.lib.init(options); 19 | }, 20 | // Library version 21 | version = "1.7.0"; 22 | 23 | // Defining the prototype of the object 24 | Toastify.lib = Toastify.prototype = { 25 | toastify: version, 26 | 27 | constructor: Toastify, 28 | 29 | // Initializing the object with required parameters 30 | init: function(options) { 31 | // Verifying and validating the input object 32 | if (!options) { 33 | options = {}; 34 | } 35 | 36 | // Creating the options object 37 | this.options = {}; 38 | 39 | this.toastElement = null; 40 | 41 | // Validating the options 42 | this.options.text = options.text || "Hi there!"; // Display message 43 | this.options.duration = options.duration === 0 ? 0 : options.duration || 3000; // Display duration 44 | this.options.selector = options.selector; // Parent selector 45 | this.options.callback = options.callback || function() {}; // Callback after display 46 | this.options.destination = options.destination; // On-click destination 47 | this.options.newWindow = options.newWindow || false; // Open destination in new window 48 | this.options.close = options.close || false; // Show toast close icon 49 | this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : "toastify-top"; // toast position - top or bottom 50 | this.options.positionLeft = options.positionLeft || false; // toast position - left or right 51 | this.options.position = options.position || ''; // toast position - left or right 52 | this.options.backgroundColor = options.backgroundColor; // toast background color 53 | this.options.avatar = options.avatar || ""; // img element src - url or a path 54 | this.options.className = options.className || ""; // additional class names for the toast 55 | this.options.stopOnFocus = options.stopOnFocus === undefined? true: options.stopOnFocus; // stop timeout on focus 56 | this.options.onClick = options.onClick; // Callback after click 57 | 58 | // Returning the current object for chaining functions 59 | return this; 60 | }, 61 | 62 | // Building the DOM element 63 | buildToast: function() { 64 | // Validating if the options are defined 65 | if (!this.options) { 66 | throw "Toastify is not initialized"; 67 | } 68 | 69 | // Creating the DOM object 70 | var divElement = document.createElement("div"); 71 | divElement.className = "toastify on " + this.options.className; 72 | 73 | // Positioning toast to left or right or center 74 | if (!!this.options.position) { 75 | divElement.className += " toastify-" + this.options.position; 76 | } else { 77 | // To be depreciated in further versions 78 | if (this.options.positionLeft === true) { 79 | divElement.className += " toastify-left"; 80 | console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.') 81 | } else { 82 | // Default position 83 | divElement.className += " toastify-right"; 84 | } 85 | } 86 | 87 | // Assigning gravity of element 88 | divElement.className += " " + this.options.gravity; 89 | 90 | if (this.options.backgroundColor) { 91 | divElement.style.background = this.options.backgroundColor; 92 | } 93 | 94 | // Adding the toast message 95 | divElement.innerHTML = this.options.text; 96 | 97 | if (this.options.avatar !== "") { 98 | var avatarElement = document.createElement("img"); 99 | avatarElement.src = this.options.avatar; 100 | 101 | avatarElement.className = "toastify-avatar"; 102 | 103 | if (this.options.position == "left" || this.options.positionLeft === true) { 104 | // Adding close icon on the left of content 105 | divElement.appendChild(avatarElement); 106 | } else { 107 | // Adding close icon on the right of content 108 | divElement.insertAdjacentElement("beforeend", avatarElement); 109 | } 110 | } 111 | 112 | // Adding a close icon to the toast 113 | if (this.options.close === true) { 114 | // Create a span for close element 115 | var closeElement = document.createElement("span"); 116 | closeElement.innerHTML = "✖"; 117 | 118 | closeElement.className = "toast-close"; 119 | 120 | // Triggering the removal of toast from DOM on close click 121 | closeElement.addEventListener( 122 | "click", 123 | function(event) { 124 | event.stopPropagation(); 125 | this.removeElement(this.toastElement); 126 | window.clearTimeout(this.toastElement.timeOutValue); 127 | }.bind(this) 128 | ); 129 | 130 | //Calculating screen width 131 | var width = window.innerWidth > 0 ? window.innerWidth : screen.width; 132 | 133 | // Adding the close icon to the toast element 134 | // Display on the right if screen width is less than or equal to 360px 135 | if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) { 136 | // Adding close icon on the left of content 137 | divElement.insertAdjacentElement("afterbegin", closeElement); 138 | } else { 139 | // Adding close icon on the right of content 140 | divElement.appendChild(closeElement); 141 | } 142 | } 143 | 144 | // Clear timeout while toast is focused 145 | if (this.options.stopOnFocus && this.options.duration > 0) { 146 | const self = this; 147 | // stop countdown 148 | divElement.addEventListener( 149 | "mouseover", 150 | function(event) { 151 | window.clearTimeout(divElement.timeOutValue); 152 | } 153 | ) 154 | // add back the timeout 155 | divElement.addEventListener( 156 | "mouseleave", 157 | function() { 158 | divElement.timeOutValue = window.setTimeout( 159 | function() { 160 | // Remove the toast from DOM 161 | self.removeElement(divElement); 162 | }, 163 | self.options.duration 164 | ) 165 | } 166 | ) 167 | } 168 | 169 | // Adding an on-click destination path 170 | if (typeof this.options.destination !== "undefined") { 171 | divElement.addEventListener( 172 | "click", 173 | function(event) { 174 | event.stopPropagation(); 175 | if (this.options.newWindow === true) { 176 | window.open(this.options.destination, "_blank"); 177 | } else { 178 | window.location = this.options.destination; 179 | } 180 | }.bind(this) 181 | ); 182 | } 183 | 184 | if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") { 185 | divElement.addEventListener( 186 | "click", 187 | function(event) { 188 | event.stopPropagation(); 189 | this.options.onClick(); 190 | }.bind(this) 191 | ); 192 | } 193 | 194 | // Returning the generated element 195 | return divElement; 196 | }, 197 | 198 | // Displaying the toast 199 | showToast: function() { 200 | // Creating the DOM object for the toast 201 | this.toastElement = this.buildToast(); 202 | 203 | // Getting the root element to with the toast needs to be added 204 | var rootElement; 205 | if (typeof this.options.selector === "undefined") { 206 | rootElement = document.body; 207 | } else { 208 | rootElement = document.getElementById(this.options.selector); 209 | } 210 | 211 | // Validating if root element is present in DOM 212 | if (!rootElement) { 213 | throw "Root element is not defined"; 214 | } 215 | 216 | // Adding the DOM element 217 | rootElement.insertBefore(this.toastElement, rootElement.firstChild); 218 | 219 | // Repositioning the toasts in case multiple toasts are present 220 | Toastify.reposition(); 221 | 222 | if (this.options.duration > 0) { 223 | this.toastElement.timeOutValue = window.setTimeout( 224 | function() { 225 | // Remove the toast from DOM 226 | this.removeElement(this.toastElement); 227 | }.bind(this), 228 | this.options.duration 229 | ); // Binding `this` for function invocation 230 | } 231 | 232 | // Supporting function chaining 233 | return this; 234 | }, 235 | 236 | hideToast: function() { 237 | if (this.toastElement.timeOutValue) { 238 | clearTimeout(this.toastElement.timeOutValue); 239 | } 240 | this.removeElement(this.toastElement); 241 | }, 242 | 243 | // Removing the element from the DOM 244 | removeElement: function(toastElement) { 245 | // Hiding the element 246 | // toastElement.classList.remove("on"); 247 | toastElement.className = toastElement.className.replace(" on", ""); 248 | 249 | // Removing the element from DOM after transition end 250 | window.setTimeout( 251 | function() { 252 | // Remove the elemenf from the DOM, only when the parent node was not removed before. 253 | if (toastElement.parentNode) { 254 | toastElement.parentNode.removeChild(toastElement); 255 | } 256 | 257 | // Calling the callback function 258 | this.options.callback.call(toastElement); 259 | 260 | // Repositioning the toasts again 261 | Toastify.reposition(); 262 | }.bind(this), 263 | 400 264 | ); // Binding `this` for function invocation 265 | }, 266 | }; 267 | 268 | // Positioning the toasts on the DOM 269 | Toastify.reposition = function() { 270 | // Top margins with gravity 271 | var topLeftOffsetSize = { 272 | top: 15, 273 | bottom: 15, 274 | }; 275 | var topRightOffsetSize = { 276 | top: 15, 277 | bottom: 15, 278 | }; 279 | var offsetSize = { 280 | top: 15, 281 | bottom: 15, 282 | }; 283 | 284 | // Get all toast messages on the DOM 285 | var allToasts = document.getElementsByClassName("toastify"); 286 | 287 | var classUsed; 288 | 289 | // Modifying the position of each toast element 290 | for (var i = 0; i < allToasts.length; i++) { 291 | // Getting the applied gravity 292 | if (containsClass(allToasts[i], "toastify-top") === true) { 293 | classUsed = "toastify-top"; 294 | } else { 295 | classUsed = "toastify-bottom"; 296 | } 297 | 298 | var height = allToasts[i].offsetHeight; 299 | classUsed = classUsed.substr(9, classUsed.length-1) 300 | // Spacing between toasts 301 | var offset = 15; 302 | 303 | var width = window.innerWidth > 0 ? window.innerWidth : screen.width; 304 | 305 | // Show toast in center if screen with less than or qual to 360px 306 | if (width <= 360) { 307 | // Setting the position 308 | allToasts[i].style[classUsed] = offsetSize[classUsed] + "px"; 309 | 310 | offsetSize[classUsed] += height + offset; 311 | } else { 312 | if (containsClass(allToasts[i], "toastify-left") === true) { 313 | // Setting the position 314 | allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px"; 315 | 316 | topLeftOffsetSize[classUsed] += height + offset; 317 | } else { 318 | // Setting the position 319 | allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px"; 320 | 321 | topRightOffsetSize[classUsed] += height + offset; 322 | } 323 | } 324 | } 325 | 326 | // Supporting function chaining 327 | return this; 328 | }; 329 | 330 | function containsClass(elem, yourClass) { 331 | if (!elem || typeof yourClass !== "string") { 332 | return false; 333 | } else if ( 334 | elem.className && 335 | elem.className 336 | .trim() 337 | .split(/\s+/gi) 338 | .indexOf(yourClass) > -1 339 | ) { 340 | return true; 341 | } else { 342 | return false; 343 | } 344 | } 345 | 346 | // Setting up the prototype for the init object 347 | Toastify.lib.init.prototype = Toastify.lib; 348 | 349 | // Returning the Toastify function to be assigned to the window object/module 350 | return Toastify; 351 | }); 352 | --------------------------------------------------------------------------------