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);
20 $.extend(this, RTE.ROUTINE);
23 // nothing extra yet for triggers
26 $.extend(this, RTE.EVENT);
33 * @var string param_template Template for a row in the routine editor
39 * @var RTE.COMMON a JavaScript namespace containing the functionality
40 * for Routines, Triggers and Events
42 * This namespace is extended by the functionality required
43 * to handle a specific item (a routine, trigger or event)
44 * in the relevant javascript files in this folder
48 * @var $ajaxDialog Query object containing the reference to the
49 * dialog that contains the editor
53 * @var syntaxHiglighter Reference to the codemirror editor
55 syntaxHiglighter: null,
57 * @var buttonOptions Object containing options for
58 * the jQueryUI dialog buttons
62 * Validate editor form fields.
64 validate: function () {
66 * @var $elm a jQuery object containing the reference
67 * to an element that is being validated
70 // Common validation. At the very least the name
71 // and the definition must be provided for an item
72 $elm = $('table.rte_table').last().find('input[name=item_name]');
73 if ($elm.val() === '') {
75 alert(PMA_messages.strFormEmpty);
78 $elm = $('table.rte_table').find('textarea[name=item_definition]');
79 if ($elm.val() === '') {
80 if (this.syntaxHiglighter !== null) {
81 this.syntaxHiglighter.focus();
84 $('textarea[name=item_definition]').last().focus();
86 alert(PMA_messages.strFormEmpty);
89 // The validation has so far passed, so now
90 // we can validate item-specific fields.
91 return this.validateCustom();
94 * Validate custom editor form fields.
95 * This function can be overridden by
96 * other files in this folder
98 validateCustom: function () {
100 }, // end validateCustom()
102 * Execute some code after the ajax
103 * dialog for the editor is shown.
104 * This function can be overridden by
105 * other files in this folder
107 postDialogShow: function () {
108 // Nothing by default
109 }, // end postDialogShow()
111 exportDialog: function ($this) {
112 var $msg = PMA_ajaxShowMessage();
113 if ($this.hasClass('mult_submit')) {
116 title: PMA_messages.strExport,
120 // export anchors of all selected rows
121 var export_anchors = $('input.checkall:checked').parents('tr').find('.export_anchor');
122 var count = export_anchors.length;
125 export_anchors.each(function () {
126 $.get($(this).attr('href'), {'ajax_request': true}, function (data) {
128 if (data.success === true) {
129 combined.message += "\n" + data.message + "\n";
130 if (returnCount == count) {
131 showExport(combined);
134 // complain even if one export is failing
135 combined.success = false;
136 combined.error += "\n" + data.error + "\n";
137 if (returnCount == count) {
138 showExport(combined);
144 $.get($this.attr('href'), {'ajax_request': true}, showExport);
147 function showExport(data) {
148 if (data.success === true) {
149 PMA_ajaxRemoveMessage($msg);
151 * @var button_options Object containing options
152 * for jQueryUI dialog buttons
154 var button_options = {};
155 button_options[PMA_messages.strClose] = function () {
156 $(this).dialog("close").remove();
159 * Display the dialog to the user
161 data.message = '<textarea cols="40" rows="15" style="width: 100%;">' + data.message + '</textarea>';
162 var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
164 buttons: button_options,
167 // Attach syntax highlighted editor to export dialog
169 * @var $elm jQuery object containing the reference
170 * to the Export textarea.
172 var $elm = $ajaxDialog.find('textarea');
173 PMA_getSQLEditor($elm);
175 PMA_ajaxShowMessage(data.error, false);
177 } // end showExport()
178 }, // end exportDialog()
179 editorDialog: function (is_new, $this) {
182 * @var $edit_row jQuery object containing the reference to
183 * the row of the the item being edited
184 * from the list of items
186 var $edit_row = null;
187 if ($this.hasClass('edit_anchor')) {
188 // Remeber the row of the item being edited for later,
189 // so that if the edit is successful, we can replace the
190 // row with info about the modified item.
191 $edit_row = $this.parents('tr');
194 * @var $msg jQuery object containing the reference to
195 * the AJAX message shown to the user
197 var $msg = PMA_ajaxShowMessage();
198 $.get($this.attr('href'), {'ajax_request': true}, function (data) {
199 if (data.success === true) {
200 // We have successfully fetched the editor form
201 PMA_ajaxRemoveMessage($msg);
202 // Now define the function that is called when
203 // the user presses the "Go" button
204 that.buttonOptions[PMA_messages.strGo] = function () {
205 // Move the data from the codemirror editor back to the
206 // textarea, where it can be used in the form submission.
207 if (typeof CodeMirror != 'undefined') {
208 that.syntaxHiglighter.save();
210 // Validate editor and submit request, if passed.
211 if (that.validate()) {
213 * @var data Form data to be sent in the AJAX request
215 var data = $('form.rte_form').last().serialize();
216 $msg = PMA_ajaxShowMessage(
217 PMA_messages.strProcessingRequest
219 var url = $('form.rte_form').last().attr('action');
220 $.post(url, data, function (data) {
221 if (data.success === true) {
222 // Item created successfully
223 PMA_ajaxRemoveMessage($msg);
224 PMA_slidingMessage(data.message);
225 that.$ajaxDialog.dialog('close');
226 // If we are in 'edit' mode, we must
227 // remove the reference to the old row.
228 if (mode === 'edit' && $edit_row !== null ) {
231 // Sometimes, like when moving a trigger from
232 // a table to another one, the new row should
233 // not be inserted into the list. In this case
234 // "data.insert" will be set to false.
236 // Insert the new row at the correct
237 // location in the list of items
239 * @var text Contains the name of an item from
240 * the list that is used in comparisons
241 * to find the correct location where
242 * to insert a new row.
246 * @var inserted Whether a new item has been
247 * inserted in the list or not
249 var inserted = false;
250 $('table.data').find('tr').each(function () {
258 if (text !== '' && text > data.name) {
259 $(this).before(data.new_row);
265 // If we didn't manage to insert the row yet,
266 // it must belong at the end of the list,
267 // so we insert it there.
268 $('table.data').append(data.new_row);
270 // Fade-in the new row
273 .removeClass('ajaxInsert');
274 } else if ($('table.data').find('tr').has('td').length === 0) {
275 // If we are not supposed to insert the new row,
276 // we will now check if the table is empty and
277 // needs to be hidden. This will be the case if
278 // we were editing the only item in the list,
279 // which we removed and will not be inserting
280 // something else in its place.
281 $('table.data').hide("slow", function () {
282 $('#nothing2display').show("slow");
285 // Now we have inserted the row at the correct
286 // position, but surely at least some row classes
287 // are wrong now. So we will itirate throught
288 // all rows and assign correct classes to them
290 * @var ct Count of processed rows
294 * @var rowclass Class to be attached to the row
295 * that is being processed
298 $('table.data').find('tr').has('td').each(function () {
299 rowclass = (ct % 2 === 0) ? 'odd' : 'even';
300 $(this).removeClass().addClass(rowclass);
303 // If this is the first item being added, remove
304 // the "No items" message and show the list.
305 if ($('table.data').find('tr').has('td').length > 0 &&
306 $('#nothing2display').is(':visible')
308 $('#nothing2display').hide("slow", function () {
309 $('table.data').show("slow");
312 PMA_reloadNavigation();
314 PMA_ajaxShowMessage(data.error, false);
317 } // end "if (that.validate())"
318 }; // end of function that handles the submission of the Editor
319 that.buttonOptions[PMA_messages.strClose] = function () {
320 $(this).dialog("close");
323 * Display the dialog to the user
325 that.$ajaxDialog = $('<div id="rteDialog">' + data.message + '</div>').dialog({
328 maxHeight: $(window).height(),
329 buttons: that.buttonOptions,
333 if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) {
334 $('#rteDialog').dialog("option", "height", $(window).height());
336 $(this).find('input[name=item_name]').focus();
337 $(this).find('input.datefield').each(function () {
338 PMA_addDatepicker($(this).css('width', '95%'), 'date');
340 $(this).find('input.datetimefield').each(function () {
341 PMA_addDatepicker($(this).css('width', '95%'), 'datetime');
343 $.datepicker.initialized = false;
350 * @var mode Used to remeber whether the editor is in
351 * "Edit" or "Add" mode
354 if ($('input[name=editor_process_edit]').length > 0) {
357 // Attach syntax highlighted editor to the definition
359 * @var elm jQuery object containing the reference to
360 * the Definition textarea.
362 var $elm = $('textarea[name=item_definition]').last();
363 that.syntaxHiglighter = PMA_getSQLEditor($elm);
365 // Execute item-specific code
366 that.postDialogShow(data);
368 PMA_ajaxShowMessage(data.error, false);
373 dropDialog: function ($this) {
375 * @var $curr_row Object containing reference to the current row
377 var $curr_row = $this.parents('tr');
379 * @var question String containing the question to be asked for confirmation
381 var question = $('<div/>').text(
382 $curr_row.children('td').children('.drop_sql').html()
384 // We ask for confirmation first here, before submitting the ajax request
385 $this.PMA_confirm(question, $this.attr('href'), function (url) {
387 * @var msg jQuery object containing the reference to
388 * the AJAX message shown to the user
390 var $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
391 $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function (data) {
392 if (data.success === true) {
394 * @var $table Object containing reference
395 * to the main list of elements
397 var $table = $curr_row.parent();
398 // Check how many rows will be left after we remove
399 // the one that the user has requested us to remove
400 if ($table.find('tr').length === 3) {
401 // If there are two rows left, it means that they are
402 // the header of the table and the rows that we are
403 // about to remove, so after the removal there will be
404 // nothing to show in the table, so we hide it.
405 $table.hide("slow", function () {
406 $(this).find('tr.even, tr.odd').remove();
407 $('.withSelected').remove();
408 $('#nothing2display').show("slow");
411 $curr_row.hide("slow", function () {
413 // Now we have removed the row from the list, but maybe
414 // some row classes are wrong now. So we will itirate
415 // throught all rows and assign correct classes to them.
417 * @var ct Count of processed rows
421 * @var rowclass Class to be attached to the row
422 * that is being processed
425 $table.find('tr').has('td').each(function () {
426 rowclass = (ct % 2 === 1) ? 'odd' : 'even';
427 $(this).removeClass().addClass(rowclass);
432 // Get rid of the "Loading" message
433 PMA_ajaxRemoveMessage($msg);
434 // Show the query that we just executed
435 PMA_slidingMessage(data.sql_query);
436 PMA_reloadNavigation();
438 PMA_ajaxShowMessage(data.error, false);
441 }); // end $.PMA_confirm()
444 dropMultipleDialog: function ($this) {
445 // We ask for confirmation here
446 $this.PMA_confirm(PMA_messages.strDropRTEitems, '', function (url) {
448 * @var msg jQuery object containing the reference to
449 * the AJAX message shown to the user
451 var $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
453 // drop anchors of all selected rows
454 var drop_anchors = $('input.checkall:checked').parents('tr').find('.drop_anchor');
456 var count = drop_anchors.length;
459 drop_anchors.each(function () {
460 var $anchor = $(this);
462 * @var $curr_row Object containing reference to the current row
464 var $curr_row = $anchor.parents('tr');
465 $.get($anchor.attr('href'), {'is_js_confirmed': 1, 'ajax_request': true}, function (data) {
467 if (data.success === true) {
469 * @var $table Object containing reference
470 * to the main list of elements
472 var $table = $curr_row.parent();
473 // Check how many rows will be left after we remove
474 // the one that the user has requested us to remove
475 if ($table.find('tr').length === 3) {
476 // If there are two rows left, it means that they are
477 // the header of the table and the rows that we are
478 // about to remove, so after the removal there will be
479 // nothing to show in the table, so we hide it.
480 $table.hide("slow", function () {
481 $(this).find('tr.even, tr.odd').remove();
482 $('.withSelected').remove();
483 $('#nothing2display').show("slow");
486 $curr_row.hide("fast", function () {
488 // Now we have removed the row from the list, but maybe
489 // some row classes are wrong now. So we will itirate
490 // throught all rows and assign correct classes to them.
492 * @var ct Count of processed rows
496 * @var rowclass Class to be attached to the row
497 * that is being processed
500 $table.find('tr').has('td').each(function () {
501 rowclass = (ct % 2 === 1) ? 'odd' : 'even';
502 $(this).removeClass().addClass(rowclass);
507 if (returnCount == count) {
509 // Get rid of the "Loading" message
510 PMA_ajaxRemoveMessage($msg);
511 $('#rteListForm_checkall').prop({checked: false, indeterminate: false});
513 PMA_reloadNavigation();
516 PMA_ajaxShowMessage(data.error, false);
518 if (returnCount == count) {
519 PMA_reloadNavigation();
523 }); // end drop_anchors.each()
524 }); // end $.PMA_confirm()
526 }; // end RTE namespace
529 * @var RTE.EVENT JavaScript functionality for events
532 validateCustom: function () {
534 * @var elm a jQuery object containing the reference
535 * to an element that is being validated
538 if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'RECURRING') {
539 // The interval field must not be empty for recurring events
540 $elm = this.$ajaxDialog.find('input[name=item_interval_value]');
541 if ($elm.val() === '') {
543 alert(PMA_messages.strFormEmpty);
547 // The execute_at field must not be empty for "once off" events
548 $elm = this.$ajaxDialog.find('input[name=item_execute_at]');
549 if ($elm.val() === '') {
551 alert(PMA_messages.strFormEmpty);
560 * @var RTE.ROUTINE JavaScript functionality for routines
564 * Overriding the postDialogShow() function defined in common.js
566 * @param data JSON-encoded data from the ajax request
568 postDialogShow: function (data) {
569 // Cache the template for a parameter table row
570 RTE.param_template = data.param_template;
572 // Make adjustments in the dialog to make it AJAX compatible
573 $('td.routine_param_remove').show();
574 $('input[name=routine_removeparameter]').remove();
575 $('input[name=routine_addparameter]').css('width', '100%');
576 // Enable/disable the 'options' dropdowns for parameters as necessary
577 $('table.routine_params_table').last().find('th[colspan=2]').attr('colspan', '1');
578 $('table.routine_params_table').last().find('tr').has('td').each(function () {
579 that.setOptionsForParameter(
580 $(this).find('select[name^=item_param_type]'),
581 $(this).find('input[name^=item_param_length]'),
582 $(this).find('select[name^=item_param_opts_text]'),
583 $(this).find('select[name^=item_param_opts_num]')
586 // Enable/disable the 'options' dropdowns for
587 // function return value as necessary
588 this.setOptionsForParameter(
589 $('table.rte_table').last().find('select[name=item_returntype]'),
590 $('table.rte_table').last().find('input[name=item_returnlength]'),
591 $('table.rte_table').last().find('select[name=item_returnopts_text]'),
592 $('table.rte_table').last().find('select[name=item_returnopts_num]')
596 * Overriding the validateCustom() function defined in common.js
598 validateCustom: function () {
600 * @var isSuccess Stores the outcome of the validation
602 var isSuccess = true;
604 * @var inputname The value of the "name" attribute for
605 * the field that is being processed
608 this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () {
609 // Every parameter of a routine must have
610 // a non-empty direction, name and type
612 $(this).find(':input').each(function () {
613 inputname = $(this).attr('name');
614 if (inputname.substr(0, 14) === 'item_param_dir' ||
615 inputname.substr(0, 15) === 'item_param_name' ||
616 inputname.substr(0, 15) === 'item_param_type') {
617 if ($(this).val() === '') {
629 alert(PMA_messages.strFormEmpty);
632 this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () {
633 // SET, ENUM, VARCHAR and VARBINARY fields must have length/values
634 var $inputtyp = $(this).find('select[name^=item_param_type]');
635 var $inputlen = $(this).find('input[name^=item_param_length]');
636 if ($inputtyp.length && $inputlen.length) {
637 if (($inputtyp.val() === 'ENUM' || $inputtyp.val() === 'SET' || $inputtyp.val().substr(0, 3) === 'VAR') &&
638 $inputlen.val() === ''
647 alert(PMA_messages.strFormEmpty);
650 if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
651 // The length/values of return variable for functions must
652 // be set, if the type is SET, ENUM, VARCHAR or VARBINARY.
653 var $returntyp = this.$ajaxDialog.find('select[name=item_returntype]');
654 var $returnlen = this.$ajaxDialog.find('input[name=item_returnlength]');
655 if (($returntyp.val() === 'ENUM' || $returntyp.val() === 'SET' || $returntyp.val().substr(0, 3) === 'VAR') &&
656 $returnlen.val() === ''
659 alert(PMA_messages.strFormEmpty);
663 if ($('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
664 // A function must contain a RETURN statement in its definition
665 if (this.$ajaxDialog.find('table.rte_table').find('textarea[name=item_definition]').val().toUpperCase().indexOf('RETURN') < 0) {
666 this.syntaxHiglighter.focus();
667 alert(PMA_messages.MissingReturn);
674 * Enable/disable the "options" dropdown and "length" input for
675 * parameters and the return variable in the routine editor
678 * @param type a jQuery object containing the reference
679 * to the "Type" dropdown box
680 * @param len a jQuery object containing the reference
681 * to the "Length" input box
682 * @param text a jQuery object containing the reference
683 * to the dropdown box with options for
684 * parameters of text type
685 * @param num a jQuery object containing the reference
686 * to the dropdown box with options for
687 * parameters of numeric type
689 setOptionsForParameter: function ($type, $len, $text, $num) {
691 * @var no_opts a jQuery object containing the reference
692 * to an element to be displayed when no
693 * options are available
695 var $no_opts = $text.parent().parent().find('.no_opts');
697 * @var no_len a jQuery object containing the reference
698 * to an element to be displayed when no
699 * "length/values" field is available
701 var $no_len = $len.parent().parent().find('.no_len');
703 // Process for parameter options
704 switch ($type.val()) {
714 $text.parent().hide();
715 $num.parent().show();
726 $text.parent().show();
727 $num.parent().hide();
731 $text.parent().hide();
732 $num.parent().hide();
736 // Process for parameter length
737 switch ($type.val()) {
749 $text.closest('tr').find('a:first').hide();
750 $len.parent().hide();
754 if ($type.val() == 'ENUM' || $type.val() == 'SET') {
755 $text.closest('tr').find('a:first').show();
757 $text.closest('tr').find('a:first').hide();
759 $len.parent().show();
764 executeDialog: function ($this) {
767 * @var msg jQuery object containing the reference to
768 * the AJAX message shown to the user
770 var $msg = PMA_ajaxShowMessage();
771 $.get($this.attr('href'), {'ajax_request': true}, function (data) {
772 if (data.success === true) {
773 PMA_ajaxRemoveMessage($msg);
774 // If 'data.dialog' is true we show a dialog with a form
775 // to get the input parameters for routine, otherwise
776 // we just show the results of the query
778 // Define the function that is called when
779 // the user presses the "Go" button
780 that.buttonOptions[PMA_messages.strGo] = function () {
782 * @var data Form data to be sent in the AJAX request
784 var data = $('form.rte_form').last().serialize();
785 $msg = PMA_ajaxShowMessage(
786 PMA_messages.strProcessingRequest
788 $.post('db_routines.php', data, function (data) {
789 if (data.success === true) {
790 // Routine executed successfully
791 PMA_ajaxRemoveMessage($msg);
792 PMA_slidingMessage(data.message);
793 $ajaxDialog.dialog('close');
795 PMA_ajaxShowMessage(data.error, false);
799 that.buttonOptions[PMA_messages.strClose] = function () {
800 $(this).dialog("close");
803 * Display the dialog to the user
805 var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
807 buttons: that.buttonOptions,
814 $ajaxDialog.find('input[name^=params]').first().focus();
816 * Attach the datepickers to the relevant form fields
818 $ajaxDialog.find('input.datefield, input.datetimefield').each(function () {
819 PMA_addDatepicker($(this).css('width', '95%'));
822 * Define the function if the user presses enter
824 $('form.rte_form').on('keyup', function (event) {
825 event.preventDefault();
826 if (event.keyCode === 13) {
828 * @var data Form data to be sent in the AJAX request
830 var data = $(this).serialize();
831 $msg = PMA_ajaxShowMessage(
832 PMA_messages.strProcessingRequest
834 var url = $(this).attr('action');
835 $.post(url, data, function (data) {
836 if (data.success === true) {
837 // Routine executed successfully
838 PMA_ajaxRemoveMessage($msg);
839 PMA_slidingMessage(data.message);
840 $('form.rte_form').off('keyup');
841 $ajaxDialog.remove();
843 PMA_ajaxShowMessage(data.error, false);
849 // Routine executed successfully
850 PMA_slidingMessage(data.message);
853 PMA_ajaxShowMessage(data.error, false);
860 * Attach Ajax event handlers for the Routines, Triggers and Events editor
864 * Attach Ajax event handlers for the Add/Edit functionality.
866 $(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) {
867 event.preventDefault();
868 var type = $(this).attr('href').substr(0, $(this).attr('href').indexOf('?'));
869 if (type.indexOf('routine') != -1) {
871 } else if (type.indexOf('trigger') != -1) {
873 } else if (type.indexOf('event') != -1) {
878 var dialog = new RTE.object(type);
879 dialog.editorDialog($(this).hasClass('add_anchor'), $(this));
880 }); // end $(document).on()
883 * Attach Ajax event handlers for the Execute routine functionality
885 $(document).on('click', 'a.ajax.exec_anchor', function (event) {
886 event.preventDefault();
887 var dialog = new RTE.object('routine');
888 dialog.executeDialog($(this));
889 }); // end $(document).on()
892 * Attach Ajax event handlers for Export of Routines, Triggers and Events
894 $(document).on('click', 'a.ajax.export_anchor', function (event) {
895 event.preventDefault();
896 var dialog = new RTE.object();
897 dialog.exportDialog($(this));
898 }); // end $(document).on()
900 $(document).on('click', '#rteListForm.ajax .mult_submit[value="export"]', function (event) {
901 event.preventDefault();
902 var dialog = new RTE.object();
903 dialog.exportDialog($(this));
904 }); // end $(document).on()
907 * Attach Ajax event handlers for Drop functionality
908 * of Routines, Triggers and Events.
910 $(document).on('click', 'a.ajax.drop_anchor', function (event) {
911 event.preventDefault();
912 var dialog = new RTE.object();
913 dialog.dropDialog($(this));
914 }); // end $(document).on()
916 $(document).on('click', '#rteListForm.ajax .mult_submit[value="drop"]', function (event) {
917 event.preventDefault();
918 var dialog = new RTE.object();
919 dialog.dropMultipleDialog($(this));
920 }); // end $(document).on()
923 * Attach Ajax event handlers for the "Change event/routine type"
924 * functionality in the events editor, so that the correct
925 * rows are shown in the editor when changing the event type
927 $(document).on('change', 'select[name=item_type]', function () {
930 .find('tr.recurring_event_row, tr.onetime_event_row, tr.routine_return_row, .routine_direction_cell')
932 }); // end $(document).on()
935 * Attach Ajax event handlers for the "Change parameter type"
936 * functionality in the routines editor, so that the correct
937 * option/length fields, if any, are shown when changing
940 $(document).on('change', 'select[name^=item_param_type]', function () {
942 * @var row jQuery object containing the reference to
943 * a row in the routine parameters table
945 var $row = $(this).parents('tr').first();
946 var rte = new RTE.object('routine');
947 rte.setOptionsForParameter(
948 $row.find('select[name^=item_param_type]'),
949 $row.find('input[name^=item_param_length]'),
950 $row.find('select[name^=item_param_opts_text]'),
951 $row.find('select[name^=item_param_opts_num]')
953 }); // end $(document).on()
956 * Attach Ajax event handlers for the "Change the type of return
957 * variable of function" functionality, so that the correct fields,
958 * if any, are shown when changing the function return type type
960 $(document).on('change', 'select[name=item_returntype]', function () {
961 var rte = new RTE.object('routine');
962 var $table = $(this).closest('table.rte_table');
963 rte.setOptionsForParameter(
964 $table.find('select[name=item_returntype]'),
965 $table.find('input[name=item_returnlength]'),
966 $table.find('select[name=item_returnopts_text]'),
967 $table.find('select[name=item_returnopts_num]')
969 }); // end $(document).on()
972 * Attach Ajax event handlers for the "Add parameter to routine" functionality
974 $(document).on('click', 'input[name=routine_addparameter]', function (event) {
975 event.preventDefault();
977 * @var routine_params_table jQuery object containing the reference
978 * to the routine parameters table
980 var $routine_params_table = $(this).closest('div.ui-dialog').find('.routine_params_table');
982 * @var new_param_row A string containing the HTML code for the
983 * new row for the routine parameters table
985 var new_param_row = RTE.param_template.replace(/%s/g, $routine_params_table.find('tr').length - 1);
986 // Append the new row to the parameters table
987 $routine_params_table.append(new_param_row);
988 // Make sure that the row is correctly shown according to the type of routine
989 if ($(this).closest('div.ui-dialog').find('table.rte_table select[name=item_type]').val() === 'FUNCTION') {
990 $('tr.routine_return_row').show();
991 $('td.routine_direction_cell').hide();
994 * @var newrow jQuery object containing the reference to the newly
995 * inserted row in the routine parameters table
997 var $newrow = $(this).closest('div.ui-dialog').find('table.routine_params_table').find('tr').has('td').last();
998 // Enable/disable the 'options' dropdowns for parameters as necessary
999 var rte = new RTE.object('routine');
1000 rte.setOptionsForParameter(
1001 $newrow.find('select[name^=item_param_type]'),
1002 $newrow.find('input[name^=item_param_length]'),
1003 $newrow.find('select[name^=item_param_opts_text]'),
1004 $newrow.find('select[name^=item_param_opts_num]')
1006 }); // end $(document).on()
1009 * Attach Ajax event handlers for the
1010 * "Remove parameter from routine" functionality
1012 $(document).on('click', 'a.routine_param_remove_anchor', function (event) {
1013 event.preventDefault();
1014 $(this).parent().parent().remove();
1015 // After removing a parameter, the indices of the name attributes in
1016 // the input fields lose the correct order and need to be reordered.
1018 * @var index Counter used for reindexing the input
1019 * fields in the routine parameters table
1022 $(this).closest('div.ui-dialog').find('table.routine_params_table').find('tr').has('td').each(function () {
1023 $(this).find(':input').each(function () {
1025 * @var inputname The value of the name attribute of
1026 * the input field being reindexed
1028 var inputname = $(this).attr('name');
1029 if (inputname.substr(0, 14) === 'item_param_dir') {
1030 $(this).attr('name', inputname.substr(0, 14) + '[' + index + ']');
1031 } else if (inputname.substr(0, 15) === 'item_param_name') {
1032 $(this).attr('name', inputname.substr(0, 15) + '[' + index + ']');
1033 } else if (inputname.substr(0, 15) === 'item_param_type') {
1034 $(this).attr('name', inputname.substr(0, 15) + '[' + index + ']');
1035 } else if (inputname.substr(0, 17) === 'item_param_length') {
1036 $(this).attr('name', inputname.substr(0, 17) + '[' + index + ']');
1037 $(this).attr('id', 'item_param_length_' + index);
1038 } else if (inputname.substr(0, 20) === 'item_param_opts_text') {
1039 $(this).attr('name', inputname.substr(0, 20) + '[' + index + ']');
1040 } else if (inputname.substr(0, 19) === 'item_param_opts_num') {
1041 $(this).attr('name', inputname.substr(0, 19) + '[' + index + ']');
1046 }); // end $(document).on()