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 47KB

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