lib/assets/javascripts/up/modal.js.coffee in upjs-rails-0.1.0 vs lib/assets/javascripts/up/modal.js.coffee in upjs-rails-0.2.0
- old
+ new
@@ -1,51 +1,192 @@
###*
-Modal dialogs (WIP).
-
-@class up.modal
+Modal dialogs
+=============
+
+TODO: Write some documentation
+
+@class up.modal
###
up.modal = (->
-# configuration =
-# width: 600
-# height: 400
-# template:
-# """
-# <div class="up-modal">
-# <div class="up-modal-overlay"></div>
-# <div class="up-modal-dialog">
-# <a href="#" class="up-modal-close">
-# <span class="up-modal-close-label">Close</span>
-# <span class="up-modal-close-key">ESC</span>
-# </a>
-# <div class="up-modal-content"></div>
-# </div>
-# </div>
-# """
-#
-# defaults = (defaults) ->
-# up.util.extend(configuration, defaults)
-#
-# open = (link, options) ->
-# $link = $(link)
-# url = $link.attr("href")
-# selector = $link.attr("up-modal") || $link.attr("up-target") || 'body'
-# options.source = true
-# replace(selector, url, options)
-# options = up.util.options(options, configuration)
-# createElements()
-# update(options)
-#
-# close = ->
-# if $container
-# $container.remove()
-# $container = null
-
+ u = up.util
+
+ config =
+ width: 'auto'
+ height: 'auto'
+ openAnimation: 'fade-in'
+ closeAnimation: 'fade-out'
+ closeLabel: 'X'
+ template: (config) ->
+ """
+ <div class="up-modal">
+ <div class="up-modal-dialog">
+ <div class="up-modal-close" up-close>#{config.closeLabel}</div>
+ <div class="up-modal-content"></div>
+ </div>
+ </div>
+ """
+
+ ###*
+ @method up.modal.defaults
+ @param {Number} options.width
+ @param {Number} options.height
+ @param {String|Function(config)} options.template
+ @param {String} options.closeLabel
+ @param {String} options.openAnimation
+ @param {String} options.closeAnimation
+ ###
+ defaults = (options) ->
+ u.extend(config, options)
+
+ templateHtml = ->
+ template = config.template
+ if u.isFunction(template)
+ template(config)
+ else
+ template
+
+ createHiddenModal = (selector, width, height, sticky) ->
+ $modal = $(templateHtml())
+ $modal.attr('up-sticky', '') if sticky
+ $modal.attr('up-previous-url', up.browser.url())
+ $modal.attr('up-previous-title', document.title)
+ $dialog = $modal.find('.up-modal-dialog')
+ $dialog.css('width', width) if u.isPresent(width)
+ $dialog.css('height', height) if u.isPresent(height)
+ $content = $dialog.find('.up-modal-content')
+ $placeholder = u.$createElementFromSelector(selector)
+ $placeholder.appendTo($content)
+ $modal.appendTo(document.body)
+ $modal.hide()
+ $modal
+
+ updated = ($modal, animation) ->
+ $modal.show()
+ up.animate($modal, animation)
+
+ ###*
+ Opens a modal overlay.
+
+ @method up.modal.open
+ @param {Element|jQuery|String} elementOrSelector
+ @param {Number} [options.width]
+ @param {Number} [options.height]
+ @param {String} [options.origin='bottom-right']
+ @param {String} [options.animation]
+ @param {Boolean} [options.sticky=false]
+ If set to `true`, the modal remains
+ open even if the page changes in the background.
+ @param {Object} [options.history=true]
+ ###
+ open = (linkOrSelector, options) ->
+ $link = $(linkOrSelector)
+
+ options = u.options(options)
+ url = u.option($link.attr('href'))
+ selector = u.option(options.target, $link.attr('up-modal'), 'body')
+ width = u.option(options.width, $link.attr('up-width'), config.width)
+ height = u.option(options.height, $link.attr('up-height'), config.height)
+ animation = u.option(options.animation, $link.attr('up-animation'), config.openAnimation)
+ sticky = u.option(options.sticky, $link.is('[up-sticky]'))
+ history = u.option(options.history, $link.attr('up-history'), true)
+
+ close()
+ $modal = createHiddenModal(selector, width, height, sticky)
+
+ up.replace(selector, url,
+ history: history
+ insert: -> updated($modal, animation)
+ )
+
+ ###*
+ Returns the source URL for the fragment displayed
+ in the current modal overlay, or `undefined` if no
+ modal is open.
+
+ @method up.modal.source
+ @return {String}
+ the source URL
+ ###
source = ->
- $('.up-modal').find('[up-source]').attr('up-source')
+ $modal = $('.up-modal')
+ unless $modal.is('.up-destroying')
+ $modal.find('[up-source]').attr('up-source')
-# defaults: defaults
-# open: open
-# close: close
+ ###*
+ Closes a currently opened modal overlay.
+ Does nothing if no modal is currently open.
+
+ @method up.modal.close
+ @param {Object} options
+ See options for [`up.animate`](/up.motion#up.animate)
+ ###
+ close = (options) ->
+ $modal = $('.up-modal')
+ if $modal.length
+ options = u.options(options,
+ animation: config.closeAnimation,
+ url: $modal.attr('up-previous-url')
+ title: $modal.attr('up-previous-title')
+ )
+ up.destroy($modal, options)
+
+ autoclose = ->
+ unless $('.up-modal').is('[up-sticky]')
+ close()
+
+ ###*
+ Opens the target of this link in a modal dialog:
+
+ <a href="/decks" up-modal=".deck_list">Switch deck</a>
+
+ If the `up-sticky` attribute is set, the dialog does not auto-close
+ if a page fragment below the dialog updates:
+
+ <a href="/settings" up-modal=".options" up-sticky>Settings</a>
+
+ @method a[up-modal]
+ @ujs
+ @param up-target
+ @param [up-sticky]
+ ###
+ up.on('click', 'a[up-modal]', (event, $link) ->
+ event.preventDefault()
+ if $link.is('.up-current')
+ close()
+ else
+ open($link)
+ )
+
+ # Close the modal when someone clicks outside the dialog
+ # (but not on a modal opener).
+ up.on('click', 'body', (event, $body) ->
+ $target = $(event.target)
+ unless $target.closest('.up-dialog').length || $target.closest('[up-modal]').length
+ close()
+ )
+
+ up.bus.on('fragment:ready', ($fragment) ->
+ unless $fragment.closest('.up-modal').length
+ autoclose()
+ )
+
+ # Close the pop-up overlay when the user presses ESC.
+ up.magic.onEscape(-> close())
+
+ ###*
+ When this element is clicked, closes a currently open dialog.
+
+ @method [up-close]
+ @ujs
+ ###
+ up.on('click', '[up-close]', (event, $element) ->
+ if $element.closest('.up-modal')
+ close()
+ )
+
+ open: open
+ close: close
source: source
+ defaults: defaults
)()