tbl_change.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. /* vim: set expandtab sw=4 ts=4 sts=4: */
  2. /**
  3. * @fileoverview function used in table data manipulation pages
  4. *
  5. * @requires jQuery
  6. * @requires jQueryUI
  7. * @requires js/functions.js
  8. *
  9. */
  10. /**
  11. * Modify form controls when the "NULL" checkbox is checked
  12. *
  13. * @param theType string the MySQL field type
  14. * @param urlField string the urlencoded field name - OBSOLETE
  15. * @param md5Field string the md5 hashed field name
  16. * @param multi_edit string the multi_edit row sequence number
  17. *
  18. * @return boolean always true
  19. */
  20. function nullify(theType, urlField, md5Field, multi_edit)
  21. {
  22. var rowForm = document.forms['insertForm'];
  23. if (typeof(rowForm.elements['funcs' + multi_edit + '[' + md5Field + ']']) != 'undefined') {
  24. rowForm.elements['funcs' + multi_edit + '[' + md5Field + ']'].selectedIndex = -1;
  25. }
  26. // "ENUM" field with more than 20 characters
  27. if (theType == 1) {
  28. rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'][1].selectedIndex = -1;
  29. }
  30. // Other "ENUM" field
  31. else if (theType == 2) {
  32. var elts = rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'];
  33. // when there is just one option in ENUM:
  34. if (elts.checked) {
  35. elts.checked = false;
  36. } else {
  37. var elts_cnt = elts.length;
  38. for (var i = 0; i < elts_cnt; i++) {
  39. elts[i].checked = false;
  40. } // end for
  41. } // end if
  42. }
  43. // "SET" field
  44. else if (theType == 3) {
  45. rowForm.elements['fields' + multi_edit + '[' + md5Field + '][]'].selectedIndex = -1;
  46. }
  47. // Foreign key field (drop-down)
  48. else if (theType == 4) {
  49. rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'].selectedIndex = -1;
  50. }
  51. // foreign key field (with browsing icon for foreign values)
  52. else if (theType == 6) {
  53. rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'].value = '';
  54. }
  55. // Other field types
  56. else /*if (theType == 5)*/ {
  57. rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'].value = '';
  58. } // end if... else if... else
  59. return true;
  60. } // end of the 'nullify()' function
  61. /**
  62. * javascript DateTime format validation.
  63. * its used to prevent adding default (0000-00-00 00:00:00) to database when user enter wrong values
  64. * Start of validation part
  65. */
  66. //function checks the number of days in febuary
  67. function daysInFebruary(year)
  68. {
  69. return (((year % 4 === 0) && (((year % 100 !== 0)) || (year % 400 === 0))) ? 29 : 28);
  70. }
  71. //function to convert single digit to double digit
  72. function fractionReplace(num)
  73. {
  74. num = parseInt(num, 10);
  75. return num >= 1 && num <= 9 ? '0' + num : '00';
  76. }
  77. /* function to check the validity of date
  78. * The following patterns are accepted in this validation (accepted in mysql as well)
  79. * 1) 2001-12-23
  80. * 2) 2001-1-2
  81. * 3) 02-12-23
  82. * 4) And instead of using '-' the following punctuations can be used (+,.,*,^,@,/) All these are accepted by mysql as well. Therefore no issues
  83. */
  84. function isDate(val, tmstmp)
  85. {
  86. val = val.replace(/[.|*|^|+|//|@]/g, '-');
  87. var arrayVal = val.split("-");
  88. for (var a = 0; a < arrayVal.length; a++) {
  89. if (arrayVal[a].length == 1) {
  90. arrayVal[a] = fractionReplace(arrayVal[a]);
  91. }
  92. }
  93. val = arrayVal.join("-");
  94. var pos = 2;
  95. var dtexp = new RegExp(/^([0-9]{4})-(((01|03|05|07|08|10|12)-((0[0-9])|([1-2][0-9])|(3[0-1])))|((02|04|06|09|11)-((0[0-9])|([1-2][0-9])|30)))$/);
  96. if (val.length == 8) {
  97. pos = 0;
  98. }
  99. if (dtexp.test(val)) {
  100. var month = parseInt(val.substring(pos + 3, pos + 5), 10);
  101. var day = parseInt(val.substring(pos + 6, pos + 8), 10);
  102. var year = parseInt(val.substring(0, pos + 2), 10);
  103. if (month == 2 && day > daysInFebruary(year)) {
  104. return false;
  105. }
  106. if (val.substring(0, pos + 2).length == 2) {
  107. year = parseInt("20" + val.substring(0, pos + 2), 10);
  108. }
  109. if (tmstmp === true) {
  110. if (year < 1978) {
  111. return false;
  112. }
  113. if (year > 2038 || (year > 2037 && day > 19 && month >= 1) || (year > 2037 && month > 1)) {
  114. return false;
  115. }
  116. }
  117. } else {
  118. return false;
  119. }
  120. return true;
  121. }
  122. /* function to check the validity of time
  123. * The following patterns are accepted in this validation (accepted in mysql as well)
  124. * 1) 2:3:4
  125. * 2) 2:23:43
  126. * 3) 2:23:43.123456
  127. */
  128. function isTime(val)
  129. {
  130. var arrayVal = val.split(":");
  131. for (var a = 0, l = arrayVal.length; a < l; a++) {
  132. if (arrayVal[a].length == 1) {
  133. arrayVal[a] = fractionReplace(arrayVal[a]);
  134. }
  135. }
  136. val = arrayVal.join(":");
  137. var tmexp = new RegExp(/^(([0-1][0-9])|(2[0-3])):((0[0-9])|([1-5][0-9])):((0[0-9])|([1-5][0-9]))(\.[0-9]{1,6}){0,1}$/);
  138. return tmexp.test(val);
  139. }
  140. function verificationsAfterFieldChange(urlField, multi_edit, theType)
  141. {
  142. var evt = window.event || arguments.callee.caller.arguments[0];
  143. var target = evt.target || evt.srcElement;
  144. //To generate the textbox that can take the salt
  145. var new_salt_box = "<br><input type=text name=salt[multi_edit][" + multi_edit + "][" + urlField + "]" +
  146. " id=salt_" + target.id + " placeholder='" + PMA_messages.strEncryptionKey + "'>";
  147. //If AES_ENCRYPT is Selected then append the new textbox for salt
  148. if (target.value == "AES_DECRYPT" || target.value == "AES_ENCRYPT") {
  149. if (!($("#salt_" + target.id).length)) {
  150. $("#" + target.id).parent().next("td").next("td").find("input[name*='fields']").after(new_salt_box);
  151. }
  152. } else {
  153. //The value of the select is no longer AES_ENCRYPT, remove the textbox for salt
  154. $("#salt_" + target.id).remove();
  155. }
  156. // Unchecks the corresponding "NULL" control
  157. $("input[name='fields_null[multi_edit][" + multi_edit + "][" + urlField + "]']").prop('checked', false);
  158. // Unchecks the Ignore checkbox for the current row
  159. $("input[name='insert_ignore_" + multi_edit + "']").prop('checked', false);
  160. var $this_input = $("input[name='fields[multi_edit][" + multi_edit + "][" + urlField + "]']");
  161. // Does this field come from datepicker?
  162. if ($this_input.data('comes_from') == 'datepicker') {
  163. // Yes, so do not validate because the final value is not yet in
  164. // the field and hopefully the datepicker returns a valid date+time
  165. $this_input.removeClass("invalid_value");
  166. return true;
  167. }
  168. if (target.name.substring(0, 6) == "fields") {
  169. // validate for date time
  170. if (theType == "datetime" || theType == "time" || theType == "date" || theType == "timestamp") {
  171. $this_input.removeClass("invalid_value");
  172. var dt_value = $this_input.val();
  173. if (theType == "date") {
  174. if (! isDate(dt_value)) {
  175. $this_input.addClass("invalid_value");
  176. return false;
  177. }
  178. } else if (theType == "time") {
  179. if (! isTime(dt_value)) {
  180. $this_input.addClass("invalid_value");
  181. return false;
  182. }
  183. } else if (theType == "datetime" || theType == "timestamp") {
  184. var tmstmp = false;
  185. if (dt_value == "CURRENT_TIMESTAMP") {
  186. return true;
  187. }
  188. if (theType == "timestamp") {
  189. tmstmp = true;
  190. }
  191. if (dt_value == "0000-00-00 00:00:00") {
  192. return true;
  193. }
  194. var dv = dt_value.indexOf(" ");
  195. if (dv == -1) {
  196. $this_input.addClass("invalid_value");
  197. return false;
  198. } else {
  199. if (! (isDate(dt_value.substring(0, dv), tmstmp) && isTime(dt_value.substring(dv + 1)))) {
  200. $this_input.addClass("invalid_value");
  201. return false;
  202. }
  203. }
  204. }
  205. }
  206. //validate for integer type
  207. if (theType.substring(0, 3) == "int") {
  208. $this_input.removeClass("invalid_value");
  209. if (isNaN($this_input.val())) {
  210. $this_input.addClass("invalid_value");
  211. return false;
  212. }
  213. }
  214. }
  215. }
  216. /* End of datetime validation*/
  217. /**
  218. * Unbind all event handlers before tearing down a page
  219. */
  220. AJAX.registerTeardown('tbl_change.js', function () {
  221. $('span.open_gis_editor').die('click');
  222. $("input[name='gis_data[save]']").die('click');
  223. $('input.checkbox_null').die('click');
  224. $('select[name="submit_type"]').unbind('change');
  225. $("#insert_rows").die('change');
  226. $("select[name*='funcs']").die('click');
  227. });
  228. /**
  229. * Ajax handlers for Change Table page
  230. *
  231. * Actions Ajaxified here:
  232. * Submit Data to be inserted into the table.
  233. * Restart insertion with 'N' rows.
  234. */
  235. AJAX.registerOnload('tbl_change.js', function () {
  236. $.datepicker.initialized = false;
  237. $('span.open_gis_editor').live('click', function (event) {
  238. event.preventDefault();
  239. var $span = $(this);
  240. // Current value
  241. var value = $span.parent('td').children("input[type='text']").val();
  242. // Field name
  243. var field = $span.parents('tr').children('td:first').find("input[type='hidden']").val();
  244. // Column type
  245. var type = $span.parents('tr').find('span.column_type').text();
  246. // Names of input field and null checkbox
  247. var input_name = $span.parent('td').children("input[type='text']").attr('name');
  248. //Token
  249. var token = $("input[name='token']").val();
  250. openGISEditor();
  251. if (!gisEditorLoaded) {
  252. loadJSAndGISEditor(value, field, type, input_name, token);
  253. } else {
  254. loadGISEditor(value, field, type, input_name, token);
  255. }
  256. });
  257. /**
  258. * Uncheck the null checkbox as geometry data is placed on the input field
  259. */
  260. $("input[name='gis_data[save]']").live('click', function (event) {
  261. var input_name = $('form#gis_data_editor_form').find("input[name='input_name']").val();
  262. var $null_checkbox = $("input[name='" + input_name + "']").parents('tr').find('.checkbox_null');
  263. $null_checkbox.prop('checked', false);
  264. });
  265. /**
  266. * Handles all current checkboxes for Null; this only takes care of the
  267. * checkboxes on currently displayed rows as the rows generated by
  268. * "Continue insertion" are handled in the "Continue insertion" code
  269. *
  270. */
  271. $('input.checkbox_null').live('click', function (e) {
  272. nullify(
  273. // use hidden fields populated by tbl_change.php
  274. $(this).siblings('.nullify_code').val(),
  275. $(this).closest('tr').find('input:hidden').first().val(),
  276. $(this).siblings('.hashed_field').val(),
  277. $(this).siblings('.multi_edit').val()
  278. );
  279. });
  280. /**
  281. * Reset the auto_increment column to 0 when selecting any of the
  282. * insert options in submit_type-dropdown. Only perform the reset
  283. * when we are in edit-mode, and not in insert-mode(no previous value
  284. * available).
  285. */
  286. $('select[name="submit_type"]').bind('change', function (e) {
  287. var $table = $('table.insertRowTable');
  288. var auto_increment_column = $table.find('input[name^="auto_increment"]').attr('name');
  289. if (auto_increment_column) {
  290. var prev_value_field = $table.find('input[name="' + auto_increment_column.replace('auto_increment', 'fields_prev') + '"]');
  291. var value_field = $table.find('input[name="' + auto_increment_column.replace('auto_increment', 'fields') + '"]');
  292. var previous_value = $(prev_value_field).val();
  293. if (previous_value !== undefined) {
  294. if ($(this).val() == 'insert' || $(this).val() == 'insertignore' || $(this).val() == 'showinsert') {
  295. $(value_field).val(0);
  296. } else {
  297. $(value_field).val(previous_value);
  298. }
  299. }
  300. }
  301. });
  302. /**
  303. * Continue Insertion form
  304. */
  305. $("#insert_rows").live('change', function (event) {
  306. event.preventDefault();
  307. /**
  308. * @var columnCount Number of number of columns table has.
  309. */
  310. var columnCount = $("table.insertRowTable:first").find("tr").has("input[name*='fields_name']").length;
  311. /**
  312. * @var curr_rows Number of current insert rows already on page
  313. */
  314. var curr_rows = $("table.insertRowTable").length;
  315. /**
  316. * @var target_rows Number of rows the user wants
  317. */
  318. var target_rows = $("#insert_rows").val();
  319. // remove all datepickers
  320. $('input.datefield, input.datetimefield').each(function () {
  321. $(this).datepicker('destroy');
  322. });
  323. if (curr_rows < target_rows) {
  324. while (curr_rows < target_rows) {
  325. /**
  326. * @var $last_row Object referring to the last row
  327. */
  328. var $last_row = $("#insertForm").find(".insertRowTable:last");
  329. // need to access this at more than one level
  330. // (also needs improvement because it should be calculated
  331. // just once per cloned row, not once per column)
  332. var new_row_index = 0;
  333. //Clone the insert tables
  334. $last_row
  335. .clone(true, true)
  336. .insertBefore("#actions_panel")
  337. .find('input[name*=multi_edit],select[name*=multi_edit],textarea[name*=multi_edit]')
  338. .each(function () {
  339. var $this_element = $(this);
  340. /**
  341. * Extract the index from the name attribute for all input/select fields and increment it
  342. * name is of format funcs[multi_edit][10][<long random string of alphanum chars>]
  343. */
  344. /**
  345. * @var this_name String containing name of the input/select elements
  346. */
  347. var this_name = $this_element.attr('name');
  348. /** split {@link this_name} at [10], so we have the parts that can be concatenated later */
  349. var name_parts = this_name.split(/\[\d+\]/);
  350. /** extract the [10] from {@link name_parts} */
  351. var old_row_index_string = this_name.match(/\[\d+\]/)[0];
  352. /** extract 10 - had to split into two steps to accomodate double digits */
  353. var old_row_index = parseInt(old_row_index_string.match(/\d+/)[0], 10);
  354. /** calculate next index i.e. 11 */
  355. new_row_index = old_row_index + 1;
  356. /** generate the new name i.e. funcs[multi_edit][11][foobarbaz] */
  357. var new_name = name_parts[0] + '[' + new_row_index + ']' + name_parts[1];
  358. var hashed_field = name_parts[1].match(/\[(.+)\]/)[1];
  359. $this_element.attr('name', new_name);
  360. /** If element is select[name*='funcs'], update id */
  361. if ($this_element.is("select[name*='funcs']")) {
  362. var this_id = $this_element.attr("id");
  363. var id_parts = this_id.split(/\_/);
  364. var old_id_index = id_parts[1];
  365. var prevSelectedValue = $("#field_" + old_id_index + "_1").val();
  366. var new_id_index = parseInt(old_id_index) + columnCount;
  367. var new_id = 'field_' + new_id_index + '_1';
  368. $this_element.attr('id', new_id);
  369. $this_element.find("option").filter(function () {
  370. return $(this).text() === prevSelectedValue;
  371. }).attr("selected","selected");
  372. // If salt field is there then update its id.
  373. var nextSaltInput = $this_element.parent().next("td").next("td").find("input[name*='salt']");
  374. if (nextSaltInput.length !== 0) {
  375. nextSaltInput.attr("id", "salt_" + new_id);
  376. }
  377. }
  378. // handle input text fields and textareas
  379. if ($this_element.is('.textfield') || $this_element.is('.char')) {
  380. // do not remove the 'value' attribute for ENUM columns
  381. if ($this_element.closest('tr').find('span.column_type').html() != 'enum') {
  382. $this_element.val($this_element.closest('tr').find('span.default_value').html());
  383. }
  384. $this_element
  385. .unbind('change')
  386. // Remove onchange attribute that was placed
  387. // by tbl_change.php; it refers to the wrong row index
  388. .attr('onchange', null)
  389. // Keep these values to be used when the element
  390. // will change
  391. .data('hashed_field', hashed_field)
  392. .data('new_row_index', new_row_index)
  393. .bind('change', function (e) {
  394. var $changed_element = $(this);
  395. verificationsAfterFieldChange(
  396. $changed_element.data('hashed_field'),
  397. $changed_element.data('new_row_index'),
  398. $changed_element.closest('tr').find('span.column_type').html()
  399. );
  400. });
  401. }
  402. if ($this_element.is('.checkbox_null')) {
  403. $this_element
  404. // this event was bound earlier by jQuery but
  405. // to the original row, not the cloned one, so unbind()
  406. .unbind('click')
  407. // Keep these values to be used when the element
  408. // will be clicked
  409. .data('hashed_field', hashed_field)
  410. .data('new_row_index', new_row_index)
  411. .bind('click', function (e) {
  412. var $changed_element = $(this);
  413. nullify(
  414. $changed_element.siblings('.nullify_code').val(),
  415. $this_element.closest('tr').find('input:hidden').first().val(),
  416. $changed_element.data('hashed_field'),
  417. '[multi_edit][' + $changed_element.data('new_row_index') + ']'
  418. );
  419. });
  420. }
  421. }) // end each
  422. .end()
  423. .find('.foreign_values_anchor')
  424. .each(function () {
  425. var $anchor = $(this);
  426. var new_value = 'rownumber=' + new_row_index;
  427. // needs improvement in case something else inside
  428. // the href contains this pattern
  429. var new_href = $anchor.attr('href').replace(/rownumber=\d+/, new_value);
  430. $anchor.attr('href', new_href);
  431. });
  432. //Insert/Clone the ignore checkboxes
  433. if (curr_rows == 1) {
  434. $('<input id="insert_ignore_1" type="checkbox" name="insert_ignore_1" checked="checked" />')
  435. .insertBefore("table.insertRowTable:last")
  436. .after('<label for="insert_ignore_1">' + PMA_messages.strIgnore + '</label>');
  437. } else {
  438. /**
  439. * @var $last_checkbox Object reference to the last checkbox in #insertForm
  440. */
  441. var $last_checkbox = $("#insertForm").children('input:checkbox:last');
  442. /** name of {@link $last_checkbox} */
  443. var last_checkbox_name = $last_checkbox.attr('name');
  444. /** index of {@link $last_checkbox} */
  445. var last_checkbox_index = parseInt(last_checkbox_name.match(/\d+/), 10);
  446. /** name of new {@link $last_checkbox} */
  447. var new_name = last_checkbox_name.replace(/\d+/, last_checkbox_index + 1);
  448. $last_checkbox
  449. .clone()
  450. .attr({'id': new_name, 'name': new_name})
  451. .prop('checked', true)
  452. .add('label[for^=insert_ignore]:last')
  453. .clone()
  454. .attr('for', new_name)
  455. .before('<br />')
  456. .insertBefore("table.insertRowTable:last");
  457. }
  458. curr_rows++;
  459. }
  460. // recompute tabindex for text fields and other controls at footer;
  461. // IMO it's not really important to handle the tabindex for
  462. // function and Null
  463. var tabindex = 0;
  464. $('.textfield, .char, textarea')
  465. .each(function () {
  466. tabindex++;
  467. $(this).attr('tabindex', tabindex);
  468. // update the IDs of textfields to ensure that they are unique
  469. $(this).attr('id', "field_" + tabindex + "_3");
  470. });
  471. $('.control_at_footer')
  472. .each(function () {
  473. tabindex++;
  474. $(this).attr('tabindex', tabindex);
  475. });
  476. } else if (curr_rows > target_rows) {
  477. while (curr_rows > target_rows) {
  478. $("input[id^=insert_ignore]:last")
  479. .nextUntil("fieldset")
  480. .andSelf()
  481. .remove();
  482. curr_rows--;
  483. }
  484. }
  485. });
  486. // Add all the required datepickers back
  487. addDateTimePicker();
  488. /**
  489. * @var $function_option_dialog object holds dialog for selected function options.
  490. */
  491. var $function_option_dialog = null;
  492. PMA_tooltip(
  493. $("select[name*='funcs']"),
  494. 'select',
  495. PMA_messages.strFunctionHint
  496. );
  497. $("select[name*='funcs']").live('click', function (event) {
  498. if (! event.shiftKey) {
  499. return false;
  500. }
  501. // Name of selected function.
  502. var functionName = $(this).find("option:selected").html();
  503. var currId = $(this).attr("id");
  504. // Name of column.
  505. var columnName = $(this).closest("tr").find("input[name*='fields_name']").val();
  506. var targetRows = $("tr").has("input[value='" + columnName + "']");
  507. var salt;
  508. var copySalt = false;
  509. if (functionName === 'AES_ENCRYPT' || functionName === 'AES_DECRYPT') {
  510. // Dialog title.
  511. var title = functionName;
  512. // Dialog buttons functions.
  513. var buttonOptions = {};
  514. buttonOptions[PMA_messages.strYes] = function () {
  515. // Go function.
  516. copySalt = true;
  517. salt = $("#salt_" + currId).val();
  518. applyFunctionToAllRows(currId, functionName, copySalt, salt, targetRows);
  519. $(this).dialog("close");
  520. };
  521. buttonOptions[PMA_messages.strNo] = function () {
  522. copySalt = false;
  523. salt = "";
  524. applyFunctionToAllRows(currId, functionName, copySalt, salt, targetRows);
  525. $(this).dialog("close");
  526. };
  527. // Contents of dialog.
  528. var dialog = "<div>" +
  529. "<fieldset>" +
  530. "<span style='font-weight: bold;'>" +
  531. PMA_messages.strCopyEncryptionKey +
  532. "</fieldset>" +
  533. "</div>";
  534. // Show the dialog
  535. var width = parseInt(
  536. (parseInt($('html').css('font-size'), 10) / 13) * 340,
  537. 10
  538. );
  539. if (! width) {
  540. width = 340;
  541. }
  542. $function_option_dialog = $(dialog).dialog({
  543. minWidth: width,
  544. modal: true,
  545. title: title,
  546. buttons: buttonOptions,
  547. resizable: false,
  548. open: function () {
  549. // Focus the "Go" button after opening the dialog
  550. $(this).closest('.ui-dialog').find('.ui-dialog-buttonpane button:first').focus();
  551. },
  552. close: function () {
  553. $(this).remove();
  554. }
  555. });
  556. }
  557. applyFunctionToAllRows(currId, functionName, copySalt, "", targetRows);
  558. });
  559. });
  560. function changeValueFieldType(elem, searchIndex)
  561. {
  562. var fieldsValue = $("select#fieldID_" + searchIndex);
  563. if (0 == fieldsValue.size()) {
  564. return;
  565. }
  566. var type = $(elem).val();
  567. if (
  568. 'IN (...)' == type
  569. || 'NOT IN (...)' == type
  570. || 'BETWEEN' == type
  571. || 'NOT BETWEEN' == type
  572. ) {
  573. $("#fieldID_" + searchIndex).attr('multiple', '');
  574. } else {
  575. $("#fieldID_" + searchIndex).removeAttr('multiple');
  576. }
  577. }
  578. function applyFunctionToAllRows(currId, functionName, copySalt, salt, targetRows)
  579. {
  580. targetRows.each(function () {
  581. var currentRowNum = /\d/.exec($(this).find("input[name*='fields_name']").attr("name"));
  582. /* // Ignore the rows whose insert_ignore_* checkbox is checked.
  583. var insert_ignore = $(this).closest("table.insertRowTable").prevAll("input[name*='insert_ignore']");
  584. if (insert_ignore.length) {
  585. if ($(insert_ignore).attr("checked")) {
  586. return;
  587. }
  588. } */
  589. // Append the function select list.
  590. var targetSelectList = $(this).find("select[name*='funcs[multi_edit]']");
  591. if (targetSelectList.attr("id") === currId) {
  592. return;
  593. }
  594. targetSelectList.find("option").filter(function () {
  595. return $(this).text() === functionName;
  596. }).attr("selected","selected");
  597. // Handle salt field.
  598. if (functionName === 'AES_ENCRYPT' || functionName === 'AES_DECRYPT') {
  599. if ($("#salt_" + targetSelectList.attr("id")).length === 0) {
  600. // Get hash value.
  601. var hashed_value = targetSelectList.attr("name").match(/\[multi\_edit\]\[\d\]\[(.*)\]/);
  602. //To generate the textbox that can take the salt
  603. var new_salt_box = "<br><input type=text name=salt[multi_edit][" + currentRowNum + "][" + hashed_value[1] + "]" +
  604. " id=salt_" + targetSelectList.attr("id") + " placeholder='" + PMA_messages.strEncryptionKey + "'>";
  605. targetSelectList.parent().next("td").next("td").find("input[name*='fields']").after(new_salt_box);
  606. }
  607. if (copySalt) {
  608. $("#salt_" + targetSelectList.attr("id")).attr("value", salt);
  609. }
  610. } else {
  611. var id = targetSelectList.attr("id");
  612. if ($("#salt_" + id).length) {
  613. $("#salt_" + id).remove();
  614. }
  615. }
  616. });
  617. }