bootstrap-dialog.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. /* ================================================
  2. * Make use of Twitter Bootstrap's modal more monkey-friendly.
  3. *
  4. * For Bootstrap 3.
  5. *
  6. * javanoob@hotmail.com
  7. *
  8. * https://github.com/nakupanda/bootstrap3-dialog
  9. *
  10. * Licensed under The MIT License.
  11. * ================================================ */
  12. var BootstrapDialog = null;
  13. !function($) {
  14. "use strict";
  15. BootstrapDialog = function(options) {
  16. this.defaultOptions = {
  17. id: BootstrapDialog.newGuid(),
  18. type: BootstrapDialog.TYPE_PRIMARY,
  19. size: BootstrapDialog.SIZE_NORMAL,
  20. cssClass: '',
  21. title: null,
  22. message: null,
  23. buttons: [],
  24. closable: true,
  25. spinicon: BootstrapDialog.ICON_SPINNER,
  26. data: {},
  27. onshow: null,
  28. onhide: null,
  29. autodestroy: true,
  30. draggable: true
  31. };
  32. this.indexedButtons = {};
  33. this.registeredButtonHotkeys = {};
  34. this.realized = false;
  35. this.opened = false;
  36. this.initOptions(options);
  37. this.holdThisInstance();
  38. };
  39. /**
  40. * Some constants.
  41. */
  42. BootstrapDialog.NAMESPACE = 'bootstrap-dialog';
  43. BootstrapDialog.TYPE_DEFAULT = 'type-default';
  44. BootstrapDialog.TYPE_INFO = 'type-info';
  45. BootstrapDialog.TYPE_PRIMARY = 'type-primary';
  46. BootstrapDialog.TYPE_SUCCESS = 'type-success';
  47. BootstrapDialog.TYPE_WARNING = 'type-warning';
  48. BootstrapDialog.TYPE_DANGER = 'type-danger';
  49. BootstrapDialog.DEFAULT_TEXTS = {};
  50. BootstrapDialog.DEFAULT_TEXTS[BootstrapDialog.TYPE_DEFAULT] = 'Information';
  51. BootstrapDialog.DEFAULT_TEXTS[BootstrapDialog.TYPE_INFO] = 'Information';
  52. BootstrapDialog.DEFAULT_TEXTS[BootstrapDialog.TYPE_PRIMARY] = 'Information';
  53. BootstrapDialog.DEFAULT_TEXTS[BootstrapDialog.TYPE_SUCCESS] = 'Success';
  54. BootstrapDialog.DEFAULT_TEXTS[BootstrapDialog.TYPE_WARNING] = 'Warning';
  55. BootstrapDialog.DEFAULT_TEXTS[BootstrapDialog.TYPE_DANGER] = 'Danger';
  56. BootstrapDialog.SIZE_NORMAL = 'size-normal';
  57. BootstrapDialog.SIZE_LARGE = 'size-large';
  58. BootstrapDialog.BUTTON_SIZES = {};
  59. BootstrapDialog.BUTTON_SIZES[BootstrapDialog.SIZE_NORMAL] = '';
  60. BootstrapDialog.BUTTON_SIZES[BootstrapDialog.SIZE_LARGE] = 'btn-lg';
  61. BootstrapDialog.ICON_SPINNER = 'glyphicon glyphicon-asterisk';
  62. /**
  63. * Open / Close all created dialogs all at once.
  64. */
  65. BootstrapDialog.dialogs = {};
  66. BootstrapDialog.openAll = function() {
  67. $.each(BootstrapDialog.dialogs, function(id, dialogInstance) {
  68. dialogInstance.open();
  69. });
  70. };
  71. BootstrapDialog.closeAll = function() {
  72. $.each(BootstrapDialog.dialogs, function(id, dialogInstance) {
  73. dialogInstance.close();
  74. });
  75. };
  76. BootstrapDialog.prototype = {
  77. constructor: BootstrapDialog,
  78. initOptions: function(options) {
  79. this.options = $.extend(true, this.defaultOptions, options);
  80. return this;
  81. },
  82. holdThisInstance: function() {
  83. BootstrapDialog.dialogs[this.getId()] = this;
  84. return this;
  85. },
  86. initModalStuff: function() {
  87. this.setModal(this.createModal())
  88. .setModalDialog(this.createModalDialog())
  89. .setModalContent(this.createModalContent())
  90. .setModalHeader(this.createModalHeader())
  91. .setModalBody(this.createModalBody())
  92. .setModalFooter(this.createModalFooter());
  93. this.getModal().append(this.getModalDialog());
  94. this.getModalDialog().append(this.getModalContent());
  95. this.getModalContent()
  96. .append(this.getModalHeader())
  97. .append(this.getModalBody())
  98. .append(this.getModalFooter());
  99. var _isMouseDown = false;
  100. var _self = this;
  101. var _mouseOffset = {};
  102. if (this.options.draggable) {
  103. this.getModalHeader().on('mousedown', function (event) {
  104. _isMouseDown = true;
  105. var _dialogOffset = _self.getModalContent().offset();
  106. _mouseOffset = {
  107. top: event.clientY - _dialogOffset.top,
  108. left: event.clientX - _dialogOffset.left
  109. }
  110. });
  111. this.getModal().on('mouseup mouseleave', function () {
  112. _isMouseDown = false;
  113. });
  114. $('body').on('mousemove', function (event) {
  115. if (!_isMouseDown)
  116. return;
  117. _self.getModalContent().offset({
  118. top: event.clientY - _mouseOffset.top,
  119. left: event.clientX - _mouseOffset.left,
  120. });
  121. });
  122. }
  123. return this;
  124. },
  125. createModal: function() {
  126. var $modal = $('<div class="modal fade" tabindex="-1"></div>');
  127. $modal.prop('id', this.getId());
  128. return $modal;
  129. },
  130. getModal: function() {
  131. return this.$modal;
  132. },
  133. setModal: function($modal) {
  134. this.$modal = $modal;
  135. return this;
  136. },
  137. createModalDialog: function() {
  138. return $('<div class="modal-dialog"></div>');
  139. },
  140. getModalDialog: function() {
  141. return this.$modalDialog;
  142. },
  143. setModalDialog: function($modalDialog) {
  144. this.$modalDialog = $modalDialog;
  145. return this;
  146. },
  147. createModalContent: function() {
  148. return $('<div class="modal-content"></div>');
  149. },
  150. getModalContent: function() {
  151. return this.$modalContent;
  152. },
  153. setModalContent: function($modalContent) {
  154. this.$modalContent = $modalContent;
  155. return this;
  156. },
  157. createModalHeader: function() {
  158. return $('<div class="modal-header"></div>');
  159. },
  160. getModalHeader: function() {
  161. return this.$modalHeader;
  162. },
  163. setModalHeader: function($modalHeader) {
  164. this.$modalHeader = $modalHeader;
  165. return this;
  166. },
  167. createModalBody: function() {
  168. return $('<div class="modal-body"></div>');
  169. },
  170. getModalBody: function() {
  171. return this.$modalBody;
  172. },
  173. setModalBody: function($modalBody) {
  174. this.$modalBody = $modalBody;
  175. return this;
  176. },
  177. createModalFooter: function() {
  178. return $('<div class="modal-footer"></div>');
  179. },
  180. getModalFooter: function() {
  181. return this.$modalFooter;
  182. },
  183. setModalFooter: function($modalFooter) {
  184. this.$modalFooter = $modalFooter;
  185. return this;
  186. },
  187. createDynamicContent: function(rawContent) {
  188. var content = null;
  189. if (typeof rawContent === 'function') {
  190. content = rawContent.call(rawContent, this);
  191. } else {
  192. content = rawContent;
  193. }
  194. if (typeof content === 'string') {
  195. content = this.formatStringContent(content);
  196. }
  197. return content;
  198. },
  199. formatStringContent: function(content) {
  200. return content.replace(/\r\n/g, '<br />').replace(/[\r\n]/g, '<br />');
  201. },
  202. setData: function(key, value) {
  203. this.options.data[key] = value;
  204. return this;
  205. },
  206. getData: function(key) {
  207. return this.options.data[key];
  208. },
  209. setId: function(id) {
  210. this.options.id = id;
  211. return this;
  212. },
  213. getId: function() {
  214. return this.options.id;
  215. },
  216. getType: function() {
  217. return this.options.type;
  218. },
  219. setType: function(type) {
  220. this.options.type = type;
  221. return this;
  222. },
  223. getSize: function() {
  224. return this.options.size;
  225. },
  226. setSize: function(size) {
  227. this.options.size = size;
  228. return this;
  229. },
  230. getCssClass: function() {
  231. return this.options.cssClass;
  232. },
  233. setCssClass: function(cssClass) {
  234. this.options.cssClass = cssClass;
  235. return this;
  236. },
  237. getTitle: function() {
  238. return this.options.title;
  239. },
  240. setTitle: function(title) {
  241. this.options.title = title;
  242. this.updateTitle();
  243. return this;
  244. },
  245. updateTitle: function() {
  246. if (this.isRealized()) {
  247. var title = this.getTitle() !== null ? this.createDynamicContent(this.getTitle()) : this.getDefaultText();
  248. this.getModalHeader().find('.' + this.getNamespace('title')).html('').append(title);
  249. }
  250. return this;
  251. },
  252. getMessage: function() {
  253. return this.options.message;
  254. },
  255. setMessage: function(message) {
  256. this.options.message = message;
  257. this.updateMessage();
  258. return this;
  259. },
  260. updateMessage: function() {
  261. if (this.isRealized()) {
  262. var message = this.createDynamicContent(this.getMessage());
  263. this.getModalBody().find('.' + this.getNamespace('message')).html('').append(message);
  264. }
  265. return this;
  266. },
  267. isClosable: function() {
  268. return this.options.closable;
  269. },
  270. setClosable: function(closable) {
  271. this.options.closable = closable;
  272. this.updateClosable();
  273. return this;
  274. },
  275. getSpinicon: function() {
  276. return this.options.spinicon;
  277. },
  278. setSpinicon: function(spinicon) {
  279. this.options.spinicon = spinicon;
  280. return this;
  281. },
  282. addButton: function(button) {
  283. this.options.buttons.push(button);
  284. return this;
  285. },
  286. addButtons: function(buttons) {
  287. var that = this;
  288. $.each(buttons, function(index, button) {
  289. that.addButton(button);
  290. });
  291. return this;
  292. },
  293. getButtons: function() {
  294. return this.options.buttons;
  295. },
  296. setButtons: function(buttons) {
  297. this.options.buttons = buttons;
  298. return this;
  299. },
  300. /**
  301. * If there is id provided for a button option, it will be in dialog.indexedButtons list.
  302. *
  303. * In that case you can use dialog.getButton(id) to find the button.
  304. *
  305. * @param {type} id
  306. * @returns {undefined}
  307. */
  308. getButton: function(id) {
  309. if (typeof this.indexedButtons[id] !== 'undefined') {
  310. return this.indexedButtons[id];
  311. }
  312. return null;
  313. },
  314. getButtonSize: function() {
  315. if (typeof BootstrapDialog.BUTTON_SIZES[this.getSize()] !== 'undefined') {
  316. return BootstrapDialog.BUTTON_SIZES[this.getSize()];
  317. }
  318. return '';
  319. },
  320. isAutodestroy: function() {
  321. return this.options.autodestroy;
  322. },
  323. setAutodestroy: function(autodestroy) {
  324. this.options.autodestroy = autodestroy;
  325. },
  326. getDefaultText: function() {
  327. return BootstrapDialog.DEFAULT_TEXTS[this.getType()];
  328. },
  329. getNamespace: function(name) {
  330. return BootstrapDialog.NAMESPACE + '-' + name;
  331. },
  332. createHeaderContent: function() {
  333. var $container = $('<div></div>');
  334. $container.addClass(this.getNamespace('header'));
  335. // title
  336. $container.append(this.createTitleContent());
  337. // Close button
  338. $container.append(this.createCloseButton());
  339. return $container;
  340. },
  341. createTitleContent: function() {
  342. var $title = $('<div></div>');
  343. $title.addClass(this.getNamespace('title'));
  344. return $title;
  345. },
  346. createCloseButton: function() {
  347. var $container = $('<div></div>');
  348. $container.addClass(this.getNamespace('close-button'));
  349. var $icon = $('<button class="close">×</button>');
  350. $container.append($icon);
  351. $container.on('click', {dialog: this}, function(event) {
  352. event.data.dialog.close();
  353. });
  354. return $container;
  355. },
  356. createBodyContent: function() {
  357. var $container = $('<div></div>');
  358. $container.addClass(this.getNamespace('body'));
  359. // Message
  360. $container.append(this.createMessageContent());
  361. return $container;
  362. },
  363. createMessageContent: function() {
  364. var $message = $('<div></div>');
  365. $message.addClass(this.getNamespace('message'));
  366. return $message;
  367. },
  368. createFooterContent: function() {
  369. var $container = $('<div></div>');
  370. $container.addClass(this.getNamespace('footer'));
  371. // Buttons
  372. $container.append(this.createFooterButtons());
  373. return $container;
  374. },
  375. createFooterButtons: function() {
  376. var that = this;
  377. var $container = $('<div></div>');
  378. $container.addClass(this.getNamespace('footer-buttons'));
  379. this.indexedButtons = {};
  380. $.each(this.options.buttons, function(index, button) {
  381. if (!button.id) {
  382. button.id = BootstrapDialog.newGuid();
  383. }
  384. var $button = that.createButton(button);
  385. that.indexedButtons[button.id] = $button;
  386. $container.append($button);
  387. });
  388. return $container;
  389. },
  390. createButton: function(button) {
  391. var $button = $('<button class="btn"></button>');
  392. $button.addClass(this.getButtonSize());
  393. $button.prop('id', button.id);
  394. // Icon
  395. if (typeof button.icon !== undefined && $.trim(button.icon) !== '') {
  396. $button.append(this.createButtonIcon(button.icon));
  397. }
  398. // Label
  399. if (typeof button.label !== undefined) {
  400. $button.append(button.label);
  401. }
  402. // Css class
  403. if (typeof button.cssClass !== undefined && $.trim(button.cssClass) !== '') {
  404. $button.addClass(button.cssClass);
  405. } else {
  406. $button.addClass('btn-default');
  407. }
  408. // Hotkey
  409. if (typeof button.hotkey !== undefined) {
  410. this.registeredButtonHotkeys[button.hotkey] = $button;
  411. }
  412. // Button on click
  413. $button.on('click', {dialog: this, $button: $button, button: button}, function(event) {
  414. var dialog = event.data.dialog;
  415. var $button = event.data.$button;
  416. var button = event.data.button;
  417. if (typeof button.action === 'function') {
  418. button.action.call($button, dialog);
  419. }
  420. if (button.autospin) {
  421. $button.toggleSpin(true);
  422. }
  423. });
  424. // Dynamically add extra functions to $button
  425. this.enhanceButton($button);
  426. return $button;
  427. },
  428. /**
  429. * Dynamically add extra functions to $button
  430. *
  431. * Using '$this' to reference 'this' is just for better readability.
  432. *
  433. * @param {type} $button
  434. * @returns {_L13.BootstrapDialog.prototype}
  435. */
  436. enhanceButton: function($button) {
  437. $button.dialog = this;
  438. // Enable / Disable
  439. $button.toggleEnable = function(enable) {
  440. var $this = this;
  441. $this.prop("disabled", !enable).toggleClass('disabled', !enable);
  442. return $this;
  443. };
  444. $button.enable = function() {
  445. var $this = this;
  446. $this.toggleEnable(true);
  447. return $this;
  448. };
  449. $button.disable = function() {
  450. var $this = this;
  451. $this.toggleEnable(false);
  452. return $this;
  453. };
  454. // Icon spinning, helpful for indicating ajax loading status.
  455. $button.toggleSpin = function(spin) {
  456. var $this = this;
  457. var dialog = $this.dialog;
  458. var $icon = $this.find('.' + dialog.getNamespace('button-icon'));
  459. if (spin) {
  460. $icon.hide();
  461. $button.prepend(dialog.createButtonIcon(dialog.getSpinicon()).addClass('icon-spin'));
  462. } else {
  463. $icon.show();
  464. $button.find('.icon-spin').remove();
  465. }
  466. return $this;
  467. };
  468. $button.spin = function() {
  469. var $this = this;
  470. $this.toggleSpin(true);
  471. return $this;
  472. };
  473. $button.stopSpin = function() {
  474. var $this = this;
  475. $this.toggleSpin(false);
  476. return $this;
  477. };
  478. return this;
  479. },
  480. createButtonIcon: function(icon) {
  481. var $icon = $('<span></span>');
  482. $icon.addClass(this.getNamespace('button-icon')).addClass(icon);
  483. return $icon;
  484. },
  485. /**
  486. * Invoke this only after the dialog is realized.
  487. *
  488. * @param {type} enable
  489. * @returns {undefined}
  490. */
  491. enableButtons: function(enable) {
  492. $.each(this.indexedButtons, function(id, $button) {
  493. $button.toggleEnable(enable);
  494. });
  495. return this;
  496. },
  497. /**
  498. * Invoke this only after the dialog is realized.
  499. *
  500. * @returns {undefined}
  501. */
  502. updateClosable: function() {
  503. if (this.isRealized()) {
  504. // Close button
  505. this.getModalHeader().find('.' + this.getNamespace('close-button')).toggle(this.isClosable());
  506. }
  507. return this;
  508. },
  509. /**
  510. * Set handler for modal event 'show'.
  511. * This is a setter!
  512. *
  513. * @param {type} onopen
  514. * @returns {_L9.BootstrapDialog.prototype}
  515. */
  516. onShow: function(onshow) {
  517. this.options.onshow = onshow;
  518. return this;
  519. },
  520. /**
  521. * Set handler for modal event 'hide'.
  522. * This is a setter!
  523. *
  524. * @param {type} onclose
  525. * @returns {_L9.BootstrapDialog.prototype}
  526. */
  527. onHide: function(onhide) {
  528. this.options.onhide = onhide;
  529. return this;
  530. },
  531. isRealized: function() {
  532. return this.realized;
  533. },
  534. setRealized: function(realized) {
  535. this.realized = realized;
  536. return this;
  537. },
  538. isOpened: function() {
  539. return this.opened;
  540. },
  541. setOpened: function(opened) {
  542. this.opened = opened;
  543. return this;
  544. },
  545. handleModalEvents: function() {
  546. this.getModal().on('show.bs.modal', {dialog: this}, function(event) {
  547. var dialog = event.data.dialog;
  548. typeof dialog.options.onshow === 'function' && dialog.options.onshow(dialog);
  549. dialog.showPageScrollBar(true);
  550. });
  551. this.getModal().on('hide.bs.modal', {dialog: this}, function(event) {
  552. var dialog = event.data.dialog;
  553. typeof dialog.options.onhide === 'function' && dialog.options.onhide(dialog);
  554. });
  555. this.getModal().on('hidden.bs.modal', {dialog: this}, function(event) {
  556. var dialog = event.data.dialog;
  557. dialog.isAutodestroy() && $(this).remove();
  558. dialog.showPageScrollBar(false);
  559. });
  560. // Backdrop, I did't find a way to change bs3 backdrop option after the dialog is popped up, so here's a new wheel.
  561. this.getModal().on('click', {dialog: this}, function(event) {
  562. event.target === this && event.data.dialog.isClosable() && event.data.dialog.close();
  563. });
  564. // ESC key support
  565. this.getModal().on('keyup', {dialog: this}, function(event) {
  566. event.which === 27 && event.data.dialog.isClosable() && event.data.dialog.close();
  567. });
  568. // Button hotkey
  569. this.getModal().on('keyup', {dialog: this}, function(event) {
  570. var dialog = event.data.dialog;
  571. if (typeof dialog.registeredButtonHotkeys[event.which] !== 'undefined') {
  572. var $button = $(dialog.registeredButtonHotkeys[event.which]);
  573. !$button.prop('disabled') && $button.focus().trigger('click');
  574. }
  575. });
  576. return this;
  577. },
  578. showPageScrollBar: function(show) {
  579. $(document.body).toggleClass('modal-open', show);
  580. },
  581. realize: function() {
  582. this.initModalStuff();
  583. this.getModal().addClass(BootstrapDialog.NAMESPACE)
  584. .addClass(this.getType())
  585. .addClass(this.getSize())
  586. .addClass(this.getCssClass());
  587. this.getModalFooter().append(this.createFooterContent());
  588. this.getModalHeader().append(this.createHeaderContent());
  589. this.getModalBody().append(this.createBodyContent());
  590. this.getModal().modal({
  591. backdrop: 'static',
  592. keyboard: false,
  593. show: false
  594. });
  595. this.handleModalEvents();
  596. this.setRealized(true);
  597. this.updateTitle();
  598. this.updateMessage();
  599. this.updateClosable();
  600. return this;
  601. },
  602. open: function() {
  603. !this.isRealized() && this.realize();
  604. this.getModal().modal('show');
  605. this.setOpened(true);
  606. return this;
  607. },
  608. close: function() {
  609. this.getModal().modal('hide');
  610. if (this.isAutodestroy()) {
  611. delete BootstrapDialog.dialogs[this.getId()];
  612. }
  613. this.setOpened(false);
  614. return this;
  615. }
  616. };
  617. /**
  618. * RFC4122 version 4 compliant unique id creator.
  619. *
  620. * Added by https://github.com/tufanbarisyildirim/
  621. *
  622. * @returns {String}
  623. */
  624. BootstrapDialog.newGuid = function() {
  625. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  626. var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
  627. return v.toString(16);
  628. });
  629. };
  630. /* ================================================
  631. * For lazy people
  632. * ================================================ */
  633. /**
  634. * Shortcut function: show
  635. *
  636. * @param {type} options
  637. * @returns the created dialog instance
  638. */
  639. BootstrapDialog.show = function(options) {
  640. return new BootstrapDialog(options).open();
  641. };
  642. /**
  643. * Alert window
  644. *
  645. * @param {type} message
  646. * @param {type} callback
  647. * @returns the created dialog instance
  648. */
  649. BootstrapDialog.alert = function(message, callback) {
  650. return new BootstrapDialog({
  651. message: message,
  652. data: {
  653. 'callback': callback
  654. },
  655. closable: false,
  656. buttons: [{
  657. label: 'OK',
  658. action: function(dialog) {
  659. typeof dialog.getData('callback') === 'function' && dialog.getData('callback')(true);
  660. dialog.close();
  661. }
  662. }]
  663. }).open();
  664. };
  665. /**
  666. * Confirm window
  667. *
  668. * @param {type} message
  669. * @param {type} callback
  670. * @returns the created dialog instance
  671. */
  672. BootstrapDialog.confirm = function(message, callback) {
  673. return new BootstrapDialog({
  674. title: 'Confirmation',
  675. message: message,
  676. closable: false,
  677. data: {
  678. 'callback': callback
  679. },
  680. buttons: [{
  681. label: 'Cancel',
  682. action: function(dialog) {
  683. typeof dialog.getData('callback') === 'function' && dialog.getData('callback')(false);
  684. dialog.close();
  685. }
  686. }, {
  687. label: 'OK',
  688. cssClass: 'btn-primary',
  689. action: function(dialog) {
  690. typeof dialog.getData('callback') === 'function' && dialog.getData('callback')(true);
  691. dialog.close();
  692. }
  693. }]
  694. }).open();
  695. };
  696. }(window.jQuery);