Built files from Bizgaze WebServer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

edit.js 54KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218
  1. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  2. /* Tabulator v4.8.2 (c) Oliver Folkerd */
  3. var Edit = function Edit(table) {
  4. this.table = table; //hold Tabulator object
  5. this.currentCell = false; //hold currently editing cell
  6. this.mouseClick = false; //hold mousedown state to prevent click binding being overriden by editor opening
  7. this.recursionBlock = false; //prevent focus recursion
  8. this.invalidEdit = false;
  9. this.editedCells = [];
  10. };
  11. //initialize column editor
  12. Edit.prototype.initializeColumn = function (column) {
  13. var self = this,
  14. config = {
  15. editor: false,
  16. blocked: false,
  17. check: column.definition.editable,
  18. params: column.definition.editorParams || {}
  19. };
  20. //set column editor
  21. switch (_typeof(column.definition.editor)) {
  22. case "string":
  23. if (column.definition.editor === "tick") {
  24. column.definition.editor = "tickCross";
  25. console.warn("DEPRECATION WARNING - the tick editor has been deprecated, please use the tickCross editor");
  26. }
  27. if (self.editors[column.definition.editor]) {
  28. config.editor = self.editors[column.definition.editor];
  29. } else {
  30. console.warn("Editor Error - No such editor found: ", column.definition.editor);
  31. }
  32. break;
  33. case "function":
  34. config.editor = column.definition.editor;
  35. break;
  36. case "boolean":
  37. if (column.definition.editor === true) {
  38. if (typeof column.definition.formatter !== "function") {
  39. if (column.definition.formatter === "tick") {
  40. column.definition.formatter = "tickCross";
  41. console.warn("DEPRECATION WARNING - the tick editor has been deprecated, please use the tickCross editor");
  42. }
  43. if (self.editors[column.definition.formatter]) {
  44. config.editor = self.editors[column.definition.formatter];
  45. } else {
  46. config.editor = self.editors["input"];
  47. }
  48. } else {
  49. console.warn("Editor Error - Cannot auto lookup editor for a custom formatter: ", column.definition.formatter);
  50. }
  51. }
  52. break;
  53. }
  54. if (config.editor) {
  55. column.modules.edit = config;
  56. }
  57. };
  58. Edit.prototype.getCurrentCell = function () {
  59. return this.currentCell ? this.currentCell.getComponent() : false;
  60. };
  61. Edit.prototype.clearEditor = function (cancel) {
  62. var cell = this.currentCell,
  63. cellEl;
  64. this.invalidEdit = false;
  65. if (cell) {
  66. this.currentCell = false;
  67. cellEl = cell.getElement();
  68. if (cancel) {
  69. cell.validate();
  70. } else {
  71. cellEl.classList.remove("tabulator-validation-fail");
  72. }
  73. cellEl.classList.remove("tabulator-editing");
  74. while (cellEl.firstChild) {
  75. cellEl.removeChild(cellEl.firstChild);
  76. }cell.row.getElement().classList.remove("tabulator-row-editing");
  77. }
  78. };
  79. Edit.prototype.cancelEdit = function () {
  80. if (this.currentCell) {
  81. var cell = this.currentCell;
  82. var component = this.currentCell.getComponent();
  83. this.clearEditor(true);
  84. cell.setValueActual(cell.getValue());
  85. cell.cellRendered();
  86. if (cell.column.definition.editor == "textarea" || cell.column.definition.variableHeight) {
  87. cell.row.normalizeHeight(true);
  88. }
  89. if (cell.column.cellEvents.cellEditCancelled) {
  90. cell.column.cellEvents.cellEditCancelled.call(this.table, component);
  91. }
  92. this.table.options.cellEditCancelled.call(this.table, component);
  93. }
  94. };
  95. //return a formatted value for a cell
  96. Edit.prototype.bindEditor = function (cell) {
  97. var self = this,
  98. element = cell.getElement();
  99. element.setAttribute("tabindex", 0);
  100. element.addEventListener("click", function (e) {
  101. if (!element.classList.contains("tabulator-editing")) {
  102. element.focus({ preventScroll: true });
  103. }
  104. });
  105. element.addEventListener("mousedown", function (e) {
  106. if (e.button === 2) {
  107. e.preventDefault();
  108. } else {
  109. self.mouseClick = true;
  110. }
  111. });
  112. element.addEventListener("focus", function (e) {
  113. if (!self.recursionBlock) {
  114. self.edit(cell, e, false);
  115. }
  116. });
  117. };
  118. Edit.prototype.focusCellNoEvent = function (cell, block) {
  119. this.recursionBlock = true;
  120. if (!(block && this.table.browser === "ie")) {
  121. cell.getElement().focus({ preventScroll: true });
  122. }
  123. this.recursionBlock = false;
  124. };
  125. Edit.prototype.editCell = function (cell, forceEdit) {
  126. this.focusCellNoEvent(cell);
  127. this.edit(cell, false, forceEdit);
  128. };
  129. Edit.prototype.focusScrollAdjust = function (cell) {
  130. if (this.table.rowManager.getRenderMode() == "virtual") {
  131. var topEdge = this.table.rowManager.element.scrollTop,
  132. bottomEdge = this.table.rowManager.element.clientHeight + this.table.rowManager.element.scrollTop,
  133. rowEl = cell.row.getElement(),
  134. offset = rowEl.offsetTop;
  135. if (rowEl.offsetTop < topEdge) {
  136. this.table.rowManager.element.scrollTop -= topEdge - rowEl.offsetTop;
  137. } else {
  138. if (rowEl.offsetTop + rowEl.offsetHeight > bottomEdge) {
  139. this.table.rowManager.element.scrollTop += rowEl.offsetTop + rowEl.offsetHeight - bottomEdge;
  140. }
  141. }
  142. var leftEdge = this.table.rowManager.element.scrollLeft,
  143. rightEdge = this.table.rowManager.element.clientWidth + this.table.rowManager.element.scrollLeft,
  144. cellEl = cell.getElement(),
  145. offset = cellEl.offsetLeft;
  146. if (this.table.modExists("frozenColumns")) {
  147. leftEdge += parseInt(this.table.modules.frozenColumns.leftMargin);
  148. rightEdge -= parseInt(this.table.modules.frozenColumns.rightMargin);
  149. }
  150. if (cellEl.offsetLeft < leftEdge) {
  151. this.table.rowManager.element.scrollLeft -= leftEdge - cellEl.offsetLeft;
  152. } else {
  153. if (cellEl.offsetLeft + cellEl.offsetWidth > rightEdge) {
  154. this.table.rowManager.element.scrollLeft += cellEl.offsetLeft + cellEl.offsetWidth - rightEdge;
  155. }
  156. }
  157. }
  158. };
  159. Edit.prototype.edit = function (cell, e, forceEdit) {
  160. var self = this,
  161. allowEdit = true,
  162. rendered = function rendered() {},
  163. element = cell.getElement(),
  164. cellEditor,
  165. component,
  166. params;
  167. //prevent editing if another cell is refusing to leave focus (eg. validation fail)
  168. if (this.currentCell) {
  169. if (!this.invalidEdit) {
  170. this.cancelEdit();
  171. }
  172. return;
  173. }
  174. //handle successfull value change
  175. function success(value) {
  176. if (self.currentCell === cell) {
  177. var valid = true;
  178. if (cell.column.modules.validate && self.table.modExists("validate") && self.table.options.validationMode != "manual") {
  179. valid = self.table.modules.validate.validate(cell.column.modules.validate, cell, value);
  180. }
  181. if (valid === true || self.table.options.validationMode === "highlight") {
  182. self.clearEditor();
  183. if (!cell.modules.edit) {
  184. cell.modules.edit = {};
  185. }
  186. cell.modules.edit.edited = true;
  187. if (self.editedCells.indexOf(cell) == -1) {
  188. self.editedCells.push(cell);
  189. }
  190. cell.setValue(value, true);
  191. if (self.table.options.dataTree && self.table.modExists("dataTree")) {
  192. self.table.modules.dataTree.checkForRestyle(cell);
  193. }
  194. if (valid !== true) {
  195. element.classList.add("tabulator-validation-fail");
  196. self.table.options.validationFailed.call(self.table, cell.getComponent(), value, valid);
  197. return false;
  198. }
  199. return true;
  200. } else {
  201. self.invalidEdit = true;
  202. element.classList.add("tabulator-validation-fail");
  203. self.focusCellNoEvent(cell, true);
  204. rendered();
  205. self.table.options.validationFailed.call(self.table, cell.getComponent(), value, valid);
  206. return false;
  207. }
  208. } else {
  209. // console.warn("Edit Success Error - cannot call success on a cell that is no longer being edited");
  210. }
  211. }
  212. //handle aborted edit
  213. function cancel() {
  214. if (self.currentCell === cell) {
  215. self.cancelEdit();
  216. if (self.table.options.dataTree && self.table.modExists("dataTree")) {
  217. self.table.modules.dataTree.checkForRestyle(cell);
  218. }
  219. } else {
  220. // console.warn("Edit Success Error - cannot call cancel on a cell that is no longer being edited");
  221. }
  222. }
  223. function onRendered(callback) {
  224. rendered = callback;
  225. }
  226. if (!cell.column.modules.edit.blocked) {
  227. if (e) {
  228. e.stopPropagation();
  229. }
  230. switch (_typeof(cell.column.modules.edit.check)) {
  231. case "function":
  232. allowEdit = cell.column.modules.edit.check(cell.getComponent());
  233. break;
  234. case "boolean":
  235. allowEdit = cell.column.modules.edit.check;
  236. break;
  237. }
  238. if (allowEdit || forceEdit) {
  239. self.cancelEdit();
  240. self.currentCell = cell;
  241. this.focusScrollAdjust(cell);
  242. component = cell.getComponent();
  243. if (this.mouseClick) {
  244. this.mouseClick = false;
  245. if (cell.column.cellEvents.cellClick) {
  246. cell.column.cellEvents.cellClick.call(this.table, e, component);
  247. }
  248. }
  249. if (cell.column.cellEvents.cellEditing) {
  250. cell.column.cellEvents.cellEditing.call(this.table, component);
  251. }
  252. self.table.options.cellEditing.call(this.table, component);
  253. params = typeof cell.column.modules.edit.params === "function" ? cell.column.modules.edit.params(component) : cell.column.modules.edit.params;
  254. cellEditor = cell.column.modules.edit.editor.call(self, component, onRendered, success, cancel, params);
  255. //if editor returned, add to DOM, if false, abort edit
  256. if (cellEditor !== false) {
  257. if (cellEditor instanceof Node) {
  258. element.classList.add("tabulator-editing");
  259. cell.row.getElement().classList.add("tabulator-row-editing");
  260. while (element.firstChild) {
  261. element.removeChild(element.firstChild);
  262. }element.appendChild(cellEditor);
  263. //trigger onRendered Callback
  264. rendered();
  265. //prevent editing from triggering rowClick event
  266. var children = element.children;
  267. for (var i = 0; i < children.length; i++) {
  268. children[i].addEventListener("click", function (e) {
  269. e.stopPropagation();
  270. });
  271. }
  272. } else {
  273. console.warn("Edit Error - Editor should return an instance of Node, the editor returned:", cellEditor);
  274. element.blur();
  275. return false;
  276. }
  277. } else {
  278. element.blur();
  279. return false;
  280. }
  281. return true;
  282. } else {
  283. this.mouseClick = false;
  284. element.blur();
  285. return false;
  286. }
  287. } else {
  288. this.mouseClick = false;
  289. element.blur();
  290. return false;
  291. }
  292. };
  293. Edit.prototype.maskInput = function (el, options) {
  294. var mask = options.mask,
  295. maskLetter = typeof options.maskLetterChar !== "undefined" ? options.maskLetterChar : "A",
  296. maskNumber = typeof options.maskNumberChar !== "undefined" ? options.maskNumberChar : "9",
  297. maskWildcard = typeof options.maskWildcardChar !== "undefined" ? options.maskWildcardChar : "*",
  298. success = false;
  299. function fillSymbols(index) {
  300. var symbol = mask[index];
  301. if (typeof symbol !== "undefined" && symbol !== maskWildcard && symbol !== maskLetter && symbol !== maskNumber) {
  302. el.value = el.value + "" + symbol;
  303. fillSymbols(index + 1);
  304. }
  305. }
  306. el.addEventListener("keydown", function (e) {
  307. var index = el.value.length,
  308. char = e.key;
  309. if (e.keyCode > 46) {
  310. if (index >= mask.length) {
  311. e.preventDefault();
  312. e.stopPropagation();
  313. success = false;
  314. return false;
  315. } else {
  316. switch (mask[index]) {
  317. case maskLetter:
  318. if (char.toUpperCase() == char.toLowerCase()) {
  319. e.preventDefault();
  320. e.stopPropagation();
  321. success = false;
  322. return false;
  323. }
  324. break;
  325. case maskNumber:
  326. if (isNaN(char)) {
  327. e.preventDefault();
  328. e.stopPropagation();
  329. success = false;
  330. return false;
  331. }
  332. break;
  333. case maskWildcard:
  334. break;
  335. default:
  336. if (char !== mask[index]) {
  337. e.preventDefault();
  338. e.stopPropagation();
  339. success = false;
  340. return false;
  341. }
  342. }
  343. }
  344. success = true;
  345. }
  346. return;
  347. });
  348. el.addEventListener("keyup", function (e) {
  349. if (e.keyCode > 46) {
  350. if (options.maskAutoFill) {
  351. fillSymbols(el.value.length);
  352. }
  353. }
  354. });
  355. if (!el.placeholder) {
  356. el.placeholder = mask;
  357. }
  358. if (options.maskAutoFill) {
  359. fillSymbols(el.value.length);
  360. }
  361. };
  362. Edit.prototype.getEditedCells = function () {
  363. var output = [];
  364. this.editedCells.forEach(function (cell) {
  365. output.push(cell.getComponent());
  366. });
  367. return output;
  368. };
  369. Edit.prototype.clearEdited = function (cell) {
  370. var editIndex;
  371. if (cell.modules.validate && cell.modules.edit && cell.modules.edit.edited) {
  372. cell.modules.validate.invalid = false;
  373. editIndex = this.editedCells.indexOf(cell);
  374. if (editIndex > -1) {
  375. this.editedCells.splice(editIndex, 1);
  376. }
  377. }
  378. };
  379. //default data editors
  380. Edit.prototype.editors = {
  381. //input element
  382. input: function input(cell, onRendered, success, cancel, editorParams) {
  383. //create and style input
  384. var cellValue = cell.getValue(),
  385. input = document.createElement("input");
  386. input.setAttribute("type", editorParams.search ? "search" : "text");
  387. input.style.padding = "4px";
  388. input.style.width = "100%";
  389. input.style.boxSizing = "border-box";
  390. if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
  391. for (var key in editorParams.elementAttributes) {
  392. if (key.charAt(0) == "+") {
  393. key = key.slice(1);
  394. input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
  395. } else {
  396. input.setAttribute(key, editorParams.elementAttributes[key]);
  397. }
  398. }
  399. }
  400. input.value = typeof cellValue !== "undefined" ? cellValue : "";
  401. onRendered(function () {
  402. input.focus({ preventScroll: true });
  403. input.style.height = "100%";
  404. });
  405. function onChange(e) {
  406. if ((cellValue === null || typeof cellValue === "undefined") && input.value !== "" || input.value !== cellValue) {
  407. if (success(input.value)) {
  408. cellValue = input.value; //persist value if successfully validated incase editor is used as header filter
  409. }
  410. } else {
  411. cancel();
  412. }
  413. }
  414. //submit new value on blur or change
  415. input.addEventListener("change", onChange);
  416. input.addEventListener("blur", onChange);
  417. //submit new value on enter
  418. input.addEventListener("keydown", function (e) {
  419. switch (e.keyCode) {
  420. // case 9:
  421. case 13:
  422. onChange(e);
  423. break;
  424. case 27:
  425. cancel();
  426. break;
  427. case 35:
  428. case 36:
  429. e.stopPropagation();
  430. break;
  431. }
  432. });
  433. if (editorParams.mask) {
  434. this.table.modules.edit.maskInput(input, editorParams);
  435. }
  436. return input;
  437. },
  438. //resizable text area element
  439. textarea: function textarea(cell, onRendered, success, cancel, editorParams) {
  440. var self = this,
  441. cellValue = cell.getValue(),
  442. vertNav = editorParams.verticalNavigation || "hybrid",
  443. value = String(cellValue !== null && typeof cellValue !== "undefined" ? cellValue : ""),
  444. count = (value.match(/(?:\r\n|\r|\n)/g) || []).length + 1,
  445. input = document.createElement("textarea"),
  446. scrollHeight = 0;
  447. //create and style input
  448. input.style.display = "block";
  449. input.style.padding = "2px";
  450. input.style.height = "100%";
  451. input.style.width = "100%";
  452. input.style.boxSizing = "border-box";
  453. input.style.whiteSpace = "pre-wrap";
  454. input.style.resize = "none";
  455. if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
  456. for (var key in editorParams.elementAttributes) {
  457. if (key.charAt(0) == "+") {
  458. key = key.slice(1);
  459. input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
  460. } else {
  461. input.setAttribute(key, editorParams.elementAttributes[key]);
  462. }
  463. }
  464. }
  465. input.value = value;
  466. onRendered(function () {
  467. input.focus({ preventScroll: true });
  468. input.style.height = "100%";
  469. input.scrollHeight;
  470. input.style.height = input.scrollHeight + "px";
  471. cell.getRow().normalizeHeight();
  472. });
  473. function onChange(e) {
  474. if ((cellValue === null || typeof cellValue === "undefined") && input.value !== "" || input.value !== cellValue) {
  475. if (success(input.value)) {
  476. cellValue = input.value; //persist value if successfully validated incase editor is used as header filter
  477. }
  478. setTimeout(function () {
  479. cell.getRow().normalizeHeight();
  480. }, 300);
  481. } else {
  482. cancel();
  483. }
  484. }
  485. //submit new value on blur or change
  486. input.addEventListener("change", onChange);
  487. input.addEventListener("blur", onChange);
  488. input.addEventListener("keyup", function () {
  489. input.style.height = "";
  490. var heightNow = input.scrollHeight;
  491. input.style.height = heightNow + "px";
  492. if (heightNow != scrollHeight) {
  493. scrollHeight = heightNow;
  494. cell.getRow().normalizeHeight();
  495. }
  496. });
  497. input.addEventListener("keydown", function (e) {
  498. switch (e.keyCode) {
  499. case 27:
  500. cancel();
  501. break;
  502. case 38:
  503. //up arrow
  504. if (vertNav == "editor" || vertNav == "hybrid" && input.selectionStart) {
  505. e.stopImmediatePropagation();
  506. e.stopPropagation();
  507. }
  508. break;
  509. case 40:
  510. //down arrow
  511. if (vertNav == "editor" || vertNav == "hybrid" && input.selectionStart !== input.value.length) {
  512. e.stopImmediatePropagation();
  513. e.stopPropagation();
  514. }
  515. break;
  516. case 35:
  517. case 36:
  518. e.stopPropagation();
  519. break;
  520. }
  521. });
  522. if (editorParams.mask) {
  523. this.table.modules.edit.maskInput(input, editorParams);
  524. }
  525. return input;
  526. },
  527. //input element with type of number
  528. number: function number(cell, onRendered, success, cancel, editorParams) {
  529. var cellValue = cell.getValue(),
  530. vertNav = editorParams.verticalNavigation || "editor",
  531. input = document.createElement("input");
  532. input.setAttribute("type", "number");
  533. if (typeof editorParams.max != "undefined") {
  534. input.setAttribute("max", editorParams.max);
  535. }
  536. if (typeof editorParams.min != "undefined") {
  537. input.setAttribute("min", editorParams.min);
  538. }
  539. if (typeof editorParams.step != "undefined") {
  540. input.setAttribute("step", editorParams.step);
  541. }
  542. //create and style input
  543. input.style.padding = "4px";
  544. input.style.width = "100%";
  545. input.style.boxSizing = "border-box";
  546. if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
  547. for (var key in editorParams.elementAttributes) {
  548. if (key.charAt(0) == "+") {
  549. key = key.slice(1);
  550. input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
  551. } else {
  552. input.setAttribute(key, editorParams.elementAttributes[key]);
  553. }
  554. }
  555. }
  556. input.value = cellValue;
  557. var blurFunc = function blurFunc(e) {
  558. onChange();
  559. };
  560. onRendered(function () {
  561. //submit new value on blur
  562. input.removeEventListener("blur", blurFunc);
  563. input.focus({ preventScroll: true });
  564. input.style.height = "100%";
  565. //submit new value on blur
  566. input.addEventListener("blur", blurFunc);
  567. });
  568. function onChange() {
  569. var value = input.value;
  570. if (!isNaN(value) && value !== "") {
  571. value = Number(value);
  572. }
  573. if (value !== cellValue) {
  574. if (success(value)) {
  575. cellValue = value; //persist value if successfully validated incase editor is used as header filter
  576. }
  577. } else {
  578. cancel();
  579. }
  580. }
  581. //submit new value on enter
  582. input.addEventListener("keydown", function (e) {
  583. switch (e.keyCode) {
  584. case 13:
  585. // case 9:
  586. onChange();
  587. break;
  588. case 27:
  589. cancel();
  590. break;
  591. case 38: //up arrow
  592. case 40:
  593. //down arrow
  594. if (vertNav == "editor") {
  595. e.stopImmediatePropagation();
  596. e.stopPropagation();
  597. }
  598. break;
  599. case 35:
  600. case 36:
  601. e.stopPropagation();
  602. break;
  603. }
  604. });
  605. if (editorParams.mask) {
  606. this.table.modules.edit.maskInput(input, editorParams);
  607. }
  608. return input;
  609. },
  610. //input element with type of number
  611. range: function range(cell, onRendered, success, cancel, editorParams) {
  612. var cellValue = cell.getValue(),
  613. input = document.createElement("input");
  614. input.setAttribute("type", "range");
  615. if (typeof editorParams.max != "undefined") {
  616. input.setAttribute("max", editorParams.max);
  617. }
  618. if (typeof editorParams.min != "undefined") {
  619. input.setAttribute("min", editorParams.min);
  620. }
  621. if (typeof editorParams.step != "undefined") {
  622. input.setAttribute("step", editorParams.step);
  623. }
  624. //create and style input
  625. input.style.padding = "4px";
  626. input.style.width = "100%";
  627. input.style.boxSizing = "border-box";
  628. if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
  629. for (var key in editorParams.elementAttributes) {
  630. if (key.charAt(0) == "+") {
  631. key = key.slice(1);
  632. input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
  633. } else {
  634. input.setAttribute(key, editorParams.elementAttributes[key]);
  635. }
  636. }
  637. }
  638. input.value = cellValue;
  639. onRendered(function () {
  640. input.focus({ preventScroll: true });
  641. input.style.height = "100%";
  642. });
  643. function onChange() {
  644. var value = input.value;
  645. if (!isNaN(value) && value !== "") {
  646. value = Number(value);
  647. }
  648. if (value != cellValue) {
  649. if (success(value)) {
  650. cellValue = value; //persist value if successfully validated incase editor is used as header filter
  651. }
  652. } else {
  653. cancel();
  654. }
  655. }
  656. //submit new value on blur
  657. input.addEventListener("blur", function (e) {
  658. onChange();
  659. });
  660. //submit new value on enter
  661. input.addEventListener("keydown", function (e) {
  662. switch (e.keyCode) {
  663. case 13:
  664. // case 9:
  665. onChange();
  666. break;
  667. case 27:
  668. cancel();
  669. break;
  670. }
  671. });
  672. return input;
  673. },
  674. //select
  675. select: function select(cell, onRendered, success, cancel, editorParams) {
  676. var _this = this;
  677. var self = this,
  678. cellEl = cell.getElement(),
  679. initialValue = cell.getValue(),
  680. vertNav = editorParams.verticalNavigation || "editor",
  681. initialDisplayValue = typeof initialValue !== "undefined" || initialValue === null ? Array.isArray(initialValue) ? initialValue : [initialValue] : typeof editorParams.defaultValue !== "undefined" ? editorParams.defaultValue : [],
  682. input = document.createElement("input"),
  683. listEl = document.createElement("div"),
  684. multiselect = editorParams.multiselect,
  685. dataItems = [],
  686. currentItem = {},
  687. displayItems = [],
  688. currentItems = [],
  689. blurable = true,
  690. blockListShow = false;
  691. if (Array.isArray(editorParams) || !Array.isArray(editorParams) && (typeof editorParams === "undefined" ? "undefined" : _typeof(editorParams)) === "object" && !editorParams.values) {
  692. console.warn("DEPRECATION WARNING - values for the select editor must now be passed into the values property of the editorParams object, not as the editorParams object");
  693. editorParams = { values: editorParams };
  694. }
  695. function getUniqueColumnValues(field) {
  696. var output = {},
  697. data = self.table.getData(),
  698. column;
  699. if (field) {
  700. column = self.table.columnManager.getColumnByField(field);
  701. } else {
  702. column = cell.getColumn()._getSelf();
  703. }
  704. if (column) {
  705. data.forEach(function (row) {
  706. var val = column.getFieldValue(row);
  707. if (val !== null && typeof val !== "undefined" && val !== "") {
  708. output[val] = true;
  709. }
  710. });
  711. if (editorParams.sortValuesList) {
  712. if (editorParams.sortValuesList == "asc") {
  713. output = Object.keys(output).sort();
  714. } else {
  715. output = Object.keys(output).sort().reverse();
  716. }
  717. } else {
  718. output = Object.keys(output);
  719. }
  720. } else {
  721. console.warn("unable to find matching column to create select lookup list:", field);
  722. }
  723. return output;
  724. }
  725. function parseItems(inputValues, curentValues) {
  726. var dataList = [];
  727. var displayList = [];
  728. function processComplexListItem(item) {
  729. var item = {
  730. label: item.label,
  731. value: item.value,
  732. itemParams: item.itemParams,
  733. elementAttributes: item.elementAttributes,
  734. element: false
  735. };
  736. // if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){
  737. // setCurrentItem(item);
  738. // }
  739. if (curentValues.indexOf(item.value) > -1) {
  740. setItem(item);
  741. }
  742. dataList.push(item);
  743. displayList.push(item);
  744. return item;
  745. }
  746. if (typeof inputValues == "function") {
  747. inputValues = inputValues(cell);
  748. }
  749. if (Array.isArray(inputValues)) {
  750. inputValues.forEach(function (value) {
  751. var item;
  752. if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
  753. if (value.options) {
  754. item = {
  755. label: value.label,
  756. group: true,
  757. itemParams: value.itemParams,
  758. elementAttributes: value.elementAttributes,
  759. element: false
  760. };
  761. displayList.push(item);
  762. value.options.forEach(function (item) {
  763. processComplexListItem(item);
  764. });
  765. } else {
  766. processComplexListItem(value);
  767. }
  768. } else {
  769. item = {
  770. label: value,
  771. value: value,
  772. element: false
  773. };
  774. // if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){
  775. // setCurrentItem(item);
  776. // }
  777. if (curentValues.indexOf(item.value) > -1) {
  778. setItem(item);
  779. }
  780. dataList.push(item);
  781. displayList.push(item);
  782. }
  783. });
  784. } else {
  785. for (var key in inputValues) {
  786. var item = {
  787. label: inputValues[key],
  788. value: key,
  789. element: false
  790. };
  791. // if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){
  792. // setCurrentItem(item);
  793. // }
  794. if (curentValues.indexOf(item.value) > -1) {
  795. setItem(item);
  796. }
  797. dataList.push(item);
  798. displayList.push(item);
  799. }
  800. }
  801. dataItems = dataList;
  802. displayItems = displayList;
  803. fillList();
  804. }
  805. function fillList() {
  806. while (listEl.firstChild) {
  807. listEl.removeChild(listEl.firstChild);
  808. }displayItems.forEach(function (item) {
  809. var el = item.element;
  810. if (!el) {
  811. el = document.createElement("div");
  812. item.label = editorParams.listItemFormatter ? editorParams.listItemFormatter(item.value, item.label, cell, el, item.itemParams) : item.label;
  813. if (item.group) {
  814. el.classList.add("tabulator-edit-select-list-group");
  815. el.tabIndex = 0;
  816. el.innerHTML = item.label === "" ? "&nbsp;" : item.label;
  817. } else {
  818. el.classList.add("tabulator-edit-select-list-item");
  819. el.tabIndex = 0;
  820. el.innerHTML = item.label === "" ? "&nbsp;" : item.label;
  821. el.addEventListener("click", function () {
  822. blockListShow = true;
  823. setTimeout(function () {
  824. blockListShow = false;
  825. }, 10);
  826. // setCurrentItem(item);
  827. // chooseItem();
  828. if (multiselect) {
  829. toggleItem(item);
  830. input.focus();
  831. } else {
  832. chooseItem(item);
  833. }
  834. });
  835. // if(item === currentItem){
  836. // el.classList.add("active");
  837. // }
  838. if (currentItems.indexOf(item) > -1) {
  839. el.classList.add("active");
  840. }
  841. }
  842. if (item.elementAttributes && _typeof(item.elementAttributes) == "object") {
  843. for (var key in item.elementAttributes) {
  844. if (key.charAt(0) == "+") {
  845. key = key.slice(1);
  846. el.setAttribute(key, input.getAttribute(key) + item.elementAttributes["+" + key]);
  847. } else {
  848. el.setAttribute(key, item.elementAttributes[key]);
  849. }
  850. }
  851. }
  852. el.addEventListener("mousedown", function () {
  853. blurable = false;
  854. setTimeout(function () {
  855. blurable = true;
  856. }, 10);
  857. });
  858. item.element = el;
  859. }
  860. listEl.appendChild(el);
  861. });
  862. }
  863. function setCurrentItem(item, active) {
  864. if (!multiselect && currentItem && currentItem.element) {
  865. currentItem.element.classList.remove("active");
  866. }
  867. if (currentItem && currentItem.element) {
  868. currentItem.element.classList.remove("focused");
  869. }
  870. currentItem = item;
  871. if (item.element) {
  872. item.element.classList.add("focused");
  873. if (active) {
  874. item.element.classList.add("active");
  875. }
  876. }
  877. }
  878. // function chooseItem(){
  879. // hideList();
  880. // if(initialValue !== currentItem.value){
  881. // initialValue = currentItem.value;
  882. // success(currentItem.value);
  883. // }else{
  884. // cancel();
  885. // }
  886. // }
  887. function setItem(item) {
  888. var index = currentItems.indexOf(item);
  889. if (index == -1) {
  890. currentItems.push(item);
  891. setCurrentItem(item, true);
  892. }
  893. fillInput();
  894. }
  895. function unsetItem(index) {
  896. var item = currentItems[index];
  897. if (index > -1) {
  898. currentItems.splice(index, 1);
  899. if (item.element) {
  900. item.element.classList.remove("active");
  901. }
  902. }
  903. }
  904. function toggleItem(item) {
  905. if (!item) {
  906. item = currentItem;
  907. }
  908. var index = currentItems.indexOf(item);
  909. if (index > -1) {
  910. unsetItem(index);
  911. } else {
  912. if (multiselect !== true && currentItems.length >= multiselect) {
  913. unsetItem(0);
  914. }
  915. setItem(item);
  916. }
  917. fillInput();
  918. }
  919. function chooseItem(item) {
  920. hideList();
  921. if (!item) {
  922. item = currentItem;
  923. }
  924. if (item) {
  925. input.value = item.label;
  926. success(item.value);
  927. }
  928. initialDisplayValue = input.value;
  929. }
  930. function chooseItems(silent) {
  931. if (!silent) {
  932. hideList();
  933. }
  934. var output = [];
  935. currentItems.forEach(function (item) {
  936. output.push(item.value);
  937. });
  938. initialDisplayValue = input.value;
  939. success(output);
  940. }
  941. function fillInput() {
  942. var output = [];
  943. currentItems.forEach(function (item) {
  944. output.push(item.label);
  945. });
  946. input.value = output.join(", ");
  947. if (self.currentCell === false) {
  948. chooseItems(true);
  949. }
  950. }
  951. function unsetItems() {
  952. var len = currentItems.length;
  953. for (var i = 0; i < len; i++) {
  954. unsetItem(0);
  955. }
  956. }
  957. function cancelItem() {
  958. hideList();
  959. cancel();
  960. }
  961. function showList() {
  962. currentItems = [];
  963. if (!listEl.parentNode) {
  964. if (editorParams.values === true) {
  965. parseItems(getUniqueColumnValues(), initialDisplayValue);
  966. } else if (typeof editorParams.values === "string") {
  967. parseItems(getUniqueColumnValues(editorParams.values), initialDisplayValue);
  968. } else {
  969. parseItems(editorParams.values || [], initialDisplayValue);
  970. }
  971. var offset = Tabulator.prototype.helpers.elOffset(cellEl);
  972. listEl.style.minWidth = cellEl.offsetWidth + "px";
  973. listEl.style.top = offset.top + cellEl.offsetHeight + "px";
  974. listEl.style.left = offset.left + "px";
  975. listEl.addEventListener("mousedown", function (e) {
  976. blurable = false;
  977. setTimeout(function () {
  978. blurable = true;
  979. }, 10);
  980. });
  981. document.body.appendChild(listEl);
  982. }
  983. }
  984. function hideList() {
  985. if (listEl.parentNode) {
  986. listEl.parentNode.removeChild(listEl);
  987. }
  988. removeScrollListener();
  989. }
  990. function removeScrollListener() {
  991. self.table.rowManager.element.removeEventListener("scroll", cancelItem);
  992. }
  993. //style input
  994. input.setAttribute("type", "text");
  995. input.style.padding = "4px";
  996. input.style.width = "100%";
  997. input.style.boxSizing = "border-box";
  998. input.style.cursor = "default";
  999. input.readOnly = this.currentCell != false;
  1000. if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
  1001. for (var key in editorParams.elementAttributes) {
  1002. if (key.charAt(0) == "+") {
  1003. key = key.slice(1);
  1004. input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
  1005. } else {
  1006. input.setAttribute(key, editorParams.elementAttributes[key]);
  1007. }
  1008. }
  1009. }
  1010. input.value = typeof initialValue !== "undefined" || initialValue === null ? initialValue : "";
  1011. // if(editorParams.values === true){
  1012. // parseItems(getUniqueColumnValues(), initialValue);
  1013. // }else if(typeof editorParams.values === "string"){
  1014. // parseItems(getUniqueColumnValues(editorParams.values), initialValue);
  1015. // }else{
  1016. // parseItems(editorParams.values || [], initialValue);
  1017. // }
  1018. input.addEventListener("search", function (e) {
  1019. if (!input.value) {
  1020. unsetItems();
  1021. chooseItems();
  1022. }
  1023. });
  1024. //allow key based navigation
  1025. input.addEventListener("keydown", function (e) {
  1026. var index;
  1027. switch (e.keyCode) {
  1028. case 38:
  1029. //up arrow
  1030. index = dataItems.indexOf(currentItem);
  1031. if (vertNav == "editor" || vertNav == "hybrid" && index) {
  1032. e.stopImmediatePropagation();
  1033. e.stopPropagation();
  1034. e.preventDefault();
  1035. if (index > 0) {
  1036. setCurrentItem(dataItems[index - 1], !multiselect);
  1037. }
  1038. }
  1039. break;
  1040. case 40:
  1041. //down arrow
  1042. index = dataItems.indexOf(currentItem);
  1043. if (vertNav == "editor" || vertNav == "hybrid" && index < dataItems.length - 1) {
  1044. e.stopImmediatePropagation();
  1045. e.stopPropagation();
  1046. e.preventDefault();
  1047. if (index < dataItems.length - 1) {
  1048. if (index == -1) {
  1049. setCurrentItem(dataItems[0], !multiselect);
  1050. } else {
  1051. setCurrentItem(dataItems[index + 1], !multiselect);
  1052. }
  1053. }
  1054. }
  1055. break;
  1056. case 37: //left arrow
  1057. case 39:
  1058. //right arrow
  1059. e.stopImmediatePropagation();
  1060. e.stopPropagation();
  1061. e.preventDefault();
  1062. break;
  1063. case 13:
  1064. //enter
  1065. // chooseItem();
  1066. if (multiselect) {
  1067. toggleItem();
  1068. } else {
  1069. chooseItem();
  1070. }
  1071. break;
  1072. case 27:
  1073. //escape
  1074. cancelItem();
  1075. break;
  1076. case 9:
  1077. //tab
  1078. break;
  1079. default:
  1080. if (self.currentCell === false) {
  1081. e.preventDefault();
  1082. }
  1083. }
  1084. });
  1085. input.addEventListener("blur", function (e) {
  1086. if (blurable) {
  1087. if (multiselect) {
  1088. chooseItems();
  1089. } else {
  1090. cancelItem();
  1091. }
  1092. }
  1093. });
  1094. input.addEventListener("focus", function (e) {
  1095. if (!blockListShow) {
  1096. showList();
  1097. }
  1098. });
  1099. //style list element
  1100. listEl = document.createElement("div");
  1101. listEl.classList.add("tabulator-edit-select-list");
  1102. onRendered(function () {
  1103. input.style.height = "100%";
  1104. input.focus({ preventScroll: true });
  1105. });
  1106. setTimeout(function () {
  1107. _this.table.rowManager.element.addEventListener("scroll", cancelItem);
  1108. }, 10);
  1109. return input;
  1110. },
  1111. //autocomplete
  1112. autocomplete: function autocomplete(cell, onRendered, success, cancel, editorParams) {
  1113. var _this2 = this;
  1114. var self = this,
  1115. cellEl = cell.getElement(),
  1116. initialValue = cell.getValue(),
  1117. vertNav = editorParams.verticalNavigation || "editor",
  1118. initialDisplayValue = typeof initialValue !== "undefined" || initialValue === null ? initialValue : typeof editorParams.defaultValue !== "undefined" ? editorParams.defaultValue : "",
  1119. input = document.createElement("input"),
  1120. listEl = document.createElement("div"),
  1121. allItems = [],
  1122. displayItems = [],
  1123. values = [],
  1124. currentItem = false,
  1125. blurable = true,
  1126. uniqueColumnValues = false;
  1127. //style input
  1128. input.setAttribute("type", "search");
  1129. input.style.padding = "4px";
  1130. input.style.width = "100%";
  1131. input.style.boxSizing = "border-box";
  1132. if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
  1133. for (var key in editorParams.elementAttributes) {
  1134. if (key.charAt(0) == "+") {
  1135. key = key.slice(1);
  1136. input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
  1137. } else {
  1138. input.setAttribute(key, editorParams.elementAttributes[key]);
  1139. }
  1140. }
  1141. }
  1142. //style list element
  1143. listEl.classList.add("tabulator-edit-select-list");
  1144. listEl.addEventListener("mousedown", function (e) {
  1145. blurable = false;
  1146. setTimeout(function () {
  1147. blurable = true;
  1148. }, 10);
  1149. });
  1150. function genUniqueColumnValues() {
  1151. if (editorParams.values === true) {
  1152. uniqueColumnValues = getUniqueColumnValues();
  1153. } else if (typeof editorParams.values === "string") {
  1154. uniqueColumnValues = getUniqueColumnValues(editorParams.values);
  1155. }
  1156. }
  1157. function getUniqueColumnValues(field) {
  1158. var output = {},
  1159. data = self.table.getData(),
  1160. column;
  1161. if (field) {
  1162. column = self.table.columnManager.getColumnByField(field);
  1163. } else {
  1164. column = cell.getColumn()._getSelf();
  1165. }
  1166. if (column) {
  1167. data.forEach(function (row) {
  1168. var val = column.getFieldValue(row);
  1169. if (val !== null && typeof val !== "undefined" && val !== "") {
  1170. output[val] = true;
  1171. }
  1172. });
  1173. if (editorParams.sortValuesList) {
  1174. if (editorParams.sortValuesList == "asc") {
  1175. output = Object.keys(output).sort();
  1176. } else {
  1177. output = Object.keys(output).sort().reverse();
  1178. }
  1179. } else {
  1180. output = Object.keys(output);
  1181. }
  1182. } else {
  1183. console.warn("unable to find matching column to create autocomplete lookup list:", field);
  1184. }
  1185. return output;
  1186. }
  1187. function filterList(term, intialLoad) {
  1188. var matches = [],
  1189. values,
  1190. items,
  1191. searchEl;
  1192. //lookup base values list
  1193. if (uniqueColumnValues) {
  1194. values = uniqueColumnValues;
  1195. } else {
  1196. values = editorParams.values || [];
  1197. }
  1198. if (editorParams.searchFunc) {
  1199. matches = editorParams.searchFunc(term, values);
  1200. if (matches instanceof Promise) {
  1201. addNotice(typeof editorParams.searchingPlaceholder !== "undefined" ? editorParams.searchingPlaceholder : "Searching...");
  1202. matches.then(function (result) {
  1203. fillListIfNotEmpty(parseItems(result), intialLoad);
  1204. }).catch(function (err) {
  1205. console.err("error in autocomplete search promise:", err);
  1206. });
  1207. } else {
  1208. fillListIfNotEmpty(parseItems(matches), intialLoad);
  1209. }
  1210. } else {
  1211. items = parseItems(values);
  1212. if (term === "") {
  1213. if (editorParams.showListOnEmpty) {
  1214. matches = items;
  1215. }
  1216. } else {
  1217. items.forEach(function (item) {
  1218. if (item.value !== null || typeof item.value !== "undefined") {
  1219. if (String(item.value).toLowerCase().indexOf(String(term).toLowerCase()) > -1 || String(item.title).toLowerCase().indexOf(String(term).toLowerCase()) > -1) {
  1220. matches.push(item);
  1221. }
  1222. }
  1223. });
  1224. }
  1225. fillListIfNotEmpty(matches, intialLoad);
  1226. }
  1227. }
  1228. function addNotice(notice) {
  1229. var searchEl = document.createElement("div");
  1230. clearList();
  1231. if (notice !== false) {
  1232. searchEl.classList.add("tabulator-edit-select-list-notice");
  1233. searchEl.tabIndex = 0;
  1234. if (notice instanceof Node) {
  1235. searchEl.appendChild(notice);
  1236. } else {
  1237. searchEl.innerHTML = notice;
  1238. }
  1239. listEl.appendChild(searchEl);
  1240. }
  1241. }
  1242. function parseItems(inputValues) {
  1243. var itemList = [];
  1244. if (Array.isArray(inputValues)) {
  1245. inputValues.forEach(function (value) {
  1246. var item = {};
  1247. if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
  1248. item.title = editorParams.listItemFormatter ? editorParams.listItemFormatter(value.value, value.label) : value.label;
  1249. item.value = value.value;
  1250. } else {
  1251. item.title = editorParams.listItemFormatter ? editorParams.listItemFormatter(value, value) : value;
  1252. item.value = value;
  1253. }
  1254. itemList.push(item);
  1255. });
  1256. } else {
  1257. for (var key in inputValues) {
  1258. var item = {
  1259. title: editorParams.listItemFormatter ? editorParams.listItemFormatter(key, inputValues[key]) : inputValues[key],
  1260. value: key
  1261. };
  1262. itemList.push(item);
  1263. }
  1264. }
  1265. return itemList;
  1266. }
  1267. function clearList() {
  1268. while (listEl.firstChild) {
  1269. listEl.removeChild(listEl.firstChild);
  1270. }
  1271. }
  1272. function fillListIfNotEmpty(items, intialLoad) {
  1273. if (items.length) {
  1274. fillList(items, intialLoad);
  1275. } else {
  1276. if (editorParams.emptyPlaceholder) {
  1277. addNotice(editorParams.emptyPlaceholder);
  1278. }
  1279. }
  1280. }
  1281. function fillList(items, intialLoad) {
  1282. var current = false;
  1283. clearList();
  1284. displayItems = items;
  1285. displayItems.forEach(function (item) {
  1286. var el = item.element;
  1287. if (!el) {
  1288. el = document.createElement("div");
  1289. el.classList.add("tabulator-edit-select-list-item");
  1290. el.tabIndex = 0;
  1291. el.innerHTML = item.title;
  1292. el.addEventListener("click", function (e) {
  1293. setCurrentItem(item);
  1294. chooseItem();
  1295. });
  1296. el.addEventListener("mousedown", function (e) {
  1297. blurable = false;
  1298. setTimeout(function () {
  1299. blurable = true;
  1300. }, 10);
  1301. });
  1302. item.element = el;
  1303. if (intialLoad && item.value == initialValue) {
  1304. input.value = item.title;
  1305. item.element.classList.add("active");
  1306. current = true;
  1307. }
  1308. if (item === currentItem) {
  1309. item.element.classList.add("active");
  1310. current = true;
  1311. }
  1312. }
  1313. listEl.appendChild(el);
  1314. });
  1315. if (!current) {
  1316. setCurrentItem(false);
  1317. }
  1318. }
  1319. function chooseItem() {
  1320. hideList();
  1321. if (currentItem) {
  1322. if (initialValue !== currentItem.value) {
  1323. initialValue = currentItem.value;
  1324. input.value = currentItem.title;
  1325. success(currentItem.value);
  1326. } else {
  1327. cancel();
  1328. }
  1329. } else {
  1330. if (editorParams.freetext) {
  1331. initialValue = input.value;
  1332. success(input.value);
  1333. } else {
  1334. if (editorParams.allowEmpty && input.value === "") {
  1335. initialValue = input.value;
  1336. success(input.value);
  1337. } else {
  1338. cancel();
  1339. }
  1340. }
  1341. }
  1342. }
  1343. function showList() {
  1344. if (!listEl.parentNode) {
  1345. while (listEl.firstChild) {
  1346. listEl.removeChild(listEl.firstChild);
  1347. }var offset = Tabulator.prototype.helpers.elOffset(cellEl);
  1348. listEl.style.minWidth = cellEl.offsetWidth + "px";
  1349. listEl.style.top = offset.top + cellEl.offsetHeight + "px";
  1350. listEl.style.left = offset.left + "px";
  1351. document.body.appendChild(listEl);
  1352. }
  1353. }
  1354. function setCurrentItem(item, showInputValue) {
  1355. if (currentItem && currentItem.element) {
  1356. currentItem.element.classList.remove("active");
  1357. }
  1358. currentItem = item;
  1359. if (item && item.element) {
  1360. item.element.classList.add("active");
  1361. }
  1362. }
  1363. function hideList() {
  1364. if (listEl.parentNode) {
  1365. listEl.parentNode.removeChild(listEl);
  1366. }
  1367. removeScrollListener();
  1368. }
  1369. function cancelItem() {
  1370. hideList();
  1371. cancel();
  1372. }
  1373. function removeScrollListener() {
  1374. self.table.rowManager.element.removeEventListener("scroll", cancelItem);
  1375. }
  1376. //allow key based navigation
  1377. input.addEventListener("keydown", function (e) {
  1378. var index;
  1379. switch (e.keyCode) {
  1380. case 38:
  1381. //up arrow
  1382. index = displayItems.indexOf(currentItem);
  1383. if (vertNav == "editor" || vertNav == "hybrid" && index) {
  1384. e.stopImmediatePropagation();
  1385. e.stopPropagation();
  1386. e.preventDefault();
  1387. if (index > 0) {
  1388. setCurrentItem(displayItems[index - 1]);
  1389. } else {
  1390. setCurrentItem(false);
  1391. }
  1392. }
  1393. break;
  1394. case 40:
  1395. //down arrow
  1396. index = displayItems.indexOf(currentItem);
  1397. if (vertNav == "editor" || vertNav == "hybrid" && index < displayItems.length - 1) {
  1398. e.stopImmediatePropagation();
  1399. e.stopPropagation();
  1400. e.preventDefault();
  1401. if (index < displayItems.length - 1) {
  1402. if (index == -1) {
  1403. setCurrentItem(displayItems[0]);
  1404. } else {
  1405. setCurrentItem(displayItems[index + 1]);
  1406. }
  1407. }
  1408. }
  1409. break;
  1410. case 37: //left arrow
  1411. case 39:
  1412. //right arrow
  1413. e.stopImmediatePropagation();
  1414. e.stopPropagation();
  1415. // e.preventDefault();
  1416. break;
  1417. case 13:
  1418. //enter
  1419. chooseItem();
  1420. break;
  1421. case 27:
  1422. //escape
  1423. cancelItem();
  1424. break;
  1425. case 36: //home
  1426. case 35:
  1427. //end
  1428. //prevent table navigation while using input element
  1429. e.stopImmediatePropagation();
  1430. break;
  1431. }
  1432. });
  1433. input.addEventListener("keyup", function (e) {
  1434. switch (e.keyCode) {
  1435. case 38: //up arrow
  1436. case 37: //left arrow
  1437. case 39: //up arrow
  1438. case 40: //right arrow
  1439. case 13: //enter
  1440. case 27:
  1441. //escape
  1442. break;
  1443. default:
  1444. filterList(input.value);
  1445. }
  1446. });
  1447. input.addEventListener("search", function (e) {
  1448. filterList(input.value);
  1449. });
  1450. input.addEventListener("blur", function (e) {
  1451. if (blurable) {
  1452. chooseItem();
  1453. }
  1454. });
  1455. input.addEventListener("focus", function (e) {
  1456. var value = initialDisplayValue;
  1457. genUniqueColumnValues();
  1458. showList();
  1459. input.value = value;
  1460. filterList(value, true);
  1461. });
  1462. onRendered(function () {
  1463. input.style.height = "100%";
  1464. input.focus({ preventScroll: true });
  1465. });
  1466. if (editorParams.mask) {
  1467. this.table.modules.edit.maskInput(input, editorParams);
  1468. }
  1469. setTimeout(function () {
  1470. _this2.table.rowManager.element.addEventListener("scroll", cancelItem);
  1471. }, 10);
  1472. genUniqueColumnValues();
  1473. input.value = initialDisplayValue;
  1474. filterList(initialDisplayValue, true);
  1475. return input;
  1476. },
  1477. //star rating
  1478. star: function star(cell, onRendered, success, cancel, editorParams) {
  1479. var self = this,
  1480. element = cell.getElement(),
  1481. value = cell.getValue(),
  1482. maxStars = element.getElementsByTagName("svg").length || 5,
  1483. size = element.getElementsByTagName("svg")[0] ? element.getElementsByTagName("svg")[0].getAttribute("width") : 14,
  1484. stars = [],
  1485. starsHolder = document.createElement("div"),
  1486. star = document.createElementNS('http://www.w3.org/2000/svg', "svg");
  1487. //change star type
  1488. function starChange(val) {
  1489. stars.forEach(function (star, i) {
  1490. if (i < val) {
  1491. if (self.table.browser == "ie") {
  1492. star.setAttribute("class", "tabulator-star-active");
  1493. } else {
  1494. star.classList.replace("tabulator-star-inactive", "tabulator-star-active");
  1495. }
  1496. star.innerHTML = '<polygon fill="#488CE9" stroke="#014AAE" stroke-width="37.6152" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="259.216,29.942 330.27,173.919 489.16,197.007 374.185,309.08 401.33,467.31 259.216,392.612 117.104,467.31 144.25,309.08 29.274,197.007 188.165,173.919 "/>';
  1497. } else {
  1498. if (self.table.browser == "ie") {
  1499. star.setAttribute("class", "tabulator-star-inactive");
  1500. } else {
  1501. star.classList.replace("tabulator-star-active", "tabulator-star-inactive");
  1502. }
  1503. star.innerHTML = '<polygon fill="#010155" stroke="#686868" stroke-width="37.6152" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="259.216,29.942 330.27,173.919 489.16,197.007 374.185,309.08 401.33,467.31 259.216,392.612 117.104,467.31 144.25,309.08 29.274,197.007 188.165,173.919 "/>';
  1504. }
  1505. });
  1506. }
  1507. //build stars
  1508. function buildStar(i) {
  1509. var starHolder = document.createElement("span");
  1510. var nextStar = star.cloneNode(true);
  1511. stars.push(nextStar);
  1512. starHolder.addEventListener("mouseenter", function (e) {
  1513. e.stopPropagation();
  1514. e.stopImmediatePropagation();
  1515. starChange(i);
  1516. });
  1517. starHolder.addEventListener("mousemove", function (e) {
  1518. e.stopPropagation();
  1519. e.stopImmediatePropagation();
  1520. });
  1521. starHolder.addEventListener("click", function (e) {
  1522. e.stopPropagation();
  1523. e.stopImmediatePropagation();
  1524. success(i);
  1525. element.blur();
  1526. });
  1527. starHolder.appendChild(nextStar);
  1528. starsHolder.appendChild(starHolder);
  1529. }
  1530. //handle keyboard navigation value change
  1531. function changeValue(val) {
  1532. value = val;
  1533. starChange(val);
  1534. }
  1535. //style cell
  1536. element.style.whiteSpace = "nowrap";
  1537. element.style.overflow = "hidden";
  1538. element.style.textOverflow = "ellipsis";
  1539. //style holding element
  1540. starsHolder.style.verticalAlign = "middle";
  1541. starsHolder.style.display = "inline-block";
  1542. starsHolder.style.padding = "4px";
  1543. //style star
  1544. star.setAttribute("width", size);
  1545. star.setAttribute("height", size);
  1546. star.setAttribute("viewBox", "0 0 512 512");
  1547. star.setAttribute("xml:space", "preserve");
  1548. star.style.padding = "0 1px";
  1549. if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
  1550. for (var key in editorParams.elementAttributes) {
  1551. if (key.charAt(0) == "+") {
  1552. key = key.slice(1);
  1553. starsHolder.setAttribute(key, starsHolder.getAttribute(key) + editorParams.elementAttributes["+" + key]);
  1554. } else {
  1555. starsHolder.setAttribute(key, editorParams.elementAttributes[key]);
  1556. }
  1557. }
  1558. }
  1559. //create correct number of stars
  1560. for (var i = 1; i <= maxStars; i++) {
  1561. buildStar(i);
  1562. }
  1563. //ensure value does not exceed number of stars
  1564. value = Math.min(parseInt(value), maxStars);
  1565. // set initial styling of stars
  1566. starChange(value);
  1567. starsHolder.addEventListener("mousemove", function (e) {
  1568. starChange(0);
  1569. });
  1570. starsHolder.addEventListener("click", function (e) {
  1571. success(0);
  1572. });
  1573. element.addEventListener("blur", function (e) {
  1574. cancel();
  1575. });
  1576. //allow key based navigation
  1577. element.addEventListener("keydown", function (e) {
  1578. switch (e.keyCode) {
  1579. case 39:
  1580. //right arrow
  1581. changeValue(value + 1);
  1582. break;
  1583. case 37:
  1584. //left arrow
  1585. changeValue(value - 1);
  1586. break;
  1587. case 13:
  1588. //enter
  1589. success(value);
  1590. break;
  1591. case 27:
  1592. //escape
  1593. cancel();
  1594. break;
  1595. }
  1596. });
  1597. return starsHolder;
  1598. },
  1599. //draggable progress bar
  1600. progress: function progress(cell, onRendered, success, cancel, editorParams) {
  1601. var element = cell.getElement(),
  1602. max = typeof editorParams.max === "undefined" ? element.getElementsByTagName("div")[0].getAttribute("max") || 100 : editorParams.max,
  1603. min = typeof editorParams.min === "undefined" ? element.getElementsByTagName("div")[0].getAttribute("min") || 0 : editorParams.min,
  1604. percent = (max - min) / 100,
  1605. value = cell.getValue() || 0,
  1606. handle = document.createElement("div"),
  1607. bar = document.createElement("div"),
  1608. mouseDrag,
  1609. mouseDragWidth;
  1610. //set new value
  1611. function updateValue() {
  1612. var calcVal = percent * Math.round(bar.offsetWidth / (element.clientWidth / 100)) + min;
  1613. success(calcVal);
  1614. element.setAttribute("aria-valuenow", calcVal);
  1615. element.setAttribute("aria-label", value);
  1616. }
  1617. //style handle
  1618. handle.style.position = "absolute";
  1619. handle.style.right = "0";
  1620. handle.style.top = "0";
  1621. handle.style.bottom = "0";
  1622. handle.style.width = "5px";
  1623. handle.classList.add("tabulator-progress-handle");
  1624. //style bar
  1625. bar.style.display = "inline-block";
  1626. bar.style.position = "relative";
  1627. // bar.style.top = "8px";
  1628. // bar.style.bottom = "8px";
  1629. // bar.style.left = "4px";
  1630. // bar.style.marginRight = "4px";
  1631. bar.style.height = "100%";
  1632. bar.style.backgroundColor = "#488CE9";
  1633. bar.style.maxWidth = "100%";
  1634. bar.style.minWidth = "0%";
  1635. if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
  1636. for (var key in editorParams.elementAttributes) {
  1637. if (key.charAt(0) == "+") {
  1638. key = key.slice(1);
  1639. bar.setAttribute(key, bar.getAttribute(key) + editorParams.elementAttributes["+" + key]);
  1640. } else {
  1641. bar.setAttribute(key, editorParams.elementAttributes[key]);
  1642. }
  1643. }
  1644. }
  1645. //style cell
  1646. element.style.padding = "4px 4px";
  1647. //make sure value is in range
  1648. value = Math.min(parseFloat(value), max);
  1649. value = Math.max(parseFloat(value), min);
  1650. //workout percentage
  1651. value = Math.round((value - min) / percent);
  1652. // bar.style.right = value + "%";
  1653. bar.style.width = value + "%";
  1654. element.setAttribute("aria-valuemin", min);
  1655. element.setAttribute("aria-valuemax", max);
  1656. bar.appendChild(handle);
  1657. handle.addEventListener("mousedown", function (e) {
  1658. mouseDrag = e.screenX;
  1659. mouseDragWidth = bar.offsetWidth;
  1660. });
  1661. handle.addEventListener("mouseover", function () {
  1662. handle.style.cursor = "ew-resize";
  1663. });
  1664. element.addEventListener("mousemove", function (e) {
  1665. if (mouseDrag) {
  1666. bar.style.width = mouseDragWidth + e.screenX - mouseDrag + "px";
  1667. }
  1668. });
  1669. element.addEventListener("mouseup", function (e) {
  1670. if (mouseDrag) {
  1671. e.stopPropagation();
  1672. e.stopImmediatePropagation();
  1673. mouseDrag = false;
  1674. mouseDragWidth = false;
  1675. updateValue();
  1676. }
  1677. });
  1678. //allow key based navigation
  1679. element.addEventListener("keydown", function (e) {
  1680. switch (e.keyCode) {
  1681. case 39:
  1682. //right arrow
  1683. e.preventDefault();
  1684. bar.style.width = bar.clientWidth + element.clientWidth / 100 + "px";
  1685. break;
  1686. case 37:
  1687. //left arrow
  1688. e.preventDefault();
  1689. bar.style.width = bar.clientWidth - element.clientWidth / 100 + "px";
  1690. break;
  1691. case 9: //tab
  1692. case 13:
  1693. //enter
  1694. updateValue();
  1695. break;
  1696. case 27:
  1697. //escape
  1698. cancel();
  1699. break;
  1700. }
  1701. });
  1702. element.addEventListener("blur", function () {
  1703. cancel();
  1704. });
  1705. return bar;
  1706. },
  1707. //checkbox
  1708. tickCross: function tickCross(cell, onRendered, success, cancel, editorParams) {
  1709. var value = cell.getValue(),
  1710. input = document.createElement("input"),
  1711. tristate = editorParams.tristate,
  1712. indetermValue = typeof editorParams.indeterminateValue === "undefined" ? null : editorParams.indeterminateValue,
  1713. indetermState = false;
  1714. input.setAttribute("type", "checkbox");
  1715. input.style.marginTop = "5px";
  1716. input.style.boxSizing = "border-box";
  1717. if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
  1718. for (var key in editorParams.elementAttributes) {
  1719. if (key.charAt(0) == "+") {
  1720. key = key.slice(1);
  1721. input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
  1722. } else {
  1723. input.setAttribute(key, editorParams.elementAttributes[key]);
  1724. }
  1725. }
  1726. }
  1727. input.value = value;
  1728. if (tristate && (typeof value === "undefined" || value === indetermValue || value === "")) {
  1729. indetermState = true;
  1730. input.indeterminate = true;
  1731. }
  1732. if (this.table.browser != "firefox") {
  1733. //prevent blur issue on mac firefox
  1734. onRendered(function () {
  1735. input.focus({ preventScroll: true });
  1736. });
  1737. }
  1738. input.checked = value === true || value === "true" || value === "True" || value === 1;
  1739. onRendered(function () {
  1740. input.focus();
  1741. });
  1742. function setValue(blur) {
  1743. if (tristate) {
  1744. if (!blur) {
  1745. if (input.checked && !indetermState) {
  1746. input.checked = false;
  1747. input.indeterminate = true;
  1748. indetermState = true;
  1749. return indetermValue;
  1750. } else {
  1751. indetermState = false;
  1752. return input.checked;
  1753. }
  1754. } else {
  1755. if (indetermState) {
  1756. return indetermValue;
  1757. } else {
  1758. return input.checked;
  1759. }
  1760. }
  1761. } else {
  1762. return input.checked;
  1763. }
  1764. }
  1765. //submit new value on blur
  1766. input.addEventListener("change", function (e) {
  1767. success(setValue());
  1768. });
  1769. input.addEventListener("blur", function (e) {
  1770. success(setValue(true));
  1771. });
  1772. //submit new value on enter
  1773. input.addEventListener("keydown", function (e) {
  1774. if (e.keyCode == 13) {
  1775. success(setValue());
  1776. }
  1777. if (e.keyCode == 27) {
  1778. cancel();
  1779. }
  1780. });
  1781. return input;
  1782. }
  1783. };
  1784. Tabulator.prototype.registerModule("edit", Edit);