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
11 * Get the field name for the current field. Required to construct the query
14 * @param this_field_obj jQuery object that points to the current field's tr
15 * @param disp_mode string
17 function getFieldName(this_field_obj, disp_mode) {
19 if(disp_mode == 'vertical') {
20 var field_name = $(this_field_obj).siblings('th').find('a').text();
23 var this_field_index = $(this_field_obj).index();
24 if(window.parent.text_dir == 'ltr') {
25 // 4 columns to account for the checkbox, edit, delete and appended inline edit anchors
26 var field_name = $(this_field_obj).parents('table').find('thead').find('th:nth('+ (this_field_index-4 )+') a').text();
29 var field_name = $(this_field_obj).parents('table').find('thead').find('th:nth('+ this_field_index+') a').text();
33 field_name = $.trim(field_name);
39 * The function that iterates over each row in the table_results and appends a
40 * new inline edit anchor to each table row.
42 * @param disp_mode string
44 function appendInlineAnchor(disp_mode) {
45 if(disp_mode == 'vertical') {
46 var cloned_row = $('.edit_row_anchor').removeClass('edit_row_anchor').parent('tr').clone();
48 var img_object = $(cloned_row).find('img:first').attr('title', PMA_messages['strInlineEdit']);
50 $(cloned_row).find('td').addClass('edit_row_anchor')
51 .find('a').attr('href', '#')
53 .text(PMA_messages['strInlineEdit'])
56 $(cloned_row).insertBefore($('.where_clause').parent('tr'));
58 $("#table_results").find('tr:first').find('th')
59 .attr('rowspan', '4');
62 $('.edit_row_anchor').each(function() {
64 $(this).removeClass('edit_row_anchor');
66 var cloned_anchor = $(this).clone();
68 var img_object = $(cloned_anchor).find('img').attr('title', PMA_messages['strInlineEdit']);
70 $(cloned_anchor).addClass('edit_row_anchor')
71 .find('a').attr('href', '#')
73 .text(PMA_messages['strInlineEdit'])
76 $(this).siblings('.where_clause')
77 .before(cloned_anchor);
80 $('#rowsDeleteForm').find('thead').find('th').each(function() {
81 if($(this).attr('colspan') == 3) {
82 $(this).attr('colspan', '4')
93 * @description <p>Ajax scripts for sql and browse pages</p>
95 * Actions ajaxified here:
97 * <li>Retrieve results of an SQL query</li>
98 * <li>Paginate the results table</li>
99 * <li>Sort the results table</li>
100 * <li>Change table according to display options</li>
101 * <li>Inline editing of data</li>
104 * @name document.ready
107 $(document).ready(function() {
110 * Set a parameter for all Ajax queries made on this page. Don't let the
111 * web server serve cached pages
118 * current value of the direction in which the table is displayed
123 var disp_mode = $("#top_direction_dropdown").val();
126 * Update value of {@link jQuery.disp_mode} everytime the direction dropdown changes value
128 * @name direction_dropdown_change
130 $("#top_direction_dropdown, #bottom_direction_dropdown").live('change', function(event) {
131 disp_mode = $(this).val();
135 * Attach the {@link appendInlineAnchor} function to a custom event, which
136 * will be triggered manually everytime the table of results is reloaded
138 * @name sqlqueryresults_live
140 $("#sqlqueryresults").live('appendAnchor',function() {
141 appendInlineAnchor(disp_mode);
145 * Trigger the appendAnchor event to prepare the first table for inline edit
148 * @name sqlqueryresults_trigger
150 $("#sqlqueryresults").trigger('appendAnchor');
153 * Append the Toggle Query Box message to the query input form
156 * @name appendToggleSpan
158 $('<span id="togglequerybox"></span>')
159 .html(PMA_messages['strToggleQueryBox'])
160 .appendTo("#sqlqueryform");
162 // Attach the toggling of the query box visibility to a click
163 $("#togglequerybox").live('click', function() {
164 $(this).siblings().slideToggle("medium");
168 * Ajax Event handler for 'SQL Query Submit'
170 * @see PMA_ajaxShowMessage()
172 * @name sqlqueryform_submit
174 $("#sqlqueryform").live('submit', function(event) {
175 event.preventDefault();
177 PMA_ajaxShowMessage();
179 $(this).append('<input type="hidden" name="ajax_request" value="true" />');
181 $.post($(this).attr('action'), $(this).serialize() , function(data) {
182 if(data.success == true) {
183 PMA_ajaxShowMessage(data.message);
185 else if (data.success == false ) {
186 PMA_ajaxShowMessage(data.error);
189 $("#sqlqueryresults").html(data);
190 $("#sqlqueryresults").trigger('appendAnchor');
191 if($("#togglequerybox").siblings(":visible").length > 0) {
192 $("#togglequerybox").trigger('click');
196 }) // end SQL Query submit
199 * Ajax Event handlers for Paginating the results table
203 * Paginate when we click any of the navigation buttons
205 * @name paginate_nav_button_click
206 * @uses PMA_ajaxShowMessage()
208 $("input[name=navig]").live('click', function(event) {
210 event.preventDefault();
212 PMA_ajaxShowMessage();
215 * @var the_form Object referring to the form element that paginates the results table
217 var the_form = $(this).parent("form");
219 $(the_form).append('<input type="hidden" name="ajax_request" value="true" />');
221 $.post($(the_form).attr('action'), $(the_form).serialize(), function(data) {
222 $("#sqlqueryresults").html(data);
223 $("#sqlqueryresults").trigger('appendAnchor');
225 })// end Paginate results table
228 * Paginate results with Page Selector dropdown
230 * @name paginate_dropdown_change
232 $("#pageselector").live('change', function(event) {
233 event.preventDefault();
235 PMA_ajaxShowMessage();
237 $.get($(this).attr('href'), $(this).serialize() + '&ajax_request=true', function(data) {
238 $("#sqlqueryresults").html(data);
239 $("#sqlqueryresults").trigger('appendAnchor');
241 })// end Paginate results with Page Selector
244 * Ajax Event handler for sorting the results table
246 * @name table_results_sort_click
248 $("#table_results").find("a[title=Sort]").live('click', function(event) {
249 event.preventDefault();
251 PMA_ajaxShowMessage();
253 $.get($(this).attr('href'), $(this).serialize() + '&ajax_request=true', function(data) {
254 $("#sqlqueryresults").html(data);
255 $("#sqlqueryresults").trigger('appendAnchor');
257 })//end Sort results table
260 * Ajax Event handler for the display options
262 * @name displayOptionsForm_submit
264 $("#displayOptionsForm").live('submit', function(event) {
265 event.preventDefault();
267 $.post($(this).attr('action'), $(this).serialize() + '&ajax_request=true' , function(data) {
268 $("#sqlqueryresults").html(data);
269 $("#sqlqueryresults").trigger('appendAnchor');
272 //end displayOptionsForm handler
275 * Ajax Event handlers for Inline Editing
279 * On click, replace the current field with an input/textarea
281 * @name inline_edit_start
282 * @see PMA_ajaxShowMessage()
283 * @see getFieldName()
285 $(".edit_row_anchor").live('click', function(event) {
287 event.preventDefault();
289 $(this).removeClass('edit_row_anchor').addClass('edit_row_anchor_active');
291 // Initialize some variables
292 if(disp_mode == 'vertical') {
294 * @var this_row_index Index of the current <td> in the parent <tr>
295 * Current <td> is the inline edit anchor.
297 var this_row_index = $(this).index();
299 * @var input_siblings Object referring to all inline editable events from same row
301 var input_siblings = $(this).parents('tbody').find('tr').find('.data_inline_edit:nth('+this_row_index+')');
303 * @var where_clause String containing the WHERE clause to select this row
305 var where_clause = $(this).parents('tbody').find('tr').find('.where_clause:nth('+this_row_index+')').val();
308 var input_siblings = $(this).parent('tr').find('.data_inline_edit');
309 var where_clause = $(this).parent('tr').find('.where_clause').val();
312 $(input_siblings).each(function() {
315 * @var data_value Current value of this field
317 var data_value = $(this).html();
319 // We need to retrieve the value from the server for truncated/relation fields
320 // Find the field name
323 * @var this_field Object referring to this field (<td>)
325 var this_field = $(this);
327 * @var field_name String containing the name of this field.
328 * @see getFieldName()
330 var field_name = getFieldName($(this), disp_mode);
332 // In each input sibling, wrap the current value in a textarea
333 // and store the current value in a hidden span
334 if($(this).is(':not(.truncated, .transformed, .relation, .enum, .null)')) {
335 // handle non-truncated, non-transformed, non-relation values
336 // We don't need to get any more data, just wrap the value
337 $(this).html('<textarea>'+data_value+'</textarea>')
338 .append('<span class="original_data">'+data_value+'</span>');
339 $(".original_data").hide();
341 else if($(this).is('.truncated, .transformed')) {
343 //handle truncated/transformed values values
346 * @var sql_query String containing the SQL query used to retrieve value of truncated/transformed data
348 var sql_query = 'SELECT ' + field_name + ' FROM ' + window.parent.table + ' WHERE ' + where_clause;
350 // Make the Ajax call and get the data, wrap it and insert it
352 'token' : window.parent.token,
353 'db' : window.parent.db,
354 'ajax_request' : true,
355 'sql_query' : sql_query,
358 if(data.success == true) {
359 $(this_field).html('<textarea>'+data.value+'</textarea>')
360 .append('<span class="original_data">'+data_value+'</span>');
361 $(".original_data").hide();
364 PMA_ajaxShowMessage(data.error);
368 else if($(this).is('.relation')) {
373 * @var curr_value String containing the current value of this relational field
375 var curr_value = $(this).find('a').text();
378 * @var post_params Object containing parameters for the POST request
381 'ajax_request' : true,
382 'get_relational_values' : true,
383 'db' : window.parent.db,
384 'table' : window.parent.table,
385 'column' : field_name,
386 'token' : window.parent.token,
387 'curr_value' : curr_value
390 $.post('sql.php', post_params, function(data) {
391 $(this_field).html(data.dropdown)
392 .append('<span class="original_data">'+data_value+'</span>');
393 $(".original_data").hide();
396 else if($(this).is('.enum')) {
400 * @var curr_value String containing the current value of this relational field
402 var curr_value = $(this).text();
405 * @var post_params Object containing parameters for the POST request
408 'ajax_request' : true,
409 'get_enum_values' : true,
410 'db' : window.parent.db,
411 'table' : window.parent.table,
412 'column' : field_name,
413 'token' : window.parent.token,
414 'curr_value' : curr_value
417 $.post('sql.php', post_params, function(data) {
418 $(this_field).html(data.dropdown)
419 .append('<span class="original_data">'+data_value+'</span>');
420 $(".original_data").hide();
423 else if($(this).is('.null')) {
425 $(this_field).html('<textarea></textarea>')
426 .append('<span class="original_data">NULL</span>');
427 $(".original_data").hide();
430 }) // End On click, replace the current field with an input/textarea
433 * After editing, clicking again should post data
436 * @name inline_edit_save
437 * @see PMA_ajaxShowMessage()
438 * @see getFieldName()
440 $(".edit_row_anchor_active").live('click', function(event) {
442 event.preventDefault();
445 * @var this_row Object referring to current row that is being edited
447 var this_row = $(this);
449 // Initialize variables
450 if(disp_mode == 'vertical') {
452 * @var this_row_index Index of the current <td> in the parent <tr>
453 * Current <td> is the inline edit anchor.
455 var this_row_index = $(this).index();
457 * @var input_siblings Object referring to all inline editable events from same row
459 var input_siblings = $(this).parents('tbody').find('tr').find('.data_inline_edit:nth('+this_row_index+')');
461 * @var where_clause String containing the WHERE clause to select this row
463 var where_clause = $(this).parents('tbody').find('tr').find('.where_clause:nth('+this_row_index+')').val();
466 var input_siblings = $(this).parent('tr').find('.data_inline_edit');
467 var where_clause = $(this).parent('tr').find('.where_clause').val();
471 * @var nonunique Boolean, whether this row is unique or not
473 if($(this).is('.nonunique')) {
480 // Collect values of all fields to submit, we don't know which changed
482 * @var params_to_submit Array containing the name/value pairs of all fields
484 var params_to_submit = {};
486 * @var relation_fields Array containing the name/value pairs of relational fields
488 var relation_fields = {};
490 * @var transform_fields Array containing the name/value pairs for transformed fields
492 var transform_fields = {};
494 * @var transformation_fields Boolean, if there are any transformed fields in this row
496 var transformation_fields = false;
498 $(input_siblings).each(function() {
501 * @var this_field Object referring to this field (<td>)
503 var this_field = $(this);
505 * @var field_name String containing the name of this field.
506 * @see getFieldName()
508 var field_name = getFieldName($(this), disp_mode);
511 * @var this_field_params Array temporary storage for the name/value of current field
513 var this_field_params = {};
515 if($(this).is('.transformed')) {
516 transformation_fields = true;
519 if($(this).is(":not(.relation, .enum)")) {
520 this_field_params[field_name] = $(this).find('textarea').val();
521 if($(this).is('.transformed')) {
522 $.extend(transform_fields, this_field_params);
526 this_field_params[field_name] = $(this).find('select').val();
528 if($(this).is('.relation')) {
529 $.extend(relation_fields, this_field_params);
533 $.extend(params_to_submit, this_field_params);
537 * @var sql_query String containing the SQL query to update this row
539 var sql_query = 'UPDATE ' + window.parent.table + ' SET ';
541 $.each(params_to_submit, function(key, value) {
542 if(value.length == 0) {
545 sql_query += ' ' + key + "='" + value + "' , ";
547 //Remove the last ',' appended in the above loop
548 sql_query = sql_query.replace(/,\s$/, '');
549 sql_query += ' WHERE ' + where_clause;
552 * @var rel_fields_list String, url encoded representation of {@link relations_fields}
554 var rel_fields_list = $.param(relation_fields);
557 * @var transform_fields_list String, url encoded representation of {@link transform_fields}
559 var transform_fields_list = $.param(transform_fields);
561 // Make the Ajax post after setting all parameters
563 * @var post_params Object containing parameters for the POST request
565 var post_params = {'ajax_request' : true,
566 'sql_query' : sql_query,
567 'disp_direction' : disp_mode,
568 'token' : window.parent.token,
569 'db' : window.parent.db,
570 'table' : window.parent.table,
571 'clause_is_unique' : nonunique,
572 'where_clause' : where_clause,
573 'rel_fields_list' : rel_fields_list,
574 'do_transformations' : transformation_fields,
575 'transform_fields_list' : transform_fields_list,
579 $.post('tbl_replace.php', post_params, function(data) {
580 if(data.success == true) {
581 PMA_ajaxShowMessage(data.message);
582 $(this_row).removeClass('edit_row_anchor_active').addClass('edit_row_anchor');
584 $(input_siblings).each(function() {
585 // Inline edit post has been successful.
586 if($(this).is(':not(.relation, .enum)')) {
588 * @var new_html String containing value of the data field after edit
590 var new_html = $(this).find('textarea').val();
592 if($(this).is('.transformed')) {
593 var field_name = getFieldName($(this), disp_mode);
594 var this_field = $(this);
596 $.each(data.transformations, function(key, value) {
597 if(key == field_name) {
598 if($(this_field).is('.text_plain, .application_octetstream')) {
603 var new_value = $(this_field).find('textarea').val();
604 new_html = $(value).append(new_value);
612 var new_html = $(this).find('select').val();
613 if($(this).is('.relation')) {
614 var field_name = getFieldName($(this), disp_mode);
615 var this_field = $(this);
617 $.each(data.relations, function(key, value) {
618 if(key == field_name) {
619 var new_value = $(this_field).find('select').val();
620 new_html = $(value).append(new_value);
626 $(this).html(new_html);
630 PMA_ajaxShowMessage(data.error);
633 }) // End After editing, clicking again should post data
634 }, 'top.frame_content') // end $(document).ready()