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