notifIt.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. /*
  2. * notifIt! by @naoxink
  3. */
  4. (function(root, factory) {
  5. if (typeof define === 'function' && define.amd) {
  6. // AMD. Register as an anonymous module.
  7. define(factory);
  8. } else {
  9. // Browser globals
  10. var package = factory(root.b);
  11. root.notif = package.notif;
  12. root.notif_confirm = package.notif_confirm;
  13. root.notif_prompt = package.notif_prompt;
  14. }
  15. }(this, function() {
  16. // Notification
  17. function notif(config) {
  18. // Util stuff
  19. var create_close_button = function() {
  20. return $('<span>', {
  21. 'id': 'notifIt_close',
  22. 'html': '&times'
  23. });
  24. }
  25. var create_notification = function() {
  26. var div = $('<div>', {
  27. 'id': 'ui_notifIt'
  28. });
  29. var p = $('<p>', {
  30. html: defaults.msg
  31. });
  32. div.append(p);
  33. return div;
  34. }
  35. // We love jQuery
  36. var $ = jQuery;
  37. var destroy = function() {
  38. $("#ui_notifIt").remove();
  39. clearTimeout(window.notifit_timeout);
  40. }
  41. var dismiss = function() {
  42. clearTimeout(window.notifit_timeout);
  43. if (!defaults.fade) {
  44. // Set animations
  45. if (defaults.animations &&
  46. defaults.animations[defaults.animation] &&
  47. defaults.animations[defaults.animation][defaults.position] &&
  48. defaults.animations[defaults.animation][defaults.position].out &&
  49. defaults.animations[defaults.animation][defaults.position].out.start &&
  50. defaults.animations[defaults.animation][defaults.position].out.end) {
  51. animation1 = defaults.animations[defaults.animation][defaults.position].out.start
  52. animation2 = defaults.animations[defaults.animation][defaults.position].out.end
  53. } else if (defaults.animations[defaults.available_animations[0]] &&
  54. defaults.animations[defaults.available_animations[0]][defaults.position] &&
  55. defaults.animations[defaults.available_animations[0]][defaults.position].out &&
  56. defaults.animations[defaults.available_animations[0]][defaults.position].out.start &&
  57. defaults.animations[defaults.available_animations[0]][defaults.position].out.end) {
  58. animation1 = defaults.animations[defaults.available_animations[0]][defaults.position].out.start
  59. animation2 = defaults.animations[defaults.available_animations[0]][defaults.position].out.end
  60. } else {
  61. throw new Error('Invalid animation')
  62. }
  63. // Execute animations
  64. $("#ui_notifIt").animate(animation1, 100, function() {
  65. $("#ui_notifIt").animate(animation2, 100, function() {
  66. $("#ui_notifIt").remove();
  67. if (defaults.callback) {
  68. defaults.callback();
  69. }
  70. });
  71. });
  72. } else {
  73. // jQuery's fade, why create my own?
  74. $("#ui_notifIt").fadeOut("slow", function() {
  75. $("#ui_notifIt").remove();
  76. if (defaults.callback) {
  77. defaults.callback();
  78. }
  79. });
  80. }
  81. }
  82. destroy()
  83. // Global timeout
  84. window.notifit_timeout = null;
  85. // Mid position
  86. var mid = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) / 2;
  87. // Available positions
  88. var available_positions = ['left', 'center', 'right', 'bottom'];
  89. // Default config
  90. var defaults = {
  91. type: "default",
  92. width: 400,
  93. height: 60,
  94. position: "right",
  95. autohide: 1,
  96. msg: "This is my default message",
  97. opacity: 1,
  98. multiline: 0,
  99. fade: 0,
  100. bgcolor: "",
  101. color: "",
  102. timeout: 5000,
  103. zindex: null,
  104. offset: 0,
  105. callback: null,
  106. clickable: false,
  107. animation: 'slide'
  108. };
  109. // Extend with new params
  110. $.extend(defaults, config);
  111. // Animation config
  112. // ** Maybe create an external js with only animations for easier customizing? **
  113. defaults.animations = {}
  114. // Slide animation [DEFAULT]
  115. defaults.animations.slide = {
  116. 'center': {
  117. 'css_start': {
  118. "top": parseInt(0 - (defaults.height + 10)),
  119. "left": mid - parseInt(defaults.width / 2)
  120. },
  121. 'in': {
  122. 'top': parseInt(10 + defaults.offset)
  123. },
  124. 'out': {
  125. 'start': {
  126. 'top': parseInt(defaults.height - (defaults.height / 2))
  127. },
  128. 'end': {
  129. 'top': parseInt(0 - (defaults.height * 2))
  130. }
  131. }
  132. },
  133. 'bottom': {
  134. 'css_start': {
  135. "top": 'auto',
  136. "bottom": parseInt(0 - (defaults.height + 10)),
  137. "left": mid - parseInt(defaults.width / 2)
  138. },
  139. 'in': {
  140. 'bottom': parseInt(10 + defaults.offset)
  141. },
  142. 'out': {
  143. 'start': {
  144. 'bottom': parseInt(defaults.height - (defaults.height / 2))
  145. },
  146. 'end': {
  147. 'bottom': parseInt(0 - (defaults.height * 2))
  148. }
  149. }
  150. },
  151. 'right': {
  152. 'css_start': {
  153. "right": parseInt(0 - (defaults.width + 10)),
  154. "right": parseInt(0 - (defaults.width * 2))
  155. },
  156. 'in': {
  157. 'right': parseInt(10 + defaults.offset)
  158. },
  159. 'out': {
  160. 'start': {
  161. 'right': parseFloat(defaults.width - (defaults.width * 0.9))
  162. },
  163. 'end': {
  164. 'right': parseInt(0 - (defaults.width * 2))
  165. }
  166. }
  167. },
  168. 'left': {
  169. 'css_start': {
  170. "left": parseInt(0 - (defaults.width + 10))
  171. },
  172. 'in': {
  173. 'left': parseInt(10 + defaults.offset)
  174. },
  175. 'out': {
  176. 'start': {
  177. 'left': parseFloat(defaults.width - (defaults.width * 0.9))
  178. },
  179. 'end': {
  180. 'left': parseInt(0 - (defaults.width * 2))
  181. }
  182. }
  183. }
  184. };
  185. // Zoom animation
  186. defaults.animations.zoom = {
  187. 'center': { // Not working well
  188. 'css_start': {
  189. "top": 10,
  190. "left": mid - parseInt(defaults.width / 2),
  191. "zoom": 0.01
  192. },
  193. 'in': {
  194. 'zoom': 1
  195. },
  196. 'out': {
  197. 'start': {
  198. 'zoom': 1.3
  199. },
  200. 'end': {
  201. 'zoom': 0.01
  202. }
  203. }
  204. },
  205. 'bottom': { // Not working well
  206. 'css_start': {
  207. "top": 'auto',
  208. "bottom": 10,
  209. "left": mid - parseInt(defaults.width / 2),
  210. "zoom": 0.01
  211. },
  212. 'in': {
  213. 'zoom': 1
  214. },
  215. 'out': {
  216. 'start': {
  217. 'zoom': 1.3
  218. },
  219. 'end': {
  220. 'zoom': 0.01
  221. }
  222. }
  223. },
  224. 'right': {
  225. 'css_start': {
  226. 'right': 10,
  227. 'zoom': 0.01
  228. },
  229. 'in': {
  230. 'right': parseInt(10 + defaults.offset),
  231. 'zoom': 1
  232. },
  233. 'out': {
  234. 'start': {
  235. 'zoom': 1.3
  236. },
  237. 'end': {
  238. 'zoom': 0.01
  239. }
  240. }
  241. },
  242. 'left': {
  243. 'css_start': {
  244. 'left': 10,
  245. 'zoom': 0.01
  246. },
  247. 'in': {
  248. 'zoom': 1
  249. },
  250. 'out': {
  251. 'start': {
  252. 'zoom': 1.3
  253. },
  254. 'end': {
  255. 'zoom': 0.01
  256. }
  257. }
  258. }
  259. };
  260. // Check if animation exists
  261. defaults.available_animations = Object.keys(defaults.animations)
  262. if (!defaults.available_animations.length) {
  263. throw new Error('No animations')
  264. }
  265. if (!available_positions.length) {
  266. throw new Error('No available positions')
  267. }
  268. if (available_positions.indexOf(defaults.position) === -1) {
  269. defaults.position = available_positions[0]
  270. }
  271. if (defaults.available_animations.indexOf(defaults.animation) === -1) {
  272. defaults.animation = defaults.available_animations[0]
  273. }
  274. // Check callback
  275. if (typeof defaults.callback !== 'function') {
  276. defaults.callback = null;
  277. }
  278. // Width & Height
  279. if (defaults.width > 0) {
  280. defaults.width = defaults.width;
  281. } else if (defaults.width === "all") {
  282. defaults.width = screen.width - 60;
  283. } else {
  284. defaults.width = 400;
  285. }
  286. if (defaults.height > 100 || defaults.height < 0) {
  287. defaults.height = 60;
  288. }
  289. // Create notification itself
  290. var div = create_notification()
  291. // If clickable add close button
  292. if (defaults.clickable) {
  293. div.append(create_close_button())
  294. }
  295. $("body").append(div);
  296. // Set z-index
  297. if (defaults.zindex) {
  298. $("#ui_notifIt").css("z-index", defaults.zindex);
  299. }
  300. // If multiline we have to set the padding instead line-height
  301. if (defaults.multiline) {
  302. $("#ui_notifIt").css("padding", 15);
  303. } else {
  304. $("#ui_notifIt").css("height", defaults.height);
  305. $("#ui_notifIt p").css("line-height", defaults.height + "px");
  306. }
  307. // Basic css
  308. $("#ui_notifIt").css({
  309. "width": defaults.width,
  310. "opacity": defaults.opacity,
  311. "background-color": defaults.bgcolor,
  312. "color": defaults.color
  313. });
  314. $("#ui_notifIt p").css({
  315. "color": defaults.color
  316. })
  317. // Class 'success', 'error', 'warning', 'info'..
  318. $("#ui_notifIt").addClass(defaults.type);
  319. // Set entry animation
  320. if (defaults.animations[defaults.animation][defaults.position].css_start) {
  321. $("#ui_notifIt").css(defaults.animations[defaults.animation][defaults.position].css_start);
  322. } else {
  323. $("#ui_notifIt").css(defaults.animations[defaults.available_animations[0]][defaults.position].css_start);
  324. }
  325. // Execute entry animation
  326. $("#ui_notifIt").animate(defaults.animations[defaults.animation][defaults.position].in);
  327. // Events
  328. if (!defaults.clickable) {
  329. $("#ui_notifIt").click(function(e) {
  330. e.stopPropagation();
  331. dismiss(defaults);
  332. });
  333. }
  334. $('body').on('click', '#ui_notifIt #notifIt_close', function() {
  335. dismiss(defaults);
  336. });
  337. if (defaults.autohide) {
  338. if (!isNaN(defaults.timeout)) {
  339. window.notifit_timeout = setTimeout(function() {
  340. dismiss(defaults);
  341. }, defaults.timeout);
  342. }
  343. }
  344. return {
  345. 'destroy': destroy,
  346. 'dismiss': dismiss
  347. }
  348. }
  349. // Confirm
  350. function notif_confirm(config) {
  351. var $ = jQuery
  352. var _config = {
  353. 'textaccept': 'Accept',
  354. 'textcancel': 'Cancel',
  355. 'message': 'Is that what you want to do?',
  356. 'fullscreen': false,
  357. 'callback': null
  358. }
  359. var settings = $.extend({}, _config, config)
  360. var $confirm = $('.notifit_confirm')[0] ? $('.notifit_confirm') : null;
  361. var $bg = $('.notifit_confirm_bg')[0] ? $('.notifit_confirm_bg') : null;
  362. function _create() {
  363. if ($confirm !== null) {
  364. return $confirm
  365. }
  366. var $acceptButton = $('<button>', {
  367. 'class': 'notifit_confirm_accept',
  368. 'text': settings.textaccept
  369. })
  370. var $cancelButton = $('<button>', {
  371. 'class': 'notifit_confirm_cancel',
  372. 'text': settings.textcancel
  373. })
  374. var $message = $('<div>', {
  375. 'class': 'notifit_confirm_message',
  376. 'text': settings.message
  377. })
  378. $confirm = $('<div>', {
  379. 'class': 'notifit_confirm'
  380. })
  381. $confirm
  382. .append($message)
  383. .append($acceptButton)
  384. .append($cancelButton)
  385. $bg = $('<div>', { 'class': 'notifit_confirm_bg' })
  386. return $confirm
  387. }
  388. function _show() {
  389. if ($confirm) {
  390. if (settings.fullscreen) {
  391. $bg.hide()
  392. $confirm.hide()
  393. $('body').append($bg)
  394. $('body').append($confirm)
  395. $confirm.css({
  396. 'top': $bg.outerHeight() / 2 - ($confirm.outerHeight() / 2),
  397. 'left': $bg.outerWidth() / 2 - ($confirm.outerWidth() / 2)
  398. })
  399. $bg.fadeIn('fast', function() { $confirm.slideDown('fast') })
  400. } else {
  401. $confirm.css({
  402. 'top': '20px',
  403. 'left': 'auto',
  404. 'right': '20px',
  405. 'display': 'none'
  406. })
  407. $('body').append($confirm)
  408. $confirm.slideDown('fast')
  409. }
  410. }
  411. }
  412. function _hide() {
  413. if ($confirm) {
  414. $confirm.slideUp('fast', function() {
  415. $confirm.remove()
  416. })
  417. }
  418. if ($bg) {
  419. $bg.fadeOut('fast', function() {
  420. $bg.remove()
  421. })
  422. }
  423. }
  424. function _callback() {
  425. _hide()
  426. var response = null
  427. if ($(this).hasClass('notifit_confirm_accept')) {
  428. response = true
  429. } else if ($(this).hasClass('notifit_confirm_cancel')) {
  430. response = false
  431. }
  432. if (typeof settings.callback === 'function') {
  433. return settings.callback(response)
  434. }
  435. return response
  436. }
  437. function _setListeners() {
  438. $('html').one('click', '.notifit_confirm_accept, .notifit_confirm_cancel', _callback)
  439. }
  440. // Get the party started! \o/
  441. _create()
  442. _show()
  443. _setListeners()
  444. }
  445. // Prompt
  446. function notif_prompt(config) {
  447. var $ = jQuery
  448. var _config = {
  449. 'message': 'Tell me something',
  450. 'default_value': '',
  451. 'textaccept': 'Accept',
  452. 'textcancel': 'Cancel',
  453. 'fullscreen': false,
  454. 'callback': null
  455. }
  456. var settings = $.extend({}, _config, config)
  457. var $prompt = $('.notifit_prompt')[0] ? $('.notifit_prompt') : null;
  458. var $bg = $('.notifit_prompt_bg')[0] ? $('.notifit_prompt_bg') : null;
  459. function _create() {
  460. if ($prompt !== null) { return $prompt }
  461. var $acceptButton = $('<button>', {
  462. 'class': 'notifit_prompt_accept',
  463. 'text': settings.textaccept
  464. })
  465. var $cancelButton = $('<button>', {
  466. 'class': 'notifit_prompt_cancel',
  467. 'text': settings.textcancel
  468. })
  469. var $message = $('<p>', {
  470. 'class': 'notifit_prompt_message',
  471. 'text': settings.message
  472. })
  473. var $input = $('<input>', {
  474. 'type': 'text',
  475. 'class': 'notifit_prompt_input',
  476. 'value': settings.default_value
  477. })
  478. $prompt = $('<div>', {
  479. 'class': 'notifit_prompt'
  480. })
  481. $prompt
  482. .append($message)
  483. .append($input)
  484. .append($cancelButton)
  485. .append($acceptButton)
  486. $bg = $('<div>', { 'class': 'notifit_prompt_bg' })
  487. return $prompt
  488. }
  489. function _show() {
  490. if ($prompt) {
  491. if (settings.fullscreen) {
  492. $bg.hide()
  493. $prompt.hide()
  494. $('body').append($bg)
  495. $('body').append($prompt)
  496. $prompt.css({
  497. 'top': $bg.outerHeight() / 2 - ($prompt.outerHeight() / 2),
  498. 'left': $bg.outerWidth() / 2 - ($prompt.outerWidth() / 2)
  499. })
  500. $bg.fadeIn('fast', function() { $prompt.slideDown('fast', function() { $(this).find('.notifit_prompt_input').focus() }) })
  501. } else {
  502. $prompt.css({
  503. 'top': '20px',
  504. 'left': 'auto',
  505. 'right': '20px',
  506. 'display': 'none'
  507. })
  508. $('body').append($prompt)
  509. $prompt.slideDown('fast', function() { $(this).find('.notifit_prompt_input').focus() })
  510. }
  511. }
  512. }
  513. function _hide() {
  514. if ($prompt) {
  515. $prompt.slideUp('fast', function() {
  516. $prompt.remove()
  517. })
  518. }
  519. if ($bg) {
  520. $bg.fadeOut('fast', function() {
  521. $bg.remove()
  522. })
  523. }
  524. }
  525. function _callback() {
  526. _hide()
  527. var response = null
  528. if ($(this).hasClass('notifit_prompt_accept')) {
  529. response = $(this).parents('.notifit_prompt').find('.notifit_prompt_input').val()
  530. } else if ($(this).hasClass('notifit_prompt_cancel')) {
  531. response = false
  532. }
  533. if (typeof settings.callback === 'function') {
  534. return settings.callback(response)
  535. }
  536. return response
  537. }
  538. function _setListeners() {
  539. $('html').one('click', '.notifit_prompt_accept, .notifit_prompt_cancel', _callback)
  540. }
  541. // Get the party started! Again! \o/
  542. _create()
  543. _show()
  544. _setListeners()
  545. }
  546. return {
  547. notif: notif,
  548. notif_confirm: notif_confirm,
  549. notif_prompt: notif_prompt
  550. };
  551. }));