Commit 755cdd3d authored by Randall Leeds's avatar Randall Leeds

Use transclusion for status-button directive

Using transclusion allows for the directive to be set on an element
with non-trivial content and have that content nested inside the
status-button wrapper spans, but pre-bound to its lexical markup
scope.

Not sure we'll need it here, but I also wanted to see how one might
approximate 'replace' now that it's deprecated. The answer is by
not replacing but just adding the template you want after the passed
placeholder comment node.
parent 8f5cf7d9
......@@ -13,7 +13,7 @@ statusButton = ->
STATE_SUCCESS = 'success'
template = '''
<span class="btn-with-message" status-button-state>
<span class="btn-with-message">
<span class="btn-message btn-message-loading">
<span class="btn-icon spinner"><span><span></span></span></span>
</span>
......@@ -23,25 +23,22 @@ statusButton = ->
</span>
'''
compile: (button, attr) ->
link: (scope, placeholder, attr, ctrl, transclude) ->
targetForm = attr.statusButton
unless targetForm
throw new Error('status-button attribute should provide a form name')
# Remove the attribute to prevent recusive parsing.
button.removeAttr('status-button')
elem = angular.element(template)
placeholder.after(elem)
transclude(scope, (clone) -> elem.append(clone))
wrapper = angular.element(template)
wrapper.insertBefore(button)
wrapper.append(button)
post: (scope, elem, attr) ->
scope.$on 'formState', (event, formName, formState) ->
return unless formName == targetForm
unless formState in [STATE_LOADING, STATE_SUCCESS]
formState = ''
wrapper.attr(STATE_ATTRIBUTE, formState)
scope.$on 'formState', (event, formName, formState) ->
return unless formName == targetForm
unless formState in [STATE_LOADING, STATE_SUCCESS]
formState = ''
elem.attr(STATE_ATTRIBUTE, formState)
transclude: 'element'
angular.module('h.directives').directive('statusButton', statusButton)
......@@ -16,26 +16,21 @@ describe 'h.directives.statusButton', ->
<button status-button="test">Test Button</button>
'''
$element = $compile(angular.element(template))($scope)
$element = $compile(angular.element(template))($scope).next()
it 'wraps the button with status labels', ->
parent = $element.parent()
assert.include(parent.prop('className'), 'btn-with-message')
assert.equal(parent.find('.btn-message-loading').length, 1)
assert.equal(parent.find('.btn-message-success').length, 1)
assert.include($element.prop('className'), 'btn-with-message')
assert.equal($element.find('.btn-message-loading').length, 1)
assert.equal($element.find('.btn-message-success').length, 1)
it 'sets the status-button-state attribute when a loading event is triggered', ->
parent = $element.parent()
$scope.$emit('formState', 'test', 'loading')
assert.equal(parent.attr('status-button-state'), 'loading')
assert.equal($element.attr('status-button-state'), 'loading')
it 'sets the status-button-state attribute when a success event is triggered', ->
parent = $element.parent()
$scope.$emit('formState', 'test', 'success')
assert.equal(parent.attr('status-button-state'), 'success')
assert.equal($element.attr('status-button-state'), 'success')
it 'unsets the status-button-state attribute when another event is triggered', ->
parent = $element.parent()
$scope.$emit('formState', 'test', 'reset')
assert.equal(parent.attr('status-button-state'), '')
assert.equal($element.attr('status-button-state'), '')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment