diff --git a/ChangeLog b/ChangeLog index dd3db745d7..0550c6e83e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,8 @@ phpMyAdmin - ChangeLog - bug [display] Added missing icons in original theme - bug #3516761 [edit] Query error after search - bug #3516405 [display] Chart title is getting wrong within chart export +- bug #3517021 [interface] Header links except 'More' hide after closing dialog +- bug #3516817 [interface] "More" actions in table structure 3.5.0.0 (2012-04-07) + rfe #2021981 [interface] Add support for mass prefix change. diff --git a/js/functions.js b/js/functions.js index 21f3f48946..94792eb40e 100644 --- a/js/functions.js +++ b/js/functions.js @@ -1350,9 +1350,9 @@ function PMA_showNoticeForEnum(selectElement) function PMA_createTableDialog( $div, url , target) { /** - * @var button_options Object that stores the options passed to jQueryUI - * dialog - */ + * @var button_options Object that stores the options passed to jQueryUI + * dialog + */ var button_options = {}; // in the following function we need to use $(this) button_options[PMA_messages['strCancel']] = function() { @@ -1372,8 +1372,8 @@ function PMA_createTableDialog( $div, url , target) var $msgbox = PMA_ajaxShowMessage(); - $.get( target , url , function(data) { - //in the case of an error, show the error message returned. + $.get(target, url, function(data) { + //in the case of an error, show the error message returned. if (data.success != undefined && data.success == false) { $div .append(data.error) @@ -1385,7 +1385,8 @@ function PMA_createTableDialog( $div, url , target) })// end dialog options //remove the redundant [Back] link in the error message. .find('fieldset').remove(); - } else { + } + else { var size = getWindowSize(); var timeout; $div @@ -1437,12 +1438,15 @@ function PMA_createTableDialog( $div, url , target) close: function() { $(window).unbind('resize.dialog-resizer'); $('#content-hide > *').unwrap(); + // resize topmenu + menuResize(); + menuResize(); // somehow need to call it twice to work }, buttons: button_options }); // end dialog options } - PMA_convertFootnotesToTooltips($div); - PMA_ajaxRemoveMessage($msgbox); + PMA_convertFootnotesToTooltips($div); + PMA_ajaxRemoveMessage($msgbox); }); // end $.get() } @@ -2065,80 +2069,6 @@ $(document).ready(function() { }, 'top.frame_content'); //end $(document).ready for 'Create Table' -/** - * jQuery coding for 'Change Table' and 'Add Column'. Used on tbl_structure.php * - * Attach Ajax Event handlers for Change Table - */ -$(document).ready(function() { - /** - *Ajax action for submitting the "Column Change" and "Add Column" form - **/ - $("#append_fields_form input[name=do_save_data]").live('click', function(event) { - event.preventDefault(); - /** - * @var the_form object referring to the export form - */ - var $form = $("#append_fields_form"); - - /* - * First validate the form; if there is a problem, avoid submitting it - * - * checkTableEditForm() needs a pure element and not a jQuery object, - * this is why we pass $form[0] as a parameter (the jQuery object - * is actually an array of DOM elements) - */ - if (checkTableEditForm($form[0], $form.find('input[name=orig_num_fields]').val())) { - // OK, form passed validation step - if ($form.hasClass('ajax')) { - PMA_prepareForAjaxRequest($form); - //User wants to submit the form - $.post($form.attr('action'), $form.serialize()+"&do_save_data=Save", function(data) { - if ($("#sqlqueryresults").length != 0) { - $("#sqlqueryresults").remove(); - } else if ($("div.error").length != 0) { - $("div.error").remove(); - } - if (data.success == true) { - PMA_ajaxShowMessage(data.message); - $("
").insertAfter("#floating_menubar"); - $("#sqlqueryresults").html(data.sql_query); - $("#result_query .notice").remove(); - $("#result_query").prepend((data.message)); - if ($("#change_column_dialog").length > 0) { - $("#change_column_dialog").dialog("close").remove(); - } else if ($("#add_columns").length > 0) { - $("#add_columns").dialog("close").remove(); - } - /*Reload the field form*/ - $.post($("#fieldsForm").attr('action'), $("#fieldsForm").serialize()+"&ajax_request=true", function(form_data) { - $("#fieldsForm").remove(); - $("#addColumns").remove(); - var $temp_div = $("
").append(form_data); - if ($("#sqlqueryresults").length != 0) { - $temp_div.find("#fieldsForm").insertAfter("#sqlqueryresults"); - } else { - $temp_div.find("#fieldsForm").insertAfter("div.error"); - } - $temp_div.find("#addColumns").insertBefore("iframe.IE_hack"); - /*Call the function to display the more options in table*/ - displayMoreTableOpts(); - }); - } else { - var $temp_div = $("
").append(data); - var $error = $temp_div.find(".error code").addClass("error"); - PMA_ajaxShowMessage($error, false); - } - }); // end $.post() - } else { - // non-Ajax submit - $form.append(''); - $form.submit(); - } - } - }); // end change table button "do_save_data" - -}, 'top.frame_content'); //end $(document).ready for 'Change Table' - /** * jQuery coding for 'Table operations'. Used on tbl_operations.php * Attach Ajax Event handlers for Table operations @@ -2666,82 +2596,6 @@ $(document).ready(function() { }); }); -/** - * Hides certain table structure actions, replacing them - * with the word "More". They are displayed in a dropdown - * menu when the user hovers over the word "More." - */ -$(document).ready(function() { - displayMoreTableOpts(); -}); - -function displayMoreTableOpts() -{ - // Remove the actions from the table cells (they are available by default for JavaScript-disabled browsers) - // if the table is not a view or information_schema (otherwise there is only one action to hide and there's no point) - if ($("input[type='hidden'][name='table_type']").val() == "table") { - var $table = $("table#tablestructure"); - $table.find("td.replaced_by_more").remove(); - $table.find("th.action").attr("colspan", 3); - - // Display the "more" text - $table.find("td.more_opts").show(); - - // Position the dropdown - $("div.structure_actions_dropdown").each(function() { - // Optimize DOM querying - var $this_dropdown = $(this); - // The top offset must be set for IE even if it didn't change - var cell_right_edge_offset = $this_dropdown.parent().position().left + $this_dropdown.parent().innerWidth(); - var left_offset = cell_right_edge_offset - $this_dropdown.innerWidth(); - var top_offset = $this_dropdown.parent().position().top + $this_dropdown.parent().innerHeight(); - $this_dropdown.offset({ top: top_offset, left: left_offset }); - }); - - // A hack for IE6 to prevent the after_field select element from being displayed on top of the dropdown by - // positioning an iframe directly on top of it - var $after_field = $("select[name='after_field']"); - $("iframe.IE_hack") - .width($after_field.width()) - .height($after_field.height()) - .offset({ - top: $after_field.offset().top, - left: $after_field.offset().left - }); - - // When "more" is hovered over, show the hidden actions - $table.find("td.more_opts") - .mouseenter(function() { - if ($.browser.msie && $.browser.version == "6.0") { - $("iframe.IE_hack") - .show() - .width($after_field.width()+4) - .height($after_field.height()+4) - .offset({ - top: $after_field.offset().top, - left: $after_field.offset().left - }); - } - $("div.structure_actions_dropdown").hide(); // Hide all the other ones that may be open - $(this).children("div.structure_actions_dropdown").show(); - // Need to do this again for IE otherwise the offset is wrong - if ($.browser.msie) { - var left_offset_IE = $(this).offset().left + $(this).innerWidth() - $(this).children("div.structure_actions_dropdown").innerWidth(); - var top_offset_IE = $(this).offset().top + $(this).innerHeight(); - $(this).children("div.structure_actions_dropdown").offset({ - top: top_offset_IE, - left: left_offset_IE }); - } - }) - .mouseleave(function() { - $(this).children("div.structure_actions_dropdown").hide(); - if ($.browser.msie && $.browser.version == "6.0") { - $("iframe.IE_hack").hide(); - } - }); - } - -} $(document).ready(function() { PMA_convertFootnotesToTooltips(); }); diff --git a/js/tbl_structure.js b/js/tbl_structure.js index ee058dfc9b..cda6d43dd1 100644 --- a/js/tbl_structure.js +++ b/js/tbl_structure.js @@ -495,3 +495,209 @@ function changeColumns(action,url) }); // end $.get() } +/** + * jQuery coding for 'Change Table' and 'Add Column'. Used on tbl_structure.php * + * Attach Ajax Event handlers for Change Table + */ +$(document).ready(function() { + /** + *Ajax action for submitting the "Column Change" and "Add Column" form + **/ + $("#append_fields_form input[name=do_save_data]").live('click', function(event) { + event.preventDefault(); + /** + * @var the_form object referring to the export form + */ + var $form = $("#append_fields_form"); + + /* + * First validate the form; if there is a problem, avoid submitting it + * + * checkTableEditForm() needs a pure element and not a jQuery object, + * this is why we pass $form[0] as a parameter (the jQuery object + * is actually an array of DOM elements) + */ + if (checkTableEditForm($form[0], $form.find('input[name=orig_num_fields]').val())) { + // OK, form passed validation step + if ($form.hasClass('ajax')) { + PMA_prepareForAjaxRequest($form); + //User wants to submit the form + $.post($form.attr('action'), $form.serialize()+"&do_save_data=Save", function(data) { + if ($("#sqlqueryresults").length != 0) { + $("#sqlqueryresults").remove(); + } else if ($(".error").length != 0) { + $(".error").remove(); + } + if (data.success == true) { + PMA_ajaxShowMessage(data.message); + $("
").insertAfter("#floating_menubar"); + $("#sqlqueryresults").html(data.sql_query); + $("#result_query .notice").remove(); + $("#result_query").prepend((data.message)); + if ($("#change_column_dialog").length > 0) { + $("#change_column_dialog").dialog("close").remove(); + } else if ($("#add_columns").length > 0) { + $("#add_columns").dialog("close").remove(); + } + /*Reload the field form*/ + $.post($("#fieldsForm").attr('action'), $("#fieldsForm").serialize()+"&ajax_request=true", function(form_data) { + $("#fieldsForm").remove(); + $("#addColumns").remove(); + var $temp_div = $("
").append(form_data); + if ($("#sqlqueryresults").length != 0) { + $temp_div.find("#fieldsForm").insertAfter("#sqlqueryresults"); + } else { + $temp_div.find("#fieldsForm").insertAfter(".error"); + } + $temp_div.find("#addColumns").insertBefore("iframe.IE_hack"); + /*Call the function to display the more options in table*/ + $table_clone = false; + moreOptsMenuResize(); + }); + } else { + var $temp_div = $("
").append(data); + var $error = $temp_div.find(".error code").addClass("error"); + PMA_ajaxShowMessage($error, false); + } + }) // end $.post() + } else { + // non-Ajax submit + $form.append(''); + $form.submit(); + } + } + }) // end change table button "do_save_data" + +}, 'top.frame_content'); //end $(document).ready for 'Change Table' + +/** + * Hides certain table structure actions, replacing them + * with the word "More". They are displayed in a dropdown + * menu when the user hovers over the word "More." + */ + +var $table_clone = false; + +function moreOptsMenuResize() { + var $table = $("table#tablestructure"); + + // don't use More menu if we're only showing icons and no text + if ($table.length == 0 || $table.hasClass("PropertiesIconic")) { + return; + } + + // reset table to defaults + if ($table_clone === false) { + $table_clone = $table.clone(); + } + else { + $table.replaceWith($table_clone); + $table = $table_clone; + $table_clone = $table.clone(); + } + + var getCurWidth = function() { + var cur_width = 0; + $table.find("tr").eq(1) + .find("td.edit, td.drop, .replaced_by_more:visible, .more_opts:visible") + .each(function () { + cur_width += $(this).outerWidth(); + }); + return cur_width; + }; + + // get window width + var window_width = $(window).width(); + // find out maximum action links width + var max_width = window_width; + $table.find("th").each(function () { + if ($(this).index() < 8) { + max_width -= $(this).outerWidth() + 1; + } + }); + // current action links width + var cur_width = getCurWidth(); + + // remove some links if current width is wider than maximum allowed + if (cur_width > max_width) { + while (cur_width > max_width + && $(".replaced_by_more:visible").length > 0) { + + // hide last visible element + var css_class = $table.find("tr").eq(1) + .find(".replaced_by_more:visible").last().prop("className").split(" "); + $table.find("." + css_class.join(".")).hide(); + // show corresponding more-menu entry + $table.find(".replace_in_more.action_" + css_class[0]).show(); + // recalculate width + cur_width = getCurWidth(); + } + } + + if ($(".replaced_by_more:hidden").length == 0) { + $table.find("td.more_opts").hide(); + } + else { + $table.find("td.more_opts").show(); + } + + // Position the dropdown + $(".structure_actions_dropdown").each(function() { + // Optimize DOM querying + var $this_dropdown = $(this); + // The top offset must be set for IE even if it didn't change + var cell_right_edge_offset = $this_dropdown.parent().position().left + $this_dropdown.parent().innerWidth(); + var left_offset = cell_right_edge_offset - $this_dropdown.innerWidth(); + var top_offset = $this_dropdown.parent().position().top + $this_dropdown.parent().innerHeight(); + $this_dropdown.offset({ top: top_offset, left: left_offset }); + }); + + // A hack for IE6 to prevent the after_field select element from being displayed on top of the dropdown by + // positioning an iframe directly on top of it + var $after_field = $("select[name='after_field']"); + $("iframe[class='IE_hack']") + .width($after_field.width()) + .height($after_field.height()) + .offset({ + top: $after_field.offset().top, + left: $after_field.offset().left + }); + + // When "more" is hovered over, show the hidden actions + $table.find("td.more_opts") + .unbind("mouseenter") + .bind("mouseenter", function() { + if($.browser.msie && $.browser.version == "6.0") { + $("iframe[class='IE_hack']") + .show() + .width($after_field.width()+4) + .height($after_field.height()+4) + .offset({ + top: $after_field.offset().top, + left: $after_field.offset().left + }); + } + $(".structure_actions_dropdown").hide(); // Hide all the other ones that may be open + $(this).children(".structure_actions_dropdown").show(); + // Need to do this again for IE otherwise the offset is wrong + if($.browser.msie) { + var left_offset_IE = $(this).offset().left + $(this).innerWidth() - $(this).children(".structure_actions_dropdown").innerWidth(); + var top_offset_IE = $(this).offset().top + $(this).innerHeight(); + $(this).children(".structure_actions_dropdown").offset({ + top: top_offset_IE, + left: left_offset_IE }); + } + }) + .unbind("mouseleave") + .bind("mouseleave", function() { + $(this).children(".structure_actions_dropdown").hide(); + if($.browser.msie && $.browser.version == "6.0") { + $("iframe[class='IE_hack']").hide(); + } + }); +} +$(window).resize(moreOptsMenuResize); +$(function () { + $(".replace_in_more").hide(); + moreOptsMenuResize(); +}); diff --git a/libraries/common.lib.php b/libraries/common.lib.php index 4d550e6155..534e431894 100644 --- a/libraries/common.lib.php +++ b/libraries/common.lib.php @@ -3026,6 +3026,22 @@ function PMA_extractFieldSpec($fieldspec) $attribute = 'UNSIGNED ZEROFILL'; } + $can_contain_collation = false; + if ( + ! $binary + && + preg_match("@^(char|varchar|text|tinytext|mediumtext|longtext|set|enum)@", $type)) { + $can_contain_collation = true; + } + + // for the case ENUM('–','“') + $displayed_type = htmlspecialchars($printtype); + if (strlen($printtype) > $GLOBALS['cfg']['LimitChars']) { + $displayed_type = ''; + $displayed_type .= substr($printtype, 0, $GLOBALS['cfg']['LimitChars']); + $displayed_type .= ''; + } + return array( 'type' => $type, 'spec_in_brackets' => $spec_in_brackets, @@ -3035,6 +3051,8 @@ function PMA_extractFieldSpec($fieldspec) 'unsigned' => $unsigned, 'zerofill' => $zerofill, 'attribute' => $attribute, + 'can_contain_collation' => $can_contain_collation, + 'displayed_type' => $displayed_type ); } diff --git a/tbl_structure.php b/tbl_structure.php index 30c937e15a..a7af132ad9 100644 --- a/tbl_structure.php +++ b/tbl_structure.php @@ -193,7 +193,8 @@ $i = 0; echo '"table" />'; } ?> - +
@@ -207,8 +208,16 @@ $i = 0; - - + + @@ -257,36 +266,10 @@ foreach ($fields as $row) { if (empty($type)) { $type = ' '; } - // for the case ENUM('–','“') - $type = htmlspecialchars($type); - // in case it is too long - $start = 0; - if (strlen($type) > $GLOBALS['cfg']['LimitChars']) { - $start = 13; - $type = '' . substr($type, 0, $GLOBALS['cfg']['LimitChars']) . ''; - } - unset($field_charset); - if ((substr($type, $start, 4) == 'char' - || substr($type, $start, 7) == 'varchar' - || substr($type, $start, 4) == 'text' - || substr($type, $start, 8) == 'tinytext' - || substr($type, $start, 10) == 'mediumtext' - || substr($type, $start, 8) == 'longtext' - || substr($type, $start, 3) == 'set' - || substr($type, $start, 4) == 'enum') - && !$extracted_fieldspec['binary'] - ) { - if (strpos($type, ' character set ')) { - $type = substr($type, 0, strpos($type, ' character set ')); - } - if (!empty($row['Collation'])) { - $field_charset = $row['Collation']; - } else { - $field_charset = ''; - } - } else { - $field_charset = ''; + $field_charset = ''; + if ($extracted_fieldspec['can_contain_collation'] && ! empty($row['Collation'])) { + $field_charset = $row['Collation']; } // Display basic mimetype [MIME] @@ -343,7 +326,7 @@ foreach ($fields as $row) { - > + > @@ -359,10 +342,6 @@ foreach ($fields as $row) { echo '' . _pgettext('None for default', 'None') . ''; } ?> - - + + - - - + if ($GLOBALS['cfg']['PropertiesIconic'] !== true) { ?>
' . $field_charset . ''); ?> - - - @@ -372,7 +351,12 @@ foreach ($fields as $row) { href="sql.php?&sql_query=&dropped_column=&message_to_show=" > + + + + hasColumn($field_name))) { echo $titles['NoPrimary'] . "\n"; @@ -387,7 +371,7 @@ foreach ($fields as $row) { echo "\n"; ?> + + + + + - + @@ -453,24 +440,25 @@ foreach ($fields as $row) { } else { echo "\n"; ?> - +
-
+ -
> +
@@ -483,7 +471,7 @@ foreach ($fields as $row) { } } ?>
-
+
@@ -496,7 +484,7 @@ foreach ($fields as $row) { } } ?>
-
+
@@ -510,7 +498,7 @@ foreach ($fields as $row) { } ?>
-
+
@@ -523,7 +511,7 @@ foreach ($fields as $row) { } } ?>
-
+
@@ -540,6 +528,7 @@ foreach ($fields as $row) {