1 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 * @fileoverview functions used wherever an sql query form is used
6 * @requires js/functions.js
12 * Get the field name for the current field. Required to construct the query
15 * @param this_field_obj jQuery object that points to the current field's tr
16 * @param disp_mode string
18 function getFieldName(this_field_obj, disp_mode) {
20 if(disp_mode == 'vertical') {
21 var field_name = $(this_field_obj).siblings('th').find('a').text();
24 var this_field_index = $(this_field_obj).index();
25 if(window.parent.text_dir == 'ltr') {
26 // 4 columns to account for the checkbox, edit, delete and appended inline edit anchors
27 var field_name = $(this_field_obj).parents('table').find('thead').find('th:nth('+ (this_field_index-4 )+') a').text();
30 var field_name = $(this_field_obj).parents('table').find('thead').find('th:nth('+ this_field_index+') a').text();
34 field_name = $.trim(field_name);
40 * The function that iterates over each row in the table_results and appends a
41 * new inline edit anchor to each table row.
43 * @param disp_mode string
45 function appendInlineAnchor(disp_mode) {
46 if(disp_mode == 'vertical') {
47 var cloned_row = $('.edit_row_anchor').removeClass('edit_row_anchor').parent('tr').clone();
49 var img_object = $(cloned_row).find('img:first').attr('title', PMA_messages['strInlineEdit']);
51 $(cloned_row).find('td').addClass('edit_row_anchor')
52 .find('a').attr('href', '#')
54 .text(PMA_messages['strInlineEdit'])
57 $(cloned_row).insertBefore($('.where_clause').parent('tr'));
59 $("#table_results").find('tr:first').find('th')
60 .attr('rowspan', '4');
63 $('.edit_row_anchor').each(function() {
65 $(this).removeClass('edit_row_anchor');
67 var cloned_anchor = $(this).clone();
69 var img_object = $(cloned_anchor).find('img').attr('title', PMA_messages['strInlineEdit']);
71 $(cloned_anchor).addClass('edit_row_anchor')
72 .find('a').attr('href', '#')
74 .text(PMA_messages['strInlineEdit'])
77 $(this).siblings('.where_clause')
78 .before(cloned_anchor);
81 $('#rowsDeleteForm').find('thead').find('th').each(function() {
82 if($(this).attr('colspan') == 3) {
83 $(this).attr('colspan', '4')
94 * @description <p>Ajax scripts for sql and browse pages</p>
96 * Actions ajaxified here:
98 * <li>Retrieve results of an SQL query</li>
99 * <li>Paginate the results table</li>
100 * <li>Sort the results table</li>
101 * <li>Change table according to display options</li>
102 * <li>Inline editing of data</li>
105 * @name document.ready
108 $(document).ready(function() {
111 * Set a parameter for all Ajax queries made on this page. Don't let the
112 * web server serve cached pages
119 * current value of the direction in which the table is displayed
124 var disp_mode = $("#top_direction_dropdown").val();
127 * Update value of {@link jQuery.disp_mode} everytime the direction dropdown changes value
129 * @name direction_dropdown_change
131 $("#top_direction_dropdown, #bottom_direction_dropdown").live('change', function(event) {
132 disp_mode = $(this).val();
136 * Attach the {@link appendInlineAnchor} function to a custom event, which
137 * will be triggered manually everytime the table of results is reloaded
139 * @name sqlqueryresults_live
141 $("#sqlqueryresults").live('appendAnchor',function() {
142 appendInlineAnchor(disp_mode);
146 * Trigger the appendAnchor event to prepare the first table for inline edit
149 * @name sqlqueryresults_trigger
151 $("#sqlqueryresults").trigger('appendAnchor');
154 * Append the Toggle Query Box message to the query input form
157 * @name appendToggleSpan
159 $('<span id="togglequerybox"></span>')
160 .html(PMA_messages['strToggleQueryBox'])
161 .appendTo("#sqlqueryform");
163 // Attach the toggling of the query box visibility to a click
164 $("#togglequerybox").live('click', function() {
165 $(this).siblings().slideToggle("medium");
169 * Ajax Event handler for 'SQL Query Submit'
171 * @see PMA_ajaxShowMessage()
173 * @name sqlqueryform_submit
175 $("#sqlqueryform").live('submit', function(event) {
176 event.preventDefault();
178 PMA_ajaxShowMessage();
180 $(this).append('<input type="hidden" name="ajax_request" value="true" />');
182 $.post($(this).attr('action'), $(this).serialize() , function(data) {
183 if(data.success == true) {
184 PMA_ajaxShowMessage(data.message);
186 else if (data.success == false ) {
187 PMA_ajaxShowMessage(data.error);
190 $("#sqlqueryresults").html(data);
191 $("#sqlqueryresults").trigger('appendAnchor');
192 if($("#togglequerybox").siblings(":visible").length > 0) {
193 $("#togglequerybox").trigger('click');
197 }) // end SQL Query submit
200 * Ajax Event handlers for Paginating the results table
204 * Paginate when we click any of the navigation buttons
206 * @name paginate_nav_button_click
207 * @uses PMA_ajaxShowMessage()
209 $("input[name=navig]").live('click', function(event) {
211 event.preventDefault();
213 PMA_ajaxShowMessage();
216 * @var the_form Object referring to the form element that paginates the results table
218 var the_form = $(this).parent("form");
220 $(the_form).append('<input type="hidden" name="ajax_request" value="true" />');
222 $.post($(the_form).attr('action'), $(the_form).serialize(), function(data) {
223 $("#sqlqueryresults").html(data);
224 $("#sqlqueryresults").trigger('appendAnchor');
226 })// end Paginate results table
229 * Paginate results with Page Selector dropdown
231 * @name paginate_dropdown_change
233 $("#pageselector").live('change', function(event) {
234 event.preventDefault();
236 PMA_ajaxShowMessage();
238 $.get($(this).attr('href'), $(this).serialize() + '&ajax_request=true', function(data) {
239 $("#sqlqueryresults").html(data);
240 $("#sqlqueryresults").trigger('appendAnchor');
242 })// end Paginate results with Page Selector
245 * Ajax Event handler for sorting the results table
247 * @name table_results_sort_click
249 $("#table_results").find("a[title=Sort]").live('click', function(event) {
250 event.preventDefault();
252 PMA_ajaxShowMessage();
254 $.get($(this).attr('href'), $(this).serialize() + '&ajax_request=true', function(data) {
255 $("#sqlqueryresults").html(data);
256 $("#sqlqueryresults").trigger('appendAnchor');
258 })//end Sort results table
261 * Ajax Event handler for the display options
263 * @name displayOptionsForm_submit
265 $("#displayOptionsForm").live('submit', function(event) {
266 event.preventDefault();
268 $.post($(this).attr('action'), $(this).serialize() + '&ajax_request=true' , function(data) {
269 $("#sqlqueryresults").html(data);
270 $("#sqlqueryresults").trigger('appendAnchor');
273 //end displayOptionsForm handler
276 * Ajax Event handlers for Inline Editing
280 * On click, replace the current field with an input/textarea
282 * @name inline_edit_start
283 * @see PMA_ajaxShowMessage()
284 * @see getFieldName()
286 $(".edit_row_anchor").live('click', function(event) {
288 event.preventDefault();
290 $(this).removeClass('edit_row_anchor').addClass('edit_row_anchor_active');
292 // Initialize some variables
293 if(disp_mode == 'vertical') {
295 * @var this_row_index Index of the current <td> in the parent <tr>
296 * Current <td> is the inline edit anchor.
298 var this_row_index = $(this).index();
300 * @var input_siblings Object referring to all inline editable events from same row
302 var input_siblings = $(this).parents('tbody').find('tr').find('.data_inline_edit:nth('+this_row_index+')');
304 * @var where_clause String containing the WHERE clause to select this row
306 var where_clause = $(this).parents('tbody').find('tr').find('.where_clause:nth('+this_row_index+')').val();
309 var input_siblings = $(this).parent('tr').find('.data_inline_edit');
310 var where_clause = $(this).parent('tr').find('.where_clause').val();
313 $(input_siblings).each(function() {
316 * @var data_value Current value of this field
318 var data_value = $(this).html();
320 // We need to retrieve the value from the server for truncated/relation fields
321 // Find the field name
324 * @var this_field Object referring to this field (<td>)
326 var this_field = $(this);
328 * @var field_name String containing the name of this field.
329 * @see getFieldName()
331 var field_name = getFieldName($(this), disp_mode);
333 // In each input sibling, wrap the current value in a textarea
334 // and store the current value in a hidden span
335 if($(this).is(':not(.truncated, .transformed, .relation, .enum, .null)')) {
336 // handle non-truncated, non-transformed, non-relation values
337 // We don't need to get any more data, just wrap the value
338 $(this).html('<textarea>'+data_value+'</textarea>')
339 .append('<span class="original_data">'+data_value+'</span>');
340 $(".original_data").hide();
342 else if($(this).is('.truncated, .transformed')) {
344 //handle truncated/transformed values values
347 * @var sql_query String containing the SQL query used to retrieve value of truncated/transformed data
349 var sql_query = 'SELECT ' + field_name + ' FROM ' + window.parent.table + ' WHERE ' + where_clause;
351 // Make the Ajax call and get the data, wrap it and insert it
353 'token' : window.parent.token,
354 'db' : window.parent.db,
355 'ajax_request' : true,
356 'sql_query' : sql_query,
359 if(data.success == true) {
360 $(this_field).html('<textarea>'+data.value+'</textarea>')
361 .append('<span class="original_data">'+data_value+'</span>');
362 $(".original_data").hide();
365 PMA_ajaxShowMessage(data.error);
369 else if($(this).is('.relation')) {
374 * @var curr_value String containing the current value of this relational field
376 var curr_value = $(this).find('a').text();
379 * @var post_params Object containing parameters for the POST request
382 'ajax_request' : true,
383 'get_relational_values' : true,
384 'db' : window.parent.db,
385 'table' : window.parent.table,
386 'column' : field_name,
387 'token' : window.parent.token,
388 'curr_value' : curr_value
391 $.post('sql.php', post_params, function(data) {
392 $(this_field).html(data.dropdown)
393 .append('<span class="original_data">'+data_value+'</span>');
394 $(".original_data").hide();
397 else if($(this).is('.enum')) {
401 * @var curr_value String containing the current value of this relational field
403 var curr_value = $(this).text();
406 * @var post_params Object containing parameters for the POST request
409 'ajax_request' : true,
410 'get_enum_values' : true,
411 'db' : window.parent.db,
412 'table' : window.parent.table,
413 'column' : field_name,
414 'token' : window.parent.token,
415 'curr_value' : curr_value
418 $.post('sql.php', post_params, function(data) {
419 $(this_field).html(data.dropdown)
420 .append('<span class="original_data">'+data_value+'</span>');
421 $(".original_data").hide();
424 else if($(this).is('.null')) {
426 $(this_field).html('<textarea></textarea>')
427 .append('<span class="original_data">NULL</span>');
428 $(".original_data").hide();
431 }) // End On click, replace the current field with an input/textarea
434 * After editing, clicking again should post data
437 * @name inline_edit_save
438 * @see PMA_ajaxShowMessage()
439 * @see getFieldName()
441 $(".edit_row_anchor_active").live('click', function(event) {
443 event.preventDefault();
446 * @var this_row Object referring to current row that is being edited
448 var this_row = $(this);
450 // Initialize variables
451 if(disp_mode == 'vertical') {
453 * @var this_row_index Index of the current <td> in the parent <tr>
454 * Current <td> is the inline edit anchor.
456 var this_row_index = $(this).index();
458 * @var input_siblings Object referring to all inline editable events from same row
460 var input_siblings = $(this).parents('tbody').find('tr').find('.data_inline_edit:nth('+this_row_index+')');
462 * @var where_clause String containing the WHERE clause to select this row
464 var where_clause = $(this).parents('tbody').find('tr').find('.where_clause:nth('+this_row_index+')').val();
467 var input_siblings = $(this).parent('tr').find('.data_inline_edit');
468 var where_clause = $(this).parent('tr').find('.where_clause').val();
472 * @var nonunique Boolean, whether this row is unique or not
474 if($(this).is('.nonunique')) {
481 // Collect values of all fields to submit, we don't know which changed
483 * @var params_to_submit Array containing the name/value pairs of all fields
485 var params_to_submit = {};
487 * @var relation_fields Array containing the name/value pairs of relational fields
489 var relation_fields = {};
491 * @var transform_fields Array containing the name/value pairs for transformed fields
493 var transform_fields = {};
495 * @var transformation_fields Boolean, if there are any transformed fields in this row
497 var transformation_fields = false;
499 $(input_siblings).each(function() {
502 * @var this_field Object referring to this field (<td>)
504 var this_field = $(this);
506 * @var field_name String containing the name of this field.
507 * @see getFieldName()
509 var field_name = getFieldName($(this), disp_mode);
512 * @var this_field_params Array temporary storage for the name/value of current field
514 var this_field_params = {};
516 if($(this).is('.transformed')) {
517 transformation_fields = true;
520 if($(this).is(":not(.relation, .enum)")) {
521 this_field_params[field_name] = $(this).find('textarea').val();
522 if($(this).is('.transformed')) {
523 $.extend(transform_fields, this_field_params);
527 this_field_params[field_name] = $(this).find('select').val();
529 if($(this).is('.relation')) {
530 $.extend(relation_fields, this_field_params);
534 $.extend(params_to_submit, this_field_params);
538 * @var sql_query String containing the SQL query to update this row
540 var sql_query = 'UPDATE ' + window.parent.table + ' SET ';
542 $.each(params_to_submit, function(key, value) {
543 if(value.length == 0) {
546 sql_query += ' ' + key + "='" + value + "' , ";
548 //Remove the last ',' appended in the above loop
549 sql_query = sql_query.replace(/,\s$/, '');
550 sql_query += ' WHERE ' + where_clause;
553 * @var rel_fields_list String, url encoded representation of {@link relations_fields}
555 var rel_fields_list = $.param(relation_fields);
558 * @var transform_fields_list String, url encoded representation of {@link transform_fields}
560 var transform_fields_list = $.param(transform_fields);
562 // Make the Ajax post after setting all parameters
564 * @var post_params Object containing parameters for the POST request
566 var post_params = {'ajax_request' : true,
567 'sql_query' : sql_query,
568 'disp_direction' : disp_mode,
569 'token' : window.parent.token,
570 'db' : window.parent.db,
571 'table' : window.parent.table,
572 'clause_is_unique' : nonunique,
573 'where_clause' : where_clause,
574 'rel_fields_list' : rel_fields_list,
575 'do_transformations' : transformation_fields,
576 'transform_fields_list' : transform_fields_list,
580 $.post('tbl_replace.php', post_params, function(data) {
581 if(data.success == true) {
582 PMA_ajaxShowMessage(data.message);
583 $(this_row).removeClass('edit_row_anchor_active').addClass('edit_row_anchor');
585 $(input_siblings).each(function() {
586 // Inline edit post has been successful.
587 if($(this).is(':not(.relation, .enum)')) {
589 * @var new_html String containing value of the data field after edit
591 var new_html = $(this).find('textarea').val();
593 if($(this).is('.transformed')) {
594 var field_name = getFieldName($(this), disp_mode);
595 var this_field = $(this);
597 $.each(data.transformations, function(key, value) {
598 if(key == field_name) {
599 if($(this_field).is('.text_plain, .application_octetstream')) {
604 var new_value = $(this_field).find('textarea').val();
605 new_html = $(value).append(new_value);
613 var new_html = $(this).find('select').val();
614 if($(this).is('.relation')) {
615 var field_name = getFieldName($(this), disp_mode);
616 var this_field = $(this);
618 $.each(data.relations, function(key, value) {
619 if(key == field_name) {
620 var new_value = $(this_field).find('select').val();
621 new_html = $(value).append(new_value);
627 $(this).html(new_html);
631 PMA_ajaxShowMessage(data.error);
634 }) // End After editing, clicking again should post data
635 }, 'top.frame_content') // end $(document).ready()