Skip to content
This repository was archived by the owner on Nov 1, 2017. It is now read-only.

Commit 4ba137a

Browse files
committed
Add cancelable tasklist:change event
The tasklist:change event defaults to firing the tasklist:changed event after performing the update unless it's been canceled. Add $.fn.enableTaskList and $.fn.disableTaskList. Clean up some docs.
1 parent cdf00dc commit 4ba137a

File tree

4 files changed

+78
-48
lines changed

4 files changed

+78
-48
lines changed

app/assets/javascripts/task_lists.coffee

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#= provides tasklist:changing
66
#= provides tasklist:change
77
#
8+
#= require crema/element/fire
89
#= require crema/events/pageupdate
910
#
1011
# Enables Task List update behavior.
@@ -27,7 +28,7 @@
2728
#
2829
# ### Specification
2930
#
30-
# TaskLists MUST be contained in a `div.js-task-list-container`.
31+
# TaskLists MUST be contained in a `(div).js-task-list-container`.
3132
#
3233
# TaskList Items SHOULD be an a list (`UL`/`OL`) element.
3334
#
@@ -38,9 +39,10 @@
3839
# `value` attribute is the source (Markdown) to be udpated. The source MUST
3940
# follow the syntax guidelines.
4041
#
41-
# TaskList updates trigger `tasklist:change` events.
42+
# TaskList updates trigger `tasklist:change` events. If the change is
43+
# successful, `tasklist:changed` is fired. The change can be canceled.
4244
#
43-
# jQuery is required and the `$.pageUpdate` behavior MUST be available.
45+
# jQuery and crema are required.
4446
#
4547
# ### Events
4648
#
@@ -112,7 +114,25 @@ updateTaskListItem = (source, itemIndex, checked) ->
112114
line
113115
result.join("\n")
114116

115-
# Enables task list items to trigger updates.
117+
# Updates the $field value to reflect the state of $item.
118+
# Triggers the `tasklist:change` event before the value has changed, and fires
119+
# a `tasklist:changed` event once the value has changed.
120+
updateTaskList = ($item) ->
121+
$container = $item.closest '.js-task-list-container'
122+
$field = $container.find '.js-task-list-field'
123+
index = 1 + $container.find('.task-list-item-checkbox').index($item)
124+
checked = $item.prop 'checked'
125+
126+
$field.fire 'tasklist:change', [index, checked], ->
127+
$field.val updateTaskListItem($field.val(), index, checked)
128+
$field.trigger 'change'
129+
$field.fire 'tasklist:changed', [index, checked]
130+
131+
# When the task list item checkbox is updated, submit the change
132+
$(document).on 'change', '.task-list-item-checkbox', ->
133+
updateTaskList $(this)
134+
135+
# Enables TaskList item changes.
116136
enableTaskList = ($container) ->
117137
if $container.find('.js-task-list-field').length > 0
118138
$container.
@@ -121,39 +141,32 @@ enableTaskList = ($container) ->
121141
$container.addClass('is-task-list-enabled').
122142
trigger 'tasklist:enabled'
123143

144+
# Enables a collection of TaskList containers.
145+
$.fn.enableTaskList = ->
146+
for container in this
147+
enableTaskList $(container)
148+
149+
# (Re)enable a TaskList container.
150+
$(document).on 'tasklist:enable', '.js-task-list-container', (event) ->
151+
enableTaskList $(this)
152+
153+
# Disable TaskList item changes.
124154
disableTaskList = ($container) ->
125155
$container.
126156
find('.task-list-item').removeClass('enabled').
127157
find('.task-list-item-checkbox').attr('disabled', 'disabled')
128158
$container.removeClass('is-task-list-enabled').
129159
trigger 'tasklist:disabled'
130160

131-
# Updates the $field value to reflect the state of $item.
132-
# Triggers the `tasklist:change` event when the value has changed.
133-
updateTaskList = ($item) ->
134-
$container = $item.closest '.js-task-list-container'
135-
$field = $container.find '.js-task-list-field'
136-
index = 1 + $container.find('.task-list-item-checkbox').index($item)
137-
checked = $item.prop 'checked'
138-
139-
$container.trigger 'tasklist:changing', [index, checked]
140-
$field.val updateTaskListItem($field.val(), index, checked)
141-
$field.trigger 'change'
142-
$field.trigger 'tasklist:change', [index, checked]
143-
144-
# When the task list item checkbox is updated, submit the change
145-
$(document).on 'change', '.task-list-item-checkbox', ->
146-
updateTaskList $(this)
161+
# Disables a collection of TaskList containers.
162+
$.fn.disableTaskList = ->
163+
for container in this
164+
disableTaskList $(container)
147165

148166
# Disable a TaskList container.
149167
$(document).on 'tasklist:disable', '.js-task-list-container', (event) ->
150168
disableTaskList $(this)
151169

152-
# (Re)enable a TaskList container.
153-
$(document).on 'tasklist:enable', '.js-task-list-container', (event) ->
154-
enableTaskList $(this)
155-
156170
# When the page is updated, enable new TaskList containers.
157171
$.pageUpdate ->
158-
$('.js-task-list-container').each ->
159-
enableTaskList $(this)
172+
$('.js-task-list-container').enableTaskList()

