Translation update done using Pootle.
[phpmyadmin/dkf.git] / js / sql.js
blobee66044fcf62d2f565c0e3f01bddb31a43a75b15
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
2 /**
3  * @fileoverview    functions used wherever an sql query form is used
4  *
5  * @requires    jQuery
6  * @requires    js/functions.js
7  *
8  * @version $Id$
9  */
11 /**
12  * Get the field name for the current field.  Required to construct the query
13  * for inline editing
14  *
15  * @param   this_field_obj  jQuery object that points to the current field's tr
16  * @param   disp_mode       string
17  */
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();
22     }
23     else {
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();
28         }
29         else {
30             var field_name = $(this_field_obj).parents('table').find('thead').find('th:nth('+ this_field_index+') a').text();
31         }
32     }
34     field_name = $.trim(field_name);
36     return field_name;
39 /**
40  * The function that iterates over each row in the table_results and appends a
41  * new inline edit anchor to each table row.
42  *
43  * @param   disp_mode   string
44  */
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', '#')
53         .find('div')
54         .text(PMA_messages['strInlineEdit'])
55         .prepend(img_object);
57         $(cloned_row).insertBefore($('.where_clause').parent('tr'));
59         $("#table_results").find('tr:first').find('th')
60         .attr('rowspan', '4');
61     }
62     else {
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', '#')
73             .find('div')
74             .text(PMA_messages['strInlineEdit'])
75             .prepend(img_object);
77             $(this).siblings('.where_clause')
78             .before(cloned_anchor);
79         });
81         $('#rowsDeleteForm').find('thead').find('th').each(function() {
82             if($(this).attr('colspan') == 3) {
83                 $(this).attr('colspan', '4')
84             }
85         })
86     }
89 /**#@+
90  * @namespace   jQuery
91  */
93 /**
94  * @description <p>Ajax scripts for sql and browse pages</p>
95  *
96  * Actions ajaxified here:
97  * <ul>
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>
103  * </ul>
105  * @name        document.ready
106  * @memberOf    jQuery
107  */
108 $(document).ready(function() {
110     /**
111      * Set a parameter for all Ajax queries made on this page.  Don't let the
112      * web server serve cached pages
113      */
114     $.ajaxSetup({
115         cache: 'false'
116     });
118     /**
119      * current value of the direction in which the table is displayed
120      * @type    String
121      * @fieldOf jQuery
122      * @name    disp_mode
123      */
124     var disp_mode = $("#top_direction_dropdown").val();
126     /**
127      * Update value of {@link jQuery.disp_mode} everytime the direction dropdown changes value
128      * @memberOf    jQuery
129      * @name        direction_dropdown_change
130      */
131     $("#top_direction_dropdown, #bottom_direction_dropdown").live('change', function(event) {
132         disp_mode = $(this).val();
133     })
135     /**
136      * Attach the {@link appendInlineAnchor} function to a custom event, which
137      * will be triggered manually everytime the table of results is reloaded
138      * @memberOf    jQuery
139      * @name        sqlqueryresults_live
140      */
141     $("#sqlqueryresults").live('appendAnchor',function() {
142         appendInlineAnchor(disp_mode);
143     })
145     /**
146      * Trigger the appendAnchor event to prepare the first table for inline edit
147      *
148      * @memberOf    jQuery
149      * @name        sqlqueryresults_trigger
150      */
151     $("#sqlqueryresults").trigger('appendAnchor');
153     /**
154      * Append the Toggle Query Box message to the query input form
155      *
156      * @memberOf jQuery
157      * @name    appendToggleSpan
158      */
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");
166     })
167     
168     /**
169      * Ajax Event handler for 'SQL Query Submit'
170      *
171      * @see         PMA_ajaxShowMessage()
172      * @memberOf    jQuery
173      * @name        sqlqueryform_submit
174      */
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);
185             }
186             else if (data.success == false ) {
187                 PMA_ajaxShowMessage(data.error);
188             }
189             else {
190                 $("#sqlqueryresults").html(data);
191                 $("#sqlqueryresults").trigger('appendAnchor');
192                 if($("#togglequerybox").siblings(":visible").length > 0) {
193                     $("#togglequerybox").trigger('click');
194                 }
195             }
196         }) // end $.post()
197     }) // end SQL Query submit
199     /**
200      * Ajax Event handlers for Paginating the results table
201      */
203     /**
204      * Paginate when we click any of the navigation buttons
205      * @memberOf    jQuery
206      * @name        paginate_nav_button_click
207      * @uses        PMA_ajaxShowMessage()
208      */
209     $("input[name=navig]").live('click', function(event) {
210         /** @lends jQuery */
211         event.preventDefault();
213         PMA_ajaxShowMessage();
214         
215         /**
216          * @var the_form    Object referring to the form element that paginates the results table
217          */
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');
225         }) // end $.post()
226     })// end Paginate results table
228     /**
229      * Paginate results with Page Selector dropdown
230      * @memberOf    jQuery
231      * @name        paginate_dropdown_change
232      */
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');
241         }) // end $.get()
242     })// end Paginate results with Page Selector
244     /**
245      * Ajax Event handler for sorting the results table
246      * @memberOf    jQuery
247      * @name        table_results_sort_click
248      */
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');
257         }) // end $.get()
258     })//end Sort results table
260     /**
261      * Ajax Event handler for the display options
262      * @memberOf    jQuery
263      * @name        displayOptionsForm_submit
264      */
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');
271         }) // end $.post()
272     })
273     //end displayOptionsForm handler
275     /**
276      * Ajax Event handlers for Inline Editing
277      */
279     /**
280      * On click, replace the current field with an input/textarea
281      * @memberOf    jQuery
282      * @name        inline_edit_start
283      * @see         PMA_ajaxShowMessage()
284      * @see         getFieldName()
285      */
286     $(".edit_row_anchor").live('click', function(event) {
287         /** @lends jQuery */
288         event.preventDefault();
290         $(this).removeClass('edit_row_anchor').addClass('edit_row_anchor_active');
292         // Initialize some variables
293         if(disp_mode == 'vertical') {
294             /**
295              * @var this_row_index  Index of the current <td> in the parent <tr>
296              *                      Current <td> is the inline edit anchor.
297              */
298             var this_row_index = $(this).index();
299             /**
300              * @var input_siblings  Object referring to all inline editable events from same row
301              */
302             var input_siblings = $(this).parents('tbody').find('tr').find('.data_inline_edit:nth('+this_row_index+')');
303             /**
304              * @var where_clause    String containing the WHERE clause to select this row
305              */
306             var where_clause = $(this).parents('tbody').find('tr').find('.where_clause:nth('+this_row_index+')').val();
307         }
308         else {
309             var input_siblings = $(this).parent('tr').find('.data_inline_edit');
310             var where_clause = $(this).parent('tr').find('.where_clause').val();
311         }
313         $(input_siblings).each(function() {
314             /** @lends jQuery */
315             /**
316              * @var data_value  Current value of this field
317              */
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
322             
323             /**
324              * @var this_field  Object referring to this field (<td>)
325              */
326             var this_field = $(this);
327             /**
328              * @var field_name  String containing the name of this field.
329              * @see getFieldName()
330              */
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();
341             }
342             else if($(this).is('.truncated, .transformed')) {
343                 /** @lends jQuery */
344                 //handle truncated/transformed values values
346                 /**
347                  * @var sql_query   String containing the SQL query used to retrieve value of truncated/transformed data
348                  */
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
352                 $.post('sql.php', {
353                     'token' : window.parent.token,
354                     'db' : window.parent.db,
355                     'ajax_request' : true,
356                     'sql_query' : sql_query,
357                     'inline_edit' : true
358                 }, function(data) {
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();
363                     }
364                     else {
365                         PMA_ajaxShowMessage(data.error);
366                     }
367                 }) // end $.post()
368             }
369             else if($(this).is('.relation')) {
370                 /** @lends jQuery */
371                 //handle relations
373                 /**
374                  * @var curr_value  String containing the current value of this relational field
375                  */
376                 var curr_value = $(this).find('a').text();
378                 /**
379                  * @var post_params Object containing parameters for the POST request
380                  */
381                 var post_params = {
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
389                 }
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();
395                 }) // end $.post()
396             }
397             else if($(this).is('.enum')) {
398                 /** @lends jQuery */
399                 //handle enum fields
400                 /**
401                  * @var curr_value  String containing the current value of this relational field
402                  */
403                 var curr_value = $(this).text();
405                 /**
406                  * @var post_params Object containing parameters for the POST request
407                  */
408                 var post_params = {
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
416                 }
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();
422                 }) // end $.post()
423             }
424             else if($(this).is('.null')) {
425                 //handle null fields
426                 $(this_field).html('<textarea></textarea>')
427                 .append('<span class="original_data">NULL</span>');
428                 $(".original_data").hide();
429             }
430         })
431     }) // End On click, replace the current field with an input/textarea
433     /**
434      * After editing, clicking again should post data
435      *
436      * @memberOf    jQuery
437      * @name        inline_edit_save
438      * @see         PMA_ajaxShowMessage()
439      * @see         getFieldName()
440      */
441     $(".edit_row_anchor_active").live('click', function(event) {
442         /** @lends jQuery */
443         event.preventDefault();
445         /**
446          * @var this_row    Object referring to current row that is being edited
447          */
448         var this_row = $(this);
450         // Initialize variables
451         if(disp_mode == 'vertical') {
452             /**
453              * @var this_row_index  Index of the current <td> in the parent <tr>
454              *                      Current <td> is the inline edit anchor.
455              */
456             var this_row_index = $(this).index();
457             /**
458              * @var input_siblings  Object referring to all inline editable events from same row
459              */
460             var input_siblings = $(this).parents('tbody').find('tr').find('.data_inline_edit:nth('+this_row_index+')');
461             /**
462              * @var where_clause    String containing the WHERE clause to select this row
463              */
464             var where_clause = $(this).parents('tbody').find('tr').find('.where_clause:nth('+this_row_index+')').val();
465         }
466         else {
467             var input_siblings = $(this).parent('tr').find('.data_inline_edit');
468             var where_clause = $(this).parent('tr').find('.where_clause').val();
469         }
471         /**
472          * @var nonunique   Boolean, whether this row is unique or not
473          */
474         if($(this).is('.nonunique')) {
475             var nonunique = 0;
476         }
477         else {
478             var nonunique = 1;
479         }
481         // Collect values of all fields to submit, we don't know which changed
482         /**
483          * @var params_to_submit    Array containing the name/value pairs of all fields
484          */
485         var params_to_submit = {};
486         /**
487          * @var relation_fields Array containing the name/value pairs of relational fields
488          */
489         var relation_fields = {};
490         /**
491          * @var transform_fields    Array containing the name/value pairs for transformed fields
492          */
493         var transform_fields = {};
494         /**
495          * @var transformation_fields   Boolean, if there are any transformed fields in this row
496          */
497         var transformation_fields = false;
499         $(input_siblings).each(function() {
500             /** @lends jQuery */
501             /**
502              * @var this_field  Object referring to this field (<td>)
503              */
504             var this_field = $(this);
505             /**
506              * @var field_name  String containing the name of this field.
507              * @see getFieldName()
508              */
509             var field_name = getFieldName($(this), disp_mode);
511             /**
512              * @var this_field_params   Array temporary storage for the name/value of current field
513              */
514             var this_field_params = {};
516             if($(this).is('.transformed')) {
517                 transformation_fields =  true;
518             }
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);
524                 }
525             }
526             else {
527                 this_field_params[field_name] = $(this).find('select').val();
529                 if($(this).is('.relation')) {
530                     $.extend(relation_fields, this_field_params);
531                 }
532             }
534             $.extend(params_to_submit, this_field_params);
535         })
537         /**
538          * @var sql_query   String containing the SQL query to update this row
539          */
540         var sql_query = 'UPDATE ' + window.parent.table + ' SET ';
542         $.each(params_to_submit, function(key, value) {
543             if(value.length == 0) {
544                 value = 'NULL'
545             }
546            sql_query += ' ' + key + "='" + value + "' , ";
547         })
548         //Remove the last ',' appended in the above loop
549         sql_query = sql_query.replace(/,\s$/, '');
550         sql_query += ' WHERE ' + where_clause;
552         /**
553          * @var rel_fields_list  String, url encoded representation of {@link relations_fields}
554          */
555         var rel_fields_list = $.param(relation_fields);
557         /**
558          * @var transform_fields_list  String, url encoded representation of {@link transform_fields}
559          */
560         var transform_fields_list = $.param(transform_fields);
562         // Make the Ajax post after setting all parameters
563         /**
564          * @var post_params Object containing parameters for the POST request
565          */
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,
577                             'goto' : 'sql.php'
578                           };
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)')) {
588                         /**
589                          * @var new_html    String containing value of the data field after edit
590                          */
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')) {
600                                         new_html = value;
601                                         return false;
602                                     }
603                                     else {
604                                         var new_value = $(this_field).find('textarea').val();
605                                         new_html = $(value).append(new_value);
606                                         return false;
607                                     }
608                                 }
609                             })
610                         }
611                     }
612                     else {
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);
622                                     return false;
623                                 }
624                             })
625                         }
626                     }
627                     $(this).html(new_html);
628                 })
629             }
630             else {
631                 PMA_ajaxShowMessage(data.error);
632             };
633         }) // end $.post()
634     }) // End After editing, clicking again should post data
635 }, 'top.frame_content') // end $(document).ready()
637 /**#@- */