| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| define(['require', 'backbone', 'hbs!tmpl/common/modal'], function(require, Backbone, template) { |
| |
| var Modal = Backbone.View.extend({ |
| |
| className: 'modal', |
| |
| events: { |
| 'click .close': function(event) { |
| event.preventDefault(); |
| |
| this.trigger('closeModal'); |
| |
| if (this.options.content && this.options.content.trigger) { |
| this.options.content.trigger('closeModal', this, event); |
| } |
| }, |
| 'click .cancel': function(event) { |
| event.preventDefault(); |
| |
| this.trigger('closeModal'); |
| |
| if (this.options.content && this.options.content.trigger) { |
| this.options.content.trigger('closeModal', this, event); |
| } |
| }, |
| 'click .ok': function(event) { |
| event.preventDefault(); |
| |
| this.trigger('ok'); |
| |
| if (this.options.content && this.options.content.trigger) { |
| this.options.content.trigger('ok', this, event); |
| } |
| |
| if (this.options.okCloses) { |
| this.close(); |
| } |
| } |
| }, |
| |
| /** |
| * Creates an instance of a Bootstrap Modal |
| * |
| * @see http://twitter.github.com/bootstrap/javascript.html#modals |
| * |
| * @param {Object} options |
| * @param {String|View} [options.content] Modal content. Default: none |
| * @param {String} [options.title] Title. Default: none |
| * @param {String} [options.okText] Text for the OK button. Default: 'OK' |
| * @param {String} [options.cancelText] Text for the cancel button. Default: 'Cancel'. If passed a falsey value, the button will be removed |
| * @param {Boolean} [options.allowCancel Whether the modal can be closed, other than by pressing OK. Default: true |
| * @param {Boolean} [options.escape] Whether the 'esc' key can dismiss the modal. Default: true, but false if options.cancellable is true |
| * @param {Boolean} [options.animate] Whether to animate in/out. Default: false |
| * @param {Function} [options.template] Compiled underscore template to override the default one |
| */ |
| initialize: function(options) { |
| this.options = _.extend({ |
| title: null, |
| okText: 'OK', |
| focusOk: true, |
| okCloses: true, |
| cancelText: 'Cancel', |
| allowCancel: false, |
| allowBackdrop: true, |
| showFooter: true, |
| escape: true, |
| animate: true, |
| contentWithFooter: false, |
| template: template, |
| width: null, |
| buttons: null |
| }, options); |
| }, |
| |
| /** |
| * Creates the DOM element |
| * |
| * @api private |
| */ |
| render: function() { |
| var $el = this.$el, |
| options = this.options, |
| content = options.content; |
| |
| //Create the modal container |
| $el.html(options.template(options)); |
| |
| // var $content = this.$content = $el.find('.modal-body'); |
| |
| //Insert the main content if it's a view |
| if (content && content.$el) { |
| content.render(); |
| if (options.contentWithFooter) { |
| $el.find('.modal-content').append(content.$el); |
| } else { |
| $el.find('.modal-body').html(content.$el); |
| } |
| } else { |
| if (options.htmlContent) { |
| $el.find('.modal-body').append(options.htmlContent); |
| } |
| |
| } |
| |
| // if (options.mainClass) $el.addClass(options.mainClass); |
| |
| if (options.animate) $el.addClass('fade'); |
| |
| this.isRendered = true; |
| |
| return this; |
| }, |
| onClose: function() { |
| alert('close'); |
| }, |
| /** |
| * Renders and shows the modal |
| * |
| * @param {Function} [cb] Optional callback that runs only when OK is pressed. |
| */ |
| open: function(cb) { |
| if (!this.isRendered) this.render(); |
| |
| var self = this, |
| $el = this.$el; |
| |
| //Create it |
| $el.modal(_.extend({ |
| keyboard: this.options.allowCancel, |
| backdrop: this.options.allowBackdrop ? 'static' : true |
| }, this.options.modalOptions)); |
| |
| //Focus OK button |
| $el.one('shown', function() { |
| if (self.options.focusOk) { |
| $el.find('.btn.ok').focus(); |
| } |
| |
| if (self.options.content && self.options.content.trigger) { |
| self.options.content.trigger('shown', self); |
| } |
| |
| self.trigger('shown'); |
| }); |
| |
| //Adjust the modal and backdrop z-index; for dealing with multiple modals |
| var numModals = Modal.count, |
| $backdrop = $('.modal-backdrop:eq(' + numModals + ')'), |
| backdropIndex = parseInt($backdrop.css('z-index'), 10), |
| elIndex = parseInt($backdrop.css('z-index'), 10); |
| |
| $backdrop.css('z-index', backdropIndex + numModals); |
| this.$el.css('z-index', elIndex + numModals); |
| |
| if (this.options.allowCancel) { |
| $backdrop.one('click', function() { |
| if (self.options.content && self.options.content.trigger) { |
| self.options.content.trigger('closeModal', self); |
| } |
| |
| self.trigger('closeModal'); |
| }); |
| |
| $(document).one('keyup.dismiss.modal', function(e) { |
| e.which == 27 && self.trigger('closeModal'); |
| |
| if (self.options.content && self.options.content.trigger) { |
| e.which == 27 && self.options.content.trigger('shown', self); |
| } |
| }); |
| } |
| |
| this.on('cancel', function() { |
| self.close(); |
| }); |
| |
| Modal.count++; |
| |
| //Run callback on OK if provided |
| if (cb) { |
| self.on('ok', cb); |
| } |
| $el.one('shown.bs.modal', function() { |
| self.trigger('shownModal'); |
| }); |
| return this; |
| }, |
| |
| /** |
| * Closes the modal |
| */ |
| close: function() { |
| var self = this, |
| $el = this.$el; |
| |
| //Check if the modal should stay open |
| if (this._preventClose) { |
| this._preventClose = false; |
| return; |
| } |
| |
| $el.one('hidden.bs.modal', function onHidden(e) { |
| // Ignore events propagated from interior objects, like bootstrap tooltips |
| if (e.target !== e.currentTarget) { |
| return $el.one('hidden.bs.modal', onHidden); |
| } |
| self.remove(); |
| |
| if (self.options.content && self.options.content.trigger) { |
| self.options.content.trigger('hidden.bs.modal', self); |
| } |
| |
| self.trigger('hidden.bs.modal'); |
| }); |
| |
| $el.modal('hide'); |
| |
| Modal.count--; |
| }, |
| |
| /** |
| * Stop the modal from closing. |
| * Can be called from within a 'close' or 'ok' event listener. |
| */ |
| preventClose: function() { |
| this._preventClose = true; |
| } |
| }, { |
| //STATICS |
| |
| //The number of modals on display |
| count: 0 |
| }); |
| |
| return Modal; |
| }); |