test/functional/test_task_lists_behavior.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
$('.log').prepend("<li class='timestamp'><time>" + new Date + "</time></li>")
1515
}, 3000)
1616

17+
$(document).on('tasklist:enable', logEvent)
1718
$(document).on('tasklist:enabled', logEvent)
1819
$(document).on('tasklist:disabled', logEvent)
19-
$(document).on('tasklist:change', '.js-task-list-field', function(event){
20+
$(document).on('tasklist:change', logEvent)
21+
$(document).on('tasklist:changed', '.js-task-list-field', function(event){
2022
logEvent(event)
2123
$(this).closest('form').submit()
2224
})

test/unit/test_events.coffee

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
module "TaskList events",
44
setup: ->
5-
window.linkActivated = false
6-
75
@container = $ '<div>', class: 'js-task-list-container'
86

97
@list = $ '<ul>', class: 'task-list'
@@ -28,8 +26,9 @@ module "TaskList events",
2826
$(document).off 'tasklist:enabled'
2927
$(document).off 'tasklist:disabled'
3028
$(document).off 'tasklist:change'
29+
$(document).off 'tasklist:changed'
3130

32-
asyncTest "triggers a tasklist:change event on task list item changes", ->
31+
asyncTest "triggers a tasklist:change event before making task list item changes", ->
3332
expect 1
3433

3534
@field.on 'tasklist:change', (event, index, checked) ->
@@ -41,38 +40,56 @@ asyncTest "triggers a tasklist:change event on task list item changes", ->
4140

4241
@checkbox.click()
4342

44-
asyncTest "enables task list items when a .js-task-list-field is present", ->
43+
asyncTest "triggers a tasklist:changed event once a task list item changes", ->
4544
expect 1
4645

47-
$(document).on 'tasklist:enabled', (event) ->
46+
@field.on 'tasklist:changed', (event, index, checked) ->
4847
ok true
4948

50-
@container.pageUpdate()
5149
setTimeout ->
5250
start()
5351
, 20
5452

55-
asyncTest "doesn't enable task list items when a .js-task-list-field is absent", ->
56-
expect 0
53+
@checkbox.click()
5754

58-
$(document).on 'tasklist:enabled', (event) ->
55+
asyncTest "can cancel a tasklist:changed event", ->
56+
expect 2
57+
58+
@field.on 'tasklist:change', (event, index, checked) ->
5959
ok true
60+
event.preventDefault()
6061

61-
@field.remove()
62+
@field.on 'tasklist:changed', (event, index, checked) ->
63+
ok false
6264

63-
@container.pageUpdate()
64-
setTimeout ->
65+
before = @checkbox.val()
66+
setTimeout =>
67+
equal before, @checkbox.val()
6568
start()
6669
, 20
6770

68-
asyncTest "disables task list items when changing source", ->
71+
@checkbox.click()
72+
73+
asyncTest "enables task list items when a .js-task-list-field is present", ->
6974
expect 1
7075

71-
$(document).on 'tasklist:disabled', (event) ->
76+
$(document).on 'tasklist:enabled', (event) ->
7277
ok true
7378

79+
@container.pageUpdate()
7480
setTimeout ->
7581
start()
7682
, 20
7783

78-
@checkbox.click()
84+
asyncTest "doesn't enable task list items when a .js-task-list-field is absent", ->
85+
expect 0
86+
87+
$(document).on 'tasklist:enabled', (event) ->
88+
ok true
89+
90+
@field.remove()
91+
92+
@container.pageUpdate()
93+
setTimeout ->
94+
start()
95+
, 20

test/unit/test_updates.coffee

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
module "TaskList updates",
44
setup: ->
5-
window.linkActivated = false
6-
75
@container = $ '<div>', class: 'js-task-list-container'
86

97
@list = $ '<ul>', class: 'task-list'
@@ -13,7 +11,7 @@ module "TaskList updates",
1311
type: 'checkbox'
1412
class: 'task-list-item-checkbox'
1513
disabled: true
16-
checked: true # yup
14+
checked: true
1715

1816
@incompleteItem = $ '<li>', class: 'task-list-item'
1917
@incompleteCheckbox = $ '<input>',
@@ -51,12 +49,12 @@ module "TaskList updates",
5149
$('#qunit-fixture').append(@container).pageUpdate()
5250

5351
teardown: ->
54-
$(document).off 'tasklist:change'
52+
$(document).off 'tasklist:changed'
5553

5654
asyncTest "updates the source, marking the incomplete item as complete", ->
5755
expect 3
5856

59-
@field.on 'tasklist:change', (event, index, checked) =>
57+
@field.on 'tasklist:changed', (event, index, checked) =>
6058
ok checked
6159
equal index, @incompleteItem.expectedIndex
6260
equal @field.val(), @changes.toIncomplete
@@ -70,7 +68,7 @@ asyncTest "updates the source, marking the incomplete item as complete", ->
7068
asyncTest "updates the source, marking the complete item as incomplete", ->
7169
expect 3
7270

73-
@field.on 'tasklist:change', (event, index, checked) =>
71+
@field.on 'tasklist:changed', (event, index, checked) =>
7472
ok !checked
7573
equal index, @completeItem.expectedIndex
7674
equal @field.val(), @changes.toComplete

0 commit comments

Comments
 (0)