Dashboard sipadu mbip
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

jquery.tabledit.js 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. /*!
  2. * Tabledit v1.2.3 (https://github.com/markcell/jQuery-Tabledit)
  3. * Copyright (c) 2015 Celso Marques
  4. * Licensed under MIT (https://github.com/markcell/jQuery-Tabledit/blob/master/LICENSE)
  5. */
  6. /**
  7. * @description Inline editor for HTML tables compatible with Bootstrap
  8. * @version 1.2.3
  9. * @author Celso Marques
  10. */
  11. if (typeof jQuery === 'undefined') {
  12. throw new Error('Tabledit requires jQuery library.');
  13. }
  14. (function($) {
  15. 'use strict';
  16. $.fn.Tabledit = function(options) {
  17. if (!this.is('table')) {
  18. throw new Error('Tabledit only works when applied to a table.');
  19. }
  20. var $table = this;
  21. var defaults = {
  22. url: window.location.href,
  23. inputClass: 'form-control input-sm',
  24. toolbarClass: 'btn-toolbar',
  25. groupClass: 'btn-group btn-group-sm',
  26. dangerClass: 'danger',
  27. warningClass: 'warning',
  28. mutedClass: 'text-muted',
  29. eventType: 'click',
  30. rowIdentifier: 'id',
  31. hideIdentifier: false,
  32. autoFocus: true,
  33. editButton: true,
  34. deleteButton: true,
  35. saveButton: true,
  36. restoreButton: true,
  37. buttons: {
  38. edit: {
  39. class: 'btn btn-primary waves-effect waves-light',
  40. html: '<span class="icofont icofont-ui-edit"></span>',
  41. action: 'edit'
  42. },
  43. delete: {
  44. class: 'btn btn-danger waves-effect waves-light',
  45. html: '<span class="icofont icofont-ui-delete"></span>',
  46. action: 'delete'
  47. },
  48. save: {
  49. class: 'btn btn-sm btn-success',
  50. html: 'Save'
  51. },
  52. restore: {
  53. class: 'btn btn-sm btn-warning',
  54. html: 'Restore',
  55. action: 'restore'
  56. },
  57. confirm: {
  58. class: 'btn btn-sm btn-danger',
  59. html: 'Confirm'
  60. }
  61. },
  62. onDraw: function() { return; },
  63. onSuccess: function() { return; },
  64. onFail: function() { return; },
  65. onAlways: function() { return; },
  66. onAjax: function() { return; }
  67. };
  68. var settings = $.extend(true, defaults, options);
  69. var $lastEditedRow = 'undefined';
  70. var $lastDeletedRow = 'undefined';
  71. var $lastRestoredRow = 'undefined';
  72. /**
  73. * Draw Tabledit structure (identifier column, editable columns, toolbar column).
  74. *
  75. * @type {object}
  76. */
  77. var Draw = {
  78. columns: {
  79. identifier: function() {
  80. // Hide identifier column.
  81. if (settings.hideIdentifier) {
  82. $table.find('th:nth-child(' + parseInt(settings.columns.identifier[0]) + 1 + '), tbody td:nth-child(' + parseInt(settings.columns.identifier[0]) + 1 + ')').hide();
  83. }
  84. var $td = $table.find('tbody td:nth-child(' + (parseInt(settings.columns.identifier[0]) + 1) + ')');
  85. $td.each(function() {
  86. // Create hidden input with row identifier.
  87. var span = '<span class="tabledit-span tabledit-identifier">' + $(this).text() + '</span>';
  88. var input = '<input class="tabledit-input tabledit-identifier" type="hidden" name="' + settings.columns.identifier[1] + '" value="' + $(this).text() + '" disabled>';
  89. // Add elements to table cell.
  90. $(this).html(span + input);
  91. // Add attribute "id" to table row.
  92. $(this).parent('tr').attr(settings.rowIdentifier, $(this).text());
  93. });
  94. },
  95. editable: function() {
  96. //
  97. for (var i = 0; i < settings.columns.editable.length; i++) {
  98. var $td = $table.find('tbody td:nth-child(' + (parseInt(settings.columns.editable[i][0]) + 1) + ')');
  99. $td.each(function() {
  100. // Get text of this cell.
  101. var text = $(this).text();
  102. // Add pointer as cursor.
  103. if (!settings.editButton) {
  104. $(this).css('cursor', 'pointer');
  105. }
  106. // Create span element.
  107. var span = '<span class="tabledit-span">' + text + '</span>';
  108. // Check if exists the third parameter of editable array.
  109. if (typeof settings.columns.editable[i][2] !== 'undefined') {
  110. // Create select element.
  111. var input = '<select class="tabledit-input ' + settings.inputClass + '" name="' + settings.columns.editable[i][1] + '" style="display: none;" disabled>';
  112. // Create options for select element.
  113. $.each(jQuery.parseJSON(settings.columns.editable[i][2]), function(index, value) {
  114. if (text === value) {
  115. input += '<option value="' + index + '" selected>' + value + '</option>';
  116. } else {
  117. input += '<option value="' + index + '">' + value + '</option>';
  118. }
  119. });
  120. // Create last piece of select element.
  121. input += '</select>';
  122. } else {
  123. // Create text input element.
  124. var input = '<input class="tabledit-input ' + settings.inputClass + '" type="text" name="' + settings.columns.editable[i][1] + '" value="' + $(this).text() + '" style="display: none;" disabled>';
  125. }
  126. // Add elements and class "view" to table cell.
  127. $(this).html(span + input);
  128. $(this).addClass('tabledit-view-mode');
  129. });
  130. }
  131. },
  132. toolbar: function() {
  133. if (settings.editButton || settings.deleteButton) {
  134. var editButton = '';
  135. var deleteButton = '';
  136. var saveButton = '';
  137. var restoreButton = '';
  138. var confirmButton = '';
  139. // Add toolbar column header if not exists.
  140. if ($table.find('th.tabledit-toolbar-column').length === 0) {
  141. $table.find('tr:first').append('<th class="tabledit-toolbar-column"></th>');
  142. }
  143. // Create edit button.
  144. if (settings.editButton) {
  145. editButton = '<button type="button" class="tabledit-edit-button ' + settings.buttons.edit.class + '" style="float: none;margin: 5px;">' + settings.buttons.edit.html + '</button>';
  146. }
  147. // Create delete button.
  148. if (settings.deleteButton) {
  149. deleteButton = '<button type="button" class="tabledit-delete-button ' + settings.buttons.delete.class + '" style="float: none;margin: 5px;">' + settings.buttons.delete.html + '</button>';
  150. confirmButton = '<button type="button" class="tabledit-confirm-button ' + settings.buttons.confirm.class + '" style="display: none; float: none;">' + settings.buttons.confirm.html + '</button>';
  151. }
  152. // Create save button.
  153. if (settings.editButton && settings.saveButton) {
  154. saveButton = '<button type="button" class="tabledit-save-button ' + settings.buttons.save.class + '" style="display: none; float: none;">' + settings.buttons.save.html + '</button>';
  155. }
  156. // Create restore button.
  157. if (settings.deleteButton && settings.restoreButton) {
  158. restoreButton = '<button type="button" class="tabledit-restore-button ' + settings.buttons.restore.class + '" style="display: none; float: none;">' + settings.buttons.restore.html + '</button>';
  159. }
  160. var toolbar = '<div class="tabledit-toolbar ' + settings.toolbarClass + '" style="text-align: left;">\n\
  161. <div class="' + settings.groupClass + '" style="float: none;">' + editButton + deleteButton + '</div>\n\
  162. ' + saveButton + '\n\
  163. ' + confirmButton + '\n\
  164. ' + restoreButton + '\n\
  165. </div></div>';
  166. // Add toolbar column cells.
  167. $table.find('tr:gt(0)').append('<td style="white-space: nowrap; width: 1%;">' + toolbar + '</td>');
  168. }
  169. }
  170. }
  171. };
  172. /**
  173. * Change to view mode or edit mode with table td element as parameter.
  174. *
  175. * @type object
  176. */
  177. var Mode = {
  178. view: function(td) {
  179. // Get table row.
  180. var $tr = $(td).parent('tr');
  181. // Disable identifier.
  182. $(td).parent('tr').find('.tabledit-input.tabledit-identifier').prop('disabled', true);
  183. // Hide and disable input element.
  184. $(td).find('.tabledit-input').blur().hide().prop('disabled', true);
  185. // Show span element.
  186. $(td).find('.tabledit-span').show();
  187. // Add "view" class and remove "edit" class in td element.
  188. $(td).addClass('tabledit-view-mode').removeClass('tabledit-edit-mode');
  189. // Update toolbar buttons.
  190. if (settings.editButton) {
  191. $tr.find('button.tabledit-save-button').hide();
  192. $tr.find('button.tabledit-edit-button').removeClass('active').blur();
  193. }
  194. },
  195. edit: function(td) {
  196. //
  197. Delete.reset(td);
  198. // Get table row.
  199. var $tr = $(td).parent('tr');
  200. // Enable identifier.
  201. $tr.find('.tabledit-input.tabledit-identifier').prop('disabled', false);
  202. // Hide span element.
  203. $(td).find('.tabledit-span').hide();
  204. // Get input element.
  205. var $input = $(td).find('.tabledit-input');
  206. // Enable and show input element.
  207. $input.prop('disabled', false).show();
  208. // Focus on input element.
  209. if (settings.autoFocus) {
  210. $input.focus();
  211. }
  212. // Add "edit" class and remove "view" class in td element.
  213. $(td).addClass('tabledit-edit-mode').removeClass('tabledit-view-mode');
  214. // Update toolbar buttons.
  215. if (settings.editButton) {
  216. $tr.find('button.tabledit-edit-button').addClass('active');
  217. $tr.find('button.tabledit-save-button').show();
  218. }
  219. }
  220. };
  221. /**
  222. * Available actions for edit function, with table td element as parameter or set of td elements.
  223. *
  224. * @type object
  225. */
  226. var Edit = {
  227. reset: function(td) {
  228. $(td).each(function() {
  229. // Get input element.
  230. var $input = $(this).find('.tabledit-input');
  231. // Get span text.
  232. var text = $(this).find('.tabledit-span').text();
  233. // Set input/select value with span text.
  234. if ($input.is('select')) {
  235. $input.find('option').filter(function() {
  236. return $.trim($(this).text()) === text;
  237. }).attr('selected', true);
  238. } else {
  239. $input.val(text);
  240. }
  241. // Change to view mode.
  242. Mode.view(this);
  243. });
  244. },
  245. submit: function(td) {
  246. // Send AJAX request to server.
  247. var ajaxResult = ajax(settings.buttons.edit.action);
  248. if (ajaxResult === false) {
  249. return;
  250. }
  251. $(td).each(function() {
  252. // Get input element.
  253. var $input = $(this).find('.tabledit-input');
  254. // Set span text with input/select new value.
  255. if ($input.is('select')) {
  256. $(this).find('.tabledit-span').text($input.find('option:selected').text());
  257. } else {
  258. $(this).find('.tabledit-span').text($input.val());
  259. }
  260. // Change to view mode.
  261. Mode.view(this);
  262. });
  263. // Set last edited column and row.
  264. $lastEditedRow = $(td).parent('tr');
  265. }
  266. };
  267. /**
  268. * Available actions for delete function, with button as parameter.
  269. *
  270. * @type object
  271. */
  272. var Delete = {
  273. reset: function(td) {
  274. // Reset delete button to initial status.
  275. $table.find('.tabledit-confirm-button').hide();
  276. // Remove "active" class in delete button.
  277. $table.find('.tabledit-delete-button').removeClass('active').blur();
  278. },
  279. submit: function(td) {
  280. //
  281. Delete.reset(td);
  282. // Enable identifier hidden input.
  283. $(td).parent('tr').find('input.tabledit-identifier').attr('disabled', false);
  284. // Send AJAX request to server.
  285. var ajaxResult = ajax(settings.buttons.delete.action);
  286. // Disable identifier hidden input.
  287. $(td).parents('tr').find('input.tabledit-identifier').attr('disabled', true);
  288. if (ajaxResult === false) {
  289. return;
  290. }
  291. // Add class "deleted" to row.
  292. $(td).parent('tr').addClass('tabledit-deleted-row');
  293. // Hide table row.
  294. $(td).parent('tr').addClass(settings.mutedClass).find('.tabledit-toolbar button:not(.tabledit-restore-button)').attr('disabled', true);
  295. // Show restore button.
  296. $(td).find('.tabledit-restore-button').show();
  297. // Set last deleted row.
  298. $lastDeletedRow = $(td).parent('tr');
  299. var abcd=$(td).parent().parent().children().index($(td).parent('tr'));
  300. var a=abcd+1;
  301. document.getElementById("example-2").deleteRow(a);
  302. },
  303. confirm: function(td) {
  304. //
  305. // Reset all cells in edit mode.
  306. $table.find('td.tabledit-edit-mode').each(function() {
  307. Edit.reset(this);
  308. });
  309. // Add "active" class in delete button.
  310. $(td).find('.tabledit-delete-button').addClass('active');
  311. // Show confirm button.
  312. $(td).find('.tabledit-confirm-button').show();
  313. },
  314. restore: function(td) {
  315. // Enable identifier hidden input.
  316. $(td).parent('tr').find('input.tabledit-identifier').attr('disabled', false);
  317. // Send AJAX request to server.
  318. var ajaxResult = ajax(settings.buttons.restore.action);
  319. // Disable identifier hidden input.
  320. $(td).parents('tr').find('input.tabledit-identifier').attr('disabled', true);
  321. if (ajaxResult === false) {
  322. return;
  323. }
  324. // Remove class "deleted" to row.
  325. $(td).parent('tr').removeClass('tabledit-deleted-row');
  326. // Hide table row.
  327. $(td).parent('tr').removeClass(settings.mutedClass).find('.tabledit-toolbar button').attr('disabled', false);
  328. // Hide restore button.
  329. $(td).find('.tabledit-restore-button').hide();
  330. // Set last restored row.
  331. $lastRestoredRow = $(td).parent('tr');
  332. }
  333. };
  334. /**
  335. * Send AJAX request to server.
  336. *
  337. * @param {string} action
  338. */
  339. function ajax(action)
  340. {
  341. var serialize = $table.find('.tabledit-input').serialize() + '&action=' + action;
  342. var result = settings.onAjax(action, serialize);
  343. if (result === false) {
  344. return false;
  345. }
  346. var jqXHR = $.post(settings.url, serialize, function(data, textStatus, jqXHR) {
  347. if (action === settings.buttons.edit.action) {
  348. $lastEditedRow.removeClass(settings.dangerClass).addClass(settings.warningClass);
  349. setTimeout(function() {
  350. //$lastEditedRow.removeClass(settings.warningClass);
  351. $table.find('tr.' + settings.warningClass).removeClass(settings.warningClass);
  352. }, 1400);
  353. }
  354. settings.onSuccess(data, textStatus, jqXHR);
  355. }, 'json');
  356. jqXHR.fail(function(jqXHR, textStatus, errorThrown) {
  357. if (action === settings.buttons.delete.action) {
  358. $lastDeletedRow.removeClass(settings.mutedClass).addClass(settings.dangerClass);
  359. $lastDeletedRow.find('.tabledit-toolbar button').attr('disabled', false);
  360. $lastDeletedRow.find('.tabledit-toolbar .tabledit-restore-button').hide();
  361. } else if (action === settings.buttons.edit.action) {
  362. $lastEditedRow.addClass(settings.dangerClass);
  363. }
  364. settings.onFail(jqXHR, textStatus, errorThrown);
  365. });
  366. jqXHR.always(function() {
  367. settings.onAlways();
  368. });
  369. return jqXHR;
  370. }
  371. Draw.columns.identifier();
  372. Draw.columns.editable();
  373. Draw.columns.toolbar();
  374. settings.onDraw();
  375. if (settings.deleteButton) {
  376. /**
  377. * Delete one row.
  378. *
  379. * @param {object} event
  380. */
  381. $table.on('click', 'button.tabledit-delete-button', function(event) {
  382. if (event.handled !== true) {
  383. event.preventDefault();
  384. // Get current state before reset to view mode.
  385. var activated = $(this).hasClass('active');
  386. var $td = $(this).parents('td');
  387. Delete.reset($td);
  388. if (!activated) {
  389. Delete.confirm($td);
  390. }
  391. event.handled = true;
  392. }
  393. });
  394. /**
  395. * Delete one row (confirm).
  396. *
  397. * @param {object} event
  398. */
  399. $table.on('click', 'button.tabledit-confirm-button', function(event) {
  400. ////
  401. if (event.handled !== true) {
  402. event.preventDefault();
  403. var $td = $(this).parents('td');
  404. Delete.submit($td);
  405. event.handled = true;
  406. }
  407. });
  408. }
  409. if (settings.restoreButton) {
  410. /**
  411. * Restore one row.
  412. *
  413. * @param {object} event
  414. */
  415. $table.on('click', 'button.tabledit-restore-button', function(event) {
  416. if (event.handled !== true) {
  417. event.preventDefault();
  418. Delete.restore($(this).parents('td'));
  419. event.handled = true;
  420. }
  421. });
  422. }
  423. if (settings.editButton) {
  424. /**
  425. * Activate edit mode on all columns.
  426. *
  427. * @param {object} event
  428. */
  429. $table.on('click', 'button.tabledit-edit-button', function(event) {
  430. if (event.handled !== true) {
  431. event.preventDefault();
  432. var $button = $(this);
  433. // Get current state before reset to view mode.
  434. var activated = $button.hasClass('active');
  435. // Change to view mode columns that are in edit mode.
  436. Edit.reset($table.find('td.tabledit-edit-mode'));
  437. if (!activated) {
  438. // Change to edit mode for all columns in reverse way.
  439. $($button.parents('tr').find('td.tabledit-view-mode').get().reverse()).each(function() {
  440. Mode.edit(this);
  441. });
  442. }
  443. event.handled = true;
  444. }
  445. });
  446. /**
  447. * Save edited row.
  448. *
  449. * @param {object} event
  450. */
  451. $table.on('click', 'button.tabledit-save-button', function(event) {
  452. if (event.handled !== true) {
  453. event.preventDefault();
  454. // Submit and update all columns.
  455. Edit.submit($(this).parents('tr').find('td.tabledit-edit-mode'));
  456. event.handled = true;
  457. }
  458. });
  459. } else {
  460. /**
  461. * Change to edit mode on table td element.
  462. *
  463. * @param {object} event
  464. */
  465. $table.on(settings.eventType, 'tr:not(.tabledit-deleted-row) td.tabledit-view-mode', function(event) {
  466. if (event.handled !== true) {
  467. event.preventDefault();
  468. // Reset all td's in edit mode.
  469. Edit.reset($table.find('td.tabledit-edit-mode'));
  470. // Change to edit mode.
  471. Mode.edit(this);
  472. event.handled = true;
  473. }
  474. });
  475. /**
  476. * Change event when input is a select element.
  477. */
  478. $table.on('change', 'select.tabledit-input:visible', function() {
  479. if (event.handled !== true) {
  480. // Submit and update the column.
  481. Edit.submit($(this).parent('td'));
  482. event.handled = true;
  483. }
  484. });
  485. /**
  486. * Click event on document element.
  487. *
  488. * @param {object} event
  489. */
  490. $(document).on('click', function(event) {
  491. var $editMode = $table.find('.tabledit-edit-mode');
  492. // Reset visible edit mode column.
  493. if (!$editMode.is(event.target) && $editMode.has(event.target).length === 0) {
  494. Edit.reset($table.find('.tabledit-input:visible').parent('td'));
  495. }
  496. });
  497. }
  498. /**
  499. * Keyup event on document element.
  500. *
  501. * @param {object} event
  502. */
  503. $(document).on('keyup', function(event) {
  504. // Get input element with focus or confirmation button.
  505. var $input = $table.find('.tabledit-input:visible');
  506. var $button = $table.find('.tabledit-confirm-button');
  507. if ($input.length > 0) {
  508. var $td = $input.parents('td');
  509. } else if ($button.length > 0) {
  510. var $td = $button.parents('td');
  511. } else {
  512. return;
  513. }
  514. // Key?
  515. switch (event.keyCode) {
  516. case 9: // Tab.
  517. if (!settings.editButton) {
  518. Edit.submit($td);
  519. Mode.edit($td.closest('td').next());
  520. }
  521. break;
  522. case 13: // Enter.
  523. Edit.submit($td);
  524. break;
  525. case 27: // Escape.
  526. Edit.reset($td);
  527. Delete.reset($td);
  528. break;
  529. }
  530. });
  531. return this;
  532. };
  533. }(jQuery));