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 // Fire the ajax request straight away
114 $.get($this.attr('href'), {'ajax_request': true}, function (data) {
115 if (data.success === true) {
116 PMA_ajaxRemoveMessage($msg);
118 * @var button_options Object containing options
119 * for jQueryUI dialog buttons
121 var button_options = {};
122 button_options[PMA_messages.strClose] = function () {
123 $(this).dialog("close").remove();
126 * Display the dialog to the user
128 var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
130 buttons: button_options,
133 // Attach syntax highlighted editor to export dialog
135 * @var $elm jQuery object containing the reference
136 * to the Export textarea.
138 var $elm = $ajaxDialog.find('textarea');
140 * @var opts Options to pass to the codemirror editor
145 extraKeys: {"Ctrl-Space": "autocomplete"},
146 hintOptions: {"completeSingle": false, "completeOnSingleClick": true},
148 mode: "text/x-mysql",
151 CodeMirror.fromTextArea($elm[0], opts)
152 .on("inputRead", codemirrorAutocompleteOnInputRead);
154 PMA_ajaxShowMessage(data.error, false);
157 }, // end exportDialog()
158 editorDialog: function (is_new, $this) {
161 * @var $edit_row jQuery object containing the reference to
162 * the row of the the item being edited
163 * from the list of items
165 var $edit_row = null;
166 if ($this.hasClass('edit_anchor')) {
167 // Remeber the row of the item being edited for later,
168 // so that if the edit is successful, we can replace the
169 // row with info about the modified item.
170 $edit_row = $this.parents('tr');
173 * @var $msg jQuery object containing the reference to
174 * the AJAX message shown to the user
176 var $msg = PMA_ajaxShowMessage();
177 $.get($this.attr('href'), {'ajax_request': true}, function (data) {
178 if (data.success === true) {
179 // We have successfully fetched the editor form
180 PMA_ajaxRemoveMessage($msg);
181 // Now define the function that is called when
182 // the user presses the "Go" button
183 that.buttonOptions[PMA_messages.strGo] = function () {
184 // Move the data from the codemirror editor back to the
185 // textarea, where it can be used in the form submission.
186 if (typeof CodeMirror != 'undefined') {
187 that.syntaxHiglighter.save();
189 // Validate editor and submit request, if passed.
190 if (that.validate()) {
192 * @var data Form data to be sent in the AJAX request
194 var data = $('form.rte_form').last().serialize();
195 $msg = PMA_ajaxShowMessage(
196 PMA_messages.strProcessingRequest
198 var url = $('form.rte_form').last().attr('action');
199 $.post(url, data, function (data) {
200 if (data.success === true) {
201 // Item created successfully
202 PMA_ajaxRemoveMessage($msg);
203 PMA_slidingMessage(data.message);
204 that.$ajaxDialog.dialog('close');
205 // If we are in 'edit' mode, we must
206 // remove the reference to the old row.
207 if (mode === 'edit' && $edit_row !== null ) {
210 // Sometimes, like when moving a trigger from
211 // a table to another one, the new row should
212 // not be inserted into the list. In this case
213 // "data.insert" will be set to false.
215 // Insert the new row at the correct
216 // location in the list of items
218 * @var text Contains the name of an item from
219 * the list that is used in comparisons
220 * to find the correct location where
221 * to insert a new row.
225 * @var inserted Whether a new item has been
226 * inserted in the list or not
228 var inserted = false;
229 $('table.data').find('tr').each(function () {
237 if (text !== '' && text > data.name) {
238 $(this).before(data.new_row);
244 // If we didn't manage to insert the row yet,
245 // it must belong at the end of the list,
246 // so we insert it there.
247 $('table.data').append(data.new_row);
249 // Fade-in the new row
252 .removeClass('ajaxInsert');
253 } else if ($('table.data').find('tr').has('td').length === 0) {
254 // If we are not supposed to insert the new row,
255 // we will now check if the table is empty and
256 // needs to be hidden. This will be the case if
257 // we were editing the only item in the list,
258 // which we removed and will not be inserting
259 // something else in its place.
260 $('table.data').hide("slow", function () {
261 $('#nothing2display').show("slow");
264 // Now we have inserted the row at the correct
265 // position, but surely at least some row classes
266 // are wrong now. So we will itirate throught
267 // all rows and assign correct classes to them
269 * @var ct Count of processed rows
273 * @var rowclass Class to be attached to the row
274 * that is being processed
277 $('table.data').find('tr').has('td').each(function () {
278 rowclass = (ct % 2 === 0) ? 'odd' : 'even';
279 $(this).removeClass().addClass(rowclass);
282 // If this is the first item being added, remove
283 // the "No items" message and show the list.
284 if ($('table.data').find('tr').has('td').length > 0 &&
285 $('#nothing2display').is(':visible')
287 $('#nothing2display').hide("slow", function () {
288 $('table.data').show("slow");
291 PMA_reloadNavigation();
293 PMA_ajaxShowMessage(data.error, false);
296 } // end "if (that.validate())"
297 }; // end of function that handles the submission of the Editor
298 that.buttonOptions[PMA_messages.strClose] = function () {
299 $(this).dialog("close");
302 * Display the dialog to the user
304 that.$ajaxDialog = $('<div id="rteDialog">' + data.message + '</div>').dialog({
307 maxHeight: $(window).height(),
308 buttons: that.buttonOptions,
312 if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) {
313 $('#rteDialog').dialog("option", "height", $(window).height());
315 $(this).find('input[name=item_name]').focus();
316 $(this).find('input.datefield').each(function () {
317 PMA_addDatepicker($(this).css('width', '95%'), 'date');
319 $(this).find('input.datetimefield').each(function () {
320 PMA_addDatepicker($(this).css('width', '95%'), 'datetime');
322 $.datepicker.initialized = false;
329 * @var mode Used to remeber whether the editor is in
330 * "Edit" or "Add" mode
333 if ($('input[name=editor_process_edit]').length > 0) {
336 // Attach syntax highlighted editor to the definition
338 * @var elm jQuery object containing the reference to
339 * the Definition textarea.
341 var $elm = $('textarea[name=item_definition]').last();
343 * @var opts Options to pass to the codemirror editor
348 extraKeys: {"Ctrl-Space": "autocomplete"},
349 hintOptions: {"completeSingle": false, "completeOnSingleClick": true},
351 mode: "text/x-mysql",
354 if (typeof CodeMirror != 'undefined') {
355 that.syntaxHiglighter = CodeMirror.fromTextArea($elm[0], opts);
356 that.syntaxHiglighter.on("inputRead", codemirrorAutocompleteOnInputRead);
358 // Execute item-specific code
359 that.postDialogShow(data);
361 PMA_ajaxShowMessage(data.error, false);
366 dropDialog: function ($this) {
368 * @var $curr_row Object containing reference to the current row
370 var $curr_row = $this.parents('tr');
372 * @var question String containing the question to be asked for confirmation
374 var question = $('<div/>').text(
375 $curr_row.children('td').children('.drop_sql').html()
377 // We ask for confirmation first here, before submitting the ajax request
378 $this.PMA_confirm(question, $this.attr('href'), function (url) {
380 * @var msg jQuery object containing the reference to
381 * the AJAX message shown to the user
383 var $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
384 $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function (data) {
385 if (data.success === true) {
387 * @var $table Object containing reference
388 * to the main list of elements
390 var $table = $curr_row.parent();
391 // Check how many rows will be left after we remove
392 // the one that the user has requested us to remove
393 if ($table.find('tr').length === 3) {
394 // If there are two rows left, it means that they are
395 // the header of the table and the rows that we are
396 // about to remove, so after the removal there will be
397 // nothing to show in the table, so we hide it.
398 $table.hide("slow", function () {
399 $(this).find('tr.even, tr.odd').remove();
400 $('#nothing2display').show("slow");
403 $curr_row.hide("slow", function () {
405 // Now we have removed the row from the list, but maybe
406 // some row classes are wrong now. So we will itirate
407 // throught all rows and assign correct classes to them.
409 * @var ct Count of processed rows
413 * @var rowclass Class to be attached to the row
414 * that is being processed
417 $table.find('tr').has('td').each(function () {
418 rowclass = (ct % 2 === 0) ? 'odd' : 'even';
419 $(this).removeClass().addClass(rowclass);
424 // Get rid of the "Loading" message
425 PMA_ajaxRemoveMessage($msg);
426 // Show the query that we just executed
427 PMA_slidingMessage(data.sql_query);
428 PMA_reloadNavigation();
430 PMA_ajaxShowMessage(data.error, false);
433 }); // end $.PMA_confirm()
435 }; // end RTE namespace
438 * @var RTE.EVENT JavaScript functionality for events
441 validateCustom: function () {
443 * @var elm a jQuery object containing the reference
444 * to an element that is being validated
447 if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'RECURRING') {
448 // The interval field must not be empty for recurring events
449 $elm = this.$ajaxDialog.find('input[name=item_interval_value]');
450 if ($elm.val() === '') {
452 alert(PMA_messages.strFormEmpty);
456 // The execute_at field must not be empty for "once off" events
457 $elm = this.$ajaxDialog.find('input[name=item_execute_at]');
458 if ($elm.val() === '') {
460 alert(PMA_messages.strFormEmpty);
469 * @var RTE.ROUTINE JavaScript functionality for routines
473 * Overriding the postDialogShow() function defined in common.js
475 * @param data JSON-encoded data from the ajax request
477 postDialogShow: function (data) {
478 // Cache the template for a parameter table row
479 RTE.param_template = data.param_template;
481 // Make adjustments in the dialog to make it AJAX compatible
482 $('td.routine_param_remove').show();
483 $('input[name=routine_removeparameter]').remove();
484 $('input[name=routine_addparameter]').css('width', '100%');
485 // Enable/disable the 'options' dropdowns for parameters as necessary
486 $('table.routine_params_table').last().find('th[colspan=2]').attr('colspan', '1');
487 $('table.routine_params_table').last().find('tr').has('td').each(function () {
488 that.setOptionsForParameter(
489 $(this).find('select[name^=item_param_type]'),
490 $(this).find('input[name^=item_param_length]'),
491 $(this).find('select[name^=item_param_opts_text]'),
492 $(this).find('select[name^=item_param_opts_num]')
495 // Enable/disable the 'options' dropdowns for
496 // function return value as necessary
497 this.setOptionsForParameter(
498 $('table.rte_table').last().find('select[name=item_returntype]'),
499 $('table.rte_table').last().find('input[name=item_returnlength]'),
500 $('table.rte_table').last().find('select[name=item_returnopts_text]'),
501 $('table.rte_table').last().find('select[name=item_returnopts_num]')
505 * Overriding the validateCustom() function defined in common.js
507 validateCustom: function () {
509 * @var isSuccess Stores the outcome of the validation
511 var isSuccess = true;
513 * @var inputname The value of the "name" attribute for
514 * the field that is being processed
517 this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () {
518 // Every parameter of a routine must have
519 // a non-empty direction, name and type
521 $(this).find(':input').each(function () {
522 inputname = $(this).attr('name');
523 if (inputname.substr(0, 14) === 'item_param_dir' ||
524 inputname.substr(0, 15) === 'item_param_name' ||
525 inputname.substr(0, 15) === 'item_param_type') {
526 if ($(this).val() === '') {
538 alert(PMA_messages.strFormEmpty);
541 this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () {
542 // SET, ENUM, VARCHAR and VARBINARY fields must have length/values
543 var $inputtyp = $(this).find('select[name^=item_param_type]');
544 var $inputlen = $(this).find('input[name^=item_param_length]');
545 if ($inputtyp.length && $inputlen.length) {
546 if (($inputtyp.val() === 'ENUM' || $inputtyp.val() === 'SET' || $inputtyp.val().substr(0, 3) === 'VAR') &&
547 $inputlen.val() === ''
556 alert(PMA_messages.strFormEmpty);
559 if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
560 // The length/values of return variable for functions must
561 // be set, if the type is SET, ENUM, VARCHAR or VARBINARY.
562 var $returntyp = this.$ajaxDialog.find('select[name=item_returntype]');
563 var $returnlen = this.$ajaxDialog.find('input[name=item_returnlength]');
564 if (($returntyp.val() === 'ENUM' || $returntyp.val() === 'SET' || $returntyp.val().substr(0, 3) === 'VAR') &&
565 $returnlen.val() === ''
568 alert(PMA_messages.strFormEmpty);
572 if ($('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
573 // A function must contain a RETURN statement in its definition
574 if (this.$ajaxDialog.find('table.rte_table').find('textarea[name=item_definition]').val().toUpperCase().indexOf('RETURN') < 0) {
575 this.syntaxHiglighter.focus();
576 alert(PMA_messages.MissingReturn);
583 * Enable/disable the "options" dropdown and "length" input for
584 * parameters and the return variable in the routine editor
587 * @param type a jQuery object containing the reference
588 * to the "Type" dropdown box
589 * @param len a jQuery object containing the reference
590 * to the "Length" input box
591 * @param text a jQuery object containing the reference
592 * to the dropdown box with options for
593 * parameters of text type
594 * @param num a jQuery object containing the reference
595 * to the dropdown box with options for
596 * parameters of numeric type
598 setOptionsForParameter: function ($type, $len, $text, $num) {
600 * @var no_opts a jQuery object containing the reference
601 * to an element to be displayed when no
602 * options are available
604 var $no_opts = $text.parent().parent().find('.no_opts');
606 * @var no_len a jQuery object containing the reference
607 * to an element to be displayed when no
608 * "length/values" field is available
610 var $no_len = $len.parent().parent().find('.no_len');
612 // Process for parameter options
613 switch ($type.val()) {
623 $text.parent().hide();
624 $num.parent().show();
635 $text.parent().show();
636 $num.parent().hide();
640 $text.parent().hide();
641 $num.parent().hide();
645 // Process for parameter length
646 switch ($type.val()) {
658 $text.closest('tr').find('a:first').hide();
659 $len.parent().hide();
663 if ($type.val() == 'ENUM' || $type.val() == 'SET') {
664 $text.closest('tr').find('a:first').show();
666 $text.closest('tr').find('a:first').hide();
668 $len.parent().show();
673 executeDialog: function ($this) {
676 * @var msg jQuery object containing the reference to
677 * the AJAX message shown to the user
679 var $msg = PMA_ajaxShowMessage();
680 $.get($this.attr('href'), {'ajax_request': true}, function (data) {
681 if (data.success === true) {
682 PMA_ajaxRemoveMessage($msg);
683 // If 'data.dialog' is true we show a dialog with a form
684 // to get the input parameters for routine, otherwise
685 // we just show the results of the query
687 // Define the function that is called when
688 // the user presses the "Go" button
689 that.buttonOptions[PMA_messages.strGo] = function () {
691 * @var data Form data to be sent in the AJAX request
693 var data = $('form.rte_form').last().serialize();
694 $msg = PMA_ajaxShowMessage(
695 PMA_messages.strProcessingRequest
697 $.post('db_routines.php', data, function (data) {
698 if (data.success === true) {
699 // Routine executed successfully
700 PMA_ajaxRemoveMessage($msg);
701 PMA_slidingMessage(data.message);
702 $ajaxDialog.dialog('close');
704 PMA_ajaxShowMessage(data.error, false);
708 that.buttonOptions[PMA_messages.strClose] = function () {
709 $(this).dialog("close");
712 * Display the dialog to the user
714 $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
716 buttons: that.buttonOptions,
723 $ajaxDialog.find('input[name^=params]').first().focus();
725 * Attach the datepickers to the relevant form fields
727 $ajaxDialog.find('input.datefield, input.datetimefield').each(function () {
728 PMA_addDatepicker($(this).css('width', '95%'));
731 * Define the function if the user presses enter
733 $('form.rte_form').on('keyup', function (event) {
734 event.preventDefault();
735 if (event.keyCode === 13) {
737 * @var data Form data to be sent in the AJAX request
739 var data = $(this).serialize();
740 $msg = PMA_ajaxShowMessage(
741 PMA_messages.strProcessingRequest
743 var url = $(this).attr('action');
744 $.post(url, data, function (data) {
745 if (data.success === true) {
746 // Routine executed successfully
747 PMA_ajaxRemoveMessage($msg);
748 PMA_slidingMessage(data.message);
749 $('form.rte_form').off('keyup');
750 $ajaxDialog.remove();
752 PMA_ajaxShowMessage(data.error, false);
758 // Routine executed successfully
759 PMA_slidingMessage(data.message);
762 PMA_ajaxShowMessage(data.error, false);
769 * Attach Ajax event handlers for the Routines, Triggers and Events editor
773 * Attach Ajax event handlers for the Add/Edit functionality.
775 $(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) {
776 event.preventDefault();
777 var type = $(this).attr('href').substr(0, $(this).attr('href').indexOf('?'));
778 if (type.indexOf('routine') != -1) {
780 } else if (type.indexOf('trigger') != -1) {
782 } else if (type.indexOf('event') != -1) {
787 var dialog = new RTE.object(type);
788 dialog.editorDialog($(this).hasClass('add_anchor'), $(this));
789 }); // end $(document).on()
792 * Attach Ajax event handlers for the Execute routine functionality
794 $(document).on('click', 'a.ajax.exec_anchor', function (event) {
795 event.preventDefault();
796 var dialog = new RTE.object('routine');
797 dialog.executeDialog($(this));
798 }); // end $(document).on()
801 * Attach Ajax event handlers for Export of Routines, Triggers and Events
803 $(document).on('click', 'a.ajax.export_anchor', function (event) {
804 event.preventDefault();
805 var dialog = new RTE.object();
806 dialog.exportDialog($(this));
807 }); // end $(document).on()
810 * Attach Ajax event handlers for Drop functionality
811 * of Routines, Triggers and Events.
813 $(document).on('click', 'a.ajax.drop_anchor', function (event) {
814 event.preventDefault();
815 var dialog = new RTE.object();
816 dialog.dropDialog($(this));
817 }); // end $(document).on()
820 * Attach Ajax event handlers for the "Change event/routine type"
821 * functionality in the events editor, so that the correct
822 * rows are shown in the editor when changing the event type
824 $(document).on('change', 'select[name=item_type]', function () {
827 .find('tr.recurring_event_row, tr.onetime_event_row, tr.routine_return_row, .routine_direction_cell')
829 }); // end $(document).on()
832 * Attach Ajax event handlers for the "Change parameter type"
833 * functionality in the routines editor, so that the correct
834 * option/length fields, if any, are shown when changing
837 $(document).on('change', 'select[name^=item_param_type]', function () {
839 * @var row jQuery object containing the reference to
840 * a row in the routine parameters table
842 var $row = $(this).parents('tr').first();
843 var rte = new RTE.object('routine');
844 rte.setOptionsForParameter(
845 $row.find('select[name^=item_param_type]'),
846 $row.find('input[name^=item_param_length]'),
847 $row.find('select[name^=item_param_opts_text]'),
848 $row.find('select[name^=item_param_opts_num]')
850 }); // end $(document).on()
853 * Attach Ajax event handlers for the "Change the type of return
854 * variable of function" functionality, so that the correct fields,
855 * if any, are shown when changing the function return type type
857 $(document).on('change', 'select[name=item_returntype]', function () {
858 var rte = new RTE.object('routine');
859 var $table = $(this).closest('table.rte_table');
860 rte.setOptionsForParameter(
861 $table.find('select[name=item_returntype]'),
862 $table.find('input[name=item_returnlength]'),
863 $table.find('select[name=item_returnopts_text]'),
864 $table.find('select[name=item_returnopts_num]')
866 }); // end $(document).on()
869 * Attach Ajax event handlers for the "Add parameter to routine" functionality
871 $(document).on('click', 'input[name=routine_addparameter]', function (event) {
872 event.preventDefault();
874 * @var routine_params_table jQuery object containing the reference
875 * to the routine parameters table
877 var $routine_params_table = $(this).closest('div.ui-dialog').find('.routine_params_table');
879 * @var new_param_row A string containing the HTML code for the
880 * new row for the routine parameters table
882 var new_param_row = RTE.param_template.replace(/%s/g, $routine_params_table.find('tr').length - 1);
883 // Append the new row to the parameters table
884 $routine_params_table.append(new_param_row);
885 // Make sure that the row is correctly shown according to the type of routine
886 if ($(this).closest('div.ui-dialog').find('table.rte_table select[name=item_type]').val() === 'FUNCTION') {
887 $('tr.routine_return_row').show();
888 $('td.routine_direction_cell').hide();
891 * @var newrow jQuery object containing the reference to the newly
892 * inserted row in the routine parameters table
894 var $newrow = $(this).closest('div.ui-dialog').find('table.routine_params_table').find('tr').has('td').last();
895 // Enable/disable the 'options' dropdowns for parameters as necessary
896 var rte = new RTE.object('routine');
897 rte.setOptionsForParameter(
898 $newrow.find('select[name^=item_param_type]'),
899 $newrow.find('input[name^=item_param_length]'),
900 $newrow.find('select[name^=item_param_opts_text]'),
901 $newrow.find('select[name^=item_param_opts_num]')
903 }); // end $(document).on()
906 * Attach Ajax event handlers for the
907 * "Remove parameter from routine" functionality
909 $(document).on('click', 'a.routine_param_remove_anchor', function (event) {
910 event.preventDefault();
911 $(this).parent().parent().remove();
912 // After removing a parameter, the indices of the name attributes in
913 // the input fields lose the correct order and need to be reordered.
915 * @var index Counter used for reindexing the input
916 * fields in the routine parameters table
919 $(this).closest('div.ui-dialog').find('table.routine_params_table').find('tr').has('td').each(function () {
920 $(this).find(':input').each(function () {
922 * @var inputname The value of the name attribute of
923 * the input field being reindexed
925 var inputname = $(this).attr('name');
926 if (inputname.substr(0, 14) === 'item_param_dir') {
927 $(this).attr('name', inputname.substr(0, 14) + '[' + index + ']');
928 } else if (inputname.substr(0, 15) === 'item_param_name') {
929 $(this).attr('name', inputname.substr(0, 15) + '[' + index + ']');
930 } else if (inputname.substr(0, 15) === 'item_param_type') {
931 $(this).attr('name', inputname.substr(0, 15) + '[' + index + ']');
932 } else if (inputname.substr(0, 17) === 'item_param_length') {
933 $(this).attr('name', inputname.substr(0, 17) + '[' + index + ']');
934 $(this).attr('id', 'item_param_length_' + index);
935 } else if (inputname.substr(0, 20) === 'item_param_opts_text') {
936 $(this).attr('name', inputname.substr(0, 20) + '[' + index + ']');
937 } else if (inputname.substr(0, 19) === 'item_param_opts_num') {
938 $(this).attr('name', inputname.substr(0, 19) + '[' + index + ']');
943 }); // end $(document).on()