diff --git a/ChangeLog b/ChangeLog
index 633d481373..f70eae5870 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -43,6 +43,10 @@ phpMyAdmin - ChangeLog
+ AJAX for table Operations copy table
- bug #3380946 [export] no uid Query result export (Suhosin limit)
+ Grid editing in browse mode (replaces row inline edit)
++ Zoom-search in table Search
++ [interface] Editor for GIS data
++ [import] Import GIS data from ESRI Shapefiles
++ [interface] 'Function based search' for GIS data
3.4.5.0 (not yet released)
- bug #3375325 [interface] Page list in navigation frame looks odd
diff --git a/Documentation.html b/Documentation.html
index 8f7e66f871..758a2bc90f 100644
--- a/Documentation.html
+++ b/Documentation.html
@@ -2088,9 +2088,10 @@ $cfg['TrustedProxies'] =
The name of the directory where temporary files can be stored.
- This is needed to work around limitations of open_basedir
- for uploaded files, see
- FAQ
+ This is needed for importing ESRI Shapefiles, see
+ FAQ
+ 6.30 and to work around limitations of open_basedir for uploaded
+ files, see FAQ
1.11.
@@ -4373,6 +4374,41 @@ INSERT INTO REL_towns VALUES ('M', 'Montréal');
Not every table can be put to the chart. Only tables with one, two or three columns can be visualised as a chart. Moreover the table must be in a special format for chart script to understand it. Currently supported formats can be found in the wiki.
++ An ESRI Shapefile is actually a set of several files, where .shp file contains + geometry data and .dbf file contains data related to those geometry data. + To read data from .dbf file you need to have PHP compiled with the dBase extension + (--enable-dbase). Otherwise only geometry data will be imported. +
+ +To upload these set of files you can use either of the following methods:
++ Configure upload directory with + $cfg['UploadDir'], upload both + .shp and .dbf files with the same filename and chose the .shp file from the import page. +
++ Create a Zip archive with .shp and .dbf files and import it. For this to work, + you need to set $cfg['TempDir'] to a + place where the web server user can write (for example './tmp'). +
+ +To create the temporary directory on a UNIX-based system, you can do:
++cd phpMyAdmin +mkdir tmp +chmod o+rwx tmp ++
| '; - html += 'Hour'; - html += ' | '; - html += 'Minute'; - html += ' | '; - html += 'Second'; - html += ' |
|---|---|---|
| ' + tmph + ' | '; + } + + html += '
| ' + ((m < 10) ? '0' : '') + m + ' | '; + } + + html += '
| ' + ((s < 10) ? '0' : '') + s + ' | '; + } + + html += '
'
);
@@ -140,13 +166,14 @@ $(function() {
// Initialize each tab
$('div.ui-tabs-panel').each(function() {
- initTab($(this), null);
- tabStatus[$(this).attr('id')] = 'static';
+ var $tab = $(this);
+ tabStatus[$tab.attr('id')] = 'static';
+ // Initialize tabs after browser catches up with previous changes and displays tabs
+ setTimeout(function() {
+ initTab($tab, null);
+ }, 0.5);
});
- // Display button links
- $('div.buttonlinks').show();
-
// Handles refresh rate changing
$('.buttonlinks select').change(function() {
var chart = tabChart[$(this).parents('div.ui-tabs-panel').attr('id')];
@@ -362,7 +389,7 @@ $(function() {
});
$('#filterText').keyup(function(e) {
- word = $(this).val().replace(/_/g, ' ');
+ var word = $(this).val().replace(/_/g, ' ');
if (word.length == 0) {
textFilter = null;
@@ -389,6 +416,10 @@ $(function() {
/* Adjust DOM / Add handlers to the tabs */
function initTab(tab, data) {
+ if ($(tab).data('init-done') && !data) {
+ return;
+ }
+ $(tab).data('init-done', true);
switch(tab.attr('id')) {
case 'statustabs_traffic':
if (data != null) {
@@ -442,6 +473,7 @@ $(function() {
}
}
});
+ initTableSorter(tab.attr('id'));
break;
case 'statustabs_allvars':
@@ -449,43 +481,40 @@ $(function() {
tab.find('.tabInnerContent').html(data);
filterVariables();
}
+ initTableSorter(tab.attr('id'));
break;
}
-
- initTableSorter(tab.attr('id'));
}
+ // TODO: tablesorter shouldn't sort already sorted columns
function initTableSorter(tabid) {
+ var $table, opts;
switch(tabid) {
case 'statustabs_queries':
- $('#serverstatusqueriesdetails').tablesorter({
- sortList: [[3, 1]],
- widgets: ['zebra'],
- headers: {
- 1: { sorter: 'fancyNumber' },
- 2: { sorter: 'fancyNumber' }
- }
- });
-
- $('#serverstatusqueriesdetails tr:first th')
- .append('
');
-
+ $table = $('#serverstatusqueriesdetails');
+ opts = {
+ sortList: [[3, 1]],
+ widgets: ['fast-zebra'],
+ headers: {
+ 1: { sorter: 'fancyNumber' },
+ 2: { sorter: 'fancyNumber' }
+ }
+ };
break;
-
case 'statustabs_allvars':
- $('#serverstatusvariables').tablesorter({
- sortList: [[0, 0]],
- widgets: ['zebra'],
- headers: {
- 1: { sorter: 'fancyNumber' }
- }
- });
-
- $('#serverstatusvariables tr:first th')
- .append('
');
-
+ $table = $('#serverstatusvariables');
+ opts = {
+ sortList: [[0, 0]],
+ widgets: ['fast-zebra'],
+ headers: {
+ 1: { sorter: 'fancyNumber' }
+ }
+ };
break;
}
+ $table.tablesorter(opts);
+ $table.find('tr:first th')
+ .append('
');
}
/* Filters the status variables by name/category/alert in the variables tab */
diff --git a/js/server_status_monitor.js b/js/server_status_monitor.js
index f8a179d9f7..fa0f28eb77 100644
--- a/js/server_status_monitor.js
+++ b/js/server_status_monitor.js
@@ -1680,7 +1680,7 @@ $(function() {
$('div#logTable table').tablesorter({
sortList: [[cols.length - 1, 1]],
- widgets: ['zebra']
+ widgets: ['fast-zebra']
});
$('div#logTable table thead th')
@@ -1869,4 +1869,9 @@ $(function() {
$('a[href="#clearMonitorConfig"]').show();
}
+});
+
+// Run the monitor once loaded
+$(function() {
+ $('a[href="#pauseCharts"]').trigger('click');
});
\ No newline at end of file
diff --git a/js/sql.js b/js/sql.js
index f4a7475152..99fd93c703 100644
--- a/js/sql.js
+++ b/js/sql.js
@@ -334,10 +334,10 @@ $(document).ready(function() {
*/
var button_options = {};
// in the following function we need to use $(this)
- button_options[PMA_messages['strCancel']] = function() {$(this).parent().dialog('close').remove();}
+ button_options[PMA_messages['strCancel']] = function() {$(this).dialog('close').remove();}
var button_options_error = {};
- button_options_error[PMA_messages['strOK']] = function() {$(this).parent().dialog('close').remove();}
+ button_options_error[PMA_messages['strOK']] = function() {$(this).dialog('close').remove();}
var $form = $("#resultsForm");
var $msgbox = PMA_ajaxShowMessage();
@@ -351,6 +351,9 @@ $(document).ready(function() {
height: 230,
width: 900,
open: PMA_verifyTypeOfAllColumns,
+ close: function(event, ui) {
+ $('#change_row_dialog').remove();
+ },
buttons : button_options_error
})// end dialog options
} else {
@@ -361,6 +364,9 @@ $(document).ready(function() {
height: 600,
width: 900,
open: PMA_verifyTypeOfAllColumns,
+ close: function(event, ui) {
+ $('#change_row_dialog').remove();
+ },
buttons : button_options
})
//Remove the top menu container from the dialog
diff --git a/js/tbl_change.js b/js/tbl_change.js
index 17677b97ee..25bc120349 100644
--- a/js/tbl_change.js
+++ b/js/tbl_change.js
@@ -218,11 +218,38 @@ function verificationsAfterFieldChange(urlField, multi_edit, theType)
* Ajax handlers for Change Table page
*
* Actions Ajaxified here:
- * Submit Data to be inserted into the table
+ * Submit Data to be inserted into the table.
* Restart insertion with 'N' rows.
*/
$(document).ready(function() {
+ $('.open_gis_editor').live('click', function(event) {
+ event.preventDefault();
+
+ var $span = $(this);
+ // Current value
+ var value = $span.parent('td').children("input[type='text']").val();
+ // Field name
+ var field = $span.parents('tr').children('td:first').find("input[type='hidden']").val();
+ // Column type
+ var type = $span.parents('tr').find('span.column_type').text();
+ // Names of input field and null checkbox
+ var input_name = $span.parent('td').children("input[type='text']").attr('name');
+ //Token
+ var token = $("input[name='token']").val();
+
+ openGISEditor(value, field, type, input_name, token);
+ });
+
+ /**
+ * Uncheck the null checkbox as geometry data is placed on the input field
+ */
+ $("input[name='gis_data[save]']").live('click', function(event) {
+ var input_name = $('form#gis_data_editor_form').find("input[name='input_name']").val();
+ var $null_checkbox = $("input[name='" + input_name + "']").parents('tr').find('.checkbox_null');
+ $null_checkbox.attr('checked', false);
+ });
+
// these were hidden via the "hide" class
$('.foreign_values_anchor').show();
diff --git a/js/tbl_gis_visualization.js b/js/tbl_gis_visualization.js
index 978cd69308..0a84189c49 100644
--- a/js/tbl_gis_visualization.js
+++ b/js/tbl_gis_visualization.js
@@ -8,7 +8,9 @@
*/
var x = 0;
+var default_x = 0;
var y = 0;
+var default_y = 0;
var scale = 1;
var svg;
@@ -51,56 +53,52 @@ function zoomAndPan()
}
/**
- * Ajax handlers for GIS visualization page
- *
- * Actions Ajaxified here:
- *
- * Zooming in and zooming out on mousewheel movement.
- * Panning the visualization on dragging.
- * Zooming in on double clicking.
- * Zooming out on clicking the zoom out button.
- * Panning on clicking the arrow buttons.
- * Displaying tooltips for GIS objects.
+ * Initially loads either SVG or OSM visualization based on the choice.
*/
-$(document).ready(function() {
- var $placeholder = $('#placeholder');
- var $openlayersmap = $('#openlayersmap');
-
- if ($('#choice').prop('checked') != true) {
- $openlayersmap.hide();
+function selectVisualization() {
+ if ($('#choice').prop('checked') != true) {
+ $('#openlayersmap').hide();
} else {
- $placeholder.hide();
+ $('#placeholder').hide();
}
+ $('.choice').show();
+}
+/**
+ * Adds necessary styles to the div that coontains the openStreetMap.
+ */
+function styleOSM() {
+ var $placeholder = $('#placeholder');
var cssObj = {
'border' : '1px solid #aaa',
'width' : $placeholder.width(),
'height' : $placeholder.height(),
'float' : 'right'
};
- $openlayersmap.css(cssObj);
- drawOpenLayers();
+ $('#openlayersmap').css(cssObj);
+}
- $('.choice').show();
- $('#choice').bind('click', function() {
- if ($(this).prop('checked') == false) {
- $placeholder.show();
- $openlayersmap.hide();
- } else {
- $placeholder.hide();
- $openlayersmap.show();
- }
- });
+/**
+ * Loads the SVG element and make a reference to it.
+ */
+function loadSVG() {
+ var $placeholder = $('#placeholder');
- $('#placeholder').svg({
+ $placeholder.svg({
onLoad: function(svg_ref) {
svg = svg_ref;
}
});
- // Removes the second SVG element unnecessarily added due to the above command.
- $('#placeholder').find('svg:nth-child(2)').remove();
+ // Removes the second SVG element unnecessarily added due to the above command
+ $placeholder.find('svg:nth-child(2)').remove();
+}
+/**
+ * Adds controllers for zooming and panning.
+ */
+function addZoomPanControllers() {
+ var $placeholder = $('#placeholder');
if ($("#placeholder svg").length > 0) {
var pmaThemeImage = $('#pmaThemeImage').attr('value');
// add panning arrows
@@ -113,7 +111,81 @@ $(document).ready(function() {
$('
').appendTo($placeholder);
$('
').appendTo($placeholder);
}
+}
+/**
+ * Resizes the GIS visualization to fit into the space available.
+ */
+function resizeGISVisualization() {
+ var $placeholder = $('#placeholder');
+
+ // Hide inputs for width and height
+ $("input[name='visualizationSettings[width]']").parents('tr').remove();
+ $("input[name='visualizationSettings[height]']").parents('tr').remove();
+
+ var old_width = $placeholder.width();
+ var extraPadding = 100;
+ var leftWidth = $('.gis_table').width();
+ var windowWidth = document.documentElement.clientWidth;
+ var visWidth = windowWidth - extraPadding - leftWidth;
+
+ // Assign new value for width
+ $placeholder.width(visWidth);
+ $('svg').attr('width', visWidth);
+
+ // Assign the offset created due to resizing to default_x and center the svg.
+ default_x = (visWidth - old_width) / 2;
+ x = default_x;
+}
+
+/**
+ * Initialize the GIS visualization.
+ */
+function initGISVisualization() {
+ // Loads either SVG or OSM visualization based on the choice
+ selectVisualization();
+ // Resizes the GIS visualization to fit into the space available
+ resizeGISVisualization();
+ // Adds necessary styles to the div that coontains the openStreetMap
+ styleOSM();
+ // Draws openStreetMap with openLayers
+ drawOpenLayers();
+ // Loads the SVG element and make a reference to it
+ loadSVG();
+ // Adds controllers for zooming and panning
+ addZoomPanControllers();
+ zoomAndPan();
+}
+
+/**
+ * Ajax handlers for GIS visualization page
+ *
+ * Actions Ajaxified here:
+ *
+ * Zooming in and zooming out on mousewheel movement.
+ * Panning the visualization on dragging.
+ * Zooming in on double clicking.
+ * Zooming out on clicking the zoom out button.
+ * Panning on clicking the arrow buttons.
+ * Displaying tooltips for GIS objects.
+ */
+$(document).ready(function() {
+
+ // If we are in GIS visualization, initialize it
+ if ($('.gis_table').length > 0) {
+ initGISVisualization();
+ }
+
+ $('#choice').live('click', function() {
+ if ($(this).prop('checked') == false) {
+ $('#placeholder').show();
+ $('#openlayersmap').hide();
+ } else {
+ $('#placeholder').hide();
+ $('#openlayersmap').show();
+ }
+ });
+
$('#placeholder').live('mousewheel', function(event, delta) {
if (delta > 0) {
//zoom in
@@ -135,13 +207,13 @@ $(document).ready(function() {
var dragX = 0; var dragY = 0;
$('svg').live('dragstart', function(event, dd) {
- $placeholder.addClass('placeholderDrag');
+ $('#placeholder').addClass('placeholderDrag');
dragX = Math.round(dd.offsetX);
dragY = Math.round(dd.offsetY);
});
$('svg').live('mouseup', function(event) {
- $placeholder.removeClass('placeholderDrag');
+ $('#placeholder').removeClass('placeholderDrag');
});
$('svg').live('drag', function(event, dd) {
@@ -178,8 +250,8 @@ $(document).ready(function() {
$('#zoom_world').live('click', function(e) {
e.preventDefault();
scale = 1;
- x = 0;
- y = 0;
+ x = default_x;
+ y = default_y;
zoomAndPan();
});
@@ -225,7 +297,7 @@ $(document).ready(function() {
*/
$('.polygon, .multipolygon, .point, .multipoint, .linestring, .multilinestring, '
+ '.geometrycollection').live('mousemove', function(event) {
- contents = $(this).attr('name');
+ contents = $.trim($(this).attr('name'));
$("#tooltip").remove();
if (contents != '') {
$('