1 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 * JavaScript functionality for Routines, Triggers and Events.
8 * @var RTE Contains all the JavaScript functionality
9 * for Routines, Triggers and Events
13 * Construct for the object that provides the
14 * functionality for Routines, Triggers and Events
16 object: function (type) {
17 $.extend(this, RTE.COMMON);
18 this.editorType = type;
22 $.extend(this, RTE.ROUTINE);
25 // nothing extra yet for triggers
28 $.extend(this, RTE.EVENT);
35 * @var string param_template Template for a row in the routine editor
41 * @var RTE.COMMON a JavaScript namespace containing the functionality
42 * for Routines, Triggers and Events
44 * This namespace is extended by the functionality required
45 * to handle a specific item (a routine, trigger or event)
46 * in the relevant javascript files in this folder
50 * @var $ajaxDialog Query object containing the reference to the
51 * dialog that contains the editor
55 * @var syntaxHiglighter Reference to the codemirror editor
57 syntaxHiglighter: null,
59 * @var buttonOptions Object containing options for
60 * the jQueryUI dialog buttons
64 * @var editorType Type of the editor
68 * Validate editor form fields.
70 validate: function () {
72 * @var $elm a jQuery object containing the reference
73 * to an element that is being validated
76 // Common validation. At the very least the name
77 // and the definition must be provided for an item
78 $elm = $('table.rte_table').last().find('input[name=item_name]');
79 if ($elm.val() === '') {
81 alert(PMA_messages.strFormEmpty);
84 $elm = $('table.rte_table').find('textarea[name=item_definition]');
85 if ($elm.val() === '') {
86 if (this.syntaxHiglighter !== null) {
87 this.syntaxHiglighter.focus();
90 $('textarea[name=item_definition]').last().focus();
92 alert(PMA_messages.strFormEmpty);
95 // The validation has so far passed, so now
96 // we can validate item-specific fields.
97 return this.validateCustom();
100 * Validate custom editor form fields.
101 * This function can be overridden by
102 * other files in this folder
104 validateCustom: function () {
106 }, // end validateCustom()
108 * Execute some code after the ajax
109 * dialog for the editor is shown.
110 * This function can be overridden by
111 * other files in this folder
113 postDialogShow: function () {
114 // Nothing by default
115 }, // end postDialogShow()
117 exportDialog: function ($this) {
118 var $msg = PMA_ajaxShowMessage();
119 if ($this.hasClass('mult_submit')) {
122 title: PMA_messages.strExport,
126 // export anchors of all selected rows
127 var export_anchors = $('input.checkall:checked').parents('tr').find('.export_anchor');
128 var count = export_anchors.length;
131 export_anchors.each(function () {
132 $.get($(this).attr('href'), {'ajax_request': true}, function (data) {
134 if (data.success === true) {
135 combined.message += "\n" + data.message + "\n";
136 if (returnCount == count) {
137 showExport(combined);
140 // complain even if one export is failing
141 combined.success = false;
142 combined.error += "\n" + data.error + "\n";
143 if (returnCount == count) {
144 showExport(combined);
150 $.get($this.attr('href'), {'ajax_request': true}, showExport);
153 function showExport(data) {
154 if (data.success === true) {
155 PMA_ajaxRemoveMessage($msg);
157 * @var button_options Object containing options
158 * for jQueryUI dialog buttons
160 var button_options = {};
161 button_options[PMA_messages.strClose] = function () {
162 $(this).dialog("close").remove();
165 * Display the dialog to the user
167 data.message = '<textarea cols="40" rows="15" style="width: 100%;">' + data.message + '</textarea>';
168 var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
170 buttons: button_options,
173 // Attach syntax highlighted editor to export dialog
175 * @var $elm jQuery object containing the reference
176 * to the Export textarea.
178 var $elm = $ajaxDialog.find('textarea');
179 PMA_getSQLEditor($elm);
181 PMA_ajaxShowMessage(data.error, false);
183 } // end showExport()
184 }, // end exportDialog()
185 editorDialog: function (is_new, $this) {
188 * @var $edit_row jQuery object containing the reference to
189 * the row of the the item being edited
190 * from the list of items
192 var $edit_row = null;
193 if ($this.hasClass('edit_anchor')) {
194 // Remeber the row of the item being edited for later,
195 // so that if the edit is successful, we can replace the
196 // row with info about the modified item.
197 $edit_row = $this.parents('tr');
200 * @var $msg jQuery object containing the reference to
201 * the AJAX message shown to the user
203 var $msg = PMA_ajaxShowMessage();
204 $.get($this.attr('href'), {'ajax_request': true}, function (data) {
205 if (data.success === true) {
206 // We have successfully fetched the editor form
207 PMA_ajaxRemoveMessage($msg);
208 // Now define the function that is called when
209 // the user presses the "Go" button
210 that.buttonOptions[PMA_messages.strGo] = function () {
211 // Move the data from the codemirror editor back to the
212 // textarea, where it can be used in the form submission.
213 if (typeof CodeMirror != 'undefined') {
214 that.syntaxHiglighter.save();
216 // Validate editor and submit request, if passed.
217 if (that.validate()) {
219 * @var data Form data to be sent in the AJAX request
221 var data = $('form.rte_form').last().serialize();
222 $msg = PMA_ajaxShowMessage(
223 PMA_messages.strProcessingRequest
225 var url = $('form.rte_form').last().attr('action');
226 $.post(url, data, function (data) {
227 if (data.success === true) {
228 // Item created successfully
229 PMA_ajaxRemoveMessage($msg);
230 PMA_slidingMessage(data.message);
231 that.$ajaxDialog.dialog('close');
232 // If we are in 'edit' mode, we must
233 // remove the reference to the old row.
234 if (mode === 'edit' && $edit_row !== null ) {
237 // Sometimes, like when moving a trigger from
238 // a table to another one, the new row should
239 // not be inserted into the list. In this case
240 // "data.insert" will be set to false.
242 // Insert the new row at the correct
243 // location in the list of items
245 * @var text Contains the name of an item from
246 * the list that is used in comparisons
247 * to find the correct location where
248 * to insert a new row.
252 * @var inserted Whether a new item has been
253 * inserted in the list or not
255 var inserted = false;
256 $('table.data').find('tr').each(function () {
264 if (text !== '' && text > data.name) {
265 $(this).before(data.new_row);
271 // If we didn't manage to insert the row yet,
272 // it must belong at the end of the list,
273 // so we insert it there.
274 $('table.data').append(data.new_row);
276 // Fade-in the new row
279 .removeClass('ajaxInsert');
280 } else if ($('table.data').find('tr').has('td').length === 0) {
281 // If we are not supposed to insert the new row,
282 // we will now check if the table is empty and
283 // needs to be hidden. This will be the case if
284 // we were editing the only item in the list,
285 // which we removed and will not be inserting
286 // something else in its place.
287 $('table.data').hide("slow", function () {
288 $('#nothing2display').show("slow");
291 // Now we have inserted the row at the correct
292 // position, but surely at least some row classes
293 // are wrong now. So we will itirate throught
294 // all rows and assign correct classes to them
296 * @var ct Count of processed rows
300 * @var rowclass Class to be attached to the row
301 * that is being processed
304 $('table.data').find('tr').has('td').each(function () {
305 rowclass = (ct % 2 === 0) ? 'odd' : 'even';
306 $(this).removeClass().addClass(rowclass);
309 // If this is the first item being added, remove
310 // the "No items" message and show the list.
311 if ($('table.data').find('tr').has('td').length > 0 &&
312 $('#nothing2display').is(':visible')
314 $('#nothing2display').hide("slow", function () {
315 $('table.data').show("slow");
318 PMA_reloadNavigation();
320 PMA_ajaxShowMessage(data.error, false);
323 } // end "if (that.validate())"
324 }; // end of function that handles the submission of the Editor
325 that.buttonOptions[PMA_messages.strClose] = function () {
326 $(this).dialog("close");
329 * Display the dialog to the user
331 that.$ajaxDialog = $('<div id="rteDialog">' + data.message + '</div>').dialog({
334 maxHeight: $(window).height(),
335 buttons: that.buttonOptions,
339 if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) {
340 $('#rteDialog').dialog("option", "height", $(window).height());
342 $(this).find('input[name=item_name]').focus();
343 $(this).find('input.datefield').each(function () {
344 PMA_addDatepicker($(this).css('width', '95%'), 'date');
346 $(this).find('input.datetimefield').each(function () {
347 PMA_addDatepicker($(this).css('width', '95%'), 'datetime');
349 $.datepicker.initialized = false;
356 * @var mode Used to remeber whether the editor is in
357 * "Edit" or "Add" mode
360 if ($('input[name=editor_process_edit]').length > 0) {
363 // Attach syntax highlighted editor to the definition
365 * @var elm jQuery object containing the reference to
366 * the Definition textarea.
368 var $elm = $('textarea[name=item_definition]').last();
369 var linterOptions = {};
370 linterOptions[that.editorType + '_editor'] = true;
371 that.syntaxHiglighter = PMA_getSQLEditor($elm, {}, null, linterOptions);
373 // Execute item-specific code
374 that.postDialogShow(data);
376 PMA_ajaxShowMessage(data.error, false);
381 dropDialog: function ($this) {
383 * @var $curr_row Object containing reference to the current row
385 var $curr_row = $this.parents('tr');
387 * @var question String containing the question to be asked for confirmation
389 var question = $('<div/>').text(
390 $curr_row.children('td').children('.drop_sql').html()
392 // We ask for confirmation first here, before submitting the ajax request
393 $this.PMA_confirm(question, $this.attr('href'), function (url) {
395 * @var msg jQuery object containing the reference to
396 * the AJAX message shown to the user
398 var $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
399 $.post(url, {'is_js_confirmed': 1, 'ajax_request': true}, function (data) {
400 if (data.success === true) {
402 * @var $table Object containing reference
403 * to the main list of elements
405 var $table = $curr_row.parent();
406 // Check how many rows will be left after we remove
407 // the one that the user has requested us to remove
408 if ($table.find('tr').length === 3) {
409 // If there are two rows left, it means that they are
410 // the header of the table and the rows that we are
411 // about to remove, so after the removal there will be
412 // nothing to show in the table, so we hide it.
413 $table.hide("slow", function () {
414 $(this).find('tr.even, tr.odd').remove();
415 $('.withSelected').remove();
416 $('#nothing2display').show("slow");
419 $curr_row.hide("slow", function () {
421 // Now we have removed the row from the list, but maybe
422 // some row classes are wrong now. So we will itirate
423 // throught all rows and assign correct classes to them.
425 * @var ct Count of processed rows
429 * @var rowclass Class to be attached to the row
430 * that is being processed
433 $table.find('tr').has('td').each(function () {
434 rowclass = (ct % 2 === 1) ? 'odd' : 'even';
435 $(this).removeClass().addClass(rowclass);
440 // Get rid of the "Loading" message
441 PMA_ajaxRemoveMessage($msg);
442 // Show the query that we just executed
443 PMA_slidingMessage(data.sql_query);
444 PMA_reloadNavigation();
446 PMA_ajaxShowMessage(data.error, false);
449 }); // end $.PMA_confirm()
452 dropMultipleDialog: function ($this) {
453 // We ask for confirmation here
454 $this.PMA_confirm(PMA_messages.strDropRTEitems, '', function (url) {
456 * @var msg jQuery object containing the reference to
457 * the AJAX message shown to the user
459 var $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
461 // drop anchors of all selected rows
462 var drop_anchors = $('input.checkall:checked').parents('tr').find('.drop_anchor');
464 var count = drop_anchors.length;
467 drop_anchors.each(function () {
468 var $anchor = $(this);
470 * @var $curr_row Object containing reference to the current row
472 var $curr_row = $anchor.parents('tr');
473 $.post($anchor.attr('href'), {'is_js_confirmed': 1, 'ajax_request': true}, function (data) {
475 if (data.success === true) {
477 * @var $table Object containing reference
478 * to the main list of elements
480 var $table = $curr_row.parent();
481 // Check how many rows will be left after we remove
482 // the one that the user has requested us to remove
483 if ($table.find('tr').length === 3) {
484 // If there are two rows left, it means that they are
485 // the header of the table and the rows that we are
486 // about to remove, so after the removal there will be
487 // nothing to show in the table, so we hide it.
488 $table.hide("slow", function () {
489 $(this).find('tr.even, tr.odd').remove();
490 $('.withSelected').remove();
491 $('#nothing2display').show("slow");
494 $curr_row.hide("fast", function () {
496 // Now we have removed the row from the list, but maybe
497 // some row classes are wrong now. So we will itirate
498 // throught all rows and assign correct classes to them.
500 * @var ct Count of processed rows
504 * @var rowclass Class to be attached to the row
505 * that is being processed
508 $table.find('tr').has('td').each(function () {
509 rowclass = (ct % 2 === 1) ? 'odd' : 'even';
510 $(this).removeClass().addClass(rowclass);
515 if (returnCount == count) {
517 // Get rid of the "Loading" message
518 PMA_ajaxRemoveMessage($msg);
519 $('#rteListForm_checkall').prop({checked: false, indeterminate: false});
521 PMA_reloadNavigation();
524 PMA_ajaxShowMessage(data.error, false);
526 if (returnCount == count) {
527 PMA_reloadNavigation();
531 }); // end drop_anchors.each()
532 }); // end $.PMA_confirm()
534 }; // end RTE namespace
537 * @var RTE.EVENT JavaScript functionality for events
540 validateCustom: function () {
542 * @var elm a jQuery object containing the reference
543 * to an element that is being validated
546 if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'RECURRING') {
547 // The interval field must not be empty for recurring events
548 $elm = this.$ajaxDialog.find('input[name=item_interval_value]');
549 if ($elm.val() === '') {
551 alert(PMA_messages.strFormEmpty);
555 // The execute_at field must not be empty for "once off" events
556 $elm = this.$ajaxDialog.find('input[name=item_execute_at]');
557 if ($elm.val() === '') {
559 alert(PMA_messages.strFormEmpty);
568 * @var RTE.ROUTINE JavaScript functionality for routines
572 * Overriding the postDialogShow() function defined in common.js
574 * @param data JSON-encoded data from the ajax request
576 postDialogShow: function (data) {
577 // Cache the template for a parameter table row
578 RTE.param_template = data.param_template;
580 // Make adjustments in the dialog to make it AJAX compatible
581 $('td.routine_param_remove').show();
582 $('input[name=routine_removeparameter]').remove();
583 $('input[name=routine_addparameter]').css('width', '100%');
584 // Enable/disable the 'options' dropdowns for parameters as necessary
585 $('table.routine_params_table').last().find('th[colspan=2]').attr('colspan', '1');
586 $('table.routine_params_table').last().find('tr').has('td').each(function () {
587 that.setOptionsForParameter(
588 $(this).find('select[name^=item_param_type]'),
589 $(this).find('input[name^=item_param_length]'),
590 $(this).find('select[name^=item_param_opts_text]'),
591 $(this).find('select[name^=item_param_opts_num]')
594 // Enable/disable the 'options' dropdowns for
595 // function return value as necessary
596 this.setOptionsForParameter(
597 $('table.rte_table').last().find('select[name=item_returntype]'),
598 $('table.rte_table').last().find('input[name=item_returnlength]'),
599 $('table.rte_table').last().find('select[name=item_returnopts_text]'),
600 $('table.rte_table').last().find('select[name=item_returnopts_num]')
602 // Allow changing parameter order
603 $('.routine_params_table tbody').sortable({
604 containment: '.routine_params_table tbody',
605 handle: '.dragHandle',
606 stop: function(event, ui) {
607 that.reindexParameters();
612 * Reindexes the parameters after dropping a parameter or reordering parameters
614 reindexParameters: function () {
616 * @var index Counter used for reindexing the input
617 * fields in the routine parameters table
620 $('table.routine_params_table tbody').find('tr').each(function () {
621 $(this).find(':input').each(function () {
623 * @var inputname The value of the name attribute of
624 * the input field being reindexed
626 var inputname = $(this).attr('name');
627 if (inputname.substr(0, 14) === 'item_param_dir') {
628 $(this).attr('name', inputname.substr(0, 14) + '[' + index + ']');
629 } else if (inputname.substr(0, 15) === 'item_param_name') {
630 $(this).attr('name', inputname.substr(0, 15) + '[' + index + ']');
631 } else if (inputname.substr(0, 15) === 'item_param_type') {
632 $(this).attr('name', inputname.substr(0, 15) + '[' + index + ']');
633 } else if (inputname.substr(0, 17) === 'item_param_length') {
634 $(this).attr('name', inputname.substr(0, 17) + '[' + index + ']');
635 $(this).attr('id', 'item_param_length_' + index);
636 } else if (inputname.substr(0, 20) === 'item_param_opts_text') {
637 $(this).attr('name', inputname.substr(0, 20) + '[' + index + ']');
638 } else if (inputname.substr(0, 19) === 'item_param_opts_num') {
639 $(this).attr('name', inputname.substr(0, 19) + '[' + index + ']');
646 * Overriding the validateCustom() function defined in common.js
648 validateCustom: function () {
650 * @var isSuccess Stores the outcome of the validation
652 var isSuccess = true;
654 * @var inputname The value of the "name" attribute for
655 * the field that is being processed
658 this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () {
659 // Every parameter of a routine must have
660 // a non-empty direction, name and type
662 $(this).find(':input').each(function () {
663 inputname = $(this).attr('name');
664 if (inputname.substr(0, 14) === 'item_param_dir' ||
665 inputname.substr(0, 15) === 'item_param_name' ||
666 inputname.substr(0, 15) === 'item_param_type') {
667 if ($(this).val() === '') {
679 alert(PMA_messages.strFormEmpty);
682 this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () {
683 // SET, ENUM, VARCHAR and VARBINARY fields must have length/values
684 var $inputtyp = $(this).find('select[name^=item_param_type]');
685 var $inputlen = $(this).find('input[name^=item_param_length]');
686 if ($inputtyp.length && $inputlen.length) {
687 if (($inputtyp.val() === 'ENUM' || $inputtyp.val() === 'SET' || $inputtyp.val().substr(0, 3) === 'VAR') &&
688 $inputlen.val() === ''
697 alert(PMA_messages.strFormEmpty);
700 if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
701 // The length/values of return variable for functions must
702 // be set, if the type is SET, ENUM, VARCHAR or VARBINARY.
703 var $returntyp = this.$ajaxDialog.find('select[name=item_returntype]');
704 var $returnlen = this.$ajaxDialog.find('input[name=item_returnlength]');
705 if (($returntyp.val() === 'ENUM' || $returntyp.val() === 'SET' || $returntyp.val().substr(0, 3) === 'VAR') &&
706 $returnlen.val() === ''
709 alert(PMA_messages.strFormEmpty);
713 if ($('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
714 // A function must contain a RETURN statement in its definition
715 if (this.$ajaxDialog.find('table.rte_table').find('textarea[name=item_definition]').val().toUpperCase().indexOf('RETURN') < 0) {
716 this.syntaxHiglighter.focus();
717 alert(PMA_messages.MissingReturn);
724 * Enable/disable the "options" dropdown and "length" input for
725 * parameters and the return variable in the routine editor
728 * @param type a jQuery object containing the reference
729 * to the "Type" dropdown box
730 * @param len a jQuery object containing the reference
731 * to the "Length" input box
732 * @param text a jQuery object containing the reference
733 * to the dropdown box with options for
734 * parameters of text type
735 * @param num a jQuery object containing the reference
736 * to the dropdown box with options for
737 * parameters of numeric type
739 setOptionsForParameter: function ($type, $len, $text, $num) {
741 * @var no_opts a jQuery object containing the reference
742 * to an element to be displayed when no
743 * options are available
745 var $no_opts = $text.parent().parent().find('.no_opts');
747 * @var no_len a jQuery object containing the reference
748 * to an element to be displayed when no
749 * "length/values" field is available
751 var $no_len = $len.parent().parent().find('.no_len');
753 // Process for parameter options
754 switch ($type.val()) {
764 $text.parent().hide();
765 $num.parent().show();
776 $text.parent().show();
777 $num.parent().hide();
781 $text.parent().hide();
782 $num.parent().hide();
786 // Process for parameter length
787 switch ($type.val()) {
799 $text.closest('tr').find('a:first').hide();
800 $len.parent().hide();
804 if ($type.val() == 'ENUM' || $type.val() == 'SET') {
805 $text.closest('tr').find('a:first').show();
807 $text.closest('tr').find('a:first').hide();
809 $len.parent().show();
814 executeDialog: function ($this) {
817 * @var msg jQuery object containing the reference to
818 * the AJAX message shown to the user
820 var $msg = PMA_ajaxShowMessage();
821 $.post($this.attr('href'), {'ajax_request': true}, function (data) {
822 if (data.success === true) {
823 PMA_ajaxRemoveMessage($msg);
824 // If 'data.dialog' is true we show a dialog with a form
825 // to get the input parameters for routine, otherwise
826 // we just show the results of the query
828 // Define the function that is called when
829 // the user presses the "Go" button
830 that.buttonOptions[PMA_messages.strGo] = function () {
832 * @var data Form data to be sent in the AJAX request
834 var data = $('form.rte_form').last().serialize();
835 $msg = PMA_ajaxShowMessage(
836 PMA_messages.strProcessingRequest
838 $.post('db_routines.php', data, function (data) {
839 if (data.success === true) {
840 // Routine executed successfully
841 PMA_ajaxRemoveMessage($msg);
842 PMA_slidingMessage(data.message);
843 $ajaxDialog.dialog('close');
845 PMA_ajaxShowMessage(data.error, false);
849 that.buttonOptions[PMA_messages.strClose] = function () {
850 $(this).dialog("close");
853 * Display the dialog to the user
855 var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
857 buttons: that.buttonOptions,
864 $ajaxDialog.find('input[name^=params]').first().focus();
866 * Attach the datepickers to the relevant form fields
868 $ajaxDialog.find('input.datefield, input.datetimefield').each(function () {
869 PMA_addDatepicker($(this).css('width', '95%'));
872 * Define the function if the user presses enter
874 $('form.rte_form').on('keyup', function (event) {
875 event.preventDefault();
876 if (event.keyCode === 13) {
878 * @var data Form data to be sent in the AJAX request
880 var data = $(this).serialize();
881 $msg = PMA_ajaxShowMessage(
882 PMA_messages.strProcessingRequest
884 var url = $(this).attr('action');
885 $.post(url, data, function (data) {
886 if (data.success === true) {
887 // Routine executed successfully
888 PMA_ajaxRemoveMessage($msg);
889 PMA_slidingMessage(data.message);
890 $('form.rte_form').off('keyup');
891 $ajaxDialog.remove();
893 PMA_ajaxShowMessage(data.error, false);
899 // Routine executed successfully
900 PMA_slidingMessage(data.message);
903 PMA_ajaxShowMessage(data.error, false);
910 * Attach Ajax event handlers for the Routines, Triggers and Events editor
914 * Attach Ajax event handlers for the Add/Edit functionality.
916 $(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) {
917 event.preventDefault();
918 var type = $(this).attr('href').substr(0, $(this).attr('href').indexOf('?'));
919 if (type.indexOf('routine') != -1) {
921 } else if (type.indexOf('trigger') != -1) {
923 } else if (type.indexOf('event') != -1) {
928 var dialog = new RTE.object(type);
929 dialog.editorDialog($(this).hasClass('add_anchor'), $(this));
930 }); // end $(document).on()
933 * Attach Ajax event handlers for the Execute routine functionality
935 $(document).on('click', 'a.ajax.exec_anchor', function (event) {
936 event.preventDefault();
937 var dialog = new RTE.object('routine');
938 dialog.executeDialog($(this));
939 }); // end $(document).on()
942 * Attach Ajax event handlers for Export of Routines, Triggers and Events
944 $(document).on('click', 'a.ajax.export_anchor', function (event) {
945 event.preventDefault();
946 var dialog = new RTE.object();
947 dialog.exportDialog($(this));
948 }); // end $(document).on()
950 $(document).on('click', '#rteListForm.ajax .mult_submit[value="export"]', function (event) {
951 event.preventDefault();
952 var dialog = new RTE.object();
953 dialog.exportDialog($(this));
954 }); // end $(document).on()
957 * Attach Ajax event handlers for Drop functionality
958 * of Routines, Triggers and Events.
960 $(document).on('click', 'a.ajax.drop_anchor', function (event) {
961 event.preventDefault();
962 var dialog = new RTE.object();
963 dialog.dropDialog($(this));
964 }); // end $(document).on()
966 $(document).on('click', '#rteListForm.ajax .mult_submit[value="drop"]', function (event) {
967 event.preventDefault();
968 var dialog = new RTE.object();
969 dialog.dropMultipleDialog($(this));
970 }); // end $(document).on()
973 * Attach Ajax event handlers for the "Change event/routine type"
974 * functionality in the events editor, so that the correct
975 * rows are shown in the editor when changing the event type
977 $(document).on('change', 'select[name=item_type]', function () {
980 .find('tr.recurring_event_row, tr.onetime_event_row, tr.routine_return_row, .routine_direction_cell')
982 }); // end $(document).on()
985 * Attach Ajax event handlers for the "Change parameter type"
986 * functionality in the routines editor, so that the correct
987 * option/length fields, if any, are shown when changing
990 $(document).on('change', 'select[name^=item_param_type]', function () {
992 * @var row jQuery object containing the reference to
993 * a row in the routine parameters table
995 var $row = $(this).parents('tr').first();
996 var rte = new RTE.object('routine');
997 rte.setOptionsForParameter(
998 $row.find('select[name^=item_param_type]'),
999 $row.find('input[name^=item_param_length]'),
1000 $row.find('select[name^=item_param_opts_text]'),
1001 $row.find('select[name^=item_param_opts_num]')
1003 }); // end $(document).on()
1006 * Attach Ajax event handlers for the "Change the type of return
1007 * variable of function" functionality, so that the correct fields,
1008 * if any, are shown when changing the function return type type
1010 $(document).on('change', 'select[name=item_returntype]', function () {
1011 var rte = new RTE.object('routine');
1012 var $table = $(this).closest('table.rte_table');
1013 rte.setOptionsForParameter(
1014 $table.find('select[name=item_returntype]'),
1015 $table.find('input[name=item_returnlength]'),
1016 $table.find('select[name=item_returnopts_text]'),
1017 $table.find('select[name=item_returnopts_num]')
1019 }); // end $(document).on()
1022 * Attach Ajax event handlers for the "Add parameter to routine" functionality
1024 $(document).on('click', 'input[name=routine_addparameter]', function (event) {
1025 event.preventDefault();
1027 * @var routine_params_table jQuery object containing the reference
1028 * to the routine parameters table
1030 var $routine_params_table = $(this).closest('div.ui-dialog').find('.routine_params_table');
1032 * @var new_param_row A string containing the HTML code for the
1033 * new row for the routine parameters table
1035 var new_param_row = RTE.param_template.replace(/%s/g, $routine_params_table.find('tr').length - 1);
1036 // Append the new row to the parameters table
1037 $routine_params_table.append(new_param_row);
1038 // Make sure that the row is correctly shown according to the type of routine
1039 if ($(this).closest('div.ui-dialog').find('table.rte_table select[name=item_type]').val() === 'FUNCTION') {
1040 $('tr.routine_return_row').show();
1041 $('td.routine_direction_cell').hide();
1044 * @var newrow jQuery object containing the reference to the newly
1045 * inserted row in the routine parameters table
1047 var $newrow = $(this).closest('div.ui-dialog').find('table.routine_params_table').find('tr').has('td').last();
1048 // Enable/disable the 'options' dropdowns for parameters as necessary
1049 var rte = new RTE.object('routine');
1050 rte.setOptionsForParameter(
1051 $newrow.find('select[name^=item_param_type]'),
1052 $newrow.find('input[name^=item_param_length]'),
1053 $newrow.find('select[name^=item_param_opts_text]'),
1054 $newrow.find('select[name^=item_param_opts_num]')
1056 }); // end $(document).on()
1059 * Attach Ajax event handlers for the
1060 * "Remove parameter from routine" functionality
1062 $(document).on('click', 'a.routine_param_remove_anchor', function (event) {
1063 event.preventDefault();
1064 $(this).parent().parent().remove();
1065 // After removing a parameter, the indices of the name attributes in
1066 // the input fields lose the correct order and need to be reordered.
1067 RTE.ROUTINE.reindexParameters();
1068 }); // end $(document).on()