Modified the 'How to use?' message for info about mousewheel zoom and panning feature
[phpmyadmin/ammaryasirr.git] / js / rte / common.js
blob4e3893e5c0ff23705fbcd87ab92017fb16967192
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4  * @var    RTE    a JavaScript namespace containing the functionality
5  *                for Routines, Triggers and Events.
6  *
7  *                This namespace is extended by the functionality required
8  *                to handle a specific item (a routine, trigger or event)
9  *                in the relevant javascript files in this folder.
10  */
11 var RTE = {
12     /**
13      * @var    $ajaxDialog        jQuery object containing the reference to the
14      *                            dialog that contains the editor.
15      */
16     $ajaxDialog: null,
17     /**
18      * @var    syntaxHiglighter   Reference to the codemirror editor.
19      */
20     syntaxHiglighter: null,
21     /**
22      * @var    buttonOptions      Object containing options for
23      *                            the jQueryUI dialog buttons
24      */
25     buttonOptions: {},
26     /**
27      * Validate editor form fields.
28      */
29     validate: function () {
30         /**
31          * @var    $elm    a jQuery object containing the reference
32          *                 to an element that is being validated.
33          */
34         var $elm = null;
35         // Common validation. At the very least the name
36         // and the definition must be provided for an item
37         $elm = $('.rte_table').last().find('input[name=item_name]');
38         if ($elm.val() === '') {
39             $elm.focus();
40             alert(PMA_messages['strFormEmpty']);
41             return false;
42         }
43         $elm = $('.rte_table').find('textarea[name=item_definition]');
44         if ($elm.val() === '') {
45             this.syntaxHiglighter.focus();
46             alert(PMA_messages['strFormEmpty']);
47             return false;
48         }
49         // The validation has so far passed, so now
50         // we can validate item-specific fields.
51         return RTE.validateCustom();
52     }, // end validate()
53     /**
54      * Validate custom editor form fields.
55      * This function can be overridden by
56      * other files in this folder.
57      */
58     validateCustom: function () {
59         return true;
60     }, // end validateCustom()
61     /**
62      * Execute some code after the ajax
63      * dialog for the ditor is shown.
64      * This function can be overridden by
65      * other files in this folder.
66      */
67     postDialogShow: function () {
68         // Nothing by default
69     } // end postDialogShow()
70 }; // end RTE namespace
72 /**
73  * Attach Ajax event handlers for the Routines, Triggers and Events editor.
74  *
75  * @see $cfg['AjaxEnable']
76  */
77 $(document).ready(function () {
78     /**
79      * Attach Ajax event handlers for the Add/Edit functionality.
80      */
81     $('.ajax_add_anchor, .ajax_edit_anchor').live('click', function (event) {
82         event.preventDefault();
83         /**
84          * @var    $edit_row    jQuery object containing the reference to
85          *                      the row of the the item being edited
86          *                      from the list of items .
87          */
88         var $edit_row = null;
89         if ($(this).hasClass('ajax_edit_anchor')) {
90             // Remeber the row of the item being edited for later,
91             // so that if the edit is successful, we can replace the
92             // row with info about the modified item.
93             $edit_row = $(this).parents('tr');
94         }
95         /**
96          * @var    $msg    jQuery object containing the reference to
97          *                 the AJAX message shown to the user.
98          */
99         var $msg = PMA_ajaxShowMessage();
100         $.get($(this).attr('href'), {'ajax_request': true}, function (data) {
101             if (data.success === true) {
102                 // We have successfully fetched the editor form
103                 PMA_ajaxRemoveMessage($msg);
104                 // Now define the function that is called when
105                 // the user presses the "Go" button
106                 RTE.buttonOptions[PMA_messages['strGo']] = function () {
107                     // Move the data from the codemirror editor back to the
108                     // textarea, where it can be used in the form submission.
109                     RTE.syntaxHiglighter.save();
110                     // Validate editor and submit request, if passed.
111                     if (RTE.validate()) {
112                         /**
113                          * @var    data    Form data to be sent in the AJAX request.
114                          */
115                         var data = $('.rte_form').last().serialize();
116                         $msg = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
117                         $.post($('.rte_form').last().attr('action'), data, function (data) {
118                             if (data.success === true) {
119                                 // Item created successfully
120                                 PMA_ajaxRemoveMessage($msg);
121                                 PMA_slidingMessage(data.message);
122                                 RTE.$ajaxDialog.dialog('close');
123                                 // If we are in 'edit' mode, we must remove the reference to the old row.
124                                 if (mode === 'edit') {
125                                     $edit_row.remove();
126                                 }
127                                 // Sometimes, like when moving a trigger from a table to
128                                 // another one, the new row should not be inserted into the
129                                 // list. In this case "data.insert" will be set to false.
130                                 if (data.insert) {
131                                     // Insert the new row at the correct location in the list of items
132                                     /**
133                                      * @var    text    Contains the name of an item from the list
134                                      *                 that is used in comparisons to find the correct
135                                      *                 location where to insert a new row.
136                                      */
137                                     var text = '';
138                                     /**
139                                      * @var    inserted    Whether a new item has been inserted
140                                      *                     in the list or not.
141                                      */
142                                     var inserted = false;
143                                     $('table.data').find('tr').each(function () {
144                                         text = $(this)
145                                                 .children('td')
146                                                 .eq(0)
147                                                 .find('strong')
148                                                 .text()
149                                                 .toUpperCase();
150                                         text = $.trim(text);
151                                         if (text !== '' && text > data.name) {
152                                             $(this).before(data.new_row);
153                                             inserted = true;
154                                             return false;
155                                         }
156                                     });
157                                     if (! inserted) {
158                                         // If we didn't manage to insert the row yet,
159                                         // it must belong at the end of the list,
160                                         // so we insert it there.
161                                         $('table.data').append(data.new_row);
162                                     }
163                                     // Fade-in the new row
164                                     $('.ajaxInsert').show('slow').removeClass('ajaxInsert');
165                                 } else if ($('table.data').find('tr').has('td').length === 0) {
166                                     // If we are not supposed to insert the new row, we will now
167                                     // check if the table is empty and needs to be hidden. This
168                                     // will be the case if we were editing the only item in the
169                                     // list, which we removed and will not be inserting something
170                                     // else in its place.
171                                     $('table.data').hide("slow", function () {
172                                         $('#nothing2display').show("slow");
173                                     });
174                                 }
175                                 // Now we have inserted the row at the correct position, but surely
176                                 // at least some row classes are wrong now. So we will itirate
177                                 // throught all rows and assign correct classes to them.
178                                 /**
179                                  * @var    ct          Count of processed rows.
180                                  */
181                                 var ct = 0;
182                                 /**
183                                  * @var    rowclass    Class to be attached to the row
184                                  *                     that is being processed
185                                  */
186                                 var rowclass = '';
187                                 $('table.data').find('tr').has('td').each(function () {
188                                     rowclass = (ct % 2 === 0) ? 'even' : 'odd';
189                                     $(this).removeClass().addClass(rowclass);
190                                     ct++;
191                                 });
192                                 // If this is the first item being added, remove
193                                 // the "No items" message and show the list.
194                                 if ($('table.data').find('tr').has('td').length > 0
195                                     && $('#nothing2display').is(':visible')) {
196                                     $('#nothing2display').hide("slow", function () {
197                                         $('table.data').show("slow");
198                                     });
199                                 }
200                             } else {
201                                 PMA_ajaxShowMessage(data.error);
202                             }
203                         }); // end $.post()
204                     } // end "if (RTE.validate())"
205                 }; // end of function that handles the submission of the Editor
206                 RTE.buttonOptions[PMA_messages['strClose']] = function () {
207                     $(this).dialog("close");
208                 };
209                 /**
210                  * Display the dialog to the user
211                  */
212                 RTE.$ajaxDialog = $('<div>' + data.message + '</div>').dialog({
213                                 width: 700,
214                                 height: 555,
215                                 buttons: RTE.buttonOptions,
216                                 title: data.title,
217                                 modal: true,
218                                 close: function () {
219                                     $(this).remove();
220                                 }
221                         });
222                 RTE.$ajaxDialog.find('input[name=item_name]').focus();
223                 RTE.$ajaxDialog.find('.datefield, .datetimefield').each(function () {
224                     PMA_addDatepicker($(this).css('width', '95%'));
225                 });
226                 /**
227                  * @var    mode    Used to remeber whether the editor is in
228                  *                 "Edit" or "Add" mode.
229                  */
230                 var mode = 'add';
231                 if ($('input[name=editor_process_edit]').length > 0) {
232                     mode = 'edit';
233                 }
234                 // Attach syntax highlited editor to the definition
235                 /**
236                  * @var    $elm    jQuery object containing the reference to
237                  *                 the Definition textarea.
238                  */
239                 var $elm = $('textarea[name=item_definition]').last();
240                 /**
241                  * @var    opts    Options to pass to the codemirror editor.
242                  */
243                 var opts = {lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: "text/x-mysql"};
244                 RTE.syntaxHiglighter = CodeMirror.fromTextArea($elm[0], opts);
245                 // Hack to prevent the syntax highlighter from expanding beyond dialog boundries
246                 $('.CodeMirror-scroll').find('div').first().css('width', '1px');
247                 // Execute item-specific code
248                 RTE.postDialogShow(data);
249             } else {
250                 PMA_ajaxShowMessage(data.error);
251             }
252         }); // end $.get()
253     }); // end $.live()
255     /**
256      * Attach Ajax event handlers for input fields in the editor
257      * and the routine execution dialog used to submit the Ajax
258      * request when the ENTER key is pressed.
259      */
260     $('.rte_table').find('input[name^=item], input[name^=params]').live('keydown', function (e) {
261         if (e.which === 13) { // 13 is the ENTER key
262             e.preventDefault();
263             if (typeof RTE.buttonOptions[PMA_messages['strGo']] === 'function') {
264                 RTE.buttonOptions[PMA_messages['strGo']].call();
265             }
266         }
267     }); // end $.live()
269     /**
270      * Attach Ajax event handlers for Export of Routines, Triggers and Events.
271      */
272     $('.ajax_export_anchor').live('click', function (event) {
273         event.preventDefault();
274         var $msg = PMA_ajaxShowMessage();
275         // Fire the ajax request straight away
276         $.get($(this).attr('href'), {'ajax_request': true}, function (data) {
277             if (data.success === true) {
278                 PMA_ajaxRemoveMessage($msg);
279                 /**
280                  * @var button_options  Object containing options for jQueryUI dialog buttons
281                  */
282                 var button_options = {};
283                 button_options[PMA_messages['strClose']] = function () {
284                     $(this).dialog("close").remove();
285                 };
286                 /**
287                  * Display the dialog to the user
288                  */
289                 var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
290                                       width: 500,
291                                       buttons: button_options,
292                                       title: data.title
293                                   });
294                 // Attach syntax highlited editor to export dialog
295                 /**
296                  * @var    $elm    jQuery object containing the reference
297                  *                 to the Export textarea.
298                  */
299                 var $elm = $ajaxDialog.find('textarea');
300                 /**
301                  * @var    opts    Options to pass to the codemirror editor.
302                  */
303                 var opts = {lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: "text/x-mysql"};
304                 CodeMirror.fromTextArea($elm[0], opts);
305             } else {
306                 PMA_ajaxShowMessage(data.error);
307             }
308         }); // end $.get()
309     }); // end $.live()
311     /**
312      * Attach Ajax event handlers for Drop functionality of Routines, Triggers and Events.
313      */
314     $('.ajax_drop_anchor').live('click', function (event) {
315         event.preventDefault();
316         /**
317          * @var $curr_row    Object containing reference to the current row
318          */
319         var $curr_row = $(this).parents('tr');
320         /**
321          * @var question    String containing the question to be asked for confirmation
322          */
323         var question = $('<div></div>').text($curr_row.children('td').children('.drop_sql').html());
324         // We ask for confirmation first here, before submitting the ajax request
325         $(this).PMA_confirm(question, $(this).attr('href'), function (url) {
326             /**
327              * @var    $msg    jQuery object containing the reference to
328              *                 the AJAX message shown to the user.
329              */
330             var $msg = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
331             $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function (data) {
332                 if (data.success === true) {
333                     /**
334                      * @var $table    Object containing reference to the main list of elements.
335                      */
336                     var $table = $curr_row.parent();
337                     // Check how many rows will be left after we remove
338                     // the one that the user has requested us to remove
339                     if ($table.find('tr').length === 2) {
340                         // If there are two rows left, it means that they are
341                         // the header of the table and the rows that we are
342                         // about to remove, so after the removal there will be
343                         // nothing to show in the table, so we hide it.
344                         $table.hide("slow", function () {
345                             $(this).find('tr.even, tr.odd').remove();
346                             $('#nothing2display').show("slow");
347                         });
348                     } else {
349                         $curr_row.hide("slow", function () {
350                             $(this).remove();
351                             // Now we have removed the row from the list, but maybe
352                             // some row classes are wrong now. So we will itirate
353                             // throught all rows and assign correct classes to them.
354                             /**
355                              * @var    ct          Count of processed rows.
356                              */
357                             var ct = 0;
358                             /**
359                              * @var    rowclass    Class to be attached to the row
360                              *                     that is being processed
361                              */
362                             var rowclass = '';
363                             $table.find('tr').has('td').each(function () {
364                                 rowclass = (ct % 2 === 0) ? 'even' : 'odd';
365                                 $(this).removeClass().addClass(rowclass);
366                                 ct++;
367                             });
368                         });
369                     }
370                     // Get rid of the "Loading" message
371                     PMA_ajaxRemoveMessage($msg);
372                     // Show the query that we just executed
373                     PMA_slidingMessage(data.sql_query);
374                 } else {
375                     PMA_ajaxShowMessage(PMA_messages['strErrorProcessingRequest'] + " : " + data.error);
376                 }
377             }); // end $.get()
378         }); // end $.PMA_confirm()
379     }); // end $.live()
380 }); // end of $(document).ready()