|
1 YUI.add('datatable-message', function (Y, NAME) { |
|
2 |
|
3 /** |
|
4 Adds support for a message container to appear in the table. This can be used |
|
5 to indicate loading progress, lack of records, or any other communication |
|
6 needed. |
|
7 |
|
8 @module datatable |
|
9 @submodule datatable-message |
|
10 @since 3.5.0 |
|
11 **/ |
|
12 var Message; |
|
13 |
|
14 /** |
|
15 _API docs for this extension are included in the DataTable class._ |
|
16 |
|
17 Adds support for a message container to appear in the table. This can be used |
|
18 to indicate loading progress, lack of records, or any other communication |
|
19 needed. |
|
20 |
|
21 Features added to `Y.DataTable`, and made available for custom classes at |
|
22 `Y.DataTable.Message`. |
|
23 |
|
24 @class DataTable.Message |
|
25 @for DataTable |
|
26 @since 3.5.0 |
|
27 **/ |
|
28 Y.namespace('DataTable').Message = Message = function () {}; |
|
29 |
|
30 Message.ATTRS = { |
|
31 /** |
|
32 Enables the display of messages in the table. Setting this to false will |
|
33 prevent the message Node from being created and `showMessage` from doing |
|
34 anything. |
|
35 |
|
36 @attribute showMessages |
|
37 @type {Boolean} |
|
38 @default true |
|
39 @since 3.5.0 |
|
40 **/ |
|
41 showMessages: { |
|
42 value: true, |
|
43 validator: Y.Lang.isBoolean |
|
44 } |
|
45 }; |
|
46 |
|
47 Y.mix(Message.prototype, { |
|
48 /** |
|
49 Template used to generate the node that will be used to report messages. |
|
50 |
|
51 @property MESSAGE_TEMPLATE |
|
52 @type {String} |
|
53 @default <tbody class="{className}"><td class="{contentClass}" colspan="{colspan}"></td></tbody> |
|
54 @since 3.5.0 |
|
55 **/ |
|
56 MESSAGE_TEMPLATE: '<tbody class="{className}"><tr><td class="{contentClass}" colspan="{colspan}"></td></tr></tbody>', |
|
57 |
|
58 /** |
|
59 Hides the message node. |
|
60 |
|
61 @method hideMessage |
|
62 @return {DataTable} |
|
63 @chainable |
|
64 @since 3.5.0 |
|
65 **/ |
|
66 hideMessage: function () { |
|
67 this.get('boundingBox').removeClass( |
|
68 this.getClassName('message', 'visible')); |
|
69 |
|
70 return this; |
|
71 }, |
|
72 |
|
73 /** |
|
74 Display the message node and set its content to `message`. If there is a |
|
75 localized `strings` entry for the value of `message`, that string will be |
|
76 used. |
|
77 |
|
78 @method showMessage |
|
79 @param {String} message The message name or message itself to display |
|
80 @return {DataTable} |
|
81 @chainable |
|
82 @since 3.5.0 |
|
83 **/ |
|
84 showMessage: function (message) { |
|
85 var content = this.getString(message) || message; |
|
86 |
|
87 if (!this._messageNode) { |
|
88 this._initMessageNode(); |
|
89 } |
|
90 |
|
91 if (this.get('showMessages')) { |
|
92 if (content) { |
|
93 this._messageNode.one( |
|
94 '.' + this.getClassName('message', 'content')) |
|
95 .setHTML(content); |
|
96 |
|
97 this.get('boundingBox').addClass( |
|
98 this.getClassName('message','visible')); |
|
99 } else { |
|
100 // TODO: is this right? |
|
101 // If no message provided, remove the message node. |
|
102 this.hideMessage(); |
|
103 } |
|
104 } |
|
105 |
|
106 return this; |
|
107 }, |
|
108 |
|
109 //-------------------------------------------------------------------------- |
|
110 // Protected methods |
|
111 //-------------------------------------------------------------------------- |
|
112 /** |
|
113 Updates the colspan of the `<td>` used to display the messages. |
|
114 |
|
115 @method _afterMessageColumnsChange |
|
116 @param {EventFacade} e The columnsChange event |
|
117 @protected |
|
118 @since 3.5.0 |
|
119 **/ |
|
120 _afterMessageColumnsChange: function () { |
|
121 var contentNode; |
|
122 |
|
123 if (this._messageNode) { |
|
124 contentNode = this._messageNode.one( |
|
125 '.' + this.getClassName('message', 'content')); |
|
126 |
|
127 if (contentNode) { |
|
128 // FIXME: This needs to become a class extension plus a view or |
|
129 // plugin for the table view. |
|
130 contentNode.set('colSpan', this._displayColumns.length); |
|
131 } |
|
132 } |
|
133 }, |
|
134 |
|
135 /** |
|
136 Relays to `_uiSetMessage` to hide or show the message node. |
|
137 |
|
138 @method _afterMessageDataChange |
|
139 @param {EventFacade} e The dataChange event |
|
140 @protected |
|
141 @since 3.5.0 |
|
142 **/ |
|
143 _afterMessageDataChange: function () { |
|
144 this._uiSetMessage(); |
|
145 }, |
|
146 |
|
147 /** |
|
148 Removes the message node if `showMessages` is `false`, or relays to |
|
149 `_uiSetMessage` if `true`. |
|
150 |
|
151 @method _afterShowMessagesChange |
|
152 @param {EventFacade} e The showMessagesChange event |
|
153 @protected |
|
154 @since 3.5.0 |
|
155 **/ |
|
156 _afterShowMessagesChange: function (e) { |
|
157 if (e.newVal) { |
|
158 this._uiSetMessage(e); |
|
159 } else if (this._messageNode) { |
|
160 this.get('boundingBox').removeClass( |
|
161 this.getClassName('message', 'visible')); |
|
162 |
|
163 this._messageNode.remove().destroy(true); |
|
164 this._messageNode = null; |
|
165 } |
|
166 }, |
|
167 |
|
168 /** |
|
169 Binds the events necessary to keep the message node in sync with the current |
|
170 table and configuration state. |
|
171 |
|
172 @method _bindMessageUI |
|
173 @protected |
|
174 @since 3.5.0 |
|
175 **/ |
|
176 _bindMessageUI: function () { |
|
177 this.after(['dataChange', '*:add', '*:remove', '*:reset'], |
|
178 Y.bind('_afterMessageDataChange', this)); |
|
179 |
|
180 this.after('columnsChange', Y.bind('_afterMessageColumnsChange', this)); |
|
181 |
|
182 this.after('showMessagesChange', |
|
183 Y.bind('_afterShowMessagesChange', this)); |
|
184 }, |
|
185 |
|
186 /** |
|
187 Merges in the message related strings and hooks into the rendering cycle to |
|
188 also render and bind the message node. |
|
189 |
|
190 @method initializer |
|
191 @protected |
|
192 @since 3.5.0 |
|
193 **/ |
|
194 initializer: function () { |
|
195 this._initMessageStrings(); |
|
196 |
|
197 if (this.get('showMessages')) { |
|
198 this.after('table:renderBody', Y.bind('_initMessageNode', this)); |
|
199 } |
|
200 |
|
201 this.after(Y.bind('_bindMessageUI', this), this, 'bindUI'); |
|
202 this.after(Y.bind('_syncMessageUI', this), this, 'syncUI'); |
|
203 }, |
|
204 |
|
205 /** |
|
206 Creates the `_messageNode` property from the configured `MESSAGE_TEMPLATE` |
|
207 and inserts it before the `<table>`'s `<tbody>` node. |
|
208 |
|
209 @method _initMessageNode |
|
210 @protected |
|
211 @since 3.5.0 |
|
212 **/ |
|
213 _initMessageNode: function () { |
|
214 if (!this._messageNode) { |
|
215 this._messageNode = Y.Node.create( |
|
216 Y.Lang.sub(this.MESSAGE_TEMPLATE, { |
|
217 className: this.getClassName('message'), |
|
218 contentClass: this.getClassName('message', 'content'), |
|
219 colspan: this._displayColumns.length || 1 |
|
220 })); |
|
221 |
|
222 this._tableNode.insertBefore(this._messageNode, this._tbodyNode); |
|
223 } |
|
224 }, |
|
225 |
|
226 /** |
|
227 Add the messaging related strings to the `strings` map. |
|
228 |
|
229 @method _initMessageStrings |
|
230 @protected |
|
231 @since 3.5.0 |
|
232 **/ |
|
233 _initMessageStrings: function () { |
|
234 // Not a valueFn because other class extensions will want to add to it |
|
235 this.set('strings', Y.mix((this.get('strings') || {}), |
|
236 Y.Intl.get('datatable-message'))); |
|
237 }, |
|
238 |
|
239 /** |
|
240 Node used to display messages from `showMessage`. |
|
241 |
|
242 @property _messageNode |
|
243 @type {Node} |
|
244 @value `undefined` (not initially set) |
|
245 @since 3.5.0 |
|
246 **/ |
|
247 //_messageNode: null, |
|
248 |
|
249 /** |
|
250 Synchronizes the message UI with the table state. |
|
251 |
|
252 @method _syncMessageUI |
|
253 @protected |
|
254 @since 3.5.0 |
|
255 **/ |
|
256 _syncMessageUI: function () { |
|
257 this._uiSetMessage(); |
|
258 }, |
|
259 |
|
260 /** |
|
261 Calls `hideMessage` or `showMessage` as appropriate based on the presence of |
|
262 records in the `data` ModelList. |
|
263 |
|
264 This is called when `data` is reset or records are added or removed. Also, |
|
265 if the `showMessages` attribute is updated. In either case, if the |
|
266 triggering event has a `message` property on the EventFacade, it will be |
|
267 passed to `showMessage` (if appropriate). If no such property is on the |
|
268 facade, the `emptyMessage` will be used (see the strings). |
|
269 |
|
270 @method _uiSetMessage |
|
271 @param {EventFacade} e The columnsChange event |
|
272 @protected |
|
273 @since 3.5.0 |
|
274 **/ |
|
275 _uiSetMessage: function (e) { |
|
276 if (!this.data.size()) { |
|
277 this.showMessage((e && e.message) || 'emptyMessage'); |
|
278 } else { |
|
279 this.hideMessage(); |
|
280 } |
|
281 } |
|
282 }); |
|
283 |
|
284 |
|
285 if (Y.Lang.isFunction(Y.DataTable)) { |
|
286 Y.Base.mix(Y.DataTable, [ Message ]); |
|
287 } |
|
288 |
|
289 |
|
290 }, '@VERSION@', {"requires": ["datatable-base"], "lang": ["en", "fr", "es", "hu", "it"], "skinnable": true}); |