kdf
Version:
237 lines (195 loc) • 7.07 kB
text/coffeescript
KDView = require './../../core/view.coffee'
KDLoaderView = require './../loader/loaderview.coffee'
###*
* KDButtonView implements a `<button>` DOM element, with the ability to subscribe
* to click events.
*
* ## Usage
*
* ```coffee
* view = new KDButtonView
* title: 'Click me!'
* cssClass: 'cupid-green'
* callback: ->
* alert 'I got clicked!'
*
* appView.addSubView view
* ```
*
* This example will render a green button, with the text `"Click me!"`. When the
* button is pressed by the user, an alert will pop up with the message `"I got
* clicked!"`
*
* While this example is fine for an immediate action, what if we wanted our
* button to load a project? For that, we tell the button to use a
* [KDLoaderView](./kdloaderview.md). Lets see how this looks.
*
* ```coffee
* view = new KDButtonView
* title: 'Take a long time.'
* cssClass: 'clean-red'
* loader: {}
* callback: ->
* longTimeDone = =>
* @hideLoader()
* setTimeout longTimeDone, 2000
*
* appView.addSubView view
* ```
*
* In this example, a couple things are different. First, we define a loader
* object. This is an object full of options that are passed to a
* [KDLoaderView](./kdloaderview.md) instance. You'll note that we don't actually
* define any options, but the empty object will cause a loader to be used with
* the default options.
*
* Secondly, in our callback we turn the loader off with the
* [hideLoader](#hideloader) method, after a `setTimeout` of 2000.
*
* The end result of these changes is that when our button is clicked, it starts
* the loader *(with the options we define)*. When we want to turn it off, we call
* the `@hideLoader()` method. Easy!
*
* ## Styling
*
* While not complete, the following list contains some useful built-in
* css classes to style your button with.
*
* - **small-gray**: A small, gray button.
* - **small-blue**: A small, blue button.
* - **clean-gray**: A clean gray button, the default button style.
* - **clean-red**: A clean red button.
* - **cupid-green**: A green button.
* - **transparent**: And no surprise, a transparent button.
###
module.exports = class KDButtonView extends KDView
###*
* Options supports the following keys:
* - **options.title**: The title of the button.
* - **options.callback**: The function to be called when the button is pressed.
* - **options.loader**: The options to use for a loader on this button. If
* false, this button will not use a loader by default. See
* KDLoaderView for the supported options.
*
* @param {Object} options
* @param {Object} data
###
constructor:(options = {}, data)->
options.callback or= noop # a Function
options.title or= "" # a String
# options.style or= "clean-gray" # a String of one of button styles ==> DEPRECATE THIS
options.type or= "button" # a String of submit, reset, button
options.cssClass or= options.style or= "clean-gray" # a String
options.icon ?= no # a Boolean value
options.iconOnly ?= no # a Boolean value
options.iconClass or= "" # a String
options.disabled ?= no # a Boolean value
options.hint or= null # a String of HTML ---> not yet implemented
options.loader ?= no
super options,data
@setClass options.style
@setCallback options.callback
@setTitle options.title
@setIconClass options.iconClass if options.iconClass
@showIcon() if options.icon or options.iconOnly
@setIconOnly options.iconOnly if options.iconOnly
@disable() if options.disabled
if options.focus
@once "viewAppended", @bound "setFocus"
if options.loader
@once "viewAppended", @bound "setLoader"
setFocus:-> @$().trigger 'focus'
setDomElement:(cssClass)->
{lazyDomId, tagName} = @getOptions()
if lazyDomId
el = document.getElementById lazyDomId
for klass in "kdview #{cssClass}".split ' ' when klass.length
el.classList.add klass
unless el?
warn "No lazy DOM Element found with given id #{lazyDomId}." if lazyDomId
el =
"""
<button type='#{@getOptions().type}' class='kdbutton #{cssClass}' id='#{@getId()}'>
<span class='icon hidden'></span>
<span class='button-title'>Title</span>
</button>
"""
@domElement = $ el
setTitle:(title)->
@buttonTitle = title
@$('.button-title').html title
getTitle:-> @buttonTitle
setCallback:(callback)->
@buttonCallback = callback
getCallback:-> @buttonCallback
showIcon:->
@setClass "with-icon"
@$('span.icon').removeClass 'hidden'
hideIcon:->
@unsetClass "with-icon"
@$('span.icon').addClass 'hidden'
setIconClass:(iconClass)->
@$('.icon').attr 'class','icon'
@$('.icon').addClass iconClass
# @setClass iconClass
setIconOnly:->
@unsetClass "with-icon"
@$().addClass('icon-only')
$icon = @$('span.icon')
@$().html $icon
setLoader:->
@setClass "w-loader"
{loader} = @getOptions()
loaderSize = @getHeight()/2
@loader = new KDLoaderView
size :
width : loader.diameter ? loaderSize
loaderOptions :
color : loader.color or "#ffffff"
shape : loader.shape or "spiral"
diameter : loader.diameter ? loaderSize
density : loader.density ? 30
range : loader.range ? 0.4
speed : loader.speed ? 1.5
FPS : loader.FPS ? 24
@addSubView @loader, null, yes
@loader.$().css
position : "absolute"
left : loader.left or "50%"
top : loader.top or "50%"
marginTop : -(loader.diameter/2)
marginLeft : -(loader.diameter/2)
@loader.hide()
@showLoader() if loader.show
###*
* Show the KDLoaderView on this button, if any. Note that the loader is
* shown by default when the button is clicked.
###
showLoader:->
unless @loader
return warn 'KDButtonView::showLoader is called where no loader is set'
{icon, iconOnly} = @getOptions()
@setClass "loading"
@loader.show()
@hideIcon() if icon and not iconOnly
###*
* Hide the KDLoaderView on this button, if any.
###
hideLoader:->
unless @loader
return warn 'KDButtonView::hideLoader is called where no loader is set'
{icon, iconOnly} = @getOptions()
@unsetClass "loading"
@loader.hide()
@showIcon() if icon and not iconOnly
disable:-> @$().attr "disabled", yes
enable:-> @$().attr "disabled", no
focus:-> @$().trigger "focus"
blur:-> @$().trigger "blur"
click:(event)->
return @utils.stopDOMEvent() if @loader?.active
@showLoader() if @loader and not @loader.active
@utils.stopDOMEvent() if @getOption('type') is "button"
@getCallback().call @, event
return no
triggerClick:-> @doOnSubmit()