PageRenderTime 160ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/auiplugin/src/main/resources/experimental/js/atlassian/restfultable/restfultable.js

https://bitbucket.org/200ok/aui-archive-i18n
JavaScript | 869 lines | 533 code | 137 blank | 199 comment | 55 complexity | bdc36067364d4ca74da5501a927c0882 MD5 | raw file
Possible License(s): Apache-2.0
  1. (function ($) {
  2. /**
  3. * A table who's entries/rows are can be retrieved, added and updated via rest (CRUD).
  4. * It uses backbone.js to sync the tables state back to the server and vice versa, avoiding page refreshes.
  5. *
  6. * @class RestfulTable
  7. */
  8. AJS.RestfulTable = Backbone.View.extend({
  9. /**
  10. * @constructor
  11. * @param {Object} options
  12. * ... {String} id - The id for the table. This id will be used to fire events specific to this instance.
  13. * ... {boolean} allowEdit - Is the table editable. If true, clicking row will switch it to edit state.
  14. * ... {boolean} allowCreate - Can new entries be added to the table.
  15. * ... {boolean} allowReorder - Can we drag rows to reorder them.
  16. * ... {String} noEntriesMsg - Message that will be displayed under the table header if it is empty.
  17. * ... {Array} entries - initial data set to be rendered. Each item in the array will be used to create a new instance of options.model.
  18. * ... {AJS.RestfulTable.EntryModel} model - backbone model representing a row.
  19. * ... {Object} views
  20. * ... ... {AJS.RestfulTable.EditRow} editRow - Backbone view that renders the edit & create row. Your view MUST extend AJS.RestfulTable.EditRow.
  21. * ... ... {AJS.RestfulTable.Row} row - Backbone view that renders the readonly row. Your view MUST extend AJS.RestfulTable.Row.
  22. */
  23. initialize: function (options) {
  24. var instance = this;
  25. // combine default and user options
  26. instance.options = $.extend(true, instance._getDefaultOptions(options), options);
  27. // Prefix events for this instance with this id.
  28. instance.id = this.options.id;
  29. // faster lookup
  30. instance._events = AJS.RestfulTable.Events;
  31. instance.classNames = AJS.RestfulTable.ClassNames;
  32. instance.dataKeys = AJS.RestfulTable.DataKeys;
  33. // shortcuts to popular elements
  34. this.$table = $(options.el)
  35. .addClass(this.classNames.RESTFUL_TABLE)
  36. .addClass(this.classNames.ALLOW_HOVER)
  37. .addClass("aui")
  38. .addClass(instance.classNames.LOADING);
  39. this.$table.wrapAll("<form class='aui' action='#' />");
  40. this.$thead = $("<thead/>");
  41. this.$theadRow = $("<tr />").appendTo(this.$thead);
  42. this.$tbody = $("<tbody/>");
  43. if (!this.$table.length) {
  44. throw new Error("AJS.RestfulTable: Init failed! The table you have specified [" + this.$table.selector + "] cannot be found.")
  45. }
  46. if (!this.options.columns) {
  47. throw new Error("AJS.RestfulTable: Init failed! You haven't provided any columns to render.")
  48. }
  49. // Let user know the table is loading
  50. this.showGlobalLoading();
  51. $.each(this.options.columns, function (i, column) {
  52. var header = $.isFunction(column.header) ? column.header() : column.header;
  53. if (typeof header === "undefined") {
  54. console.warn("You have not specified [header] for column [" + column.id + "]. Using id for now...");
  55. header = column.id;
  56. }
  57. instance.$theadRow.append("<th>" + header + "</th>");
  58. });
  59. // columns for submit buttons and loading indicator used when editing
  60. instance.$theadRow.append("<th></th><th></th>");
  61. // create a new Backbone collection to represent rows (http://documentcloud.github.com/backbone/#Collection)
  62. this._models = new this.options.Collection([], {
  63. comparator: function (row) { // sort models in colleciton based on dom ordering
  64. var index;
  65. $.each(instance.getRows(), function (i) {
  66. if (this.model.id === row.id) {
  67. index = i;
  68. return false;
  69. }
  70. });
  71. return index;
  72. }
  73. });
  74. // shortcut to the class we use to create rows
  75. this._rowClass = this.options.views.row;
  76. if (this.options.allowEdit) {
  77. this.editRows = []; // keep track of rows that are being edited concurrently
  78. if (this.options.allowCreate !== false) {
  79. // Create row responsible for adding new entries ...
  80. this._createRow = new this.options.views.editRow({
  81. columns: this.options.columns,
  82. isCreateRow: true,
  83. model: this.options.model.extend({
  84. url: function () {
  85. return instance.options.resources.self;
  86. }
  87. }),
  88. cancelAccessKey: this.options.cancelAccessKey,
  89. submitAccessKey: this.options.submitAccessKey,
  90. allowReorder: this.options.allowReorder
  91. })
  92. .bind(this._events.CREATED, function (values) {
  93. instance.addRow(values, 0);
  94. })
  95. .bind(this._events.VALIDATION_ERROR, function () {
  96. this.trigger(instance._events.FOCUS);
  97. })
  98. .render({
  99. errors: {},
  100. values: {}
  101. });
  102. // ... and appends it as the first row
  103. this.$create = $('<tbody class="' + this.classNames.CREATE + '" />')
  104. .append(this._createRow.el);
  105. // Manage which row has focus
  106. this._applyFocusCoordinator(this._createRow);
  107. // focus create row
  108. this._createRow.trigger(this._events.FOCUS);
  109. }
  110. this.$table.closest("form").submit(function (e) {
  111. if (instance.focusedRow) {
  112. // Delegates saving of row. See AJS.RestfulTable.EditRow.submit
  113. instance.focusedRow.trigger(instance._events.SAVE);
  114. }
  115. e.preventDefault();
  116. });
  117. if (this.options.allowReorder) {
  118. // Add allowance for another cell to the thead
  119. this.$theadRow.prepend("<th />");
  120. // Allow drag and drop reordering of rows
  121. this.$tbody.sortable({
  122. handle: "." +this.classNames.DRAG_HANDLE,
  123. helper: function(e, elt) {
  124. var helper = elt.clone(true).addClass(instance.classNames.MOVEABLE);
  125. helper.children().each(function (i) {
  126. $(this).width(elt.children().eq(i).width());
  127. });
  128. return helper;
  129. },
  130. start: function (event, ui) {
  131. var $this = ui.placeholder.find("td");
  132. // Make sure that when we start dragging widths do not change
  133. ui.item
  134. .addClass(instance.classNames.MOVEABLE)
  135. .children().each(function (i) {
  136. $(this).width($this.eq(i).width());
  137. });
  138. // Add a <td> to the placeholder <tr> to inherit CSS styles.
  139. ui.placeholder
  140. .html('<td colspan="' + instance.getColumnCount() + '">&nbsp;</td>')
  141. .css("visibility", "visible");
  142. // Stop hover effects etc from occuring as we move the mouse (while dragging) over other rows
  143. instance.getRowFromElement(ui.item[0]).trigger(instance._events.MODAL);
  144. },
  145. stop: function (event, ui) {
  146. ui.item
  147. .removeClass(instance.classNames.MOVEABLE)
  148. .children().attr("style", "");
  149. ui.placeholder.removeClass(instance.classNames.ROW);
  150. // Return table to a normal state
  151. instance.getRowFromElement(ui.item[0]).trigger(instance._events.MODELESS);
  152. },
  153. update: function (event, ui) {
  154. var nextModel,
  155. nextRow,
  156. data = {},
  157. row = instance.getRowFromElement(ui.item[0])
  158. if (row) {
  159. nextRow = ui.item.next()[0];
  160. if (nextRow) {
  161. nextModel = instance.getRowFromElement(nextRow).model;
  162. // Get the url of the for the entry befores rest endpoint.
  163. // The server will use this to determine position.
  164. data.after = nextModel.url();
  165. } else {
  166. data.position = "First";
  167. }
  168. $.ajax({
  169. url: row.model.url() + "/move",
  170. type: "POST",
  171. dataType: "json",
  172. contentType: "application/json",
  173. data: JSON.stringify(data),
  174. complete: function () {
  175. // hides loading indicator (spinner)
  176. row.hideLoading();
  177. },
  178. success: function (xhr) {
  179. AJS.triggerEvtForInst(instance._events.REORDER_SUCCESS, instance, [xhr]);
  180. },
  181. error: function (xhr) {
  182. var responseData = $.parseJSON(xhr.responseText || xhr.data);
  183. AJS.triggerEvtForInst(instance._events.SERVER_ERROR, instance, [responseData, xhr]);
  184. }
  185. });
  186. // shows loading indicator (spinner)
  187. row.showLoading();
  188. }
  189. },
  190. axis: "y",
  191. delay: 0,
  192. containment: "document",
  193. cursor: "move",
  194. scroll: true,
  195. zIndex: 8000
  196. });
  197. // Prevent text selection while reordering.
  198. this.$tbody.bind("selectstart mousedown", function (event) {
  199. return !$(event.target).is("." + instance.classNames.DRAG_HANDLE);
  200. });
  201. }
  202. }
  203. // when a model is removed from the collection, remove it from the viewport also
  204. this._models.bind("remove", function (model) {
  205. $.each(instance.getRows(), function (i, row) {
  206. if (row.model === model) {
  207. if (row.hasFocus() && instance._createRow) {
  208. instance._createRow.trigger(instance._events.FOCUS);
  209. }
  210. instance.removeRow(row);
  211. }
  212. });
  213. });
  214. if ($.isFunction(this.options.resources.all)) {
  215. this.options.resources.all(function (entries) {
  216. instance.populate(entries);
  217. });
  218. } else {
  219. $.get(this.options.resources.all, function (entries) {
  220. instance.populate(entries);
  221. });
  222. }
  223. },
  224. /**
  225. * Refreshes table with entries
  226. *
  227. * @param entries
  228. */
  229. populate: function (entries) {
  230. if (this.options.reverseOrder) {
  231. entries.reverse();
  232. }
  233. this.hideGlobalLoading();
  234. if (entries && entries.length) {
  235. // Empty the models collection
  236. this._models.refresh([], { silent: true });
  237. // Add all the entries to collection and render them
  238. this.renderRows(entries);
  239. // show message to user if we have no entries
  240. if (this.isEmpty()) {
  241. this.showNoEntriesMsg();
  242. }
  243. } else {
  244. this.showNoEntriesMsg();
  245. }
  246. // Ok, lets let everyone know that we are done...
  247. this.$table
  248. .append(this.$thead)
  249. .append(this.$create)
  250. .append(this.$tbody)
  251. .removeClass(this.classNames.LOADING)
  252. .trigger(this._events.INITIALIZED, [this]);
  253. AJS.triggerEvtForInst(this._events.INITIALIZED, this, [this]);
  254. if (this.options.autoFocus) {
  255. this.$table.find(":input:text:first").focus(); // set focus to first field
  256. }
  257. },
  258. /**
  259. * Shows loading indicator and text
  260. *
  261. * @return {AJS.RestfulTable}
  262. */
  263. showGlobalLoading: function () {
  264. if (!this.$loading) {
  265. this.$loading = $('<div class="aui-restfultable-init"><span class="aui-restfultable-throbber">' +
  266. '</span><span class="aui-restfultable-loading">' + this.options.loadingMsg + '</span></div>');
  267. }
  268. if (!this.$loading.is(":visible")) {
  269. this.$loading.insertAfter(this.$table);
  270. }
  271. return this
  272. },
  273. /**
  274. * Hides loading indicator and text
  275. * @return {AJS.RestfulTable}
  276. */
  277. hideGlobalLoading: function () {
  278. if (this.$loading) {
  279. this.$loading.remove();
  280. }
  281. return this;
  282. },
  283. /**
  284. * Adds row to collection and renders it
  285. *
  286. * @param {Object} values
  287. * @param {number} index
  288. * @return {AJS.RestfulTable}
  289. */
  290. addRow: function (values, index) {
  291. var view,
  292. model;
  293. if (!values.id) {
  294. throw new Error("AJS.RestfulTable.addRow: to add a row values object must contain an id. "
  295. + "Maybe you are not returning it from your restend point?"
  296. + "Recieved:" + JSON.stringify(values));
  297. }
  298. model = new this.options.model(values);
  299. view = this._renderRow(model, index);
  300. this._models.add(model);
  301. this.removeNoEntriesMsg();
  302. // Let everyone know we added a row
  303. AJS.triggerEvtForInst(this._events.ROW_ADDED, this, [view, this]);
  304. return this;
  305. },
  306. /**
  307. * Provided a view, removes it from display and backbone collection
  308. *
  309. * @param {AJS.RestfulTable.Row}
  310. */
  311. removeRow: function (row) {
  312. this._models.remove(row.model);
  313. row.remove();
  314. if (this.isEmpty()) {
  315. this.showNoEntriesMsg();
  316. }
  317. // Let everyone know we removed a row
  318. AJS.triggerEvtForInst(this._events.ROW_REMOVED, this, [row, this]);
  319. },
  320. /**
  321. * Is there any entries in the table
  322. *
  323. * @return {Boolean}
  324. */
  325. isEmpty: function () {
  326. return this._models.length === 0;
  327. },
  328. /**
  329. * Gets all models
  330. *
  331. * @return {Backbone.Collection}
  332. */
  333. getModels: function () {
  334. return this._models;
  335. },
  336. /**
  337. * Gets table body
  338. *
  339. * @return {jQuery}
  340. */
  341. getTable: function () {
  342. return this.$table;
  343. },
  344. /**
  345. * Gets table body
  346. *
  347. * @return {jQuery}
  348. */
  349. getTableBody: function () {
  350. return this.$tbody;
  351. },
  352. /**
  353. * Gets create Row
  354. *
  355. * @return {B
  356. */
  357. getCreateRow: function () {
  358. return this._createRow;
  359. },
  360. /**
  361. * Gets the number of table colums
  362. *
  363. * @return {Number}
  364. */
  365. getColumnCount: function () {
  366. return this.options.columns.length + 2; // plus 2 accounts for the columns allocated to submit buttons and loading indicator
  367. },
  368. /**
  369. * Get the AJS.RestfulTable.Row that corresponds to the given <tr> element.
  370. *
  371. * @param {HTMLElement} tr
  372. * @return {?AJS.RestfulTable.Row}
  373. */
  374. getRowFromElement: function (tr) {
  375. return $(tr).data(this.dataKeys.ROW_VIEW);
  376. },
  377. /**
  378. * Shows message {options.noEntriesMsg} to the user if there are no entries
  379. *
  380. * @return {AJS.RestfulTable}
  381. */
  382. showNoEntriesMsg: function () {
  383. if (this.$noEntries) {
  384. this.$noEntries.remove();
  385. }
  386. this.$noEntries = $("<tr>")
  387. .addClass(this.classNames.NO_ENTRIES)
  388. .append($("<td>")
  389. .attr("colspan", this.getColumnCount())
  390. .text(this.options.noEntriesMsg)
  391. )
  392. .appendTo(this.$tbody);
  393. return this;
  394. },
  395. /**
  396. * Removes message {options.noEntriesMsg} to the user if there ARE entries
  397. *
  398. * @return {AJS.RestfulTable}
  399. */
  400. removeNoEntriesMsg: function () {
  401. if (this.$noEntries && this._models.length > 0) {
  402. this.$noEntries.remove();
  403. }
  404. return this;
  405. },
  406. /**
  407. * Gets the AJS.RestfulTable.Row from their associated <tr> elements
  408. *
  409. * @return {Array<AJS.RestfulTable.Row>}
  410. */
  411. getRows: function () {
  412. var instance = this,
  413. views = [];
  414. this.$tbody.find("." + this.classNames.READ_ONLY).each(function () {
  415. var $row = $(this),
  416. view = $row.data(instance.dataKeys.ROW_VIEW);
  417. if (view) {
  418. views.push(view);
  419. }
  420. });
  421. return views;
  422. },
  423. /**
  424. * Appends entry to end or specified index of table
  425. *
  426. * @param {AJS.RestfulTable.EntryModel} model
  427. * @param index
  428. * @return {jQuery}
  429. */
  430. _renderRow: function (model, index) {
  431. var instance = this,
  432. $rows = this.$tbody.find("." + this.classNames.READ_ONLY),
  433. $row,
  434. view;
  435. view = new this._rowClass({
  436. model: model,
  437. columns: this.options.columns,
  438. allowEdit: this.options.allowEdit,
  439. allowReorder: this.options.allowReorder
  440. });
  441. this.removeNoEntriesMsg();
  442. view.bind(this._events.EDIT_ROW, function (field) {
  443. instance.edit(this, field);
  444. });
  445. $row = view.render().$el;
  446. if (index !== -1) {
  447. if (typeof index === "number" && $rows.length !== 0) {
  448. $row.insertBefore($rows[index]);
  449. } else {
  450. this.$tbody.append($row);
  451. }
  452. }
  453. $row.data(this.dataKeys.ROW_VIEW, view);
  454. // deactivate all rows - used in the cases, such as opening a dropdown where you do not want the table editable
  455. // or any interactions
  456. view.bind(this._events.MODAL, function () {
  457. instance.$table.removeClass(instance.classNames.ALLOW_HOVER);
  458. instance.$tbody.sortable("disable");
  459. $.each(instance.getRows(), function () {
  460. if (!instance.isRowBeingEdited(this)) {
  461. this.delegateEvents({}); // clear all events
  462. }
  463. });
  464. });
  465. view.bind(this._events.ANIMATION_STARTED, function () {
  466. instance.$table.removeClass(instance.classNames.ALLOW_HOVER);
  467. });
  468. view.bind(this._events.ANIMATION_FINISHED, function () {
  469. instance.$table.addClass(instance.classNames.ALLOW_HOVER);
  470. });
  471. // activate all rows - used in the cases, such as opening a dropdown where you do not want the table editable
  472. // or any interactions
  473. view.bind(this._events.MODELESS, function () {
  474. instance.$table.addClass(instance.classNames.ALLOW_HOVER);
  475. instance.$tbody.sortable("enable");
  476. $.each(instance.getRows(), function () {
  477. if (!instance.isRowBeingEdited(this)) {
  478. this.delegateEvents(); // rebind all events
  479. }
  480. });
  481. });
  482. // ensure that when this row is focused no other are
  483. this._applyFocusCoordinator(view);
  484. this.trigger(this._events.ROW_INITIALIZED, view);
  485. return view;
  486. },
  487. /**
  488. * Returns if the row is edit mode or note
  489. *
  490. * @param {AJS.RestfulTable.Row} - read onyl row to check if being edited
  491. * @return {Boolean}
  492. */
  493. isRowBeingEdited: function (row) {
  494. var isBeingEdited = false;
  495. $.each(this.editRows, function () {
  496. if (this.el === row.el) {
  497. isBeingEdited = true;
  498. return false;
  499. }
  500. });
  501. return isBeingEdited;
  502. },
  503. /**
  504. * Ensures that when supplied view is focused no others are
  505. *
  506. * @param {Backbone.View} view
  507. * @return {AJS.RestfulTable}
  508. */
  509. _applyFocusCoordinator: function (view) {
  510. var instance = this;
  511. if (!view.hasFocusBound) {
  512. view.hasFocusBound = true;
  513. view.bind(this._events.FOCUS, function () {
  514. if (instance.focusedRow && instance.focusedRow !== view) {
  515. instance.focusedRow.trigger(instance._events.BLUR);
  516. }
  517. instance.focusedRow = view;
  518. if (view instanceof AJS.RestfulTable.Row && instance._createRow) {
  519. instance._createRow.enable();
  520. }
  521. });
  522. }
  523. return this;
  524. },
  525. /**
  526. * Remove specificed row from collection holding rows being concurrently edited
  527. *
  528. * @param {AJS.RestfulTable.EditRow} editView
  529. * @return {AJS.RestfulTable}
  530. */
  531. _removeEditRow: function (editView) {
  532. var index = $.inArray(editView, this.editRows);
  533. this.editRows.splice(index, 1);
  534. return this;
  535. },
  536. /**
  537. * Focuses last row still being edited or create row (if it exists)
  538. *
  539. * @return {AJS.RestfulTable}
  540. */
  541. _shiftFocusAfterEdit: function () {
  542. if (this.editRows.length > 0) {
  543. this.editRows[this.editRows.length-1].trigger(this._events.FOCUS);
  544. } else if (this._createRow) {
  545. this._createRow.trigger(this._events.FOCUS);
  546. }
  547. return this;
  548. },
  549. /**
  550. * Evaluate if we save row when we blur. We can only do this when there is one row being edited at a time, otherwise
  551. * it causes an infinate loop JRADEV-5325
  552. *
  553. * @return {boolean}
  554. */
  555. _saveEditRowOnBlur: function () {
  556. return this.editRows.length <= 1;
  557. },
  558. /**
  559. * Dismisses rows being edited concurrently that have no changes
  560. */
  561. dismissEditRows: function () {
  562. var instance = this;
  563. $.each(this.editRows, function () {
  564. if (!this.hasUpdates()) {
  565. this.trigger(instance._events.FINISHED_EDITING);
  566. }
  567. });
  568. },
  569. /**
  570. * Converts readonly row to editable view
  571. *
  572. * @param {Backbone.View} row
  573. * @param {String} field - field name to focus
  574. * @return {Backbone.View} editRow
  575. */
  576. edit: function (row, field) {
  577. var instance = this,
  578. editRow = new this.options.views.editRow({
  579. el: row.el,
  580. columns: this.options.columns,
  581. isUpdateMode: true,
  582. allowReorder: this.options.allowReorder,
  583. model: row.model,
  584. cancelAccessKey: this.options.cancelAccessKey,
  585. submitAccessKey: this.options.submitAccessKey
  586. }),
  587. values = row.model.toJSON();
  588. values.update = true;
  589. editRow.render({
  590. errors: {},
  591. update: true,
  592. values: values
  593. })
  594. .bind(instance._events.UPDATED, function (model, focusUpdated) {
  595. instance._removeEditRow (this);
  596. this.unbind();
  597. row.render().delegateEvents(); // render and rebind events
  598. row.trigger(instance._events.UPDATED); // trigger blur fade out
  599. if (focusUpdated !== false) {
  600. instance._shiftFocusAfterEdit();
  601. }
  602. })
  603. .bind(instance._events.VALIDATION_ERROR, function () {
  604. this.trigger(instance._events.FOCUS);
  605. })
  606. .bind(instance._events.FINISHED_EDITING, function () {
  607. instance._removeEditRow(this);
  608. row.render().delegateEvents();
  609. this.unbind(); // avoid any other updating, blurring, finished editing, cancel events being fired
  610. })
  611. .bind(instance._events.CANCEL, function () {
  612. instance._removeEditRow(this);
  613. this.unbind(); // avoid any other updating, blurring, finished editing, cancel events being fired
  614. row.render().delegateEvents(); // render and rebind events
  615. instance._shiftFocusAfterEdit();
  616. })
  617. .bind(instance._events.BLUR, function () {
  618. instance.dismissEditRows(); // dismiss edit rows that have no changes
  619. if (instance._saveEditRowOnBlur()) {
  620. this.trigger(instance._events.SAVE, false); // save row, which if successful will call the updated event above
  621. }
  622. });
  623. // Ensure that if focus is pulled to another row, we blur the edit row
  624. this._applyFocusCoordinator(editRow);
  625. // focus edit row, which has the flow on effect of blurring current focused row
  626. editRow.trigger(instance._events.FOCUS, field);
  627. // disables form fields
  628. if (instance._createRow) {
  629. instance._createRow.disable();
  630. }
  631. this.editRows.push(editRow);
  632. return editRow;
  633. },
  634. /**
  635. * Renders all specified rows
  636. *
  637. * @param {Array} array of objects describing Backbone.Model's to render
  638. * @return {AJS.RestfulTable}
  639. */
  640. renderRows: function (rows) {
  641. var model,
  642. $els = $();
  643. // Insert prepopulated entries
  644. for (var i = 0; i < rows.length; i++) {
  645. model = new this.options.model(rows[i]);
  646. $els = $els.add(this._renderRow(model, -1).el);
  647. this._models.add(model)
  648. }
  649. this.removeNoEntriesMsg();
  650. this.$tbody.append($els);
  651. return this;
  652. },
  653. /**
  654. * Gets default options
  655. *
  656. * @param {Object} options
  657. */
  658. _getDefaultOptions: function (options) {
  659. return {
  660. model: options.model || AJS.RestfulTable.EntryModel,
  661. allowEdit: true,
  662. views: {
  663. editRow: AJS.RestfulTable.EditRow,
  664. row: AJS.RestfulTable.Row
  665. },
  666. Collection: Backbone.Collection.extend({
  667. url: options.resources.self,
  668. model: options.model || AJS.RestfulTable.EntryModel
  669. }),
  670. allowReorder: false,
  671. loadingMsg: options.loadingMsg || AJS.I18n.getText("aui.words.loading")
  672. }
  673. }
  674. });
  675. // jQuery data keys (http://api.jquery.com/jQuery.data/)
  676. AJS.RestfulTable.DataKeys = {
  677. ENABLED_SUBMIT: "enabledSubmit",
  678. ROW_VIEW: "RestfulTable_Row_View"
  679. };
  680. // CSS style classes. DON'T hard code
  681. AJS.RestfulTable.ClassNames = {
  682. NO_VALUE: "aui-restfultable-editable-no-value",
  683. NO_ENTRIES: "aui-restfultable-no-entires",
  684. RESTFUL_TABLE: "aui-restfultable",
  685. ROW: "aui-restfultable-row",
  686. READ_ONLY: "aui-restfultable-readonly",
  687. ACTIVE: "aui-restfultable-active",
  688. ALLOW_HOVER: "aui-restfultable-allowhover",
  689. FOCUSED: "aui-restfultable-focused",
  690. MOVEABLE: "aui-restfultable-movable",
  691. ANIMATING: "aui-restfultable-animate",
  692. DISABLED: "aui-resfultable-disabled",
  693. SUBMIT: "aui-restfultable-submit",
  694. EDIT_ROW: "aui-restfultable-editrow",
  695. CREATE: "aui-restfultable-create",
  696. DRAG_HANDLE: "aui-restfultable-draghandle",
  697. ORDER: "aui-restfultable-order",
  698. EDITABLE: "aui-restfultable-editable",
  699. ERROR: "error",
  700. DELETE: "aui-resfultable-delete",
  701. LOADING: "loading"
  702. };
  703. // Custom events
  704. AJS.RestfulTable.Events = {
  705. // AJS events
  706. REORDER_SUCCESS: "RestfulTable.reorderSuccess",
  707. ROW_ADDED: "RestfulTable.rowAdded",
  708. ROW_REMOVED: "RestfulTable.rowRemoved",
  709. EDIT_ROW: "RestfulTable.switchedToEditMode",
  710. SERVER_ERROR: "RestfulTable.serverError",
  711. // backbone events
  712. CREATED: "created",
  713. UPDATED: "updated",
  714. FOCUS: "focus",
  715. BLUR: "blur",
  716. SUBMIT: "submit",
  717. SAVE: "save",
  718. MODAL: "modal",
  719. MODELESS: "modeless",
  720. CANCEL: "cancel",
  721. CONTENT_REFRESHED: "contentRefreshed",
  722. RENDER: "render",
  723. FINISHED_EDITING: "finishedEditing",
  724. VALIDATION_ERROR: "validationError",
  725. SUBMIT_STARTED: "submitStarted",
  726. SUBMIT_FINISHED: "submitFinished",
  727. ANIMATION_STARTED: "animationStarted",
  728. ANIMATION_FINISHED: "animationFinisehd",
  729. INITIALIZED: "initialized",
  730. ROW_INITIALIZED: "rowInitialized"
  731. };
  732. })(AJS.$);