bootstrap-modal.js 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /* =========================================================
  2. * bootstrap-modal.js v2.1.1
  3. * http://twitter.github.com/bootstrap/javascript.html#modals
  4. * =========================================================
  5. * Copyright 2012 Twitter, Inc.
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * ========================================================= */
  19. !function ($) {
  20. "use strict"; // jshint ;_;
  21. /* MODAL CLASS DEFINITION
  22. * ====================== */
  23. var Modal = function (element, options) {
  24. this.options = options
  25. this.$element = $(element)
  26. .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
  27. this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
  28. }
  29. Modal.prototype = {
  30. constructor: Modal
  31. , toggle: function () {
  32. return this[!this.isShown ? 'show' : 'hide']()
  33. }
  34. , show: function () {
  35. var that = this
  36. , e = $.Event('show')
  37. this.$element.trigger(e)
  38. if (this.isShown || e.isDefaultPrevented()) return
  39. $('body').addClass('modal-open')
  40. this.isShown = true
  41. this.escape()
  42. this.backdrop(function () {
  43. var transition = $.support.transition && that.$element.hasClass('fade')
  44. if (!that.$element.parent().length) {
  45. that.$element.appendTo(document.body) //don't move modals dom position
  46. }
  47. that.$element
  48. .show()
  49. if (transition) {
  50. that.$element[0].offsetWidth // force reflow
  51. }
  52. that.$element
  53. .addClass('in')
  54. .attr('aria-hidden', false)
  55. .focus()
  56. that.enforceFocus()
  57. transition ?
  58. that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
  59. that.$element.trigger('shown')
  60. })
  61. }
  62. , hide: function (e) {
  63. e && e.preventDefault()
  64. var that = this
  65. e = $.Event('hide')
  66. this.$element.trigger(e)
  67. if (!this.isShown || e.isDefaultPrevented()) return
  68. this.isShown = false
  69. $('body').removeClass('modal-open')
  70. this.escape()
  71. $(document).off('focusin.modal')
  72. this.$element
  73. .removeClass('in')
  74. .attr('aria-hidden', true)
  75. $.support.transition && this.$element.hasClass('fade') ?
  76. this.hideWithTransition() :
  77. this.hideModal()
  78. }
  79. , enforceFocus: function () {
  80. var that = this
  81. $(document).on('focusin.modal', function (e) {
  82. if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
  83. that.$element.focus()
  84. }
  85. })
  86. }
  87. , escape: function () {
  88. var that = this
  89. if (this.isShown && this.options.keyboard) {
  90. this.$element.on('keyup.dismiss.modal', function ( e ) {
  91. e.which == 27 && that.hide()
  92. })
  93. } else if (!this.isShown) {
  94. this.$element.off('keyup.dismiss.modal')
  95. }
  96. }
  97. , hideWithTransition: function () {
  98. var that = this
  99. , timeout = setTimeout(function () {
  100. that.$element.off($.support.transition.end)
  101. that.hideModal()
  102. }, 500)
  103. this.$element.one($.support.transition.end, function () {
  104. clearTimeout(timeout)
  105. that.hideModal()
  106. })
  107. }
  108. , hideModal: function (that) {
  109. this.$element
  110. .hide()
  111. .trigger('hidden')
  112. this.backdrop()
  113. }
  114. , removeBackdrop: function () {
  115. this.$backdrop.remove()
  116. this.$backdrop = null
  117. }
  118. , backdrop: function (callback) {
  119. var that = this
  120. , animate = this.$element.hasClass('fade') ? 'fade' : ''
  121. if (this.isShown && this.options.backdrop) {
  122. var doAnimate = $.support.transition && animate
  123. this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
  124. .appendTo(document.body)
  125. if (this.options.backdrop != 'static') {
  126. this.$backdrop.click($.proxy(this.hide, this))
  127. }
  128. if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
  129. this.$backdrop.addClass('in')
  130. doAnimate ?
  131. this.$backdrop.one($.support.transition.end, callback) :
  132. callback()
  133. } else if (!this.isShown && this.$backdrop) {
  134. this.$backdrop.removeClass('in')
  135. $.support.transition && this.$element.hasClass('fade')?
  136. this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) :
  137. this.removeBackdrop()
  138. } else if (callback) {
  139. callback()
  140. }
  141. }
  142. }
  143. /* MODAL PLUGIN DEFINITION
  144. * ======================= */
  145. $.fn.modal = function (option) {
  146. return this.each(function () {
  147. var $this = $(this)
  148. , data = $this.data('modal')
  149. , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
  150. if (!data) $this.data('modal', (data = new Modal(this, options)))
  151. if (typeof option == 'string') data[option]()
  152. else if (options.show) data.show()
  153. })
  154. }
  155. $.fn.modal.defaults = {
  156. backdrop: true
  157. , keyboard: true
  158. , show: true
  159. }
  160. $.fn.modal.Constructor = Modal
  161. /* MODAL DATA-API
  162. * ============== */
  163. $(function () {
  164. $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
  165. var $this = $(this)
  166. , href = $this.attr('href')
  167. , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
  168. , option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
  169. e.preventDefault()
  170. $target
  171. .modal(option)
  172. .one('hide', function () {
  173. $this.focus()
  174. })
  175. })
  176. })
  177. }(window.jQuery);