JAVASCRIPT 23
Sql.js Guest on 4th May 2021 10:48:10 AM
  1. /* vim: set expandtab sw=4 ts=4 sts=4: */
  2. /**
  3.  * @fileoverview    functions used wherever an sql query form is used
  4.  *
  5.  * @requires    jQuery
  6.  * @requires    js/functions.js
  7.  *
  8.  */
  9.  
  10. var $data_a;
  11. var prevScrollX = 0;
  12.  
  13. /**
  14.  * decode a string URL_encoded
  15.  *
  16.  * @param string str
  17.  * @return string the URL-decoded string
  18.  */
  19. function PMA_urldecode(str)
  20. {
  21.     if (typeof str !== 'undefined') {
  22.         return decodeURIComponent(str.replace(/\+/g, '%20'));
  23.     }
  24. }
  25.  
  26. /**
  27.  * endecode a string URL_decoded
  28.  *
  29.  * @param string str
  30.  * @return string the URL-encoded string
  31.  */
  32. function PMA_urlencode(str)
  33. {
  34.     if (typeof str !== 'undefined') {
  35.         return encodeURIComponent(str).replace(/\%20/g, '+');
  36.     }
  37. }
  38.  
  39. /**
  40.  * Get the field name for the current field.  Required to construct the query
  41.  * for grid editing
  42.  *
  43.  * @param $table_results enclosing results table
  44.  * @param $this_field    jQuery object that points to the current field's tr
  45.  */
  46. function getFieldName($table_results, $this_field)
  47. {
  48.  
  49.     var this_field_index = $this_field.index();
  50.     // ltr or rtl direction does not impact how the DOM was generated
  51.     // check if the action column in the left exist
  52.     var left_action_exist = !$table_results.find('th:first').hasClass('draggable');
  53.     // number of column span for checkbox and Actions
  54.     var left_action_skip = left_action_exist ? $table_results.find('th:first').attr('colspan') - 1 : 0;
  55.  
  56.     // If this column was sorted, the text of the a element contains something
  57.     // like <small>1</small> that is useful to indicate the order in case
  58.     // of a sort on multiple columns; however, we dont want this as part
  59.     // of the column name so we strip it ( .clone() to .end() )
  60.     var field_name = $table_results
  61.         .find('thead')
  62.         .find('th:eq(' + (this_field_index - left_action_skip) + ') a')
  63.         .clone()    // clone the element
  64.         .children() // select all the children
  65.         .remove()   // remove all of them
  66.         .end()      // go back to the selected element
  67.         .text();    // grab the text
  68.     // happens when just one row (headings contain no a)
  69.     if (field_name === '') {
  70.         var $heading = $table_results.find('thead').find('th:eq(' + (this_field_index - left_action_skip) + ')').children('span');
  71.         // may contain column comment enclosed in a span - detach it temporarily to read the column name
  72.         var $tempColComment = $heading.children().detach();
  73.         field_name = $heading.text();
  74.         // re-attach the column comment
  75.         $heading.append($tempColComment);
  76.     }
  77.  
  78.     field_name = $.trim(field_name);
  79.  
  80.     return field_name;
  81. }
  82.  
  83. /**
  84.  * Unbind all event handlers before tearing down a page
  85.  */
  86. AJAX.registerTeardown('sql.js', function () {
  87.     $(document).off('click', 'a.delete_row.ajax');
  88.     $(document).off('submit', '.bookmarkQueryForm');
  89.     $('input#bkm_label').unbind('keyup');
  90.     $(document).off('makegrid', ".sqlqueryresults");
  91.     $(document).off('stickycolumns', ".sqlqueryresults");
  92.     $("#togglequerybox").unbind('click');
  93.     $(document).off('click', "#button_submit_query");
  94.     $(document).off('change', '#id_bookmark');
  95.     $("input[name=bookmark_variable]").unbind("keypress");
  96.     $(document).off('submit', "#sqlqueryform.ajax");
  97.     $(document).off('click', "input[name=navig].ajax");
  98.     $(document).off('submit', "form[name='displayOptionsForm'].ajax");
  99.     $(document).off('mouseenter', 'th.column_heading.pointer');
  100.     $(document).off('mouseleave', 'th.column_heading.pointer');
  101.     $(document).off('click', 'th.column_heading.marker');
  102.     $(window).unbind('scroll');
  103.     $(document).off("keyup", ".filter_rows");
  104.     $(document).off('click', "#printView");
  105.     if (codemirror_editor) {
  106.         codemirror_editor.off('change');
  107.     } else {
  108.         $('#sqlquery').off('input propertychange');
  109.     }
  110.     $('body').off('click', '.navigation .showAllRows');
  111.     $('body').off('click','a.browse_foreign');
  112.     $('body').off('click', '#simulate_dml');
  113.     $('body').off('keyup', '#sqlqueryform');
  114.     $('body').off('click', 'form[name="resultsForm"].ajax button[name="submit_mult"], form[name="resultsForm"].ajax input[name="submit_mult"]');
  115. });
  116.  
  117. /**
  118.  * @description <p>Ajax scripts for sql and browse pages</p>
  119.  *
  120.  * Actions ajaxified here:
  121.  * <ul>
  122.  * <li>Retrieve results of an SQL query</li>
  123.  * <li>Paginate the results table</li>
  124.  * <li>Sort the results table</li>
  125.  * <li>Change table according to display options</li>
  126.  * <li>Grid editing of data</li>
  127.  * <li>Saving a bookmark</li>
  128.  * </ul>
  129.  *
  130.  * @name        document.ready
  131.  * @memberOf    jQuery
  132.  */
  133. AJAX.registerOnload('sql.js', function () {
  134.  
  135.     $(function () {
  136.         if (codemirror_editor) {
  137.             codemirror_editor.on('change', function () {
  138.                 var query = codemirror_editor.getValue();
  139.                 if (query) {
  140.                     $.cookie('auto_saved_sql', query);
  141.                 }
  142.             });
  143.         } else {
  144.             $('#sqlquery').on('input propertychange', function () {
  145.                 var query = $('#sqlquery').val();
  146.                 if (query) {
  147.                     $.cookie('auto_saved_sql', query);
  148.                 }
  149.             });
  150.         }
  151.     });
  152.  
  153.     // Delete row from SQL results
  154.     $(document).on('click', 'a.delete_row.ajax', function (e) {
  155.         e.preventDefault();
  156.         var question =  PMA_sprintf(PMA_messages.strDoYouReally, escapeHtml($(this).closest('td').find('div').text()));
  157.         var $link = $(this);
  158.         $link.PMA_confirm(question, $link.attr('href'), function (url) {
  159.             $msgbox = PMA_ajaxShowMessage();
  160.             if ($link.hasClass('formLinkSubmit')) {
  161.                 submitFormLink($link);
  162.             } else {
  163.                 $.post(url, {'ajax_request': true, 'is_js_confirmed': true}, function (data) {
  164.                     if (data.success) {
  165.                         PMA_ajaxShowMessage(data.message);
  166.                         $link.closest('tr').remove();
  167.                     } else {
  168.                         PMA_ajaxShowMessage(data.error, false);
  169.                     }
  170.                 });
  171.             }
  172.         });
  173.     });
  174.  
  175.     // Ajaxification for 'Bookmark this SQL query'
  176.     $(document).on('submit', '.bookmarkQueryForm', function (e) {
  177.         e.preventDefault();
  178.         PMA_ajaxShowMessage();
  179.         $.post($(this).attr('action'), 'ajax_request=1&' + $(this).serialize(), function (data) {
  180.             if (data.success) {
  181.                 PMA_ajaxShowMessage(data.message);
  182.             } else {
  183.                 PMA_ajaxShowMessage(data.error, false);
  184.             }
  185.         });
  186.     });
  187.  
  188.     /* Hides the bookmarkoptions checkboxes when the bookmark label is empty */
  189.     $('input#bkm_label').keyup(function () {
  190.         $('input#id_bkm_all_users, input#id_bkm_replace')
  191.             .parent()
  192.             .toggle($(this).val().length > 0);
  193.     }).trigger('keyup');
  194.  
  195.     /**
  196.      * Attach Event Handler for 'Copy to clipbpard
  197.      */
  198.     $(document).on('click', "#copyToClipBoard", function (event) {
  199.         event.preventDefault();
  200.  
  201.         // Print the page
  202.         copyToClipboard();
  203.     }); //end of Copy to Clipboard action
  204.  
  205.     /**
  206.      * Attach Event Handler for 'Print' link
  207.      */
  208.     $(document).on('click', "#printView", function (event) {
  209.         event.preventDefault();
  210.  
  211.         // Take to preview mode
  212.         printPreview();
  213.     }); //end of 'Print' action
  214.  
  215.     /**
  216.      * Attach the {@link makegrid} function to a custom event, which will be
  217.      * triggered manually everytime the table of results is reloaded
  218.      * @memberOf    jQuery
  219.      */
  220.     $(document).on('makegrid', ".sqlqueryresults", function () {
  221.         $('.table_results').each(function () {
  222.             PMA_makegrid(this);
  223.         });
  224.     });
  225.  
  226.     /*
  227.      * Attach a custom event for sticky column headings which will be
  228.      * triggered manually everytime the table of results is reloaded
  229.      * @memberOf    jQuery
  230.      */
  231.     $(document).on('stickycolumns', ".sqlqueryresults", function () {
  232.         $(".sticky_columns").remove();
  233.         $(".table_results").each(function () {
  234.             var $table_results = $(this);
  235.             //add sticky columns div
  236.             var $stick_columns = initStickyColumns($table_results);
  237.             rearrangeStickyColumns($stick_columns, $table_results);
  238.             //adjust sticky columns on scroll
  239.             $(window).bind('scroll', function() {
  240.                 handleStickyColumns($stick_columns, $table_results);
  241.             });
  242.         });
  243.     });
  244.  
  245.     /**
  246.      * Append the "Show/Hide query box" message to the query input form
  247.      *
  248.      * @memberOf jQuery
  249.      * @name    appendToggleSpan
  250.      */
  251.     // do not add this link more than once
  252.     if (! $('#sqlqueryform').find('a').is('#togglequerybox')) {
  253.         $('<a id="togglequerybox"></a>')
  254.         .html(PMA_messages.strHideQueryBox)
  255.         .appendTo("#sqlqueryform")
  256.         // initially hidden because at this point, nothing else
  257.         // appears under the link
  258.         .hide();
  259.  
  260.         // Attach the toggling of the query box visibility to a click
  261.         $("#togglequerybox").bind('click', function () {
  262.             var $link = $(this);
  263.             $link.siblings().slideToggle("fast");
  264.             if ($link.text() == PMA_messages.strHideQueryBox) {
  265.                 $link.text(PMA_messages.strShowQueryBox);
  266.                 // cheap trick to add a spacer between the menu tabs
  267.                 // and "Show query box"; feel free to improve!
  268.                 $('#togglequerybox_spacer').remove();
  269.                 $link.before('<br id="togglequerybox_spacer" />');
  270.             } else {
  271.                 $link.text(PMA_messages.strHideQueryBox);
  272.             }
  273.             // avoid default click action
  274.             return false;
  275.         });
  276.     }
  277.  
  278.  
  279.     /**
  280.      * Event handler for sqlqueryform.ajax button_submit_query
  281.      *
  282.      * @memberOf    jQuery
  283.      */
  284.     $(document).on('click', "#button_submit_query", function (event) {
  285.         $(".success,.error").hide();
  286.         //hide already existing error or success message
  287.         var $form = $(this).closest("form");
  288.         // the Go button related to query submission was clicked,
  289.         // instead of the one related to Bookmarks, so empty the
  290.         // id_bookmark selector to avoid misinterpretation in
  291.         // import.php about what needs to be done
  292.         $form.find("select[name=id_bookmark]").val("");
  293.         // let normal event propagation happen
  294.     });
  295.  
  296.     /**
  297.      * Event handler to show appropiate number of variable boxes
  298.      * based on the bookmarked query
  299.      */
  300.     $(document).on('change', '#id_bookmark', function (event) {
  301.  
  302.         var varCount = $(this).find('option:selected').data('varcount');
  303.         if (typeof varCount == 'undefined') {
  304.             varCount = 0;
  305.         }
  306.  
  307.         var $varDiv = $('#bookmark_variables');
  308.         $varDiv.empty();
  309.         for (var i = 1; i <= varCount; i++) {
  310.             $varDiv.append($('<label for="bookmark_variable_' + i + '">' + PMA_sprintf(PMA_messages.strBookmarkVariable, i) + '</label>'));
  311.             $varDiv.append($('<input type="text" size="10" name="bookmark_variable[' + i + ']" id="bookmark_variable_' + i + '"></input>'));
  312.         }
  313.  
  314.         if (varCount == 0) {
  315.             $varDiv.parent('.formelement').hide();
  316.         } else {
  317.             $varDiv.parent('.formelement').show();
  318.         }
  319.     });
  320.  
  321.     /**
  322.      * Event handler for hitting enter on sqlqueryform bookmark_variable
  323.      * (the Variable textfield in Bookmarked SQL query section)
  324.      *
  325.      * @memberOf    jQuery
  326.      */
  327.     $("input[name=bookmark_variable]").bind("keypress", function (event) {
  328.         // force the 'Enter Key' to implicitly click the #button_submit_bookmark
  329.         var keycode = (event.keyCode ? event.keyCode : (event.which ? event.which : event.charCode));
  330.         if (keycode == 13) { // keycode for enter key
  331.             // When you press enter in the sqlqueryform, which
  332.             // has 2 submit buttons, the default is to run the
  333.             // #button_submit_query, because of the tabindex
  334.             // attribute.
  335.             // This submits #button_submit_bookmark instead,
  336.             // because when you are in the Bookmarked SQL query
  337.             // section and hit enter, you expect it to do the
  338.             // same action as the Go button in that section.
  339.             $("#button_submit_bookmark").click();
  340.             return false;
  341.         } else  {
  342.             return true;
  343.         }
  344.     });
  345.  
  346.     /**
  347.      * Ajax Event handler for 'SQL Query Submit'
  348.      *
  349.      * @see         PMA_ajaxShowMessage()
  350.      * @memberOf    jQuery
  351.      * @name        sqlqueryform_submit
  352.      */
  353.     $(document).on('submit', "#sqlqueryform.ajax", function (event) {
  354.         event.preventDefault();
  355.  
  356.         var $form = $(this);
  357.         if (codemirror_editor) {
  358.             $form[0].elements.sql_query.value = codemirror_editor.getValue();
  359.         }
  360.         if (! checkSqlQuery($form[0])) {
  361.             return false;
  362.         }
  363.  
  364.         // remove any div containing a previous error message
  365.         $('div.error').remove();
  366.  
  367.         var $msgbox = PMA_ajaxShowMessage();
  368.         var $sqlqueryresultsouter = $('#sqlqueryresultsouter');
  369.  
  370.         PMA_prepareForAjaxRequest($form);
  371.  
  372.         $.post($form.attr('action'), $form.serialize() + '&ajax_page_request=true', function (data) {
  373.             if (typeof data !== 'undefined' && data.success === true) {
  374.                 // success happens if the query returns rows or not
  375.  
  376.                 // show a message that stays on screen
  377.                 if (typeof data.action_bookmark != 'undefined') {
  378.                     // view only
  379.                     if ('1' == data.action_bookmark) {
  380.                         $('#sqlquery').text(data.sql_query);
  381.                         // send to codemirror if possible
  382.                         setQuery(data.sql_query);
  383.                     }
  384.                     // delete
  385.                     if ('2' == data.action_bookmark) {
  386.                         $("#id_bookmark option[value='" + data.id_bookmark + "']").remove();
  387.                         // if there are no bookmarked queries now (only the empty option),
  388.                         // remove the bookmark section
  389.                         if ($('#id_bookmark option').length == 1) {
  390.                             $('#fieldsetBookmarkOptions').hide();
  391.                             $('#fieldsetBookmarkOptionsFooter').hide();
  392.                         }
  393.                     }
  394.                 }
  395.                 $sqlqueryresultsouter
  396.                     .show()
  397.                     .html(data.message);
  398.                 PMA_highlightSQL($sqlqueryresultsouter);
  399.  
  400.                 if (data._menu) {
  401.                     if (history && history.pushState) {
  402.                         history.replaceState({
  403.                                 menu : data._menu
  404.                             },
  405.                             null
  406.                         );
  407.                         AJAX.handleMenu.replace(data._menu);
  408.                     } else {
  409.                         PMA_MicroHistory.menus.replace(data._menu);
  410.                         PMA_MicroHistory.menus.add(data._menuHash, data._menu);
  411.                     }
  412.                 } else if (data._menuHash) {
  413.                     if (! (history && history.pushState)) {
  414.                         PMA_MicroHistory.menus.replace(PMA_MicroHistory.menus.get(data._menuHash));
  415.                     }
  416.                 }
  417.  
  418.                 if (data._params) {
  419.                     PMA_commonParams.setAll(data._params);
  420.                 }
  421.  
  422.                 if (typeof data.ajax_reload != 'undefined') {
  423.                     if (data.ajax_reload.reload) {
  424.                         if (data.ajax_reload.table_name) {
  425.                             PMA_commonParams.set('table', data.ajax_reload.table_name);
  426.                             PMA_commonActions.refreshMain();
  427.                         } else {
  428.                             PMA_reloadNavigation();
  429.                         }
  430.                     }
  431.                 } else if (typeof data.reload != 'undefined') {
  432.                     // this happens if a USE or DROP command was typed
  433.                     PMA_commonActions.setDb(data.db);
  434.                     var url;
  435.                     if (data.db) {
  436.                         if (data.table) {
  437.                             url = 'table_sql.php';
  438.                         } else {
  439.                             url = 'db_sql.php';
  440.                         }
  441.                     } else {
  442.                         url = 'server_sql.php';
  443.                     }
  444.                     PMA_commonActions.refreshMain(url, function () {
  445.                         $('#sqlqueryresultsouter')
  446.                             .show()
  447.                             .html(data.message);
  448.                         PMA_highlightSQL($('#sqlqueryresultsouter'));
  449.                     });
  450.                 }
  451.  
  452.                 $('.sqlqueryresults').trigger('makegrid').trigger('stickycolumns');
  453.                 $('#togglequerybox').show();
  454.                 PMA_init_slider();
  455.  
  456.                 if (typeof data.action_bookmark == 'undefined') {
  457.                     if ($('#sqlqueryform input[name="retain_query_box"]').is(':checked') !== true) {
  458.                         if ($("#togglequerybox").siblings(":visible").length > 0) {
  459.                             $("#togglequerybox").trigger('click');
  460.                         }
  461.                     }
  462.                 }
  463.             } else if (typeof data !== 'undefined' && data.success === false) {
  464.                 // show an error message that stays on screen
  465.                 $sqlqueryresultsouter
  466.                     .show()
  467.                     .html(data.error);
  468.             }
  469.             PMA_ajaxRemoveMessage($msgbox);
  470.         }); // end $.post()
  471.     }); // end SQL Query submit
  472.  
  473.     /**
  474.      * Ajax Event handler for the display options
  475.      * @memberOf    jQuery
  476.      * @name        displayOptionsForm_submit
  477.      */
  478.     $(document).on('submit', "form[name='displayOptionsForm'].ajax", function (event) {
  479.         event.preventDefault();
  480.  
  481.         $form = $(this);
  482.  
  483.         var $msgbox = PMA_ajaxShowMessage();
  484.         $.post($form.attr('action'), $form.serialize() + '&ajax_request=true', function (data) {
  485.             PMA_ajaxRemoveMessage($msgbox);
  486.             var $sqlqueryresults = $form.parents(".sqlqueryresults");
  487.             $sqlqueryresults
  488.              .html(data.message)
  489.              .trigger('makegrid')
  490.              .trigger('stickycolumns');
  491.             PMA_init_slider();
  492.             PMA_highlightSQL($sqlqueryresults);
  493.         }); // end $.post()
  494.     }); //end displayOptionsForm handler
  495.  
  496.     // Filter row handling. --STARTS--
  497.     $(document).on("keyup", ".filter_rows", function () {
  498.         var unique_id = $(this).data("for");
  499.         var $target_table = $(".table_results[data-uniqueId='" + unique_id + "']");
  500.         var $header_cells = $target_table.find("th[data-column]");
  501.         var target_columns = Array();
  502.         // To handle colspan=4, in case of edit,copy etc options.
  503.         var dummy_th = ($(".edit_row_anchor").length !== 0 ?
  504.             '<th class="hide dummy_th"></th><th class="hide dummy_th"></th><th class="hide dummy_th"></th>'
  505.             : '');
  506.         // Selecting columns that will be considered for filtering and searching.
  507.         $header_cells.each(function () {
  508.             target_columns.push($.trim($(this).text()));
  509.         });
  510.  
  511.         var phrase = $(this).val();
  512.         // Set same value to both Filter rows fields.
  513.         $(".filter_rows[data-for='" + unique_id + "']").not(this).val(phrase);
  514.         // Handle colspan.
  515.         $target_table.find("thead > tr").prepend(dummy_th);
  516.         $.uiTableFilter($target_table, phrase, target_columns);
  517.         $target_table.find("th.dummy_th").remove();
  518.     });
  519.     // Filter row handling. --ENDS--
  520.  
  521.     // Prompt to confirm on Show All
  522.     $('body').on('click', '.navigation .showAllRows', function (e) {
  523.         e.preventDefault();
  524.         var $form = $(this).parents('form');
  525.  
  526.         if (! $(this).is(':checked')) { // already showing all rows
  527.             submitShowAllForm();
  528.         } else {
  529.             $form.PMA_confirm(PMA_messages.strShowAllRowsWarning, $form.attr('action'), function (url) {
  530.                 submitShowAllForm();
  531.             });
  532.         }
  533.  
  534.         function submitShowAllForm() {
  535.             var submitData = $form.serialize() + '&ajax_request=true&ajax_page_request=true';
  536.             PMA_ajaxShowMessage();
  537.             AJAX.source = $form;
  538.             $.post($form.attr('action'), submitData, AJAX.responseHandler);
  539.         }
  540.     });
  541.  
  542.     $('body').on('keyup', '#sqlqueryform', function () {
  543.         PMA_handleSimulateQueryButton();
  544.     });
  545.  
  546.     /**
  547.      * Ajax event handler for 'Simulate DML'.
  548.      */
  549.     $('body').on('click', '#simulate_dml', function () {
  550.         var $form = $('#sqlqueryform');
  551.         var query = '';
  552.         var delimiter = $('#id_sql_delimiter').val();
  553.         var db_name = $form.find('input[name="db"]').val();
  554.  
  555.         if (codemirror_editor) {
  556.             query = codemirror_editor.getValue();
  557.         } else {
  558.             query = $('#sqlquery').val();
  559.         }
  560.  
  561.         if (query.length === 0) {
  562.             alert(PMA_messages.strFormEmpty);
  563.             $('#sqlquery').focus();
  564.             return false;
  565.         }
  566.  
  567.         var $msgbox = PMA_ajaxShowMessage();
  568.         $.ajax({
  569.             type: 'POST',
  570.             url: $form.attr('action'),
  571.             data: {
  572.                 token: $form.find('input[name="token"]').val(),
  573.                 db: db_name,
  574.                 ajax_request: '1',
  575.                 simulate_dml: '1',
  576.                 sql_query: query,
  577.                 sql_delimiter: delimiter
  578.             },
  579.             success: function (response) {
  580.                 PMA_ajaxRemoveMessage($msgbox);
  581.                 if (response.success) {
  582.                     var dialog_content = '<div class="preview_sql">';
  583.                     if (response.sql_data) {
  584.                         var len = response.sql_data.length;
  585.                         for (var i=0; i<len; i++) {
  586.                             dialog_content += '<strong>' + PMA_messages.strSQLQuery +
  587.                                 '</strong>' + response.sql_data[i].sql_query +
  588.                                 PMA_messages.strMatchedRows +
  589.                                 ' <a href="' + response.sql_data[i].matched_rows_url +
  590.                                 '">' + response.sql_data[i].matched_rows + '</a><br>';
  591.                             if (i<len-1) {
  592.                                 dialog_content += '<hr>';
  593.                             }
  594.                         }
  595.                     } else {
  596.                         dialog_content += response.message;
  597.                     }
  598.                     dialog_content += '</div>';
  599.                     var $dialog_content = $(dialog_content);
  600.                     var button_options = {};
  601.                     button_options[PMA_messages.strClose] = function () {
  602.                         $(this).dialog('close');
  603.                     };
  604.                     var $response_dialog = $('<div />').append($dialog_content).dialog({
  605.                         minWidth: 540,
  606.                         maxHeight: 400,
  607.                         modal: true,
  608.                         buttons: button_options,
  609.                         title: PMA_messages.strSimulateDML,
  610.                         open: function () {
  611.                             PMA_highlightSQL($(this));
  612.                         },
  613.                         close: function () {
  614.                             $(this).remove();
  615.                         }
  616.                     });
  617.                 } else {
  618.                     PMA_ajaxShowMessage(response.error);
  619.                 }
  620.             },
  621.             error: function (response) {
  622.                 PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest);
  623.             }
  624.         });
  625.     });
  626.  
  627.     /**
  628.      * Handles multi submits of results browsing page such as edit, delete and export
  629.      */
  630.     $('body').on('click', 'form[name="resultsForm"].ajax button[name="submit_mult"], form[name="resultsForm"].ajax input[name="submit_mult"]', function (e) {
  631.         e.preventDefault();
  632.         var $button = $(this);
  633.         var $form = $button.closest('form');
  634.         var submitData = $form.serialize() + '&ajax_request=true&ajax_page_request=true&submit_mult=' + $button.val();
  635.         PMA_ajaxShowMessage();
  636.         AJAX.source = $form;
  637.         $.post($form.attr('action'), submitData, AJAX.responseHandler);
  638.     });
  639. }); // end $()
  640.  
  641. /**
  642.  * Starting from some th, change the class of all td under it.
  643.  * If isAddClass is specified, it will be used to determine whether to add or remove the class.
  644.  */
  645. function PMA_changeClassForColumn($this_th, newclass, isAddClass)
  646. {
  647.     // index 0 is the th containing the big T
  648.     var th_index = $this_th.index();
  649.     var has_big_t = $this_th.closest('tr').children(':first').hasClass('column_action');
  650.     // .eq() is zero-based
  651.     if (has_big_t) {
  652.         th_index--;
  653.     }
  654.     var $table = $this_th.parents('.table_results');
  655.     if (! $table.length) {
  656.         $table = $this_th.parents('table').siblings('.table_results');
  657.     }
  658.     var $tds = $table.find('tbody tr').find('td.data:eq(' + th_index + ')');
  659.     if (isAddClass === undefined) {
  660.         $tds.toggleClass(newclass);
  661.     } else {
  662.         $tds.toggleClass(newclass, isAddClass);
  663.     }
  664. }
  665.  
  666. /**
  667.  * Handles browse foreign values modal dialog
  668.  *
  669.  * @param object $this_a reference to the browse foreign value link
  670.  */
  671. function browseForeignDialog($this_a)
  672. {
  673.     var formId = '#browse_foreign_form';
  674.     var showAllId = '#foreign_showAll';
  675.     var tableId = '#browse_foreign_table';
  676.     var filterId = '#input_foreign_filter';
  677.     var $dialog = null;
  678.     $.get($this_a.attr('href'), {'ajax_request': true}, function (data) {
  679.         // Creates browse foreign value dialog
  680.         $dialog = $('<div>').append(data.message).dialog({
  681.             title: PMA_messages.strBrowseForeignValues,
  682.             width: Math.min($(window).width() - 100, 700),
  683.             maxHeight: $(window).height() - 100,
  684.             dialogClass: 'browse_foreign_modal',
  685.             close: function (ev, ui) {
  686.                 // remove event handlers attached to elements related to dialog
  687.                 $(tableId).off('click', 'td a.foreign_value');
  688.                 $(formId).off('click', showAllId);
  689.                 $(formId).off('submit');
  690.                 // remove dialog itself
  691.                 $(this).remove();
  692.             },
  693.             modal: true
  694.         });
  695.     }).done(function () {
  696.         var showAll = false;
  697.         $(tableId).on('click', 'td a.foreign_value', function (e) {
  698.             e.preventDefault();
  699.             var $input = $this_a.prev('input[type=text]');
  700.             // Check if input exists or get CEdit edit_box
  701.             if ($input.length === 0 ) {
  702.                 $input = $this_a.closest('.edit_area').prev('.edit_box');
  703.             }
  704.             // Set selected value as input value
  705.             $input.val($(this).data('key'));
  706.             $dialog.dialog('close');
  707.         });
  708.         $(formId).on('click', showAllId, function () {
  709.             showAll = true;
  710.         });
  711.         $(formId).on('submit', function (e) {
  712.             e.preventDefault();
  713.             // if filter value is not equal to old value
  714.             // then reset page number to 1
  715.             if ($(filterId).val() != $(filterId).data('old')) {
  716.                 $(formId).find('select[name=pos]').val('0');
  717.             }
  718.             var postParams = $(this).serializeArray();
  719.             // if showAll button was clicked to submit form then
  720.             // add showAll button parameter to form
  721.             if (showAll) {
  722.                 postParams.push({
  723.                     name: $(showAllId).attr('name'),
  724.                     value: $(showAllId).val()
  725.                 });
  726.             }
  727.             // updates values in dialog
  728.             $.post($(this).attr('action') + '?ajax_request=1', postParams, function (data) {
  729.                 var $obj = $('<div>').html(data.message);
  730.                 $(formId).html($obj.find(formId).html());
  731.                 $(tableId).html($obj.find(tableId).html());
  732.             });
  733.             showAll = false;
  734.         });
  735.     });
  736. }
  737.  
  738. AJAX.registerOnload('sql.js', function () {
  739.     $('body').on('click', 'a.browse_foreign', function (e) {
  740.         e.preventDefault();
  741.         browseForeignDialog($(this));
  742.     });
  743.  
  744.     /**
  745.      * vertical column highlighting in horizontal mode when hovering over the column header
  746.      */
  747.     $(document).on('mouseenter', 'th.column_heading.pointer', function (e) {
  748.         PMA_changeClassForColumn($(this), 'hover', true);
  749.     });
  750.     $(document).on('mouseleave', 'th.column_heading.pointer', function (e) {
  751.         PMA_changeClassForColumn($(this), 'hover', false);
  752.     });
  753.  
  754.     /**
  755.      * vertical column marking in horizontal mode when clicking the column header
  756.      */
  757.     $(document).on('click', 'th.column_heading.marker', function () {
  758.         PMA_changeClassForColumn($(this), 'marked');
  759.     });
  760.  
  761.     /**
  762.      * create resizable table
  763.      */
  764.     $(".sqlqueryresults").trigger('makegrid').trigger('stickycolumns');
  765. });
  766.  
  767. /*
  768.  * Profiling Chart
  769.  */
  770. function makeProfilingChart()
  771. {
  772.     if ($('#profilingchart').length === 0 ||
  773.         $('#profilingchart').html().length !== 0 ||
  774.         !$.jqplot || !$.jqplot.Highlighter || !$.jqplot.PieRenderer
  775.     ) {
  776.         return;
  777.     }
  778.  
  779.     var data = [];
  780.     $.each(jQuery.parseJSON($('#profilingChartData').html()), function (key, value) {
  781.         data.push([key, parseFloat(value)]);
  782.     });
  783.  
  784.     // Remove chart and data divs contents
  785.     $('#profilingchart').html('').show();
  786.     $('#profilingChartData').html('');
  787.  
  788.     PMA_createProfilingChart('profilingchart', data);
  789. }
  790.  
  791. /*
  792.  * initialize profiling data tables
  793.  */
  794. function initProfilingTables()
  795. {
  796.     if (!$.tablesorter) {
  797.         return;
  798.     }
  799.  
  800.     $('#profiletable').tablesorter({
  801.         widgets: ['zebra'],
  802.         sortList: [[0, 0]],
  803.         textExtraction: function (node) {
  804.             if (node.children.length > 0) {
  805.                 return node.children[0].innerHTML;
  806.             } else {
  807.                 return node.innerHTML;
  808.             }
  809.         }
  810.     });
  811.  
  812.     $('#profilesummarytable').tablesorter({
  813.         widgets: ['zebra'],
  814.         sortList: [[1, 1]],
  815.         textExtraction: function (node) {
  816.             if (node.children.length > 0) {
  817.                 return node.children[0].innerHTML;
  818.             } else {
  819.                 return node.innerHTML;
  820.             }
  821.         }
  822.     });
  823. }
  824.  
  825. /*
  826.  * Set position, left, top, width of sticky_columns div
  827.  */
  828. function setStickyColumnsPosition($sticky_columns, $table_results, position, top, left, margin_left) {
  829.     $sticky_columns
  830.         .css("position", position)
  831.         .css("top", top)
  832.         .css("left", left ? left : "auto")
  833.         .css("margin-left", margin_left ? margin_left : "0px")
  834.         .css("width", $table_results.width());
  835. }
  836.  
  837. /*
  838.  * Initialize sticky columns
  839.  */
  840. function initStickyColumns($table_results) {
  841.     return $('<table class="sticky_columns"></table>')
  842.             .insertBefore($table_results)
  843.             .css("position", "fixed")
  844.             .css("z-index", "99")
  845.             .css("width", $table_results.width())
  846.             .css("margin-left", $('#page_content').css("margin-left"))
  847.             .css("top", $('#floating_menubar').height())
  848.             .css("display", "none");
  849. }
  850.  
  851. /*
  852.  * Arrange/Rearrange columns in sticky header
  853.  */
  854. function rearrangeStickyColumns($sticky_columns, $table_results) {
  855.     var $originalHeader = $table_results.find("thead");
  856.     var $originalColumns = $originalHeader.find("tr:first").children();
  857.     var $clonedHeader = $originalHeader.clone();
  858.     // clone width per cell
  859.     $clonedHeader.find("tr:first").children().width(function(i,val) {
  860.         var width = $originalColumns.eq(i).width();
  861.         var is_firefox = navigator.userAgent.indexOf('Firefox') > -1;
  862.         if (! is_firefox) {
  863.             width += 1;
  864.         }
  865.         return width;
  866.     });
  867.     $sticky_columns.empty().append($clonedHeader);
  868. }
  869.  
  870. /*
  871.  * Adjust sticky columns on horizontal/vertical scroll for all tables
  872.  */
  873. function handleAllStickyColumns() {
  874.     $('.sticky_columns').each(function () {
  875.         handleStickyColumns($(this), $(this).next('.table_results'));
  876.     });
  877. }
  878.  
  879. /*
  880.  * Adjust sticky columns on horizontal/vertical scroll
  881.  */
  882. function handleStickyColumns($sticky_columns, $table_results) {
  883.     var currentScrollX = $(window).scrollLeft();
  884.     var windowOffset = $(window).scrollTop();
  885.     var tableStartOffset = $table_results.offset().top;
  886.     var tableEndOffset = tableStartOffset + $table_results.height();
  887.     if (windowOffset >= tableStartOffset && windowOffset <= tableEndOffset) {
  888.         //for horizontal scrolling
  889.         if(prevScrollX != currentScrollX) {
  890.             prevScrollX = currentScrollX;
  891.             setStickyColumnsPosition($sticky_columns, $table_results, "absolute", $('#floating_menubar').height() + windowOffset - tableStartOffset);
  892.         //for vertical scrolling
  893.         } else {
  894.             setStickyColumnsPosition($sticky_columns, $table_results, "fixed", $('#floating_menubar').height(), $("#pma_navigation").width() - currentScrollX, $('#page_content').css("margin-left"));
  895.         }
  896.         $sticky_columns.show();
  897.     } else {
  898.         $sticky_columns.hide();
  899.     }
  900. }
  901.  
  902. AJAX.registerOnload('sql.js', function () {
  903.     makeProfilingChart();
  904.     initProfilingTables();
  905. });

Paste-bin is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.