-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathtemplates_tabs.coffee
136 lines (101 loc) · 3.74 KB
/
templates_tabs.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# Lib
# ---
@ReactiveTabs = ReactiveTabs = do ->
createInterface = (options) ->
check options, Match.ObjectIncluding
template: String
onChange: Match.Optional(Function)
template = Template[options.template]
if template
events = {}
events['click .tab-item'] = (e, t) ->
t._activeTab.set(this)
created = ->
self = this
check(self.data.tabs, Array)
check(self.data.activeTab, Match.Optional(String))
# Init--set first tab if no specified active tab
(self.data.activeTab && activeTab = {slug: self.data.activeTab}) ||
activeTab = self.data.tabs[0]
# Set up reactive data structures
self._tabs = new Blaze.ReactiveVar(self.data.tabs)
self._activeTab = new Blaze.ReactiveVar(activeTab)
# Set tabs--reactive
self.setTabs = (array) ->
if Match.test(array, Array)
self._tabs.set(array)
# Set active tab--takes a full tab object or a slug
self.setActiveTab = (tab) ->
if Match.test(tab, String)
self._activeTab.set({slug: tab})
# See if a slug is the currently active one
self.isActiveSlug = (slug) ->
return self._activeTab.get()?.slug is slug
rendered = ->
self = this
contentBlocks = self.findAll('.tabs-content-container > div')
renderCallbacks = {}
self.autorun ->
tabs = self._tabs.get()
# Reset active tab if it's no longer one of the tabs
Tracker.nonreactive ->
activeTab = self._activeTab.get()
contains = false
for tab in tabs
if tab.slug is activeTab.slug
contains = true
if !contains
self._activeTab.set(tabs[0])
# Support `<div></div>` containers using jQuery
for tab, i in tabs
# Register onRender callbacks by slug
if tab.onRender?
renderCallbacks[tab.slug] = tab.onRender
# Add data-tab attribute to all tabbed content areas
($ contentBlocks[i]).addClass('tabs-content').attr('data-tab', tab.slug)
# Sync corresponding content areas with active tab
self.autorun ->
activeTab = self._activeTab.get()
slug = activeTab?.slug
# Moved onChange to before render
if options?.onChange?
options.onChange(slug, self)
($ self.findAll('.tabs-content')).hide()
($ self.find("[data-tab='#{slug}']")).show()
# Call render callback for this slug
if renderCallbacks[slug]?
renderCallbacks[slug](slug, self)
helpers = {
# These are passed into the interface to be in the tabs' parent scope
# -------------------------------------------------------------------
__context__: ->
inst = Template.instance()
context = {
isActiveSlug: inst.isActiveSlug
}
return context
# These are used as real helpers
# ------------------------------
isActiveTab: (slug) ->
if Template.instance().isActiveSlug(slug)
return 'active'
trackActiveTab: (activeTab) ->
Template.instance().setActiveTab(activeTab)
trackTabs: (tabs) ->
Template.instance().setTabs(tabs)
}
# Put it all together!
template.created = created
template.rendered = rendered
template.helpers(helpers)
template.events(events)
return {
createInterface: createInterface
}
# Tab block
# ---------
Template['tabContent'].helpers
isActiveTab: (slug) ->
ctx = Template.parentData(1).context
if ctx?.isActiveSlug? && ctx.isActiveSlug(slug)
return 'active'