Merge remote-tracking branch 'origin/master' into drizzle
[phpmyadmin.git] / js / rte / routines.js
blob50c4f00051ff3ef09979345c10064f99ccbac6f0
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4  * @var    param_template    This variable contains the template for one row
5  *                           of the parameters table that is attached to the
6  *                           dialog when a new parameter is added.
7  */
8 RTE.param_template = '';
10 /**
11  * Overriding the postDialogShow() function defined in common.js
12  *
13  * @param   data   JSON-encoded data from the ajax request
14  */
15 RTE.postDialogShow = function (data) {
16     // Cache the template for a parameter table row
17     RTE.param_template = data.param_template;
18     // Make adjustments in the dialog to make it AJAX compatible
19     $('.routine_param_remove').show();
20     $('input[name=routine_removeparameter]').remove();
21     $('input[name=routine_addparameter]').css('width', '100%');
22     // Enable/disable the 'options' dropdowns for parameters as necessary
23     $('.routine_params_table').last().find('th[colspan=2]').attr('colspan', '1');
24     $('.routine_params_table').last().find('tr').has('td').each(function () {
25         RTE.setOptionsForParameter(
26             $(this).find('select[name^=item_param_type]'),
27             $(this).find('input[name^=item_param_length]'),
28             $(this).find('select[name^=item_param_opts_text]'),
29             $(this).find('select[name^=item_param_opts_num]')
30         );
31     });
32     // Enable/disable the 'options' dropdowns for
33     // function return value as necessary
34     RTE.setOptionsForParameter(
35         $('.rte_table').last().find('select[name=item_returntype]'),
36         $('.rte_table').last().find('input[name=item_returnlength]'),
37         $('.rte_table').last().find('select[name=item_returnopts_text]'),
38         $('.rte_table').last().find('select[name=item_returnopts_num]')
39     );
40 }; // end RTE.postDialogShow()
42 /**
43  * Overriding the validateCustom() function defined in common.js
44  */
45 RTE.validateCustom = function () {
46     /**
47      * @var   isSuccess   Stores the outcome of the validation
48      */
49     var isSuccess = true;
50     /**
51      * @var   inputname   The value of the "name" attribute for
52      *                    the field that is being processed
53      */
54     var inputname = '';
55     $('.routine_params_table').last().find('tr').each(function () {
56         // Every parameter of a routine must have
57         // a non-empty direction, name and type
58         if (isSuccess) {
59             $(this).find(':input').each(function () {
60                 inputname = $(this).attr('name');
61                 if (inputname.substr(0, 17) === 'item_param_dir' ||
62                     inputname.substr(0, 18) === 'item_param_name' ||
63                     inputname.substr(0, 18) === 'item_param_type') {
64                     if ($(this).val() === '') {
65                         $(this).focus();
66                         isSuccess = false;
67                         return false;
68                     }
69                 }
70             });
71         } else {
72             return false;
73         }
74     });
75     if (! isSuccess) {
76         alert(PMA_messages['strFormEmpty']);
77         return false;
78     }
79     $('.routine_params_table').last().find('tr').each(function () {
80         // SET, ENUM, VARCHAR and VARBINARY fields must have length/values
81         var $inputtyp = $(this).find('select[name^=item_param_type]');
82         var $inputlen = $(this).find('input[name^=item_param_length]');
83         if ($inputtyp.length && $inputlen.length) {
84             if (($inputtyp.val() === 'ENUM' || $inputtyp.val() === 'SET' || $inputtyp.val().substr(0, 3) === 'VAR')
85                && $inputlen.val() === '') {
86                 $inputlen.focus();
87                 isSuccess = false;
88                 return false;
89             }
90         }
91     });
92     if (! isSuccess) {
93         alert(PMA_messages['strFormEmpty']);
94         return false;
95     }
96     if ($('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
97         // The length/values of return variable for functions must
98         // be set, if the type is SET, ENUM, VARCHAR or VARBINARY.
99         var $returntyp = $('select[name=item_returntype]');
100         var $returnlen = $('input[name=item_returnlength]');
101         if (($returntyp.val() === 'ENUM' || $returntyp.val() === 'SET' || $returntyp.val().substr(0, 3) === 'VAR')
102            && $returnlen.val() === '') {
103             $returnlen.focus();
104             alert(PMA_messages['strFormEmpty']);
105             return false;
106         }
107     }
108     if ($('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
109         // A function must contain a RETURN statement in its definition
110         if ($('.rte_table').find('textarea[name=item_definition]').val().toUpperCase().indexOf('RETURN') < 0) {
111             RTE.syntaxHiglighter.focus();
112             alert(PMA_messages['MissingReturn']);
113             return false;
114         }
115     }
116     return true;
117 }; // end RTE.validateCustom()
120  * Enable/disable the "options" dropdown and "length" input for
121  * parameters and the return variable in the routine editor
122  * as necessary.
124  * @param    $type    a jQuery object containing the reference
125  *                    to the "Type" dropdown box
126  * @param    $len     a jQuery object containing the reference
127  *                    to the "Length" input box
128  * @param    $text    a jQuery object containing the reference
129  *                    to the dropdown box with options for
130  *                    parameters of text type
131  * @param    $num     a jQuery object containing the reference
132  *                    to the dropdown box with options for
133  *                    parameters of numeric type
134  */
135 RTE.setOptionsForParameter = function ($type, $len, $text, $num) {
136     /**
137      * @var   $no_opts   a jQuery object containing the reference
138      *                   to an element to be displayed when no
139      *                   options are available
140      */
141     var $no_opts = $text.parent().parent().find('.no_opts');
142     /**
143      * @var   $no_len    a jQuery object containing the reference
144      *                   to an element to be displayed when no
145      *                  "length/values" field is available
146      */
147     var $no_len  = $len.parent().parent().find('.no_len');
149     // Process for parameter options
150     switch ($type.val()) {
151     case 'TINYINT':
152     case 'SMALLINT':
153     case 'MEDIUMINT':
154     case 'INT':
155     case 'BIGINT':
156     case 'DECIMAL':
157     case 'FLOAT':
158     case 'DOUBLE':
159     case 'REAL':
160         $text.parent().hide();
161         $num.parent().show();
162         $no_opts.hide();
163         break;
164     case 'TINYTEXT':
165     case 'TEXT':
166     case 'MEDIUMTEXT':
167     case 'LONGTEXT':
168     case 'CHAR':
169     case 'VARCHAR':
170     case 'SET':
171     case 'ENUM':
172         $text.parent().show();
173         $num.parent().hide();
174         $no_opts.hide();
175         break;
176     default:
177         $text.parent().hide();
178         $num.parent().hide();
179         $no_opts.show();
180         break;
181     }
182     // Process for parameter length
183     switch ($type.val()) {
184     case 'DATE':
185     case 'DATETIME':
186     case 'TIME':
187     case 'TINYBLOB':
188     case 'TINYTEXT':
189     case 'BLOB':
190     case 'TEXT':
191     case 'MEDIUMBLOB':
192     case 'MEDIUMTEXT':
193     case 'LONGBLOB':
194     case 'LONGTEXT':
195         $len.parent().hide();
196         $no_len.show();
197         break;
198     default:
199         $len.parent().show();
200         $no_len.hide();
201         break;
202     }
203 }; // end RTE.setOptionsForParameter()
206  * Attach Ajax event handlers for the Routines functionalities.
208  * @see $cfg['AjaxEnable']
209  */
210 $(document).ready(function () {
211     /**
212      * Attach Ajax event handlers for the "Add parameter to routine" functionality.
213      */
214     $('input[name=routine_addparameter]').live('click', function (event) {
215         event.preventDefault();
216         /**
217          * @var    $routine_params_table    jQuery object containing the reference
218          *                                  to the routine parameters table.
219          */
220         var $routine_params_table = $('.routine_params_table').last();
221         /**
222          * @var    $new_param_row    A string containing the HTML code for the
223          *                           new row for the routine paramaters table.
224          */
225         var new_param_row = RTE.param_template.replace(/%s/g, $routine_params_table.find('tr').length - 1);
226         // Append the new row to the parameters table
227         $routine_params_table.append(new_param_row);
228         // Make sure that the row is correctly shown according to the type of routine
229         if ($('.rte_table').find('select[name=item_type]').val() === 'FUNCTION') {
230             $('.routine_return_row').show();
231             $('.routine_direction_cell').hide();
232         }
233         /**
234          * @var    $newrow    jQuery object containing the reference to the newly
235          *                    inserted row in the routine parameters table.
236          */
237         var $newrow = $('.routine_params_table').last().find('tr').has('td').last();
238         // Enable/disable the 'options' dropdowns for parameters as necessary
239         RTE.setOptionsForParameter(
240             $newrow.find('select[name^=item_param_type]'),
241             $newrow.find('input[name^=item_param_length]'),
242             $newrow.find('select[name^=item_param_opts_text]'),
243             $newrow.find('select[name^=item_param_opts_num]')
244         );
245     }); // end $.live()
247     /**
248      * Attach Ajax event handlers for the "Remove parameter from routine" functionality.
249      */
250     $('.routine_param_remove_anchor').live('click', function (event) {
251         event.preventDefault();
252         $(this).parent().parent().remove();
253         // After removing a parameter, the indices of the name attributes in
254         // the input fields lose the correct order and need to be reordered.
255         /**
256          * @var    index    Counter used for reindexing the input
257          *                  fields in the routine parameters table.
258          */
259         var index = 0;
260         $('.routine_params_table').last().find('tr').has('td').each(function () {
261             $(this).find(':input').each(function () {
262                 /**
263                  * @var    inputname    The value of the name attribute of
264                  *                      the input field being reindexed.
265                  */
266                 var inputname = $(this).attr('name');
267                 if (inputname.substr(0, 17) === 'item_param_dir') {
268                     $(this).attr('name', inputname.substr(0, 17) + '[' + index + ']');
269                 } else if (inputname.substr(0, 18) === 'item_param_name') {
270                     $(this).attr('name', inputname.substr(0, 18) + '[' + index + ']');
271                 } else if (inputname.substr(0, 18) === 'item_param_type') {
272                     $(this).attr('name', inputname.substr(0, 18) + '[' + index + ']');
273                 } else if (inputname.substr(0, 20) === 'item_param_length') {
274                     $(this).attr('name', inputname.substr(0, 20) + '[' + index + ']');
275                 } else if (inputname.substr(0, 23) === 'item_param_opts_text') {
276                     $(this).attr('name', inputname.substr(0, 23) + '[' + index + ']');
277                 } else if (inputname.substr(0, 22) === 'item_param_opts_num') {
278                     $(this).attr('name', inputname.substr(0, 22) + '[' + index + ']');
279                 }
280             });
281             index++;
282         });
283     }); // end $.live()
285     /**
286      * Attach Ajax event handlers for the "Change routine type"
287      * functionality in the routines editor, so that the correct
288      * fields are shown in the editor when changing the routine type
289      */
290     $('select[name=item_type]').live('change', function () {
291         $('.routine_return_row, .routine_direction_cell').toggle();
292     }); // end $.live()
294     /**
295      * Attach Ajax event handlers for the "Change parameter type"
296      * functionality in the routines editor, so that the correct
297      * option/length fields, if any, are shown when changing
298      * a parameter type
299      */
300     $('select[name^=item_param_type]').live('change', function () {
301         /**
302          * @var    $row    jQuery object containing the reference to
303          *                 a row in the routine parameters table
304          */
305         var $row = $(this).parents('tr').first();
306         RTE.setOptionsForParameter(
307             $row.find('select[name^=item_param_type]'),
308             $row.find('input[name^=item_param_length]'),
309             $row.find('select[name^=item_param_opts_text]'),
310             $row.find('select[name^=item_param_opts_num]')
311         );
312     }); // end $.live()
314     /**
315      * Attach Ajax event handlers for the "Change the type of return
316      * variable of function" functionality, so that the correct fields,
317      * if any, are shown when changing the function return type type
318      */
319     $('select[name=item_returntype]').live('change', function () {
320         RTE.setOptionsForParameter(
321             $('.rte_table').find('select[name=item_returntype]'),
322             $('.rte_table').find('input[name=item_returnlength]'),
323             $('.rte_table').find('select[name=item_returnopts_text]'),
324             $('.rte_table').find('select[name=item_returnopts_num]')
325         );
326     }); // end $.live()
328     /**
329      * Attach Ajax event handlers for the Execute routine functionality.
330      */
331     $('.ajax_exec_anchor').live('click', function (event) {
332         event.preventDefault();
333         /**
334          * @var    $msg    jQuery object containing the reference to
335          *                 the AJAX message shown to the user
336          */
337         var $msg = PMA_ajaxShowMessage();
338         $.get($(this).attr('href'), {'ajax_request': true}, function (data) {
339             if (data.success === true) {
340                 PMA_ajaxRemoveMessage($msg);
341                 // If 'data.dialog' is true we show a dialog with a form
342                 // to get the input parameters for routine, otherwise
343                 // we just show the results of the query
344                 if (data.dialog) {
345                     // Define the function that is called when
346                     // the user presses the "Go" button
347                     RTE.buttonOptions[PMA_messages['strGo']] = function () {
348                         /**
349                          * @var    data    Form data to be sent in the AJAX request.
350                          */
351                         var data = $('.rte_form').last().serialize();
352                         $msg = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
353                         $.post('db_routines.php', data, function (data) {
354                             if (data.success === true) {
355                                 // Routine executed successfully
356                                 PMA_ajaxRemoveMessage($msg);
357                                 PMA_slidingMessage(data.message);
358                                 $ajaxDialog.dialog('close');
359                             } else {
360                                 PMA_ajaxShowMessage(data.error);
361                             }
362                         });
363                     };
364                     RTE.buttonOptions[PMA_messages['strClose']] = function () {
365                         $(this).dialog("close");
366                     };
367                     /**
368                      * Display the dialog to the user
369                      */
370                     $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
371                                     width: 650,
372                                     buttons: RTE.buttonOptions,
373                                     title: data.title,
374                                     modal: true,
375                                     close: function () {
376                                         $(this).remove();
377                                     }
378                             });
379                     $ajaxDialog.find('input[name^=params]').first().focus();
380                     /**
381                      * Attach the datepickers to the relevant form fields
382                      */
383                     $ajaxDialog.find('.datefield, .datetimefield').each(function () {
384                         PMA_addDatepicker($(this).css('width', '95%'));
385                     });
386                 } else {
387                     // Routine executed successfully
388                     PMA_slidingMessage(data.message);
389                 }
390             } else {
391                 PMA_ajaxShowMessage(data.error);
392             }
393         }); // end $.get()
394     }); // end $.live()
395 }); // end of $(document).ready() for the Routine Functionalities