Update website
This commit is contained in:
parent
a0b0d3dae7
commit
ae7ef6ad45
3151 changed files with 566766 additions and 48 deletions
832
admin/phpMyAdmin/js/dist/table/change.js
vendored
Normal file
832
admin/phpMyAdmin/js/dist/table/change.js
vendored
Normal file
|
@ -0,0 +1,832 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* @fileoverview function used in table data manipulation pages
|
||||
*
|
||||
* @requires jQuery
|
||||
* @requires jQueryUI
|
||||
* @requires js/functions.js
|
||||
*
|
||||
*/
|
||||
|
||||
/* global extendingValidatorMessages */
|
||||
// templates/javascript/variables.twig
|
||||
|
||||
/* global openGISEditor, gisEditorLoaded, loadJSAndGISEditor, loadGISEditor */
|
||||
// js/gis_data_editor.js
|
||||
|
||||
/**
|
||||
* Modify form controls when the "NULL" checkbox is checked
|
||||
*
|
||||
* @param theType string the MySQL field type
|
||||
* @param urlField string the urlencoded field name - OBSOLETE
|
||||
* @param md5Field string the md5 hashed field name
|
||||
* @param multiEdit string the multi_edit row sequence number
|
||||
*
|
||||
* @return boolean always true
|
||||
*/
|
||||
function nullify(theType, urlField, md5Field, multiEdit) {
|
||||
var rowForm = document.forms.insertForm;
|
||||
|
||||
if (typeof rowForm.elements['funcs' + multiEdit + '[' + md5Field + ']'] !== 'undefined') {
|
||||
rowForm.elements['funcs' + multiEdit + '[' + md5Field + ']'].selectedIndex = -1;
|
||||
} // "ENUM" field with more than 20 characters
|
||||
|
||||
|
||||
if (Number(theType) === 1) {
|
||||
rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'][1].selectedIndex = -1; // Other "ENUM" field
|
||||
} else if (Number(theType) === 2) {
|
||||
var elts = rowForm.elements['fields' + multiEdit + '[' + md5Field + ']']; // when there is just one option in ENUM:
|
||||
|
||||
if (elts.checked) {
|
||||
elts.checked = false;
|
||||
} else {
|
||||
var eltsCnt = elts.length;
|
||||
|
||||
for (var i = 0; i < eltsCnt; i++) {
|
||||
elts[i].checked = false;
|
||||
} // end for
|
||||
|
||||
} // end if
|
||||
// "SET" field
|
||||
|
||||
} else if (Number(theType) === 3) {
|
||||
rowForm.elements['fields' + multiEdit + '[' + md5Field + '][]'].selectedIndex = -1; // Foreign key field (drop-down)
|
||||
} else if (Number(theType) === 4) {
|
||||
rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].selectedIndex = -1; // foreign key field (with browsing icon for foreign values)
|
||||
} else if (Number(theType) === 6) {
|
||||
rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].value = ''; // Other field types
|
||||
} else
|
||||
/* if (theType === 5)*/
|
||||
{
|
||||
rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].value = '';
|
||||
} // end if... else if... else
|
||||
|
||||
|
||||
return true;
|
||||
} // end of the 'nullify()' function
|
||||
|
||||
/**
|
||||
* javascript DateTime format validation.
|
||||
* its used to prevent adding default (0000-00-00 00:00:00) to database when user enter wrong values
|
||||
* Start of validation part
|
||||
*/
|
||||
// function checks the number of days in febuary
|
||||
|
||||
|
||||
function daysInFebruary(year) {
|
||||
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28;
|
||||
} // function to convert single digit to double digit
|
||||
|
||||
|
||||
function fractionReplace(number) {
|
||||
var num = parseInt(number, 10);
|
||||
return num >= 1 && num <= 9 ? '0' + num : '00';
|
||||
}
|
||||
/* function to check the validity of date
|
||||
* The following patterns are accepted in this validation (accepted in mysql as well)
|
||||
* 1) 2001-12-23
|
||||
* 2) 2001-1-2
|
||||
* 3) 02-12-23
|
||||
* 4) And instead of using '-' the following punctuations can be used (+,.,*,^,@,/) All these are accepted by mysql as well. Therefore no issues
|
||||
*/
|
||||
|
||||
|
||||
function isDate(val, tmstmp) {
|
||||
var value = val.replace(/[.|*|^|+|//|@]/g, '-');
|
||||
var arrayVal = value.split('-');
|
||||
|
||||
for (var a = 0; a < arrayVal.length; a++) {
|
||||
if (arrayVal[a].length === 1) {
|
||||
arrayVal[a] = fractionReplace(arrayVal[a]);
|
||||
}
|
||||
}
|
||||
|
||||
value = arrayVal.join('-');
|
||||
var pos = 2;
|
||||
var dtexp = new RegExp(/^([0-9]{4})-(((01|03|05|07|08|10|12)-((0[0-9])|([1-2][0-9])|(3[0-1])))|((02|04|06|09|11)-((0[0-9])|([1-2][0-9])|30))|((00)-(00)))$/);
|
||||
|
||||
if (value.length === 8) {
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
if (dtexp.test(value)) {
|
||||
var month = parseInt(value.substring(pos + 3, pos + 5), 10);
|
||||
var day = parseInt(value.substring(pos + 6, pos + 8), 10);
|
||||
var year = parseInt(value.substring(0, pos + 2), 10);
|
||||
|
||||
if (month === 2 && day > daysInFebruary(year)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value.substring(0, pos + 2).length === 2) {
|
||||
year = parseInt('20' + value.substring(0, pos + 2), 10);
|
||||
}
|
||||
|
||||
if (tmstmp === true) {
|
||||
if (year < 1978) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (year > 2038 || year > 2037 && day > 19 && month >= 1 || year > 2037 && month > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/* function to check the validity of time
|
||||
* The following patterns are accepted in this validation (accepted in mysql as well)
|
||||
* 1) 2:3:4
|
||||
* 2) 2:23:43
|
||||
* 3) 2:23:43.123456
|
||||
*/
|
||||
|
||||
|
||||
function isTime(val) {
|
||||
var arrayVal = val.split(':');
|
||||
|
||||
for (var a = 0, l = arrayVal.length; a < l; a++) {
|
||||
if (arrayVal[a].length === 1) {
|
||||
arrayVal[a] = fractionReplace(arrayVal[a]);
|
||||
}
|
||||
}
|
||||
|
||||
var newVal = arrayVal.join(':');
|
||||
var tmexp = new RegExp(/^(-)?(([0-7]?[0-9][0-9])|(8[0-2][0-9])|(83[0-8])):((0[0-9])|([1-5][0-9])):((0[0-9])|([1-5][0-9]))(\.[0-9]{1,6}){0,1}$/);
|
||||
return tmexp.test(newVal);
|
||||
}
|
||||
/**
|
||||
* To check whether insert section is ignored or not
|
||||
*/
|
||||
|
||||
|
||||
function checkForCheckbox(multiEdit) {
|
||||
if ($('#insert_ignore_' + multiEdit).length) {
|
||||
return $('#insert_ignore_' + multiEdit).is(':unchecked');
|
||||
}
|
||||
|
||||
return true;
|
||||
} // used in Search page mostly for INT fields
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
||||
|
||||
function verifyAfterSearchFieldChange(index, searchFormId) {
|
||||
var $thisInput = $('input[name=\'criteriaValues[' + index + ']\']'); // Add data-skip-validators attribute to skip validation in changeValueFieldType function
|
||||
|
||||
if ($('#fieldID_' + index).data('data-skip-validators')) {
|
||||
$(searchFormId).validate().destroy();
|
||||
return;
|
||||
} // validation for integer type
|
||||
|
||||
|
||||
if ($thisInput.data('type') === 'INT' || $thisInput.data('type') === 'TINYINT') {
|
||||
// Trim spaces if it's an integer
|
||||
$thisInput.val($thisInput.val().trim());
|
||||
var hasMultiple = $thisInput.prop('multiple');
|
||||
|
||||
if (hasMultiple) {
|
||||
$(searchFormId).validate({
|
||||
// update errors as we write
|
||||
onkeyup: function onkeyup(element) {
|
||||
$(element).valid();
|
||||
}
|
||||
}); // validator method for IN(...), NOT IN(...)
|
||||
// BETWEEN and NOT BETWEEN
|
||||
|
||||
jQuery.validator.addMethod('validationFunctionForMultipleInt', function (value) {
|
||||
return value.match(/^(?:(?:\d\s*)|\s*)+(?:,\s*\d+)*$/i) !== null;
|
||||
}, Messages.strEnterValidNumber);
|
||||
validateMultipleIntField($thisInput, true);
|
||||
} else {
|
||||
$(searchFormId).validate({
|
||||
// update errors as we write
|
||||
onkeyup: function onkeyup(element) {
|
||||
$(element).valid();
|
||||
}
|
||||
});
|
||||
validateIntField($thisInput, true);
|
||||
} // Update error on dropdown change
|
||||
|
||||
|
||||
$thisInput.valid();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Validate the an input contains multiple int values
|
||||
* @param {jQuery} jqueryInput the Jquery object
|
||||
* @param {boolean} returnValueIfFine the value to return if the validator passes
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
|
||||
function validateMultipleIntField(jqueryInput, returnValueIfFine) {
|
||||
// removing previous rules
|
||||
jqueryInput.rules('remove');
|
||||
jqueryInput.rules('add', {
|
||||
validationFunctionForMultipleInt: {
|
||||
param: jqueryInput.value,
|
||||
depends: function depends() {
|
||||
return returnValueIfFine;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Validate the an input contains an int value
|
||||
* @param {jQuery} jqueryInput the Jquery object
|
||||
* @param {boolean} returnValueIfIsNumber the value to return if the validator passes
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
|
||||
function validateIntField(jqueryInput, returnValueIfIsNumber) {
|
||||
var mini = parseInt(jqueryInput.data('min'));
|
||||
var maxi = parseInt(jqueryInput.data('max')); // removing previous rules
|
||||
|
||||
jqueryInput.rules('remove');
|
||||
jqueryInput.rules('add', {
|
||||
number: {
|
||||
param: true,
|
||||
depends: function depends() {
|
||||
return returnValueIfIsNumber;
|
||||
}
|
||||
},
|
||||
min: {
|
||||
param: mini,
|
||||
depends: function depends() {
|
||||
if (isNaN(jqueryInput.val())) {
|
||||
return false;
|
||||
} else {
|
||||
return returnValueIfIsNumber;
|
||||
}
|
||||
}
|
||||
},
|
||||
max: {
|
||||
param: maxi,
|
||||
depends: function depends() {
|
||||
if (isNaN(jqueryInput.val())) {
|
||||
return false;
|
||||
} else {
|
||||
return returnValueIfIsNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function verificationsAfterFieldChange(urlField, multiEdit, theType) {
|
||||
var evt = window.event || arguments.callee.caller.arguments[0];
|
||||
var target = evt.target || evt.srcElement;
|
||||
var $thisInput = $(':input[name^=\'fields[multi_edit][' + multiEdit + '][' + urlField + ']\']'); // the function drop-down that corresponds to this input field
|
||||
|
||||
var $thisFunction = $('select[name=\'funcs[multi_edit][' + multiEdit + '][' + urlField + ']\']');
|
||||
var functionSelected = false;
|
||||
|
||||
if (typeof $thisFunction.val() !== 'undefined' && $thisFunction.val() !== null && $thisFunction.val().length > 0) {
|
||||
functionSelected = true;
|
||||
} // To generate the textbox that can take the salt
|
||||
|
||||
|
||||
var newSaltBox = '<br><input type=text name=salt[multi_edit][' + multiEdit + '][' + urlField + ']' + ' id=salt_' + target.id + ' placeholder=\'' + Messages.strEncryptionKey + '\'>'; // If encrypting or decrypting functions that take salt as input is selected append the new textbox for salt
|
||||
|
||||
if (target.value === 'AES_ENCRYPT' || target.value === 'AES_DECRYPT' || target.value === 'DES_ENCRYPT' || target.value === 'DES_DECRYPT' || target.value === 'ENCRYPT') {
|
||||
if (!$('#salt_' + target.id).length) {
|
||||
$thisInput.after(newSaltBox);
|
||||
}
|
||||
} else {
|
||||
// Remove the textbox for salt
|
||||
$('#salt_' + target.id).prev('br').remove();
|
||||
$('#salt_' + target.id).remove();
|
||||
} // Remove possible blocking rules if the user changed functions
|
||||
|
||||
|
||||
$('#' + target.id).rules('remove', 'validationFunctionForMd5');
|
||||
$('#' + target.id).rules('remove', 'validationFunctionForAesDesEncrypt');
|
||||
|
||||
if (target.value === 'MD5') {
|
||||
$('#' + target.id).rules('add', {
|
||||
validationFunctionForMd5: {
|
||||
param: $thisInput,
|
||||
depends: function depends() {
|
||||
return checkForCheckbox(multiEdit);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (target.value === 'DES_ENCRYPT' || target.value === 'AES_ENCRYPT') {
|
||||
$('#' + target.id).rules('add', {
|
||||
validationFunctionForAesDesEncrypt: {
|
||||
param: $thisInput,
|
||||
depends: function depends() {
|
||||
return checkForCheckbox(multiEdit);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (target.value === 'HEX' && theType.substring(0, 3) === 'int') {
|
||||
// Add note when HEX function is selected on a int
|
||||
var newHexInfo = '<br><p id="note' + target.id + '">' + Messages.HexConversionInfo + '</p>';
|
||||
|
||||
if (!$('#note' + target.id).length) {
|
||||
$thisInput.after(newHexInfo);
|
||||
}
|
||||
} else {
|
||||
$('#note' + target.id).prev('br').remove();
|
||||
$('#note' + target.id).remove();
|
||||
} // Unchecks the corresponding "NULL" control
|
||||
|
||||
|
||||
$('input[name=\'fields_null[multi_edit][' + multiEdit + '][' + urlField + ']\']').prop('checked', false); // Unchecks the Ignore checkbox for the current row
|
||||
|
||||
$('input[name=\'insert_ignore_' + multiEdit + '\']').prop('checked', false);
|
||||
var charExceptionHandling;
|
||||
|
||||
if (theType.substring(0, 4) === 'char') {
|
||||
charExceptionHandling = theType.substring(5, 6);
|
||||
} else if (theType.substring(0, 7) === 'varchar') {
|
||||
charExceptionHandling = theType.substring(8, 9);
|
||||
}
|
||||
|
||||
if (functionSelected) {
|
||||
$thisInput.removeAttr('min');
|
||||
$thisInput.removeAttr('max'); // @todo: put back attributes if corresponding function is deselected
|
||||
}
|
||||
|
||||
if ($thisInput.data('rulesadded') === null && !functionSelected) {
|
||||
// call validate before adding rules
|
||||
$($thisInput[0].form).validate(); // validate for date time
|
||||
|
||||
if (theType === 'datetime' || theType === 'time' || theType === 'date' || theType === 'timestamp') {
|
||||
$thisInput.rules('add', {
|
||||
validationFunctionForDateTime: {
|
||||
param: theType,
|
||||
depends: function depends() {
|
||||
return checkForCheckbox(multiEdit);
|
||||
}
|
||||
}
|
||||
});
|
||||
} // validation for integer type
|
||||
|
||||
|
||||
if ($thisInput.data('type') === 'INT') {
|
||||
validateIntField($thisInput, checkForCheckbox(multiEdit)); // validation for CHAR types
|
||||
} else if ($thisInput.data('type') === 'CHAR') {
|
||||
var maxlen = $thisInput.data('maxlength');
|
||||
|
||||
if (typeof maxlen !== 'undefined') {
|
||||
if (maxlen <= 4) {
|
||||
maxlen = charExceptionHandling;
|
||||
}
|
||||
|
||||
$thisInput.rules('add', {
|
||||
maxlength: {
|
||||
param: maxlen,
|
||||
depends: function depends() {
|
||||
return checkForCheckbox(multiEdit);
|
||||
}
|
||||
}
|
||||
});
|
||||
} // validate binary & blob types
|
||||
|
||||
} else if ($thisInput.data('type') === 'HEX') {
|
||||
$thisInput.rules('add', {
|
||||
validationFunctionForHex: {
|
||||
param: true,
|
||||
depends: function depends() {
|
||||
return checkForCheckbox(multiEdit);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$thisInput.data('rulesadded', true);
|
||||
} else if ($thisInput.data('rulesadded') === true && functionSelected) {
|
||||
// remove any rules added
|
||||
$thisInput.rules('remove'); // remove any error messages
|
||||
|
||||
$thisInput.removeClass('error').removeAttr('aria-invalid').siblings('.error').remove();
|
||||
$thisInput.data('rulesadded', null);
|
||||
}
|
||||
}
|
||||
/* End of fields validation*/
|
||||
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
|
||||
|
||||
AJAX.registerTeardown('table/change.js', function () {
|
||||
$(document).off('click', 'span.open_gis_editor');
|
||||
$(document).off('click', 'input[name^=\'insert_ignore_\']');
|
||||
$(document).off('click', 'input[name=\'gis_data[save]\']');
|
||||
$(document).off('click', 'input.checkbox_null');
|
||||
$('select[name="submit_type"]').off('change');
|
||||
$(document).off('change', '#insert_rows');
|
||||
});
|
||||
/**
|
||||
* Ajax handlers for Change Table page
|
||||
*
|
||||
* Actions Ajaxified here:
|
||||
* Submit Data to be inserted into the table.
|
||||
* Restart insertion with 'N' rows.
|
||||
*/
|
||||
|
||||
AJAX.registerOnload('table/change.js', function () {
|
||||
if ($('#insertForm').length) {
|
||||
// validate the comment form when it is submitted
|
||||
$('#insertForm').validate();
|
||||
jQuery.validator.addMethod('validationFunctionForHex', function (value) {
|
||||
return value.match(/^[a-f0-9]*$/i) !== null;
|
||||
});
|
||||
jQuery.validator.addMethod('validationFunctionForMd5', function (value, element, options) {
|
||||
return !(value.substring(0, 3) === 'MD5' && typeof options.data('maxlength') !== 'undefined' && options.data('maxlength') < 32);
|
||||
});
|
||||
jQuery.validator.addMethod('validationFunctionForAesDesEncrypt', function (value, element, options) {
|
||||
var funType = value.substring(0, 3);
|
||||
|
||||
if (funType !== 'AES' && funType !== 'DES') {
|
||||
return false;
|
||||
}
|
||||
|
||||
var dataType = options.data('type');
|
||||
|
||||
if (dataType === 'HEX' || dataType === 'CHAR') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
jQuery.validator.addMethod('validationFunctionForDateTime', function (value, element, options) {
|
||||
var dtValue = value;
|
||||
var theType = options;
|
||||
|
||||
if (theType === 'date') {
|
||||
return isDate(dtValue);
|
||||
} else if (theType === 'time') {
|
||||
return isTime(dtValue);
|
||||
} else if (theType === 'datetime' || theType === 'timestamp') {
|
||||
var tmstmp = false;
|
||||
dtValue = dtValue.trim();
|
||||
|
||||
if (dtValue === 'CURRENT_TIMESTAMP' || dtValue === 'current_timestamp()') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (theType === 'timestamp') {
|
||||
tmstmp = true;
|
||||
}
|
||||
|
||||
if (dtValue === '0000-00-00 00:00:00') {
|
||||
return true;
|
||||
}
|
||||
|
||||
var dv = dtValue.indexOf(' ');
|
||||
|
||||
if (dv === -1) {
|
||||
// Only the date component, which is valid
|
||||
return isDate(dtValue, tmstmp);
|
||||
}
|
||||
|
||||
return isDate(dtValue.substring(0, dv), tmstmp) && isTime(dtValue.substring(dv + 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
/*
|
||||
* message extending script must be run
|
||||
* after initiation of functions
|
||||
*/
|
||||
|
||||
|
||||
extendingValidatorMessages();
|
||||
$.datepicker.initialized = false;
|
||||
$(document).on('click', 'span.open_gis_editor', 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 inputName = $span.parent('td').children('input[type=\'text\']').attr('name');
|
||||
openGISEditor();
|
||||
|
||||
if (!gisEditorLoaded) {
|
||||
loadJSAndGISEditor(value, field, type, inputName);
|
||||
} else {
|
||||
loadGISEditor(value, field, type, inputName);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Forced validation check of fields
|
||||
*/
|
||||
|
||||
$(document).on('click', 'input[name^=\'insert_ignore_\']', function () {
|
||||
$('#insertForm').valid();
|
||||
});
|
||||
/**
|
||||
* Uncheck the null checkbox as geometry data is placed on the input field
|
||||
*/
|
||||
|
||||
$(document).on('click', 'input[name=\'gis_data[save]\']', function () {
|
||||
var inputName = $('form#gis_data_editor_form').find('input[name=\'input_name\']').val();
|
||||
var $nullCheckbox = $('input[name=\'' + inputName + '\']').parents('tr').find('.checkbox_null');
|
||||
$nullCheckbox.prop('checked', false);
|
||||
});
|
||||
/**
|
||||
* Handles all current checkboxes for Null; this only takes care of the
|
||||
* checkboxes on currently displayed rows as the rows generated by
|
||||
* "Continue insertion" are handled in the "Continue insertion" code
|
||||
*
|
||||
*/
|
||||
|
||||
$(document).on('click', 'input.checkbox_null', function () {
|
||||
nullify( // use hidden fields populated by /table/change
|
||||
$(this).siblings('.nullify_code').val(), $(this).closest('tr').find('input:hidden').first().val(), $(this).siblings('.hashed_field').val(), $(this).siblings('.multi_edit').val());
|
||||
});
|
||||
/**
|
||||
* Reset the auto_increment column to 0 when selecting any of the
|
||||
* insert options in submit_type-dropdown. Only perform the reset
|
||||
* when we are in edit-mode, and not in insert-mode(no previous value
|
||||
* available).
|
||||
*/
|
||||
|
||||
$('select[name="submit_type"]').on('change', function () {
|
||||
var thisElemSubmitTypeVal = $(this).val();
|
||||
var $table = $('table.insertRowTable');
|
||||
var autoIncrementColumn = $table.find('input[name^="auto_increment"]');
|
||||
autoIncrementColumn.each(function () {
|
||||
var $thisElemAIField = $(this);
|
||||
var thisElemName = $thisElemAIField.attr('name');
|
||||
var prevValueField = $table.find('input[name="' + thisElemName.replace('auto_increment', 'fields_prev') + '"]');
|
||||
var valueField = $table.find('input[name="' + thisElemName.replace('auto_increment', 'fields') + '"]');
|
||||
var previousValue = $(prevValueField).val();
|
||||
|
||||
if (previousValue !== undefined) {
|
||||
if (thisElemSubmitTypeVal === 'insert' || thisElemSubmitTypeVal === 'insertignore' || thisElemSubmitTypeVal === 'showinsert') {
|
||||
$(valueField).val(null);
|
||||
} else {
|
||||
$(valueField).val(previousValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Handle ENTER key when press on Continue insert with field
|
||||
*/
|
||||
|
||||
$('#insert_rows').on('keypress', function (e) {
|
||||
var key = e.which;
|
||||
|
||||
if (key === 13) {
|
||||
addNewContinueInsertionFields(e);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Continue Insertion form
|
||||
*/
|
||||
|
||||
$(document).on('change', '#insert_rows', addNewContinueInsertionFields);
|
||||
});
|
||||
|
||||
function addNewContinueInsertionFields(event) {
|
||||
event.preventDefault();
|
||||
/**
|
||||
* @var columnCount Number of number of columns table has.
|
||||
*/
|
||||
|
||||
var columnCount = $('table.insertRowTable').first().find('tr').has('input[name*=\'fields_name\']').length;
|
||||
/**
|
||||
* @var curr_rows Number of current insert rows already on page
|
||||
*/
|
||||
|
||||
var currRows = $('table.insertRowTable').length;
|
||||
/**
|
||||
* @var target_rows Number of rows the user wants
|
||||
*/
|
||||
|
||||
var targetRows = $('#insert_rows').val(); // remove all datepickers
|
||||
|
||||
$('input.datefield, input.datetimefield').each(function () {
|
||||
$(this).datepicker('destroy');
|
||||
});
|
||||
|
||||
if (currRows < targetRows) {
|
||||
var tempIncrementIndex = function tempIncrementIndex() {
|
||||
var $thisElement = $(this);
|
||||
/**
|
||||
* Extract the index from the name attribute for all input/select fields and increment it
|
||||
* name is of format funcs[multi_edit][10][<long random string of alphanum chars>]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @var this_name String containing name of the input/select elements
|
||||
*/
|
||||
|
||||
var thisName = $thisElement.attr('name');
|
||||
/** split {@link thisName} at [10], so we have the parts that can be concatenated later */
|
||||
|
||||
var nameParts = thisName.split(/\[\d+\]/);
|
||||
/** extract the [10] from {@link nameParts} */
|
||||
|
||||
var oldRowIndexString = thisName.match(/\[\d+\]/)[0];
|
||||
/** extract 10 - had to split into two steps to accomodate double digits */
|
||||
|
||||
var oldRowIndex = parseInt(oldRowIndexString.match(/\d+/)[0], 10);
|
||||
/** calculate next index i.e. 11 */
|
||||
|
||||
newRowIndex = oldRowIndex + 1;
|
||||
/** generate the new name i.e. funcs[multi_edit][11][foobarbaz] */
|
||||
|
||||
var newName = nameParts[0] + '[' + newRowIndex + ']' + nameParts[1];
|
||||
var hashedField = nameParts[1].match(/\[(.+)\]/)[1];
|
||||
$thisElement.attr('name', newName);
|
||||
/** If element is select[name*='funcs'], update id */
|
||||
|
||||
if ($thisElement.is('select[name*=\'funcs\']')) {
|
||||
var thisId = $thisElement.attr('id');
|
||||
var idParts = thisId.split(/_/);
|
||||
var oldIdIndex = idParts[1];
|
||||
var prevSelectedValue = $('#field_' + oldIdIndex + '_1').val();
|
||||
var newIdIndex = parseInt(oldIdIndex) + columnCount;
|
||||
var newId = 'field_' + newIdIndex + '_1';
|
||||
$thisElement.attr('id', newId);
|
||||
$thisElement.find('option').filter(function () {
|
||||
return $(this).text() === prevSelectedValue;
|
||||
}).attr('selected', 'selected'); // If salt field is there then update its id.
|
||||
|
||||
var nextSaltInput = $thisElement.parent().next('td').next('td').find('input[name*=\'salt\']');
|
||||
|
||||
if (nextSaltInput.length !== 0) {
|
||||
nextSaltInput.attr('id', 'salt_' + newId);
|
||||
}
|
||||
} // handle input text fields and textareas
|
||||
|
||||
|
||||
if ($thisElement.is('.textfield') || $thisElement.is('.char') || $thisElement.is('textarea')) {
|
||||
// do not remove the 'value' attribute for ENUM columns
|
||||
// special handling for radio fields after updating ids to unique - see below
|
||||
if ($thisElement.closest('tr').find('span.column_type').html() !== 'enum') {
|
||||
$thisElement.val($thisElement.closest('tr').find('span.default_value').html());
|
||||
}
|
||||
|
||||
$thisElement.off('change') // Remove onchange attribute that was placed
|
||||
// by /table/change; it refers to the wrong row index
|
||||
.attr('onchange', null) // Keep these values to be used when the element
|
||||
// will change
|
||||
.data('hashed_field', hashedField).data('new_row_index', newRowIndex).on('change', function () {
|
||||
var $changedElement = $(this);
|
||||
verificationsAfterFieldChange($changedElement.data('hashed_field'), $changedElement.data('new_row_index'), $changedElement.closest('tr').find('span.column_type').html());
|
||||
});
|
||||
}
|
||||
|
||||
if ($thisElement.is('.checkbox_null')) {
|
||||
$thisElement // this event was bound earlier by jQuery but
|
||||
// to the original row, not the cloned one, so unbind()
|
||||
.off('click') // Keep these values to be used when the element
|
||||
// will be clicked
|
||||
.data('hashed_field', hashedField).data('new_row_index', newRowIndex).on('click', function () {
|
||||
var $changedElement = $(this);
|
||||
nullify($changedElement.siblings('.nullify_code').val(), $thisElement.closest('tr').find('input:hidden').first().val(), $changedElement.data('hashed_field'), '[multi_edit][' + $changedElement.data('new_row_index') + ']');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var tempReplaceAnchor = function tempReplaceAnchor() {
|
||||
var $anchor = $(this);
|
||||
var newValue = 'rownumber=' + newRowIndex; // needs improvement in case something else inside
|
||||
// the href contains this pattern
|
||||
|
||||
var newHref = $anchor.attr('href').replace(/rownumber=\d+/, newValue);
|
||||
$anchor.attr('href', newHref);
|
||||
};
|
||||
|
||||
var restoreValue = function restoreValue() {
|
||||
if ($(this).closest('tr').find('span.column_type').html() === 'enum') {
|
||||
if ($(this).val() === $checkedValue) {
|
||||
$(this).prop('checked', true);
|
||||
} else {
|
||||
$(this).prop('checked', false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
while (currRows < targetRows) {
|
||||
/**
|
||||
* @var $last_row Object referring to the last row
|
||||
*/
|
||||
var $lastRow = $('#insertForm').find('.insertRowTable').last(); // need to access this at more than one level
|
||||
// (also needs improvement because it should be calculated
|
||||
// just once per cloned row, not once per column)
|
||||
|
||||
var newRowIndex = 0;
|
||||
var $checkedValue = $lastRow.find('input:checked').val(); // Clone the insert tables
|
||||
|
||||
$lastRow.clone(true, true).insertBefore('#actions_panel').find('input[name*=multi_edit],select[name*=multi_edit],textarea[name*=multi_edit]').each(tempIncrementIndex).end().find('.foreign_values_anchor').each(tempReplaceAnchor);
|
||||
var $oldRow = $lastRow.find('.textfield');
|
||||
$oldRow.each(restoreValue); // set the value of enum field of new row to default
|
||||
|
||||
var $newRow = $('#insertForm').find('.insertRowTable').last();
|
||||
$newRow.find('.textfield').each(function () {
|
||||
if ($(this).closest('tr').find('span.column_type').html() === 'enum') {
|
||||
if ($(this).val() === $(this).closest('tr').find('span.default_value').html()) {
|
||||
$(this).prop('checked', true);
|
||||
} else {
|
||||
$(this).prop('checked', false);
|
||||
}
|
||||
}
|
||||
}); // Insert/Clone the ignore checkboxes
|
||||
|
||||
if (currRows === 1) {
|
||||
$('<input id="insert_ignore_1" type="checkbox" name="insert_ignore_1" checked="checked">').insertBefore($('table.insertRowTable').last()).after('<label for="insert_ignore_1">' + Messages.strIgnore + '</label>');
|
||||
} else {
|
||||
/**
|
||||
* @var $last_checkbox Object reference to the last checkbox in #insertForm
|
||||
*/
|
||||
var $lastCheckbox = $('#insertForm').children('input:checkbox').last();
|
||||
/** name of {@link $lastCheckbox} */
|
||||
|
||||
var lastCheckboxName = $lastCheckbox.attr('name');
|
||||
/** index of {@link $lastCheckbox} */
|
||||
|
||||
var lastCheckboxIndex = parseInt(lastCheckboxName.match(/\d+/), 10);
|
||||
/** name of new {@link $lastCheckbox} */
|
||||
|
||||
var newName = lastCheckboxName.replace(/\d+/, lastCheckboxIndex + 1);
|
||||
$('<br><div class="clearfloat"></div>').insertBefore($('table.insertRowTable').last());
|
||||
$lastCheckbox.clone().attr({
|
||||
'id': newName,
|
||||
'name': newName
|
||||
}).prop('checked', true).insertBefore($('table.insertRowTable').last());
|
||||
$('label[for^=insert_ignore]').last().clone().attr('for', newName).insertBefore($('table.insertRowTable').last());
|
||||
$('<br>').insertBefore($('table.insertRowTable').last());
|
||||
}
|
||||
|
||||
currRows++;
|
||||
} // recompute tabindex for text fields and other controls at footer;
|
||||
// IMO it's not really important to handle the tabindex for
|
||||
// function and Null
|
||||
|
||||
|
||||
var tabIndex = 0;
|
||||
$('.textfield, .char, textarea').each(function () {
|
||||
tabIndex++;
|
||||
$(this).attr('tabindex', tabIndex); // update the IDs of textfields to ensure that they are unique
|
||||
|
||||
$(this).attr('id', 'field_' + tabIndex + '_3');
|
||||
});
|
||||
$('.control_at_footer').each(function () {
|
||||
tabIndex++;
|
||||
$(this).attr('tabindex', tabIndex);
|
||||
});
|
||||
} else if (currRows > targetRows) {
|
||||
/**
|
||||
* Displays alert if data loss possible on decrease
|
||||
* of rows.
|
||||
*/
|
||||
var checkLock = jQuery.isEmptyObject(AJAX.lockedTargets);
|
||||
|
||||
if (checkLock || confirm(Messages.strConfirmRowChange) === true) {
|
||||
while (currRows > targetRows) {
|
||||
$('input[id^=insert_ignore]').last().nextUntil('fieldset').addBack().remove();
|
||||
currRows--;
|
||||
}
|
||||
} else {
|
||||
document.getElementById('insert_rows').value = currRows;
|
||||
}
|
||||
} // Add all the required datepickers back
|
||||
|
||||
|
||||
Functions.addDateTimePicker();
|
||||
} // eslint-disable-next-line no-unused-vars
|
||||
|
||||
|
||||
function changeValueFieldType(elem, searchIndex) {
|
||||
var fieldsValue = $('input#fieldID_' + searchIndex);
|
||||
|
||||
if (0 === fieldsValue.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var type = $(elem).val();
|
||||
|
||||
if ('LIKE' === type || 'LIKE %...%' === type || 'NOT LIKE' === type) {
|
||||
$('#fieldID_' + searchIndex).data('data-skip-validators', true);
|
||||
return;
|
||||
} else {
|
||||
$('#fieldID_' + searchIndex).data('data-skip-validators', false);
|
||||
}
|
||||
|
||||
if ('IN (...)' === type || 'NOT IN (...)' === type || 'BETWEEN' === type || 'NOT BETWEEN' === type) {
|
||||
$('#fieldID_' + searchIndex).prop('multiple', true);
|
||||
} else {
|
||||
$('#fieldID_' + searchIndex).prop('multiple', false);
|
||||
}
|
||||
}
|
437
admin/phpMyAdmin/js/dist/table/chart.js
vendored
Normal file
437
admin/phpMyAdmin/js/dist/table/chart.js
vendored
Normal file
|
@ -0,0 +1,437 @@
|
|||
"use strict";
|
||||
|
||||
/* global ColumnType, DataTable, JQPlotChartFactory */
|
||||
// js/chart.js
|
||||
|
||||
/* global codeMirrorEditor */
|
||||
// js/functions.js
|
||||
var chartData = {};
|
||||
var tempChartTitle;
|
||||
var currentChart = null;
|
||||
var currentSettings = null;
|
||||
var dateTimeCols = [];
|
||||
var numericCols = [];
|
||||
|
||||
function extractDate(dateString) {
|
||||
var matches;
|
||||
var match;
|
||||
var dateTimeRegExp = /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/;
|
||||
var dateRegExp = /[0-9]{4}-[0-9]{2}-[0-9]{2}/;
|
||||
matches = dateTimeRegExp.exec(dateString);
|
||||
|
||||
if (matches !== null && matches.length > 0) {
|
||||
match = matches[0];
|
||||
return new Date(match.substr(0, 4), parseInt(match.substr(5, 2), 10) - 1, match.substr(8, 2), match.substr(11, 2), match.substr(14, 2), match.substr(17, 2));
|
||||
} else {
|
||||
matches = dateRegExp.exec(dateString);
|
||||
|
||||
if (matches !== null && matches.length > 0) {
|
||||
match = matches[0];
|
||||
return new Date(match.substr(0, 4), parseInt(match.substr(5, 2), 10) - 1, match.substr(8, 2));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function queryChart(data, columnNames, settings) {
|
||||
if ($('#querychart').length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var plotSettings = {
|
||||
title: {
|
||||
text: settings.title,
|
||||
escapeHtml: true
|
||||
},
|
||||
grid: {
|
||||
drawBorder: false,
|
||||
shadow: false,
|
||||
background: 'rgba(0,0,0,0)'
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
placement: 'outsideGrid',
|
||||
location: 'e',
|
||||
rendererOptions: {
|
||||
numberColumns: 2
|
||||
}
|
||||
},
|
||||
axes: {
|
||||
xaxis: {
|
||||
label: Functions.escapeHtml(settings.xaxisLabel)
|
||||
},
|
||||
yaxis: {
|
||||
label: settings.yaxisLabel
|
||||
}
|
||||
},
|
||||
stackSeries: settings.stackSeries
|
||||
}; // create the chart
|
||||
|
||||
var factory = new JQPlotChartFactory();
|
||||
var chart = factory.createChart(settings.type, 'querychart'); // create the data table and add columns
|
||||
|
||||
var dataTable = new DataTable();
|
||||
|
||||
if (settings.type === 'timeline') {
|
||||
dataTable.addColumn(ColumnType.DATE, columnNames[settings.mainAxis]);
|
||||
} else if (settings.type === 'scatter') {
|
||||
dataTable.addColumn(ColumnType.NUMBER, columnNames[settings.mainAxis]);
|
||||
} else {
|
||||
dataTable.addColumn(ColumnType.STRING, columnNames[settings.mainAxis]);
|
||||
}
|
||||
|
||||
var i;
|
||||
var values = [];
|
||||
|
||||
if (settings.seriesColumn === null) {
|
||||
$.each(settings.selectedSeries, function (index, element) {
|
||||
dataTable.addColumn(ColumnType.NUMBER, columnNames[element]);
|
||||
}); // set data to the data table
|
||||
|
||||
var columnsToExtract = [settings.mainAxis];
|
||||
$.each(settings.selectedSeries, function (index, element) {
|
||||
columnsToExtract.push(element);
|
||||
});
|
||||
var newRow;
|
||||
var row;
|
||||
var col;
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
row = data[i];
|
||||
newRow = [];
|
||||
|
||||
for (var j = 0; j < columnsToExtract.length; j++) {
|
||||
col = columnNames[columnsToExtract[j]];
|
||||
|
||||
if (j === 0) {
|
||||
if (settings.type === 'timeline') {
|
||||
// first column is date type
|
||||
newRow.push(extractDate(row[col]));
|
||||
} else if (settings.type === 'scatter') {
|
||||
newRow.push(parseFloat(row[col]));
|
||||
} else {
|
||||
// first column is string type
|
||||
newRow.push(row[col]);
|
||||
}
|
||||
} else {
|
||||
// subsequent columns are of type, number
|
||||
newRow.push(parseFloat(row[col]));
|
||||
}
|
||||
}
|
||||
|
||||
values.push(newRow);
|
||||
}
|
||||
|
||||
dataTable.setData(values);
|
||||
} else {
|
||||
var seriesNames = {};
|
||||
var seriesNumber = 1;
|
||||
var seriesColumnName = columnNames[settings.seriesColumn];
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (!seriesNames[data[i][seriesColumnName]]) {
|
||||
seriesNames[data[i][seriesColumnName]] = seriesNumber;
|
||||
seriesNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
$.each(seriesNames, function (seriesName) {
|
||||
dataTable.addColumn(ColumnType.NUMBER, seriesName);
|
||||
});
|
||||
var valueMap = {};
|
||||
var xValue;
|
||||
var value;
|
||||
var mainAxisName = columnNames[settings.mainAxis];
|
||||
var valueColumnName = columnNames[settings.valueColumn];
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
xValue = data[i][mainAxisName];
|
||||
value = valueMap[xValue];
|
||||
|
||||
if (!value) {
|
||||
value = [xValue];
|
||||
valueMap[xValue] = value;
|
||||
}
|
||||
|
||||
seriesNumber = seriesNames[data[i][seriesColumnName]];
|
||||
value[seriesNumber] = parseFloat(data[i][valueColumnName]);
|
||||
}
|
||||
|
||||
$.each(valueMap, function (index, value) {
|
||||
values.push(value);
|
||||
});
|
||||
dataTable.setData(values);
|
||||
} // draw the chart and return the chart object
|
||||
|
||||
|
||||
chart.draw(dataTable, plotSettings);
|
||||
return chart;
|
||||
}
|
||||
|
||||
function drawChart() {
|
||||
currentSettings.width = $('#resizer').width() - 20;
|
||||
currentSettings.height = $('#resizer').height() - 20; // TODO: a better way using .redraw() ?
|
||||
|
||||
if (currentChart !== null) {
|
||||
currentChart.destroy();
|
||||
}
|
||||
|
||||
var columnNames = [];
|
||||
$('select[name="chartXAxis"] option').each(function () {
|
||||
columnNames.push(Functions.escapeHtml($(this).text()));
|
||||
});
|
||||
|
||||
try {
|
||||
currentChart = queryChart(chartData, columnNames, currentSettings);
|
||||
|
||||
if (currentChart !== null) {
|
||||
$('#saveChart').attr('href', currentChart.toImageString());
|
||||
}
|
||||
} catch (err) {
|
||||
Functions.ajaxShowMessage(err.message, false);
|
||||
}
|
||||
}
|
||||
|
||||
function getSelectedSeries() {
|
||||
var val = $('select[name="chartSeries"]').val() || [];
|
||||
var ret = [];
|
||||
$.each(val, function (i, v) {
|
||||
ret.push(parseInt(v, 10));
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function onXAxisChange() {
|
||||
var $xAxisSelect = $('select[name="chartXAxis"]');
|
||||
currentSettings.mainAxis = parseInt($xAxisSelect.val(), 10);
|
||||
|
||||
if (dateTimeCols.indexOf(currentSettings.mainAxis) !== -1) {
|
||||
$('span.span_timeline').show();
|
||||
} else {
|
||||
$('span.span_timeline').hide();
|
||||
|
||||
if (currentSettings.type === 'timeline') {
|
||||
$('input#radio_line').prop('checked', true);
|
||||
currentSettings.type = 'line';
|
||||
}
|
||||
}
|
||||
|
||||
if (numericCols.indexOf(currentSettings.mainAxis) !== -1) {
|
||||
$('span.span_scatter').show();
|
||||
} else {
|
||||
$('span.span_scatter').hide();
|
||||
|
||||
if (currentSettings.type === 'scatter') {
|
||||
$('input#radio_line').prop('checked', true);
|
||||
currentSettings.type = 'line';
|
||||
}
|
||||
}
|
||||
|
||||
var xAxisTitle = $xAxisSelect.children('option:selected').text();
|
||||
$('input[name="xaxis_label"]').val(xAxisTitle);
|
||||
currentSettings.xaxisLabel = xAxisTitle;
|
||||
}
|
||||
|
||||
function onDataSeriesChange() {
|
||||
var $seriesSelect = $('select[name="chartSeries"]');
|
||||
currentSettings.selectedSeries = getSelectedSeries();
|
||||
var yAxisTitle;
|
||||
|
||||
if (currentSettings.selectedSeries.length === 1) {
|
||||
$('span.span_pie').show();
|
||||
yAxisTitle = $seriesSelect.children('option:selected').text();
|
||||
} else {
|
||||
$('span.span_pie').hide();
|
||||
|
||||
if (currentSettings.type === 'pie') {
|
||||
$('input#radio_line').prop('checked', true);
|
||||
currentSettings.type = 'line';
|
||||
}
|
||||
|
||||
yAxisTitle = Messages.strYValues;
|
||||
}
|
||||
|
||||
$('input[name="yaxis_label"]').val(yAxisTitle);
|
||||
currentSettings.yaxisLabel = yAxisTitle;
|
||||
}
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
|
||||
|
||||
AJAX.registerTeardown('table/chart.js', function () {
|
||||
$('input[name="chartType"]').off('click');
|
||||
$('input[name="barStacked"]').off('click');
|
||||
$('input[name="chkAlternative"]').off('click');
|
||||
$('input[name="chartTitle"]').off('focus').off('keyup').off('blur');
|
||||
$('select[name="chartXAxis"]').off('change');
|
||||
$('select[name="chartSeries"]').off('change');
|
||||
$('select[name="chartSeriesColumn"]').off('change');
|
||||
$('select[name="chartValueColumn"]').off('change');
|
||||
$('input[name="xaxis_label"]').off('keyup');
|
||||
$('input[name="yaxis_label"]').off('keyup');
|
||||
$('#resizer').off('resizestop');
|
||||
$('#tblchartform').off('submit');
|
||||
});
|
||||
AJAX.registerOnload('table/chart.js', function () {
|
||||
// handle manual resize
|
||||
$('#resizer').on('resizestop', function () {
|
||||
// make room so that the handle will still appear
|
||||
$('#querychart').height($('#resizer').height() * 0.96);
|
||||
$('#querychart').width($('#resizer').width() * 0.96);
|
||||
|
||||
if (currentChart !== null) {
|
||||
currentChart.redraw({
|
||||
resetAxes: true
|
||||
});
|
||||
}
|
||||
}); // handle chart type changes
|
||||
|
||||
$('input[name="chartType"]').on('click', function () {
|
||||
var type = currentSettings.type = $(this).val();
|
||||
|
||||
if (type === 'bar' || type === 'column' || type === 'area') {
|
||||
$('span.barStacked').show();
|
||||
} else {
|
||||
$('input[name="barStacked"]').prop('checked', false);
|
||||
$.extend(true, currentSettings, {
|
||||
stackSeries: false
|
||||
});
|
||||
$('span.barStacked').hide();
|
||||
}
|
||||
|
||||
drawChart();
|
||||
}); // handle chosing alternative data format
|
||||
|
||||
$('input[name="chkAlternative"]').on('click', function () {
|
||||
var $seriesColumn = $('select[name="chartSeriesColumn"]');
|
||||
var $valueColumn = $('select[name="chartValueColumn"]');
|
||||
var $chartSeries = $('select[name="chartSeries"]');
|
||||
|
||||
if ($(this).is(':checked')) {
|
||||
$seriesColumn.prop('disabled', false);
|
||||
$valueColumn.prop('disabled', false);
|
||||
$chartSeries.prop('disabled', true);
|
||||
currentSettings.seriesColumn = parseInt($seriesColumn.val(), 10);
|
||||
currentSettings.valueColumn = parseInt($valueColumn.val(), 10);
|
||||
} else {
|
||||
$seriesColumn.prop('disabled', true);
|
||||
$valueColumn.prop('disabled', true);
|
||||
$chartSeries.prop('disabled', false);
|
||||
currentSettings.seriesColumn = null;
|
||||
currentSettings.valueColumn = null;
|
||||
}
|
||||
|
||||
drawChart();
|
||||
}); // handle stacking for bar, column and area charts
|
||||
|
||||
$('input[name="barStacked"]').on('click', function () {
|
||||
if ($(this).is(':checked')) {
|
||||
$.extend(true, currentSettings, {
|
||||
stackSeries: true
|
||||
});
|
||||
} else {
|
||||
$.extend(true, currentSettings, {
|
||||
stackSeries: false
|
||||
});
|
||||
}
|
||||
|
||||
drawChart();
|
||||
}); // handle changes in chart title
|
||||
|
||||
$('input[name="chartTitle"]').on('focus', function () {
|
||||
tempChartTitle = $(this).val();
|
||||
}).on('keyup', function () {
|
||||
currentSettings.title = $('input[name="chartTitle"]').val();
|
||||
drawChart();
|
||||
}).on('blur', function () {
|
||||
if ($(this).val() !== tempChartTitle) {
|
||||
drawChart();
|
||||
}
|
||||
}); // handle changing the x-axis
|
||||
|
||||
$('select[name="chartXAxis"]').on('change', function () {
|
||||
onXAxisChange();
|
||||
drawChart();
|
||||
}); // handle changing the selected data series
|
||||
|
||||
$('select[name="chartSeries"]').on('change', function () {
|
||||
onDataSeriesChange();
|
||||
drawChart();
|
||||
}); // handle changing the series column
|
||||
|
||||
$('select[name="chartSeriesColumn"]').on('change', function () {
|
||||
currentSettings.seriesColumn = parseInt($(this).val(), 10);
|
||||
drawChart();
|
||||
}); // handle changing the value column
|
||||
|
||||
$('select[name="chartValueColumn"]').on('change', function () {
|
||||
currentSettings.valueColumn = parseInt($(this).val(), 10);
|
||||
drawChart();
|
||||
}); // handle manual changes to the chart x-axis labels
|
||||
|
||||
$('input[name="xaxis_label"]').on('keyup', function () {
|
||||
currentSettings.xaxisLabel = $(this).val();
|
||||
drawChart();
|
||||
}); // handle manual changes to the chart y-axis labels
|
||||
|
||||
$('input[name="yaxis_label"]').on('keyup', function () {
|
||||
currentSettings.yaxisLabel = $(this).val();
|
||||
drawChart();
|
||||
}); // handler for ajax form submission
|
||||
|
||||
$('#tblchartform').on('submit', function () {
|
||||
var $form = $(this);
|
||||
|
||||
if (codeMirrorEditor) {
|
||||
$form[0].elements.sql_query.value = codeMirrorEditor.getValue();
|
||||
}
|
||||
|
||||
if (!Functions.checkSqlQuery($form[0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var $msgbox = Functions.ajaxShowMessage();
|
||||
Functions.prepareForAjaxRequest($form);
|
||||
$.post($form.attr('action'), $form.serialize(), function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true && typeof data.chartData !== 'undefined') {
|
||||
chartData = JSON.parse(data.chartData);
|
||||
drawChart();
|
||||
Functions.ajaxRemoveMessage($msgbox);
|
||||
} else {
|
||||
Functions.ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}, 'json'); // end $.post()
|
||||
|
||||
return false;
|
||||
}); // from jQuery UI
|
||||
|
||||
$('#resizer').resizable({
|
||||
minHeight: 240,
|
||||
minWidth: 300
|
||||
}).width($('#div_view_options').width() - 50).trigger('resizestop');
|
||||
currentSettings = {
|
||||
type: 'line',
|
||||
width: $('#resizer').width() - 20,
|
||||
height: $('#resizer').height() - 20,
|
||||
xaxisLabel: $('input[name="xaxis_label"]').val(),
|
||||
yaxisLabel: $('input[name="yaxis_label"]').val(),
|
||||
title: $('input[name="chartTitle"]').val(),
|
||||
stackSeries: false,
|
||||
mainAxis: parseInt($('select[name="chartXAxis"]').val(), 10),
|
||||
selectedSeries: getSelectedSeries(),
|
||||
seriesColumn: null
|
||||
};
|
||||
var vals = $('input[name="dateTimeCols"]').val().split(' ');
|
||||
$.each(vals, function (i, v) {
|
||||
dateTimeCols.push(parseInt(v, 10));
|
||||
});
|
||||
vals = $('input[name="numericCols"]').val().split(' ');
|
||||
$.each(vals, function (i, v) {
|
||||
numericCols.push(parseInt(v, 10));
|
||||
});
|
||||
onXAxisChange();
|
||||
onDataSeriesChange();
|
||||
$('#tblchartform').trigger('submit');
|
||||
});
|
45
admin/phpMyAdmin/js/dist/table/find_replace.js
vendored
Normal file
45
admin/phpMyAdmin/js/dist/table/find_replace.js
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
AJAX.registerTeardown('table/find_replace.js', function () {
|
||||
$('#find_replace_form').off('submit');
|
||||
$('#toggle_find').off('click');
|
||||
});
|
||||
/**
|
||||
* Bind events
|
||||
*/
|
||||
|
||||
AJAX.registerOnload('table/find_replace.js', function () {
|
||||
$('<div id="toggle_find_div"><a id="toggle_find"></a></div>').insertAfter('#find_replace_form').hide();
|
||||
$('#toggle_find').html(Messages.strHideFindNReplaceCriteria).on('click', function () {
|
||||
var $link = $(this);
|
||||
$('#find_replace_form').slideToggle();
|
||||
|
||||
if ($link.text() === Messages.strHideFindNReplaceCriteria) {
|
||||
$link.text(Messages.strShowFindNReplaceCriteria);
|
||||
} else {
|
||||
$link.text(Messages.strHideFindNReplaceCriteria);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
$('#find_replace_form').on('submit', function (e) {
|
||||
e.preventDefault();
|
||||
var findReplaceForm = $('#find_replace_form');
|
||||
Functions.prepareForAjaxRequest(findReplaceForm);
|
||||
var $msgbox = Functions.ajaxShowMessage();
|
||||
$.post(findReplaceForm.attr('action'), findReplaceForm.serialize(), function (data) {
|
||||
Functions.ajaxRemoveMessage($msgbox);
|
||||
|
||||
if (data.success === true) {
|
||||
$('#toggle_find_div').show();
|
||||
$('#toggle_find').trigger('click');
|
||||
$('#sqlqueryresultsouter').html(data.preview);
|
||||
} else {
|
||||
$('#sqlqueryresultsouter').html(data.error);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
373
admin/phpMyAdmin/js/dist/table/gis_visualization.js
vendored
Normal file
373
admin/phpMyAdmin/js/dist/table/gis_visualization.js
vendored
Normal file
|
@ -0,0 +1,373 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* @fileoverview functions used for visualizing GIS data
|
||||
*
|
||||
* @requires jquery
|
||||
* @requires vendor/jquery/jquery.svg.js
|
||||
* @requires vendor/jquery/jquery.mousewheel.js
|
||||
*/
|
||||
|
||||
/* global drawOpenLayers */
|
||||
// templates/table/gis_visualization/gis_visualization.twig
|
||||
// Constants
|
||||
var zoomFactor = 1.5;
|
||||
var defaultX = 0;
|
||||
var defaultY = 0; // Variables
|
||||
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var scale = 1;
|
||||
var svg;
|
||||
/**
|
||||
* Zooms and pans the visualization.
|
||||
*/
|
||||
|
||||
function zoomAndPan() {
|
||||
var g = svg.getElementById('groupPanel');
|
||||
|
||||
if (!g) {
|
||||
return;
|
||||
}
|
||||
|
||||
g.setAttribute('transform', 'translate(' + x + ', ' + y + ') scale(' + scale + ')');
|
||||
var id;
|
||||
var circle;
|
||||
$('circle.vector').each(function () {
|
||||
id = $(this).attr('id');
|
||||
circle = svg.getElementById(id);
|
||||
$(svg).on('change', circle, {
|
||||
r: 3 / scale,
|
||||
'stroke-width': 2 / scale
|
||||
});
|
||||
});
|
||||
var line;
|
||||
$('polyline.vector').each(function () {
|
||||
id = $(this).attr('id');
|
||||
line = svg.getElementById(id);
|
||||
$(svg).on('change', line, {
|
||||
'stroke-width': 2 / scale
|
||||
});
|
||||
});
|
||||
var polygon;
|
||||
$('path.vector').each(function () {
|
||||
id = $(this).attr('id');
|
||||
polygon = svg.getElementById(id);
|
||||
$(svg).on('change', polygon, {
|
||||
'stroke-width': 0.5 / scale
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Initially loads either SVG or OSM visualization based on the choice.
|
||||
*/
|
||||
|
||||
|
||||
function selectVisualization() {
|
||||
if ($('#choice').prop('checked') !== true) {
|
||||
$('#openlayersmap').hide();
|
||||
} else {
|
||||
$('#placeholder').hide();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Adds necessary styles to the div that contains the openStreetMap.
|
||||
*/
|
||||
|
||||
|
||||
function styleOSM() {
|
||||
var $placeholder = $('#placeholder');
|
||||
var cssObj = {
|
||||
'border': '1px solid #aaa',
|
||||
'width': $placeholder.width(),
|
||||
'height': $placeholder.height(),
|
||||
'float': 'right'
|
||||
};
|
||||
$('#openlayersmap').css(cssObj);
|
||||
}
|
||||
/**
|
||||
* Loads the SVG element and make a reference to it.
|
||||
*/
|
||||
|
||||
|
||||
function loadSVG() {
|
||||
var $placeholder = $('#placeholder');
|
||||
$placeholder.svg({
|
||||
onLoad: function onLoad(svgRef) {
|
||||
svg = svgRef;
|
||||
}
|
||||
}); // Removes the second SVG element unnecessarily added due to the above command
|
||||
|
||||
$placeholder.find('svg').eq(1).remove();
|
||||
}
|
||||
/**
|
||||
* Adds controllers for zooming and panning.
|
||||
*/
|
||||
|
||||
|
||||
function addZoomPanControllers() {
|
||||
var $placeholder = $('#placeholder');
|
||||
|
||||
if ($('#placeholder').find('svg').length > 0) {
|
||||
var themeImagePath = $('#themeImagePath').val(); // add panning arrows
|
||||
|
||||
$('<img class="button" id="left_arrow" src="' + themeImagePath + 'west-mini.png">').appendTo($placeholder);
|
||||
$('<img class="button" id="right_arrow" src="' + themeImagePath + 'east-mini.png">').appendTo($placeholder);
|
||||
$('<img class="button" id="up_arrow" src="' + themeImagePath + 'north-mini.png">').appendTo($placeholder);
|
||||
$('<img class="button" id="down_arrow" src="' + themeImagePath + 'south-mini.png">').appendTo($placeholder); // add zooming controls
|
||||
|
||||
$('<img class="button" id="zoom_in" src="' + themeImagePath + 'zoom-plus-mini.png">').appendTo($placeholder);
|
||||
$('<img class="button" id="zoom_world" src="' + themeImagePath + 'zoom-world-mini.png">').appendTo($placeholder);
|
||||
$('<img class="button" id="zoom_out" src="' + themeImagePath + 'zoom-minus-mini.png">').appendTo($placeholder);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Resizes the GIS visualization to fit into the space available.
|
||||
*/
|
||||
|
||||
|
||||
function resizeGISVisualization() {
|
||||
var $placeholder = $('#placeholder');
|
||||
var oldWidth = $placeholder.width();
|
||||
var visWidth = $('#div_view_options').width() - 48; // Assign new value for width
|
||||
|
||||
$placeholder.width(visWidth);
|
||||
$('svg').attr('width', visWidth); // Assign the offset created due to resizing to defaultX and center the svg.
|
||||
|
||||
defaultX = (visWidth - oldWidth) / 2;
|
||||
x = defaultX;
|
||||
y = 0;
|
||||
scale = 1;
|
||||
}
|
||||
/**
|
||||
* 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();
|
||||
|
||||
if (typeof ol !== 'undefined') {
|
||||
// Adds necessary styles to the div that contains the openStreetMap
|
||||
styleOSM();
|
||||
} // Loads the SVG element and make a reference to it
|
||||
|
||||
|
||||
loadSVG(); // Adds controllers for zooming and panning
|
||||
|
||||
addZoomPanControllers();
|
||||
zoomAndPan();
|
||||
}
|
||||
|
||||
function drawOpenLayerMap(openLayerCreate) {
|
||||
$('#placeholder').hide();
|
||||
$('#openlayersmap').show(); // Function doesn't work properly if #openlayersmap is hidden
|
||||
|
||||
if (!openLayerCreate) {
|
||||
// Draws openStreetMap with openLayers
|
||||
drawOpenLayers();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getRelativeCoords(e) {
|
||||
var position = $('#placeholder').offset();
|
||||
return {
|
||||
x: e.pageX - position.left,
|
||||
y: e.pageY - position.top
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
|
||||
|
||||
AJAX.registerTeardown('table/gis_visualization.js', function () {
|
||||
$(document).off('click', '#choice');
|
||||
$(document).off('mousewheel', '#placeholder');
|
||||
$(document).off('dragstart', 'svg');
|
||||
$(document).off('mouseup', 'svg');
|
||||
$(document).off('drag', 'svg');
|
||||
$(document).off('dblclick', '#placeholder');
|
||||
$(document).off('click', '#zoom_in');
|
||||
$(document).off('click', '#zoom_world');
|
||||
$(document).off('click', '#zoom_out');
|
||||
$(document).off('click', '#left_arrow');
|
||||
$(document).off('click', '#right_arrow');
|
||||
$(document).off('click', '#up_arrow');
|
||||
$(document).off('click', '#down_arrow');
|
||||
$('.vector').off('mousemove').off('mouseout');
|
||||
});
|
||||
AJAX.registerOnload('table/gis_visualization.js', function () {
|
||||
var openLayerCreate = 0; // If we are in GIS visualization, initialize it
|
||||
|
||||
if ($('#gis_div').length > 0) {
|
||||
initGISVisualization();
|
||||
}
|
||||
|
||||
if ($('#choice').prop('checked') === true) {
|
||||
openLayerCreate = drawOpenLayerMap(openLayerCreate);
|
||||
}
|
||||
|
||||
if (typeof ol === 'undefined') {
|
||||
$('#choice, #labelChoice').hide();
|
||||
}
|
||||
|
||||
$(document).on('click', '#choice', function () {
|
||||
if ($(this).prop('checked') === false) {
|
||||
$('#placeholder').show();
|
||||
$('#openlayersmap').hide();
|
||||
} else {
|
||||
openLayerCreate = drawOpenLayerMap(openLayerCreate);
|
||||
}
|
||||
});
|
||||
$(document).on('mousewheel', '#placeholder', function (event, delta) {
|
||||
var relCoords = getRelativeCoords(event);
|
||||
|
||||
if (delta > 0) {
|
||||
// zoom in
|
||||
scale *= zoomFactor; // zooming in keeping the position under mouse pointer unmoved.
|
||||
|
||||
x = relCoords.x - (relCoords.x - x) * zoomFactor;
|
||||
y = relCoords.y - (relCoords.y - y) * zoomFactor;
|
||||
zoomAndPan();
|
||||
} else {
|
||||
// zoom out
|
||||
scale /= zoomFactor; // zooming out keeping the position under mouse pointer unmoved.
|
||||
|
||||
x = relCoords.x - (relCoords.x - x) / zoomFactor;
|
||||
y = relCoords.y - (relCoords.y - y) / zoomFactor;
|
||||
zoomAndPan();
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
var dragX = 0;
|
||||
var dragY = 0;
|
||||
$('svg').draggable({
|
||||
helper: function helper() {
|
||||
return $('<div>'); // Give a fake element to be used for dragging display
|
||||
}
|
||||
});
|
||||
$(document).on('dragstart', 'svg', function (event, dd) {
|
||||
$('#placeholder').addClass('placeholderDrag');
|
||||
dragX = Math.round(dd.offset.left);
|
||||
dragY = Math.round(dd.offset.top);
|
||||
});
|
||||
$(document).on('mouseup', 'svg', function () {
|
||||
$('#placeholder').removeClass('placeholderDrag');
|
||||
});
|
||||
$(document).on('drag', 'svg', function (event, dd) {
|
||||
var newX = Math.round(dd.offset.left);
|
||||
x += newX - dragX;
|
||||
dragX = newX;
|
||||
var newY = Math.round(dd.offset.top);
|
||||
y += newY - dragY;
|
||||
dragY = newY;
|
||||
zoomAndPan();
|
||||
});
|
||||
$(document).on('dblclick', '#placeholder', function (event) {
|
||||
scale *= zoomFactor; // zooming in keeping the position under mouse pointer unmoved.
|
||||
|
||||
var relCoords = getRelativeCoords(event);
|
||||
x = relCoords.x - (relCoords.x - x) * zoomFactor;
|
||||
y = relCoords.y - (relCoords.y - y) * zoomFactor;
|
||||
zoomAndPan();
|
||||
});
|
||||
$(document).on('click', '#zoom_in', function (e) {
|
||||
e.preventDefault(); // zoom in
|
||||
|
||||
scale *= zoomFactor;
|
||||
var $placeholder = $('#placeholder').find('svg');
|
||||
var width = $placeholder.attr('width');
|
||||
var height = $placeholder.attr('height'); // zooming in keeping the center unmoved.
|
||||
|
||||
x = width / 2 - (width / 2 - x) * zoomFactor;
|
||||
y = height / 2 - (height / 2 - y) * zoomFactor;
|
||||
zoomAndPan();
|
||||
});
|
||||
$(document).on('click', '#zoom_world', function (e) {
|
||||
e.preventDefault();
|
||||
scale = 1;
|
||||
x = defaultX;
|
||||
y = defaultY;
|
||||
zoomAndPan();
|
||||
});
|
||||
$(document).on('click', '#zoom_out', function (e) {
|
||||
e.preventDefault(); // zoom out
|
||||
|
||||
scale /= zoomFactor;
|
||||
var $placeholder = $('#placeholder').find('svg');
|
||||
var width = $placeholder.attr('width');
|
||||
var height = $placeholder.attr('height'); // zooming out keeping the center unmoved.
|
||||
|
||||
x = width / 2 - (width / 2 - x) / zoomFactor;
|
||||
y = height / 2 - (height / 2 - y) / zoomFactor;
|
||||
zoomAndPan();
|
||||
});
|
||||
$(document).on('click', '#left_arrow', function (e) {
|
||||
e.preventDefault();
|
||||
x += 100;
|
||||
zoomAndPan();
|
||||
});
|
||||
$(document).on('click', '#right_arrow', function (e) {
|
||||
e.preventDefault();
|
||||
x -= 100;
|
||||
zoomAndPan();
|
||||
});
|
||||
$(document).on('click', '#up_arrow', function (e) {
|
||||
e.preventDefault();
|
||||
y += 100;
|
||||
zoomAndPan();
|
||||
});
|
||||
$(document).on('click', '#down_arrow', function (e) {
|
||||
e.preventDefault();
|
||||
y -= 100;
|
||||
zoomAndPan();
|
||||
});
|
||||
/**
|
||||
* Detect the mousemove event and show tooltips.
|
||||
*/
|
||||
|
||||
$('.vector').on('mousemove', function (event) {
|
||||
var contents = Functions.escapeHtml($(this).attr('name')).trim();
|
||||
$('#tooltip').remove();
|
||||
|
||||
if (contents !== '') {
|
||||
$('<div id="tooltip">' + contents + '</div>').css({
|
||||
position: 'absolute',
|
||||
top: event.pageY + 10,
|
||||
left: event.pageX + 10,
|
||||
border: '1px solid #fdd',
|
||||
padding: '2px',
|
||||
'background-color': '#fee',
|
||||
opacity: 0.90
|
||||
}).appendTo('body').fadeIn(200);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Detect the mouseout event and hide tooltips.
|
||||
*/
|
||||
|
||||
$('.vector').on('mouseout', function () {
|
||||
$('#tooltip').remove();
|
||||
});
|
||||
});
|
310
admin/phpMyAdmin/js/dist/table/operations.js
vendored
Normal file
310
admin/phpMyAdmin/js/dist/table/operations.js
vendored
Normal file
|
@ -0,0 +1,310 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
AJAX.registerTeardown('table/operations.js', function () {
|
||||
$(document).off('submit', '#copyTable.ajax');
|
||||
$(document).off('submit', '#moveTableForm');
|
||||
$(document).off('submit', '#tableOptionsForm');
|
||||
$(document).off('submit', '#partitionsForm');
|
||||
$(document).off('click', '#tbl_maintenance li a.maintain_action.ajax');
|
||||
$(document).off('click', '#drop_tbl_anchor.ajax');
|
||||
$(document).off('click', '#drop_view_anchor.ajax');
|
||||
$(document).off('click', '#truncate_tbl_anchor.ajax');
|
||||
});
|
||||
/**
|
||||
* jQuery coding for 'Table operations'. Used on /table/operations
|
||||
* Attach Ajax Event handlers for Table operations
|
||||
*/
|
||||
|
||||
AJAX.registerOnload('table/operations.js', function () {
|
||||
/**
|
||||
*Ajax action for submitting the "Copy table"
|
||||
**/
|
||||
$(document).on('submit', '#copyTable.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
var $form = $(this);
|
||||
Functions.prepareForAjaxRequest($form);
|
||||
var argsep = CommonParams.get('arg_separator');
|
||||
$.post($form.attr('action'), $form.serialize() + argsep + 'submit_copy=Go', function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
if ($form.find('input[name=\'switch_to_new\']').prop('checked')) {
|
||||
CommonParams.set('db', $form.find('select[name=\'target_db\'],input[name=\'target_db\']').val());
|
||||
CommonParams.set('table', $form.find('input[name=\'new_name\']').val());
|
||||
CommonActions.refreshMain(false, function () {
|
||||
Functions.ajaxShowMessage(data.message);
|
||||
});
|
||||
} else {
|
||||
Functions.ajaxShowMessage(data.message);
|
||||
} // Refresh navigation when the table is copied
|
||||
|
||||
|
||||
Navigation.reload();
|
||||
} else {
|
||||
Functions.ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
}); // end of copyTable ajax submit
|
||||
|
||||
/**
|
||||
*Ajax action for submitting the "Move table"
|
||||
*/
|
||||
|
||||
$(document).on('submit', '#moveTableForm', function (event) {
|
||||
event.preventDefault();
|
||||
var $form = $(this);
|
||||
Functions.prepareForAjaxRequest($form);
|
||||
var argsep = CommonParams.get('arg_separator');
|
||||
$.post($form.attr('action'), $form.serialize() + argsep + 'submit_move=1', function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
CommonParams.set('db', data.params.db);
|
||||
CommonParams.set('table', data.params.table);
|
||||
CommonActions.refreshMain('index.php?route=/table/sql', function () {
|
||||
Functions.ajaxShowMessage(data.message);
|
||||
}); // Refresh navigation when the table is copied
|
||||
|
||||
Navigation.reload();
|
||||
} else {
|
||||
Functions.ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
});
|
||||
/**
|
||||
* Ajax action for submitting the "Table options"
|
||||
*/
|
||||
|
||||
$(document).on('submit', '#tableOptionsForm', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
var $form = $(this);
|
||||
var $tblNameField = $form.find('input[name=new_name]');
|
||||
var $tblCollationField = $form.find('select[name=tbl_collation]');
|
||||
var collationOrigValue = $('select[name="tbl_collation"] option[selected]').val();
|
||||
var $changeAllColumnCollationsCheckBox = $('#checkbox_change_all_collations');
|
||||
var question = Messages.strChangeAllColumnCollationsWarning;
|
||||
|
||||
if ($tblNameField.val() !== $tblNameField[0].defaultValue) {
|
||||
// reload page and navigation if the table has been renamed
|
||||
Functions.prepareForAjaxRequest($form);
|
||||
|
||||
if ($tblCollationField.val() !== collationOrigValue && $changeAllColumnCollationsCheckBox.is(':checked')) {
|
||||
$form.confirm(question, $form.attr('action'), function () {
|
||||
submitOptionsForm();
|
||||
});
|
||||
} else {
|
||||
submitOptionsForm();
|
||||
}
|
||||
} else {
|
||||
if ($tblCollationField.val() !== collationOrigValue && $changeAllColumnCollationsCheckBox.is(':checked')) {
|
||||
$form.confirm(question, $form.attr('action'), function () {
|
||||
$form.removeClass('ajax').trigger('submit').addClass('ajax');
|
||||
});
|
||||
} else {
|
||||
$form.removeClass('ajax').trigger('submit').addClass('ajax');
|
||||
}
|
||||
}
|
||||
|
||||
function submitOptionsForm() {
|
||||
$.post($form.attr('action'), $form.serialize(), function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
CommonParams.set('table', data.params.table);
|
||||
CommonActions.refreshMain(false, function () {
|
||||
$('#page_content').html(data.message);
|
||||
Functions.highlightSql($('#page_content'));
|
||||
}); // Refresh navigation when the table is renamed
|
||||
|
||||
Navigation.reload();
|
||||
} else {
|
||||
Functions.ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
}
|
||||
});
|
||||
/**
|
||||
*Ajax events for actions in the "Table maintenance"
|
||||
**/
|
||||
|
||||
$(document).on('click', '#tbl_maintenance li a.maintain_action.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
var $link = $(this);
|
||||
|
||||
if ($('.sqlqueryresults').length !== 0) {
|
||||
$('.sqlqueryresults').remove();
|
||||
}
|
||||
|
||||
if ($('.result_query').length !== 0) {
|
||||
$('.result_query').remove();
|
||||
} // variables which stores the common attributes
|
||||
|
||||
|
||||
var params = $.param({
|
||||
'ajax_request': 1,
|
||||
'server': CommonParams.get('server')
|
||||
});
|
||||
var postData = $link.getPostData();
|
||||
|
||||
if (postData) {
|
||||
params += CommonParams.get('arg_separator') + postData;
|
||||
}
|
||||
|
||||
$.post($link.attr('href'), params, function (data) {
|
||||
function scrollToTop() {
|
||||
$('html, body').animate({
|
||||
scrollTop: 0
|
||||
});
|
||||
}
|
||||
|
||||
var $tempDiv;
|
||||
|
||||
if (typeof data !== 'undefined' && data.success === true && data.sql_query !== undefined) {
|
||||
Functions.ajaxShowMessage(data.message);
|
||||
$('<div class=\'sqlqueryresults ajax\'></div>').prependTo('#page_content');
|
||||
$('.sqlqueryresults').html(data.sql_query);
|
||||
Functions.highlightSql($('#page_content'));
|
||||
scrollToTop();
|
||||
} else if (typeof data !== 'undefined' && data.success === true) {
|
||||
$tempDiv = $('<div id=\'temp_div\'></div>');
|
||||
$tempDiv.html(data.message);
|
||||
var $success = $tempDiv.find('.result_query .alert-success');
|
||||
Functions.ajaxShowMessage($success);
|
||||
$('<div class=\'sqlqueryresults ajax\'></div>').prependTo('#page_content');
|
||||
$('.sqlqueryresults').html(data.message);
|
||||
Functions.highlightSql($('#page_content'));
|
||||
Functions.initSlider();
|
||||
$('.sqlqueryresults').children('fieldset,br').remove();
|
||||
scrollToTop();
|
||||
} else {
|
||||
$tempDiv = $('<div id=\'temp_div\'></div>');
|
||||
$tempDiv.html(data.error);
|
||||
var $error;
|
||||
|
||||
if ($tempDiv.find('.error code').length !== 0) {
|
||||
$error = $tempDiv.find('.error code').addClass('error');
|
||||
} else {
|
||||
$error = $tempDiv;
|
||||
}
|
||||
|
||||
Functions.ajaxShowMessage($error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
}); // end of table maintenance ajax click
|
||||
|
||||
/**
|
||||
* Ajax action for submitting the "Partition Maintenance"
|
||||
* Also, asks for confirmation when DROP partition is submitted
|
||||
*/
|
||||
|
||||
$(document).on('submit', '#partitionsForm', function (event) {
|
||||
event.preventDefault();
|
||||
var $form = $(this);
|
||||
|
||||
function submitPartitionMaintenance() {
|
||||
var argsep = CommonParams.get('arg_separator');
|
||||
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
|
||||
Functions.ajaxShowMessage(Messages.strProcessingRequest);
|
||||
AJAX.source = $form;
|
||||
$.post($form.attr('action'), submitData, AJAX.responseHandler);
|
||||
}
|
||||
|
||||
if ($('#partitionOperationRadioDrop').is(':checked')) {
|
||||
$form.confirm(Messages.strDropPartitionWarning, $form.attr('action'), function () {
|
||||
submitPartitionMaintenance();
|
||||
});
|
||||
} else if ($('#partitionOperationRadioTruncate').is(':checked')) {
|
||||
$form.confirm(Messages.strTruncatePartitionWarning, $form.attr('action'), function () {
|
||||
submitPartitionMaintenance();
|
||||
});
|
||||
} else {
|
||||
submitPartitionMaintenance();
|
||||
}
|
||||
});
|
||||
$(document).on('click', '#drop_tbl_anchor.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
var $link = $(this);
|
||||
/**
|
||||
* @var question String containing the question to be asked for confirmation
|
||||
*/
|
||||
|
||||
var question = Messages.strDropTableStrongWarning + ' ';
|
||||
question += Functions.sprintf(Messages.strDoYouReally, 'DROP TABLE `' + Functions.escapeHtml(CommonParams.get('db')) + '`.`' + Functions.escapeHtml(CommonParams.get('table') + '`')) + Functions.getForeignKeyCheckboxLoader();
|
||||
$(this).confirm(question, $(this).attr('href'), function (url) {
|
||||
var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest);
|
||||
var params = Functions.getJsConfirmCommonParam(this, $link.getPostData());
|
||||
$.post(url, params, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
Functions.ajaxRemoveMessage($msgbox); // Table deleted successfully, refresh both the frames
|
||||
|
||||
Navigation.reload();
|
||||
CommonParams.set('table', '');
|
||||
CommonActions.refreshMain(CommonParams.get('opendb_url'), function () {
|
||||
Functions.ajaxShowMessage(data.message);
|
||||
});
|
||||
} else {
|
||||
Functions.ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
}, Functions.loadForeignKeyCheckbox);
|
||||
}); // end of Drop Table Ajax action
|
||||
|
||||
$(document).on('click', '#drop_view_anchor.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
var $link = $(this);
|
||||
/**
|
||||
* @var question String containing the question to be asked for confirmation
|
||||
*/
|
||||
|
||||
var question = Messages.strDropTableStrongWarning + ' ';
|
||||
question += Functions.sprintf(Messages.strDoYouReally, 'DROP VIEW `' + Functions.escapeHtml(CommonParams.get('table') + '`'));
|
||||
$(this).confirm(question, $(this).attr('href'), function (url) {
|
||||
var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest);
|
||||
var params = Functions.getJsConfirmCommonParam(this, $link.getPostData());
|
||||
$.post(url, params, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
Functions.ajaxRemoveMessage($msgbox); // Table deleted successfully, refresh both the frames
|
||||
|
||||
Navigation.reload();
|
||||
CommonParams.set('table', '');
|
||||
CommonActions.refreshMain(CommonParams.get('opendb_url'), function () {
|
||||
Functions.ajaxShowMessage(data.message);
|
||||
});
|
||||
} else {
|
||||
Functions.ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
});
|
||||
}); // end of Drop View Ajax action
|
||||
|
||||
$(document).on('click', '#truncate_tbl_anchor.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
var $link = $(this);
|
||||
/**
|
||||
* @var question String containing the question to be asked for confirmation
|
||||
*/
|
||||
|
||||
var question = Messages.strTruncateTableStrongWarning + ' ';
|
||||
question += Functions.sprintf(Messages.strDoYouReally, 'TRUNCATE `' + Functions.escapeHtml(CommonParams.get('db')) + '`.`' + Functions.escapeHtml(CommonParams.get('table') + '`')) + Functions.getForeignKeyCheckboxLoader();
|
||||
$(this).confirm(question, $(this).attr('href'), function (url) {
|
||||
Functions.ajaxShowMessage(Messages.strProcessingRequest);
|
||||
var params = Functions.getJsConfirmCommonParam(this, $link.getPostData());
|
||||
$.post(url, params, function (data) {
|
||||
if ($('.sqlqueryresults').length !== 0) {
|
||||
$('.sqlqueryresults').remove();
|
||||
}
|
||||
|
||||
if ($('.result_query').length !== 0) {
|
||||
$('.result_query').remove();
|
||||
}
|
||||
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
Functions.ajaxShowMessage(data.message);
|
||||
$('<div class=\'sqlqueryresults ajax\'></div>').prependTo('#page_content');
|
||||
$('.sqlqueryresults').html(data.sql_query);
|
||||
Functions.highlightSql($('#page_content'));
|
||||
} else {
|
||||
Functions.ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
}, Functions.loadForeignKeyCheckbox);
|
||||
}); // end of Truncate Table Ajax action
|
||||
}); // end $(document).ready for 'Table operations'
|
208
admin/phpMyAdmin/js/dist/table/relation.js
vendored
Normal file
208
admin/phpMyAdmin/js/dist/table/relation.js
vendored
Normal file
|
@ -0,0 +1,208 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* for table relation
|
||||
*/
|
||||
var TableRelation = {};
|
||||
|
||||
TableRelation.showHideClauses = function ($thisDropdown) {
|
||||
if ($thisDropdown.val() === '') {
|
||||
$thisDropdown.parent().nextAll('span').hide();
|
||||
} else {
|
||||
if ($thisDropdown.is('select[name^="destination_foreign_column"]')) {
|
||||
$thisDropdown.parent().nextAll('span').show();
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Sets dropdown options to values
|
||||
*/
|
||||
|
||||
|
||||
TableRelation.setDropdownValues = function ($dropdown, values, selectedValue) {
|
||||
$dropdown.empty();
|
||||
var optionsAsString = ''; // add an empty string to the beginning for empty selection
|
||||
|
||||
values.unshift('');
|
||||
$.each(values, function () {
|
||||
optionsAsString += '<option value=\'' + Functions.escapeHtml(this) + '\'' + (selectedValue === Functions.escapeHtml(this) ? ' selected=\'selected\'' : '') + '>' + Functions.escapeHtml(this) + '</option>';
|
||||
});
|
||||
$dropdown.append($(optionsAsString));
|
||||
};
|
||||
/**
|
||||
* Retrieves and populates dropdowns to the left based on the selected value
|
||||
*
|
||||
* @param $dropdown the dropdown whose value got changed
|
||||
*/
|
||||
|
||||
|
||||
TableRelation.getDropdownValues = function ($dropdown) {
|
||||
var foreignDb = null;
|
||||
var foreignTable = null;
|
||||
var $databaseDd;
|
||||
var $tableDd;
|
||||
var $columnDd;
|
||||
var foreign = ''; // if the changed dropdown is for foreign key constraints
|
||||
|
||||
if ($dropdown.is('select[name^="destination_foreign"]')) {
|
||||
$databaseDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_db"]');
|
||||
$tableDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_table"]');
|
||||
$columnDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_column"]');
|
||||
foreign = '_foreign';
|
||||
} else {
|
||||
// internal relations
|
||||
$databaseDd = $dropdown.parent().find('select[name^="destination_db"]');
|
||||
$tableDd = $dropdown.parent().find('select[name^="destination_table"]');
|
||||
$columnDd = $dropdown.parent().find('select[name^="destination_column"]');
|
||||
} // if the changed dropdown is a database selector
|
||||
|
||||
|
||||
if ($dropdown.is('select[name^="destination' + foreign + '_db"]')) {
|
||||
foreignDb = $dropdown.val(); // if no database is selected empty table and column dropdowns
|
||||
|
||||
if (foreignDb === '') {
|
||||
TableRelation.setDropdownValues($tableDd, []);
|
||||
TableRelation.setDropdownValues($columnDd, []);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// if a table selector
|
||||
foreignDb = $databaseDd.val();
|
||||
foreignTable = $dropdown.val(); // if no table is selected empty the column dropdown
|
||||
|
||||
if (foreignTable === '') {
|
||||
TableRelation.setDropdownValues($columnDd, []);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var $msgbox = Functions.ajaxShowMessage();
|
||||
var $form = $dropdown.parents('form');
|
||||
var $db = $form.find('input[name="db"]').val();
|
||||
var $table = $form.find('input[name="table"]').val();
|
||||
var argsep = CommonParams.get('arg_separator');
|
||||
var params = 'getDropdownValues=true' + argsep + 'ajax_request=true' + argsep + 'db=' + encodeURIComponent($db) + argsep + 'table=' + encodeURIComponent($table) + argsep + 'foreign=' + (foreign !== '') + argsep + 'foreignDb=' + encodeURIComponent(foreignDb) + (foreignTable !== null ? argsep + 'foreignTable=' + encodeURIComponent(foreignTable) : '');
|
||||
var $server = $form.find('input[name="server"]');
|
||||
|
||||
if ($server.length > 0) {
|
||||
params += argsep + 'server=' + $form.find('input[name="server"]').val();
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'index.php?route=/table/relation',
|
||||
data: params,
|
||||
dataType: 'json',
|
||||
success: function success(data) {
|
||||
Functions.ajaxRemoveMessage($msgbox);
|
||||
|
||||
if (typeof data !== 'undefined' && data.success) {
|
||||
// if the changed dropdown is a database selector
|
||||
if (foreignTable === null) {
|
||||
// set values for table and column dropdowns
|
||||
TableRelation.setDropdownValues($tableDd, data.tables);
|
||||
TableRelation.setDropdownValues($columnDd, []);
|
||||
} else {
|
||||
// if a table selector
|
||||
// set values for the column dropdown
|
||||
var primary = null;
|
||||
|
||||
if (typeof data.primary !== 'undefined' && 1 === data.primary.length) {
|
||||
primary = data.primary[0];
|
||||
}
|
||||
|
||||
TableRelation.setDropdownValues($columnDd.first(), data.columns, primary);
|
||||
TableRelation.setDropdownValues($columnDd.slice(1), data.columns);
|
||||
}
|
||||
} else {
|
||||
Functions.ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
|
||||
|
||||
AJAX.registerTeardown('table/relation.js', function () {
|
||||
$('body').off('change', 'select[name^="destination_db"], ' + 'select[name^="destination_table"], ' + 'select[name^="destination_foreign_db"], ' + 'select[name^="destination_foreign_table"]');
|
||||
$('body').off('click', 'a.add_foreign_key_field');
|
||||
$('body').off('click', 'a.add_foreign_key');
|
||||
$('a.drop_foreign_key_anchor.ajax').off('click');
|
||||
});
|
||||
AJAX.registerOnload('table/relation.js', function () {
|
||||
/**
|
||||
* Ajax event handler to fetch table/column dropdown values.
|
||||
*/
|
||||
$('body').on('change', 'select[name^="destination_db"], ' + 'select[name^="destination_table"], ' + 'select[name^="destination_foreign_db"], ' + 'select[name^="destination_foreign_table"]', function () {
|
||||
TableRelation.getDropdownValues($(this));
|
||||
});
|
||||
/**
|
||||
* Ajax event handler to add a column to a foreign key constraint.
|
||||
*/
|
||||
|
||||
$('body').on('click', 'a.add_foreign_key_field', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation(); // Add field.
|
||||
|
||||
$(this).prev('span').clone(true, true).insertBefore($(this)).find('select').val(''); // Add foreign field.
|
||||
|
||||
var $sourceElem = $('select[name^="destination_foreign_column[' + $(this).attr('data-index') + ']"]').last().parent();
|
||||
$sourceElem.clone(true, true).insertAfter($sourceElem).find('select').val('');
|
||||
});
|
||||
/**
|
||||
* Ajax event handler to add a foreign key constraint.
|
||||
*/
|
||||
|
||||
$('body').on('click', 'a.add_foreign_key', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
var $prevRow = $(this).closest('tr').prev('tr');
|
||||
var $newRow = $prevRow.clone(true, true); // Update serial number.
|
||||
|
||||
var currIndex = $newRow.find('a.add_foreign_key_field').attr('data-index');
|
||||
var newIndex = parseInt(currIndex) + 1;
|
||||
$newRow.find('a.add_foreign_key_field').attr('data-index', newIndex); // Update form parameter names.
|
||||
|
||||
$newRow.find('select[name^="foreign_key_fields_name"]').not($newRow.find('select[name^="foreign_key_fields_name"]').first()).find('select[name^="destination_foreign_column"]').not($newRow.find('select[name^="foreign_key_fields_name"]').not($newRow.find('select[name^="foreign_key_fields_name"]').first()).find('select[name^="destination_foreign_column"]').first()).each(function () {
|
||||
$(this).parent().remove();
|
||||
});
|
||||
$newRow.find('input, select').each(function () {
|
||||
$(this).attr('name', $(this).attr('name').replace(/\d/, newIndex));
|
||||
});
|
||||
$newRow.find('input[type="text"]').each(function () {
|
||||
$(this).val('');
|
||||
}); // Finally add the row.
|
||||
|
||||
$newRow.insertAfter($prevRow);
|
||||
});
|
||||
/**
|
||||
* Ajax Event handler for 'Drop Foreign key'
|
||||
*/
|
||||
|
||||
$('a.drop_foreign_key_anchor.ajax').on('click', function (event) {
|
||||
event.preventDefault();
|
||||
var $anchor = $(this); // Object containing reference to the current field's row
|
||||
|
||||
var $currRow = $anchor.parents('tr');
|
||||
var dropQuery = Functions.escapeHtml($currRow.children('td').children('.drop_foreign_key_msg').val());
|
||||
var question = Functions.sprintf(Messages.strDoYouReally, dropQuery);
|
||||
$anchor.confirm(question, $anchor.attr('href'), function (url) {
|
||||
var $msg = Functions.ajaxShowMessage(Messages.strDroppingForeignKey, false);
|
||||
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
|
||||
$.post(url, params, function (data) {
|
||||
if (data.success === true) {
|
||||
Functions.ajaxRemoveMessage($msg);
|
||||
CommonActions.refreshMain(false, function () {// Do nothing
|
||||
});
|
||||
} else {
|
||||
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
});
|
||||
}); // end Drop Foreign key
|
||||
|
||||
var windowWidth = $(window).width();
|
||||
$('.jsresponsive').css('max-width', windowWidth - 35 + 'px');
|
||||
});
|
327
admin/phpMyAdmin/js/dist/table/select.js
vendored
Normal file
327
admin/phpMyAdmin/js/dist/table/select.js
vendored
Normal file
|
@ -0,0 +1,327 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* @fileoverview JavaScript functions used on /table/search
|
||||
*
|
||||
* @requires jQuery
|
||||
* @requires js/functions.js
|
||||
*/
|
||||
|
||||
/* global changeValueFieldType, verifyAfterSearchFieldChange */
|
||||
// js/table/change.js
|
||||
|
||||
/* global openGISEditor, gisEditorLoaded, loadJSAndGISEditor, loadGISEditor */
|
||||
// js/gis_data_editor.js
|
||||
var TableSelect = {};
|
||||
/**
|
||||
* Checks if given data-type is numeric or date.
|
||||
*
|
||||
* @param {string} dataType Column data-type
|
||||
*
|
||||
* @return {(boolean|string)}
|
||||
*/
|
||||
|
||||
TableSelect.checkIfDataTypeNumericOrDate = function (dataType) {
|
||||
// To test for numeric data-types.
|
||||
var numericRegExp = new RegExp('TINYINT|SMALLINT|MEDIUMINT|INT|BIGINT|DECIMAL|FLOAT|DOUBLE|REAL', 'i'); // To test for date data-types.
|
||||
|
||||
var dateRegExp = new RegExp('DATETIME|DATE|TIMESTAMP|TIME|YEAR', 'i'); // Return matched data-type
|
||||
|
||||
if (numericRegExp.test(dataType)) {
|
||||
return numericRegExp.exec(dataType)[0];
|
||||
}
|
||||
|
||||
if (dateRegExp.test(dataType)) {
|
||||
return dateRegExp.exec(dataType)[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
|
||||
|
||||
AJAX.registerTeardown('table/select.js', function () {
|
||||
$('#togglesearchformlink').off('click');
|
||||
$(document).off('submit', '#tbl_search_form.ajax');
|
||||
$('select.geom_func').off('change');
|
||||
$(document).off('click', 'span.open_search_gis_editor');
|
||||
$('body').off('change', 'select[name*="criteriaColumnOperators"]'); // Fix for bug #13778, changed 'click' to 'change'
|
||||
});
|
||||
AJAX.registerOnload('table/select.js', function () {
|
||||
/**
|
||||
* Prepare a div containing a link, otherwise it's incorrectly displayed
|
||||
* after a couple of clicks
|
||||
*/
|
||||
$('<div id="togglesearchformdiv"><a id="togglesearchformlink"></a></div>').insertAfter('#tbl_search_form') // don't show it until we have results on-screen
|
||||
.hide();
|
||||
$('#togglesearchformlink').html(Messages.strShowSearchCriteria).on('click', function () {
|
||||
var $link = $(this);
|
||||
$('#tbl_search_form').slideToggle();
|
||||
|
||||
if ($link.text() === Messages.strHideSearchCriteria) {
|
||||
$link.text(Messages.strShowSearchCriteria);
|
||||
} else {
|
||||
$link.text(Messages.strHideSearchCriteria);
|
||||
} // avoid default click action
|
||||
|
||||
|
||||
return false;
|
||||
});
|
||||
var tableRows = $('#fieldset_table_qbe select.column-operator');
|
||||
$.each(tableRows, function (index, item) {
|
||||
$(item).on('change', function () {
|
||||
changeValueFieldType(this, index);
|
||||
verifyAfterSearchFieldChange(index, '#tbl_search_form');
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Ajax event handler for Table search
|
||||
*/
|
||||
|
||||
$(document).on('submit', '#tbl_search_form.ajax', function (event) {
|
||||
var unaryFunctions = ['IS NULL', 'IS NOT NULL', '= \'\'', '!= \'\''];
|
||||
var geomUnaryFunctions = ['IsEmpty', 'IsSimple', 'IsRing', 'IsClosed']; // jQuery object to reuse
|
||||
|
||||
var $searchForm = $(this);
|
||||
event.preventDefault(); // empty previous search results while we are waiting for new results
|
||||
|
||||
$('#sqlqueryresultsouter').empty();
|
||||
var $msgbox = Functions.ajaxShowMessage(Messages.strSearching, false);
|
||||
Functions.prepareForAjaxRequest($searchForm);
|
||||
var values = {};
|
||||
$searchForm.find(':input').each(function () {
|
||||
var $input = $(this);
|
||||
|
||||
if ($input.attr('type') === 'checkbox' || $input.attr('type') === 'radio') {
|
||||
if ($input.is(':checked')) {
|
||||
values[this.name] = $input.val();
|
||||
}
|
||||
} else {
|
||||
values[this.name] = $input.val();
|
||||
}
|
||||
});
|
||||
var columnCount = $('select[name="columnsToDisplay[]"] option').length; // Submit values only for the columns that have unary column operator or a search criteria
|
||||
|
||||
for (var a = 0; a < columnCount; a++) {
|
||||
if ($.inArray(values['criteriaColumnOperators[' + a + ']'], unaryFunctions) >= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (values['geom_func[' + a + ']'] && $.inArray(values['geom_func[' + a + ']'], geomUnaryFunctions) >= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (values['criteriaValues[' + a + ']'] === '' || values['criteriaValues[' + a + ']'] === null) {
|
||||
delete values['criteriaValues[' + a + ']'];
|
||||
delete values['criteriaColumnOperators[' + a + ']'];
|
||||
delete values['criteriaColumnNames[' + a + ']'];
|
||||
delete values['criteriaColumnTypes[' + a + ']'];
|
||||
delete values['criteriaColumnCollations[' + a + ']'];
|
||||
}
|
||||
} // If all columns are selected, use a single parameter to indicate that
|
||||
|
||||
|
||||
if (values['columnsToDisplay[]'] !== null) {
|
||||
if (values['columnsToDisplay[]'].length === columnCount) {
|
||||
delete values['columnsToDisplay[]'];
|
||||
values.displayAllColumns = true;
|
||||
}
|
||||
} else {
|
||||
values.displayAllColumns = true;
|
||||
}
|
||||
|
||||
$.post($searchForm.attr('action'), values, function (data) {
|
||||
Functions.ajaxRemoveMessage($msgbox);
|
||||
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
if (typeof data.sql_query !== 'undefined') {
|
||||
// zero rows
|
||||
$('#sqlqueryresultsouter').html(data.sql_query);
|
||||
} else {
|
||||
// results found
|
||||
$('#sqlqueryresultsouter').html(data.message);
|
||||
$('.sqlqueryresults').trigger('makegrid');
|
||||
}
|
||||
|
||||
$('#tbl_search_form') // workaround for bug #3168569 - Issue on toggling the "Hide search criteria" in chrome.
|
||||
.slideToggle().hide();
|
||||
$('#togglesearchformlink') // always start with the Show message
|
||||
.text(Messages.strShowSearchCriteria);
|
||||
$('#togglesearchformdiv') // now it's time to show the div containing the link
|
||||
.show(); // needed for the display options slider in the results
|
||||
|
||||
Functions.initSlider();
|
||||
$('html, body').animate({
|
||||
scrollTop: 0
|
||||
}, 'fast');
|
||||
} else {
|
||||
$('#sqlqueryresultsouter').html(data.error);
|
||||
}
|
||||
|
||||
Functions.highlightSql($('#sqlqueryresultsouter'));
|
||||
}); // end $.post()
|
||||
}); // Following section is related to the 'function based search' for geometry data types.
|
||||
// Initially hide all the open_gis_editor spans
|
||||
|
||||
$('span.open_search_gis_editor').hide();
|
||||
$('select.geom_func').on('change', function () {
|
||||
var $geomFuncSelector = $(this);
|
||||
var binaryFunctions = ['Contains', 'Crosses', 'Disjoint', 'Equals', 'Intersects', 'Overlaps', 'Touches', 'Within', 'MBRContains', 'MBRDisjoint', 'MBREquals', 'MBRIntersects', 'MBROverlaps', 'MBRTouches', 'MBRWithin', 'ST_Contains', 'ST_Crosses', 'ST_Disjoint', 'ST_Equals', 'ST_Intersects', 'ST_Overlaps', 'ST_Touches', 'ST_Within'];
|
||||
var tempArray = ['Envelope', 'EndPoint', 'StartPoint', 'ExteriorRing', 'Centroid', 'PointOnSurface'];
|
||||
var outputGeomFunctions = binaryFunctions.concat(tempArray); // If the chosen function takes two geometry objects as parameters
|
||||
|
||||
var $operator = $geomFuncSelector.parents('tr').find('td').eq(4).find('select');
|
||||
|
||||
if ($.inArray($geomFuncSelector.val(), binaryFunctions) >= 0) {
|
||||
$operator.prop('readonly', true);
|
||||
} else {
|
||||
$operator.prop('readonly', false);
|
||||
} // if the chosen function's output is a geometry, enable GIS editor
|
||||
|
||||
|
||||
var $editorSpan = $geomFuncSelector.parents('tr').find('span.open_search_gis_editor');
|
||||
|
||||
if ($.inArray($geomFuncSelector.val(), outputGeomFunctions) >= 0) {
|
||||
$editorSpan.show();
|
||||
} else {
|
||||
$editorSpan.hide();
|
||||
}
|
||||
});
|
||||
$(document).on('click', 'span.open_search_gis_editor', function (event) {
|
||||
event.preventDefault();
|
||||
var $span = $(this); // Current value
|
||||
|
||||
var value = $span.parent('td').children('input[type=\'text\']').val(); // Field name
|
||||
|
||||
var field = 'Parameter'; // Column type
|
||||
|
||||
var geomFunc = $span.parents('tr').find('.geom_func').val();
|
||||
var type;
|
||||
|
||||
if (geomFunc === 'Envelope') {
|
||||
type = 'polygon';
|
||||
} else if (geomFunc === 'ExteriorRing') {
|
||||
type = 'linestring';
|
||||
} else {
|
||||
type = 'point';
|
||||
} // Names of input field and null checkbox
|
||||
|
||||
|
||||
var inputName = $span.parent('td').children('input[type=\'text\']').attr('name'); // Token
|
||||
|
||||
openGISEditor();
|
||||
|
||||
if (!gisEditorLoaded) {
|
||||
loadJSAndGISEditor(value, field, type, inputName);
|
||||
} else {
|
||||
loadGISEditor(value, field, type, inputName);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Ajax event handler for Range-Search.
|
||||
*/
|
||||
|
||||
$('body').on('change', 'select[name*="criteriaColumnOperators"]', function () {
|
||||
// Fix for bug #13778, changed 'click' to 'change'
|
||||
var $sourceSelect = $(this); // Get the column name.
|
||||
|
||||
var columnName = $(this).closest('tr').find('th').first().text(); // Get the data-type of column excluding size.
|
||||
|
||||
var dataType = $(this).closest('tr').find('td[data-type]').attr('data-type');
|
||||
dataType = TableSelect.checkIfDataTypeNumericOrDate(dataType); // Get the operator.
|
||||
|
||||
var operator = $(this).val();
|
||||
|
||||
if ((operator === 'BETWEEN' || operator === 'NOT BETWEEN') && dataType) {
|
||||
var $msgbox = Functions.ajaxShowMessage();
|
||||
$.ajax({
|
||||
url: 'index.php?route=/table/search',
|
||||
type: 'POST',
|
||||
data: {
|
||||
'server': CommonParams.get('server'),
|
||||
'ajax_request': 1,
|
||||
'db': $('input[name="db"]').val(),
|
||||
'table': $('input[name="table"]').val(),
|
||||
'column': columnName,
|
||||
'range_search': 1
|
||||
},
|
||||
success: function success(response) {
|
||||
Functions.ajaxRemoveMessage($msgbox);
|
||||
|
||||
if (response.success) {
|
||||
// Get the column min value.
|
||||
var min = response.column_data.min ? '(' + Messages.strColumnMin + ' ' + response.column_data.min + ')' : ''; // Get the column max value.
|
||||
|
||||
var max = response.column_data.max ? '(' + Messages.strColumnMax + ' ' + response.column_data.max + ')' : '';
|
||||
var buttonOptions = {};
|
||||
|
||||
buttonOptions[Messages.strGo] = function () {
|
||||
var minValue = $('#min_value').val();
|
||||
var maxValue = $('#max_value').val();
|
||||
var finalValue = '';
|
||||
|
||||
if (minValue.length && maxValue.length) {
|
||||
finalValue = minValue + ', ' + maxValue;
|
||||
}
|
||||
|
||||
var $targetField = $sourceSelect.closest('tr').find('[name*="criteriaValues"]'); // If target field is a select list.
|
||||
|
||||
if ($targetField.is('select')) {
|
||||
$targetField.val(finalValue);
|
||||
var $options = $targetField.find('option');
|
||||
var $closestMin = null;
|
||||
var $closestMax = null; // Find closest min and max value.
|
||||
|
||||
$options.each(function () {
|
||||
if ($closestMin === null || Math.abs($(this).val() - minValue) < Math.abs($closestMin.val() - minValue)) {
|
||||
$closestMin = $(this);
|
||||
}
|
||||
|
||||
if ($closestMax === null || Math.abs($(this).val() - maxValue) < Math.abs($closestMax.val() - maxValue)) {
|
||||
$closestMax = $(this);
|
||||
}
|
||||
});
|
||||
$closestMin.attr('selected', 'selected');
|
||||
$closestMax.attr('selected', 'selected');
|
||||
} else {
|
||||
$targetField.val(finalValue);
|
||||
}
|
||||
|
||||
$(this).dialog('close');
|
||||
};
|
||||
|
||||
buttonOptions[Messages.strCancel] = function () {
|
||||
$(this).dialog('close');
|
||||
}; // Display dialog box.
|
||||
|
||||
|
||||
$('<div></div>').append('<fieldset>' + '<legend>' + operator + '</legend>' + '<label for="min_value">' + Messages.strMinValue + '</label>' + '<input type="text" id="min_value">' + '<br>' + '<span class="small_font">' + min + '</span>' + '<br>' + '<label for="max_value">' + Messages.strMaxValue + '</label>' + '<input type="text" id="max_value">' + '<br>' + '<span class="small_font">' + max + '</span>' + '</fieldset>').dialog({
|
||||
width: 'auto',
|
||||
maxHeight: 400,
|
||||
modal: true,
|
||||
buttons: buttonOptions,
|
||||
title: Messages.strRangeSearch,
|
||||
open: function open() {
|
||||
// Add datepicker wherever required.
|
||||
Functions.addDatepicker($('#min_value'), dataType);
|
||||
Functions.addDatepicker($('#max_value'), dataType);
|
||||
},
|
||||
close: function close() {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Functions.ajaxShowMessage(response.error);
|
||||
}
|
||||
},
|
||||
error: function error() {
|
||||
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
var windowWidth = $(window).width();
|
||||
$('.jsresponsive').css('max-width', windowWidth - 69 + 'px');
|
||||
});
|
499
admin/phpMyAdmin/js/dist/table/structure.js
vendored
Normal file
499
admin/phpMyAdmin/js/dist/table/structure.js
vendored
Normal file
|
@ -0,0 +1,499 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* @fileoverview functions used on the table structure page
|
||||
* @name Table Structure
|
||||
*
|
||||
* @requires jQuery
|
||||
* @requires jQueryUI
|
||||
* @required js/functions.js
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
||||
/* global primaryIndexes:writable, indexes:writable, fulltextIndexes:writable, spatialIndexes:writable */
|
||||
// js/functions.js
|
||||
|
||||
/* global sprintf */
|
||||
// js/vendor/sprintf.js
|
||||
|
||||
/**
|
||||
* AJAX scripts for /table/structure
|
||||
*
|
||||
* Actions ajaxified here:
|
||||
* Drop Column
|
||||
* Add Primary Key
|
||||
* Drop Primary Key/Index
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reload fields table
|
||||
*/
|
||||
function reloadFieldForm() {
|
||||
$.post($('#fieldsForm').attr('action'), $('#fieldsForm').serialize() + CommonParams.get('arg_separator') + 'ajax_request=true', function (formData) {
|
||||
var $tempDiv = $('<div id=\'temp_div\'><div>').append(formData.message);
|
||||
$('#fieldsForm').replaceWith($tempDiv.find('#fieldsForm'));
|
||||
$('#addColumns').replaceWith($tempDiv.find('#addColumns'));
|
||||
$('#move_columns_dialog').find('ul').replaceWith($tempDiv.find('#move_columns_dialog ul'));
|
||||
$('#moveColumns').removeClass('move-active');
|
||||
});
|
||||
$('#page_content').show();
|
||||
}
|
||||
|
||||
function checkFirst() {
|
||||
if ($('select[name=after_field] option:selected').data('pos') === 'first') {
|
||||
$('input[name=field_where]').val('first');
|
||||
} else {
|
||||
$('input[name=field_where]').val('after');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
|
||||
|
||||
AJAX.registerTeardown('table/structure.js', function () {
|
||||
$(document).off('click', 'a.drop_column_anchor.ajax');
|
||||
$(document).off('click', 'a.add_key.ajax');
|
||||
$(document).off('click', '#move_columns_anchor');
|
||||
$(document).off('click', '#printView');
|
||||
$(document).off('submit', '.append_fields_form.ajax');
|
||||
$('body').off('click', '#fieldsForm.ajax button');
|
||||
$(document).off('click', 'a[id^=partition_action].ajax');
|
||||
$(document).off('click', '#remove_partitioning.ajax');
|
||||
});
|
||||
AJAX.registerOnload('table/structure.js', function () {
|
||||
// Re-initialize variables.
|
||||
primaryIndexes = [];
|
||||
indexes = [];
|
||||
fulltextIndexes = [];
|
||||
spatialIndexes = [];
|
||||
/**
|
||||
*Ajax action for submitting the "Column Change" and "Add Column" form
|
||||
*/
|
||||
|
||||
$('.append_fields_form.ajax').off();
|
||||
$(document).on('submit', '.append_fields_form.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
/**
|
||||
* @var the_form object referring to the export form
|
||||
*/
|
||||
|
||||
var $form = $(this);
|
||||
var fieldCnt = $form.find('input[name=orig_num_fields]').val();
|
||||
|
||||
function submitForm() {
|
||||
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
|
||||
$.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'do_save_data=1', function (data) {
|
||||
if ($('.sqlqueryresults').length !== 0) {
|
||||
$('.sqlqueryresults').remove();
|
||||
} else if ($('.error:not(.tab)').length !== 0) {
|
||||
$('.error:not(.tab)').remove();
|
||||
}
|
||||
|
||||
if (typeof data.success !== 'undefined' && data.success === true) {
|
||||
$('#page_content').empty().append(data.message).show();
|
||||
Functions.highlightSql($('#page_content'));
|
||||
$('.result_query .alert-primary').remove();
|
||||
reloadFieldForm();
|
||||
$form.remove();
|
||||
Functions.ajaxRemoveMessage($msg);
|
||||
Functions.initSlider();
|
||||
Navigation.reload();
|
||||
CommonActions.refreshMain('index.php?route=/table/structure');
|
||||
} else {
|
||||
Functions.ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
}
|
||||
|
||||
function checkIfConfirmRequired($form) {
|
||||
var i = 0;
|
||||
var id;
|
||||
var elm;
|
||||
var val;
|
||||
var nameOrig;
|
||||
var elmOrig;
|
||||
var valOrig;
|
||||
var checkRequired = false;
|
||||
|
||||
for (i = 0; i < fieldCnt; i++) {
|
||||
id = '#field_' + i + '_5';
|
||||
elm = $(id);
|
||||
val = elm.val();
|
||||
nameOrig = 'input[name=field_collation_orig\\[' + i + '\\]]';
|
||||
elmOrig = $form.find(nameOrig);
|
||||
valOrig = elmOrig.val();
|
||||
|
||||
if (val && valOrig && val !== valOrig) {
|
||||
checkRequired = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return checkRequired;
|
||||
}
|
||||
/*
|
||||
* First validate the form; if there is a problem, avoid submitting it
|
||||
*
|
||||
* Functions.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 (Functions.checkTableEditForm($form[0], fieldCnt)) {
|
||||
// OK, form passed validation step
|
||||
Functions.prepareForAjaxRequest($form);
|
||||
|
||||
if (Functions.checkReservedWordColumns($form)) {
|
||||
// User wants to submit the form
|
||||
// If Collation is changed, Warn and Confirm
|
||||
if (checkIfConfirmRequired($form)) {
|
||||
var question = sprintf(Messages.strChangeColumnCollation, 'https://wiki.phpmyadmin.net/pma/Garbled_data');
|
||||
$form.confirm(question, $form.attr('action'), function () {
|
||||
submitForm();
|
||||
});
|
||||
} else {
|
||||
submitForm();
|
||||
}
|
||||
}
|
||||
}
|
||||
}); // end change table button "do_save_data"
|
||||
|
||||
/**
|
||||
* Attach Event Handler for 'Drop Column'
|
||||
*/
|
||||
|
||||
$(document).on('click', 'a.drop_column_anchor.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
/**
|
||||
* @var curr_table_name String containing the name of the current table
|
||||
*/
|
||||
|
||||
var currTableName = $(this).closest('form').find('input[name=table]').val();
|
||||
/**
|
||||
* @var curr_row Object reference to the currently selected row (i.e. field in the table)
|
||||
*/
|
||||
|
||||
var $currRow = $(this).parents('tr');
|
||||
/**
|
||||
* @var curr_column_name String containing name of the field referred to by {@link curr_row}
|
||||
*/
|
||||
|
||||
var currColumnName = $currRow.children('th').children('label').text().trim();
|
||||
currColumnName = Functions.escapeHtml(currColumnName);
|
||||
/**
|
||||
* @var $after_field_item Corresponding entry in the 'After' field.
|
||||
*/
|
||||
|
||||
var $afterFieldItem = $('select[name=\'after_field\'] option[value=\'' + currColumnName + '\']');
|
||||
/**
|
||||
* @var question String containing the question to be asked for confirmation
|
||||
*/
|
||||
|
||||
var question = Functions.sprintf(Messages.strDoYouReally, 'ALTER TABLE `' + Functions.escapeHtml(currTableName) + '` DROP `' + Functions.escapeHtml(currColumnName) + '`;');
|
||||
var $thisAnchor = $(this);
|
||||
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
|
||||
var $msg = Functions.ajaxShowMessage(Messages.strDroppingColumn, false);
|
||||
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
|
||||
params += CommonParams.get('arg_separator') + 'ajax_page_request=1';
|
||||
$.post(url, params, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
Functions.ajaxRemoveMessage($msg);
|
||||
|
||||
if ($('.result_query').length) {
|
||||
$('.result_query').remove();
|
||||
}
|
||||
|
||||
if (data.sql_query) {
|
||||
$('<div class="result_query"></div>').html(data.sql_query).prependTo('#structure_content');
|
||||
Functions.highlightSql($('#page_content'));
|
||||
} // Adjust the row numbers
|
||||
|
||||
|
||||
for (var $row = $currRow.next(); $row.length > 0; $row = $row.next()) {
|
||||
var newVal = parseInt($row.find('td').eq(1).text(), 10) - 1;
|
||||
$row.find('td').eq(1).text(newVal);
|
||||
}
|
||||
|
||||
$afterFieldItem.remove();
|
||||
$currRow.hide('medium').remove(); // Remove the dropped column from select menu for 'after field'
|
||||
|
||||
$('select[name=after_field]').find('[value="' + currColumnName + '"]').remove(); // by default select the (new) last option to add new column
|
||||
// (in case last column is dropped)
|
||||
|
||||
$('select[name=after_field] option').last().attr('selected', 'selected'); // refresh table stats
|
||||
|
||||
if (data.tableStat) {
|
||||
$('#tablestatistics').html(data.tableStat);
|
||||
} // refresh the list of indexes (comes from /sql)
|
||||
|
||||
|
||||
$('.index_info').replaceWith(data.indexes_list);
|
||||
Navigation.reload();
|
||||
} else {
|
||||
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
});
|
||||
}); // end of Drop Column Anchor action
|
||||
|
||||
/**
|
||||
* Attach Event Handler for 'Print' link
|
||||
*/
|
||||
|
||||
$(document).on('click', '#printView', function (event) {
|
||||
event.preventDefault(); // Take to preview mode
|
||||
|
||||
Functions.printPreview();
|
||||
}); // end of Print View action
|
||||
|
||||
/**
|
||||
* Ajax Event handler for adding keys
|
||||
*/
|
||||
|
||||
$(document).on('click', 'a.add_key.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
var $this = $(this);
|
||||
var currTableName = $this.closest('form').find('input[name=table]').val();
|
||||
var currColumnName = $this.parents('tr').children('th').children('label').text().trim();
|
||||
var addClause = '';
|
||||
|
||||
if ($this.is('.add_primary_key_anchor')) {
|
||||
addClause = 'ADD PRIMARY KEY';
|
||||
} else if ($this.is('.add_index_anchor')) {
|
||||
addClause = 'ADD INDEX';
|
||||
} else if ($this.is('.add_unique_anchor')) {
|
||||
addClause = 'ADD UNIQUE';
|
||||
} else if ($this.is('.add_spatial_anchor')) {
|
||||
addClause = 'ADD SPATIAL';
|
||||
} else if ($this.is('.add_fulltext_anchor')) {
|
||||
addClause = 'ADD FULLTEXT';
|
||||
}
|
||||
|
||||
var question = Functions.sprintf(Messages.strDoYouReally, 'ALTER TABLE `' + Functions.escapeHtml(currTableName) + '` ' + addClause + '(`' + Functions.escapeHtml(currColumnName) + '`);');
|
||||
var $thisAnchor = $(this);
|
||||
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
|
||||
Functions.ajaxShowMessage();
|
||||
AJAX.source = $this;
|
||||
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
|
||||
params += CommonParams.get('arg_separator') + 'ajax_page_request=1';
|
||||
$.post(url, params, AJAX.responseHandler);
|
||||
});
|
||||
}); // end Add key
|
||||
|
||||
/**
|
||||
* Inline move columns
|
||||
**/
|
||||
|
||||
$(document).on('click', '#move_columns_anchor', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if ($(this).hasClass('move-active')) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* @var button_options Object that stores the options passed to jQueryUI
|
||||
* dialog
|
||||
*/
|
||||
|
||||
|
||||
var buttonOptions = {};
|
||||
|
||||
buttonOptions[Messages.strGo] = function (event) {
|
||||
event.preventDefault();
|
||||
var $msgbox = Functions.ajaxShowMessage();
|
||||
var $this = $(this);
|
||||
var $form = $this.find('form');
|
||||
var serialized = $form.serialize(); // check if any columns were moved at all
|
||||
|
||||
if (serialized === $form.data('serialized-unmoved')) {
|
||||
Functions.ajaxRemoveMessage($msgbox);
|
||||
$this.dialog('close');
|
||||
return;
|
||||
}
|
||||
|
||||
$.post($form.prop('action'), serialized + CommonParams.get('arg_separator') + 'ajax_request=true', function (data) {
|
||||
if (data.success === false) {
|
||||
Functions.ajaxRemoveMessage($msgbox);
|
||||
$this.clone().html(data.error).dialog({
|
||||
title: $(this).prop('title'),
|
||||
height: 230,
|
||||
width: 900,
|
||||
modal: true,
|
||||
buttons: buttonOptionsError
|
||||
}); // end dialog options
|
||||
} else {
|
||||
// sort the fields table
|
||||
var $fieldsTable = $('table#tablestructure tbody'); // remove all existing rows and remember them
|
||||
|
||||
var $rows = $fieldsTable.find('tr').remove(); // loop through the correct order
|
||||
|
||||
for (var i in data.columns) {
|
||||
var theColumn = data.columns[i];
|
||||
var $theRow = $rows.find('input:checkbox[value=\'' + theColumn + '\']').closest('tr'); // append the row for this column to the table
|
||||
|
||||
$fieldsTable.append($theRow);
|
||||
}
|
||||
|
||||
var $firstrow = $fieldsTable.find('tr').eq(0); // Adjust the row numbers and colors
|
||||
|
||||
for (var $row = $firstrow; $row.length > 0; $row = $row.next()) {
|
||||
$row.find('td').eq(1).text($row.index() + 1).end().removeClass('odd even').addClass($row.index() % 2 === 0 ? 'odd' : 'even');
|
||||
}
|
||||
|
||||
Functions.ajaxShowMessage(data.message);
|
||||
$this.dialog('close');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
buttonOptions[Messages.strPreviewSQL] = function () {
|
||||
// Function for Previewing SQL
|
||||
var $form = $('#move_column_form');
|
||||
Functions.previewSql($form);
|
||||
};
|
||||
|
||||
buttonOptions[Messages.strCancel] = function () {
|
||||
$(this).dialog('close');
|
||||
};
|
||||
|
||||
var buttonOptionsError = {};
|
||||
|
||||
buttonOptionsError[Messages.strOK] = function () {
|
||||
$(this).dialog('close').remove();
|
||||
};
|
||||
|
||||
var columns = [];
|
||||
$('#tablestructure').find('tbody tr').each(function () {
|
||||
var colName = $(this).find('input:checkbox').eq(0).val();
|
||||
var hiddenInput = $('<input>').prop({
|
||||
name: 'move_columns[]',
|
||||
type: 'hidden'
|
||||
}).val(colName);
|
||||
columns[columns.length] = $('<li></li>').addClass('placeholderDrag').text(colName).append(hiddenInput);
|
||||
});
|
||||
var colList = $('#move_columns_dialog').find('ul').find('li').remove().end();
|
||||
|
||||
for (var i in columns) {
|
||||
colList.append(columns[i]);
|
||||
}
|
||||
|
||||
colList.sortable({
|
||||
axis: 'y',
|
||||
containment: $('#move_columns_dialog').find('div'),
|
||||
tolerance: 'pointer'
|
||||
}).disableSelection();
|
||||
var $form = $('#move_columns_dialog').find('form');
|
||||
$form.data('serialized-unmoved', $form.serialize());
|
||||
$('#move_columns_dialog').dialog({
|
||||
modal: true,
|
||||
buttons: buttonOptions,
|
||||
open: function open() {
|
||||
if ($('#move_columns_dialog').parents('.ui-dialog').height() > $(window).height()) {
|
||||
$('#move_columns_dialog').dialog('option', 'height', $(window).height());
|
||||
}
|
||||
},
|
||||
beforeClose: function beforeClose() {
|
||||
$('#move_columns_anchor').removeClass('move-active');
|
||||
}
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Handles multi submits in table structure page such as change, browse, drop, primary etc.
|
||||
*/
|
||||
|
||||
$('body').on('click', '#fieldsForm.ajax button', function (e) {
|
||||
e.preventDefault();
|
||||
var $form = $(this).parents('form');
|
||||
var argsep = CommonParams.get('arg_separator');
|
||||
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
|
||||
Functions.ajaxShowMessage();
|
||||
AJAX.source = $form;
|
||||
$.post(this.formAction, submitData, AJAX.responseHandler);
|
||||
});
|
||||
/**
|
||||
* Handles clicks on Action links in partition table
|
||||
*/
|
||||
|
||||
$(document).on('click', 'a[id^=partition_action].ajax', function (e) {
|
||||
e.preventDefault();
|
||||
var $link = $(this);
|
||||
|
||||
function submitPartitionAction(url) {
|
||||
var params = 'ajax_request=true&ajax_page_request=true&' + $link.getPostData();
|
||||
Functions.ajaxShowMessage();
|
||||
AJAX.source = $link;
|
||||
$.post(url, params, AJAX.responseHandler);
|
||||
}
|
||||
|
||||
if ($link.is('#partition_action_DROP')) {
|
||||
$link.confirm(Messages.strDropPartitionWarning, $link.attr('href'), function (url) {
|
||||
submitPartitionAction(url);
|
||||
});
|
||||
} else if ($link.is('#partition_action_TRUNCATE')) {
|
||||
$link.confirm(Messages.strTruncatePartitionWarning, $link.attr('href'), function (url) {
|
||||
submitPartitionAction(url);
|
||||
});
|
||||
} else {
|
||||
submitPartitionAction($link.attr('href'));
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Handles remove partitioning
|
||||
*/
|
||||
|
||||
$(document).on('click', '#remove_partitioning.ajax', function (e) {
|
||||
e.preventDefault();
|
||||
var $link = $(this);
|
||||
var question = Messages.strRemovePartitioningWarning;
|
||||
$link.confirm(question, $link.attr('href'), function (url) {
|
||||
var params = Functions.getJsConfirmCommonParam({
|
||||
'ajax_request': true,
|
||||
'ajax_page_request': true
|
||||
}, $link.getPostData());
|
||||
Functions.ajaxShowMessage();
|
||||
AJAX.source = $link;
|
||||
$.post(url, params, AJAX.responseHandler);
|
||||
});
|
||||
});
|
||||
$(document).on('change', 'select[name=after_field]', function () {
|
||||
checkFirst();
|
||||
});
|
||||
});
|
||||
/** Handler for "More" dropdown in structure table rows */
|
||||
|
||||
AJAX.registerOnload('table/structure.js', function () {
|
||||
var windowwidth = $(window).width();
|
||||
|
||||
if (windowwidth > 768) {
|
||||
if (!$('#fieldsForm').hasClass('HideStructureActions')) {
|
||||
$('.table-structure-actions').width(function () {
|
||||
var width = 5;
|
||||
$(this).find('li').each(function () {
|
||||
width += $(this).outerWidth(true);
|
||||
});
|
||||
return width;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$('.jsresponsive').css('max-width', windowwidth - 35 + 'px');
|
||||
var tableRows = $('.central_columns');
|
||||
$.each(tableRows, function (index, item) {
|
||||
if ($(item).hasClass('add_button')) {
|
||||
$(item).on('click', function () {
|
||||
$('input:checkbox').prop('checked', false);
|
||||
$('#checkbox_row_' + (index + 1)).prop('checked', true);
|
||||
$('button[value=add_to_central_columns]').trigger('click');
|
||||
});
|
||||
} else {
|
||||
$(item).on('click', function () {
|
||||
$('input:checkbox').prop('checked', false);
|
||||
$('#checkbox_row_' + (index + 1)).prop('checked', true);
|
||||
$('button[value=remove_from_central_columns]').trigger('click');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
129
admin/phpMyAdmin/js/dist/table/tracking.js
vendored
Normal file
129
admin/phpMyAdmin/js/dist/table/tracking.js
vendored
Normal file
|
@ -0,0 +1,129 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Unbind all event handlers before tearing down the page
|
||||
*/
|
||||
AJAX.registerTeardown('table/tracking.js', function () {
|
||||
$('body').off('click', '#versionsForm.ajax button[name="submit_mult"], #versionsForm.ajax input[name="submit_mult"]');
|
||||
$('body').off('click', 'a.delete_version_anchor.ajax');
|
||||
$('body').off('click', 'a.delete_entry_anchor.ajax');
|
||||
});
|
||||
/**
|
||||
* Bind event handlers
|
||||
*/
|
||||
|
||||
AJAX.registerOnload('table/tracking.js', function () {
|
||||
$('#versions tr').first().find('th').append($('<div class="sorticon"></div>'));
|
||||
$('#versions').tablesorter({
|
||||
sortList: [[1, 0]],
|
||||
headers: {
|
||||
0: {
|
||||
sorter: false
|
||||
},
|
||||
1: {
|
||||
sorter: 'integer'
|
||||
},
|
||||
5: {
|
||||
sorter: false
|
||||
},
|
||||
6: {
|
||||
sorter: false
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if ($('#ddl_versions tbody tr').length > 0) {
|
||||
$('#ddl_versions tr').first().find('th').append($('<div class="sorticon"></div>'));
|
||||
$('#ddl_versions').tablesorter({
|
||||
sortList: [[0, 0]],
|
||||
headers: {
|
||||
0: {
|
||||
sorter: 'integer'
|
||||
},
|
||||
3: {
|
||||
sorter: false
|
||||
},
|
||||
4: {
|
||||
sorter: false
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ($('#dml_versions tbody tr').length > 0) {
|
||||
$('#dml_versions tr').first().find('th').append($('<div class="sorticon"></div>'));
|
||||
$('#dml_versions').tablesorter({
|
||||
sortList: [[0, 0]],
|
||||
headers: {
|
||||
0: {
|
||||
sorter: 'integer'
|
||||
},
|
||||
3: {
|
||||
sorter: false
|
||||
},
|
||||
4: {
|
||||
sorter: false
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Handles multi submit for tracking versions
|
||||
*/
|
||||
|
||||
|
||||
$('body').on('click', '#versionsForm.ajax button[name="submit_mult"], #versionsForm.ajax input[name="submit_mult"]', function (e) {
|
||||
e.preventDefault();
|
||||
var $button = $(this);
|
||||
var $form = $button.parent('form');
|
||||
var argsep = CommonParams.get('arg_separator');
|
||||
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
|
||||
|
||||
if ($button.val() === 'delete_version') {
|
||||
var question = Messages.strDeleteTrackingVersionMultiple;
|
||||
$button.confirm(question, $form.attr('action'), function (url) {
|
||||
Functions.ajaxShowMessage();
|
||||
AJAX.source = $form;
|
||||
$.post(url, submitData, AJAX.responseHandler);
|
||||
});
|
||||
} else {
|
||||
Functions.ajaxShowMessage();
|
||||
AJAX.source = $form;
|
||||
$.post($form.attr('action'), submitData, AJAX.responseHandler);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Ajax Event handler for 'Delete version'
|
||||
*/
|
||||
|
||||
$('body').on('click', 'a.delete_version_anchor.ajax', function (e) {
|
||||
e.preventDefault();
|
||||
var $anchor = $(this);
|
||||
var question = Messages.strDeleteTrackingVersion;
|
||||
$anchor.confirm(question, $anchor.attr('href'), function (url) {
|
||||
Functions.ajaxShowMessage();
|
||||
AJAX.source = $anchor;
|
||||
var argSep = CommonParams.get('arg_separator');
|
||||
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
|
||||
params += argSep + 'ajax_page_request=1';
|
||||
$.post(url, params, AJAX.responseHandler);
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Ajax Event handler for 'Delete tracking report entry'
|
||||
*/
|
||||
|
||||
$('body').on('click', 'a.delete_entry_anchor.ajax', function (e) {
|
||||
e.preventDefault();
|
||||
var $anchor = $(this);
|
||||
var question = Messages.strDeletingTrackingEntry;
|
||||
$anchor.confirm(question, $anchor.attr('href'), function (url) {
|
||||
Functions.ajaxShowMessage();
|
||||
AJAX.source = $anchor;
|
||||
var argSep = CommonParams.get('arg_separator');
|
||||
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
|
||||
params += argSep + 'ajax_page_request=1';
|
||||
$.post(url, params, AJAX.responseHandler);
|
||||
});
|
||||
});
|
||||
});
|
632
admin/phpMyAdmin/js/dist/table/zoom_plot_jqplot.js
vendored
Normal file
632
admin/phpMyAdmin/js/dist/table/zoom_plot_jqplot.js
vendored
Normal file
|
@ -0,0 +1,632 @@
|
|||
"use strict";
|
||||
|
||||
// TODO: change the axis
|
||||
|
||||
/**
|
||||
** @fileoverview JavaScript functions used on /table/search
|
||||
**
|
||||
** @requires jQuery
|
||||
** @requires js/functions.js
|
||||
**/
|
||||
|
||||
/* global changeValueFieldType, verifyAfterSearchFieldChange */
|
||||
// js/table/change.js
|
||||
|
||||
/**
|
||||
** Display Help/Info
|
||||
**/
|
||||
function displayHelp() {
|
||||
$('<div></div>').append(Messages.strDisplayHelp).appendTo('#page_content').dialog({
|
||||
width: 450,
|
||||
height: 'auto',
|
||||
title: Messages.strHelpTitle
|
||||
});
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
** Extend the array object for max function
|
||||
** @param array
|
||||
**/
|
||||
|
||||
|
||||
Array.max = function (array) {
|
||||
return Math.max.apply(Math, array);
|
||||
};
|
||||
/**
|
||||
** Extend the array object for min function
|
||||
** @param array
|
||||
**/
|
||||
|
||||
|
||||
Array.min = function (array) {
|
||||
return Math.min.apply(Math, array);
|
||||
};
|
||||
/**
|
||||
** Checks if a string contains only numeric value
|
||||
** @param n: String (to be checked)
|
||||
**/
|
||||
|
||||
|
||||
function isNumeric(n) {
|
||||
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||
}
|
||||
/**
|
||||
** Checks if an object is empty
|
||||
** @param n: Object (to be checked)
|
||||
**/
|
||||
|
||||
|
||||
function isEmpty(obj) {
|
||||
var name;
|
||||
|
||||
for (name in obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
** Converts a date/time into timestamp
|
||||
** @param val String Date
|
||||
** @param type String Field type(datetime/timestamp/time/date)
|
||||
**/
|
||||
|
||||
|
||||
function getTimeStamp(val, type) {
|
||||
if (type.toString().search(/datetime/i) !== -1 || type.toString().search(/timestamp/i) !== -1) {
|
||||
return $.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', val);
|
||||
} else if (type.toString().search(/time/i) !== -1) {
|
||||
return $.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', '1970-01-01 ' + val);
|
||||
} else if (type.toString().search(/date/i) !== -1) {
|
||||
return $.datepicker.parseDate('yy-mm-dd', val);
|
||||
}
|
||||
}
|
||||
/**
|
||||
** Classifies the field type into numeric,timeseries or text
|
||||
** @param field: field type (as in database structure)
|
||||
**/
|
||||
|
||||
|
||||
function getType(field) {
|
||||
if (field.toString().search(/int/i) !== -1 || field.toString().search(/decimal/i) !== -1 || field.toString().search(/year/i) !== -1) {
|
||||
return 'numeric';
|
||||
} else if (field.toString().search(/time/i) !== -1 || field.toString().search(/date/i) !== -1) {
|
||||
return 'time';
|
||||
} else {
|
||||
return 'text';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
|
||||
|
||||
AJAX.registerTeardown('table/zoom_plot_jqplot.js', function () {
|
||||
$('#tableid_0').off('change');
|
||||
$('#tableid_1').off('change');
|
||||
$('#tableid_2').off('change');
|
||||
$('#tableid_3').off('change');
|
||||
$('#inputFormSubmitId').off('click');
|
||||
$('#togglesearchformlink').off('click');
|
||||
$(document).off('keydown', '#dataDisplay :input');
|
||||
$('button.button-reset').off('click');
|
||||
$('div#resizer').off('resizestop');
|
||||
$('div#querychart').off('jqplotDataClick');
|
||||
});
|
||||
AJAX.registerOnload('table/zoom_plot_jqplot.js', function () {
|
||||
var currentChart = null;
|
||||
var searchedDataKey = null;
|
||||
var xLabel = $('#tableid_0').val();
|
||||
var yLabel = $('#tableid_1').val(); // will be updated via Ajax
|
||||
|
||||
var xType = $('#types_0').val();
|
||||
var yType = $('#types_1').val();
|
||||
var dataLabel = $('#dataLabel').val(); // Get query result
|
||||
|
||||
var searchedData;
|
||||
|
||||
try {
|
||||
searchedData = JSON.parse($('#querydata').html());
|
||||
} catch (err) {
|
||||
searchedData = null;
|
||||
} // adding event listener on select after AJAX request
|
||||
|
||||
|
||||
var comparisonOperatorOnChange = function comparisonOperatorOnChange() {
|
||||
var tableRows = $('#inputSection select.column-operator');
|
||||
$.each(tableRows, function (index, item) {
|
||||
$(item).on('change', function () {
|
||||
changeValueFieldType(this, index);
|
||||
verifyAfterSearchFieldChange(index, '#zoom_search_form');
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
** Input form submit on field change
|
||||
**/
|
||||
// first column choice corresponds to the X axis
|
||||
|
||||
|
||||
$('#tableid_0').on('change', function () {
|
||||
// AJAX request for field type, collation, operators, and value field
|
||||
$.post('index.php?route=/table/zoom-search', {
|
||||
'ajax_request': true,
|
||||
'change_tbl_info': true,
|
||||
'server': CommonParams.get('server'),
|
||||
'db': CommonParams.get('db'),
|
||||
'table': CommonParams.get('table'),
|
||||
'field': $('#tableid_0').val(),
|
||||
'it': 0
|
||||
}, function (data) {
|
||||
$('#tableFieldsId').find('tr').eq(1).find('td').eq(0).html(data.field_type);
|
||||
$('#tableFieldsId').find('tr').eq(1).find('td').eq(1).html(data.field_collation);
|
||||
$('#tableFieldsId').find('tr').eq(1).find('td').eq(2).html(data.field_operators);
|
||||
$('#tableFieldsId').find('tr').eq(1).find('td').eq(3).html(data.field_value);
|
||||
xLabel = $('#tableid_0').val();
|
||||
$('#types_0').val(data.field_type);
|
||||
xType = data.field_type;
|
||||
$('#collations_0').val(data.field_collations);
|
||||
comparisonOperatorOnChange();
|
||||
Functions.addDateTimePicker();
|
||||
});
|
||||
}); // second column choice corresponds to the Y axis
|
||||
|
||||
$('#tableid_1').on('change', function () {
|
||||
// AJAX request for field type, collation, operators, and value field
|
||||
$.post('index.php?route=/table/zoom-search', {
|
||||
'ajax_request': true,
|
||||
'change_tbl_info': true,
|
||||
'server': CommonParams.get('server'),
|
||||
'db': CommonParams.get('db'),
|
||||
'table': CommonParams.get('table'),
|
||||
'field': $('#tableid_1').val(),
|
||||
'it': 1
|
||||
}, function (data) {
|
||||
$('#tableFieldsId').find('tr').eq(2).find('td').eq(0).html(data.field_type);
|
||||
$('#tableFieldsId').find('tr').eq(2).find('td').eq(1).html(data.field_collation);
|
||||
$('#tableFieldsId').find('tr').eq(2).find('td').eq(2).html(data.field_operators);
|
||||
$('#tableFieldsId').find('tr').eq(2).find('td').eq(3).html(data.field_value);
|
||||
yLabel = $('#tableid_1').val();
|
||||
$('#types_1').val(data.field_type);
|
||||
yType = data.field_type;
|
||||
$('#collations_1').val(data.field_collations);
|
||||
comparisonOperatorOnChange();
|
||||
Functions.addDateTimePicker();
|
||||
});
|
||||
});
|
||||
$('#tableid_2').on('change', function () {
|
||||
// AJAX request for field type, collation, operators, and value field
|
||||
$.post('index.php?route=/table/zoom-search', {
|
||||
'ajax_request': true,
|
||||
'change_tbl_info': true,
|
||||
'server': CommonParams.get('server'),
|
||||
'db': CommonParams.get('db'),
|
||||
'table': CommonParams.get('table'),
|
||||
'field': $('#tableid_2').val(),
|
||||
'it': 2
|
||||
}, function (data) {
|
||||
$('#tableFieldsId').find('tr').eq(4).find('td').eq(0).html(data.field_type);
|
||||
$('#tableFieldsId').find('tr').eq(4).find('td').eq(1).html(data.field_collation);
|
||||
$('#tableFieldsId').find('tr').eq(4).find('td').eq(2).html(data.field_operators);
|
||||
$('#tableFieldsId').find('tr').eq(4).find('td').eq(3).html(data.field_value);
|
||||
$('#types_2').val(data.field_type);
|
||||
$('#collations_2').val(data.field_collations);
|
||||
comparisonOperatorOnChange();
|
||||
Functions.addDateTimePicker();
|
||||
});
|
||||
});
|
||||
$('#tableid_3').on('change', function () {
|
||||
// AJAX request for field type, collation, operators, and value field
|
||||
$.post('index.php?route=/table/zoom-search', {
|
||||
'ajax_request': true,
|
||||
'change_tbl_info': true,
|
||||
'server': CommonParams.get('server'),
|
||||
'db': CommonParams.get('db'),
|
||||
'table': CommonParams.get('table'),
|
||||
'field': $('#tableid_3').val(),
|
||||
'it': 3
|
||||
}, function (data) {
|
||||
$('#tableFieldsId').find('tr').eq(5).find('td').eq(0).html(data.field_type);
|
||||
$('#tableFieldsId').find('tr').eq(5).find('td').eq(1).html(data.field_collation);
|
||||
$('#tableFieldsId').find('tr').eq(5).find('td').eq(2).html(data.field_operators);
|
||||
$('#tableFieldsId').find('tr').eq(5).find('td').eq(3).html(data.field_value);
|
||||
$('#types_3').val(data.field_type);
|
||||
$('#collations_3').val(data.field_collations);
|
||||
comparisonOperatorOnChange();
|
||||
Functions.addDateTimePicker();
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Input form validation
|
||||
**/
|
||||
|
||||
$('#inputFormSubmitId').on('click', function () {
|
||||
if ($('#tableid_0').get(0).selectedIndex === 0 || $('#tableid_1').get(0).selectedIndex === 0) {
|
||||
Functions.ajaxShowMessage(Messages.strInputNull);
|
||||
} else if (xLabel === yLabel) {
|
||||
Functions.ajaxShowMessage(Messages.strSameInputs);
|
||||
}
|
||||
});
|
||||
/**
|
||||
** Prepare a div containing a link, otherwise it's incorrectly displayed
|
||||
** after a couple of clicks
|
||||
**/
|
||||
|
||||
$('<div id="togglesearchformdiv"><a id="togglesearchformlink"></a></div>').insertAfter('#zoom_search_form') // don't show it until we have results on-screen
|
||||
.hide();
|
||||
$('#togglesearchformlink').html(Messages.strShowSearchCriteria).on('click', function () {
|
||||
var $link = $(this);
|
||||
$('#zoom_search_form').slideToggle();
|
||||
|
||||
if ($link.text() === Messages.strHideSearchCriteria) {
|
||||
$link.text(Messages.strShowSearchCriteria);
|
||||
} else {
|
||||
$link.text(Messages.strHideSearchCriteria);
|
||||
} // avoid default click action
|
||||
|
||||
|
||||
return false;
|
||||
});
|
||||
/**
|
||||
** Set dialog properties for the data display form
|
||||
**/
|
||||
|
||||
var buttonOptions = {};
|
||||
/*
|
||||
* Handle saving of a row in the editor
|
||||
*/
|
||||
|
||||
buttonOptions[Messages.strSave] = function () {
|
||||
// Find changed values by comparing form values with selectedRow Object
|
||||
var newValues = {}; // Stores the values changed from original
|
||||
|
||||
var sqlTypes = {};
|
||||
var it = 0;
|
||||
var xChange = false;
|
||||
var yChange = false;
|
||||
var key;
|
||||
|
||||
var tempGetVal = function tempGetVal() {
|
||||
return $(this).val();
|
||||
};
|
||||
|
||||
for (key in selectedRow) {
|
||||
var oldVal = selectedRow[key];
|
||||
var newVal = $('#edit_fields_null_id_' + it).prop('checked') ? null : $('#edit_fieldID_' + it).val();
|
||||
|
||||
if (newVal instanceof Array) {
|
||||
// when the column is of type SET
|
||||
newVal = $('#edit_fieldID_' + it).map(tempGetVal).get().join(',');
|
||||
}
|
||||
|
||||
if (oldVal !== newVal) {
|
||||
selectedRow[key] = newVal;
|
||||
newValues[key] = newVal;
|
||||
|
||||
if (key === xLabel) {
|
||||
xChange = true;
|
||||
searchedData[searchedDataKey][xLabel] = newVal;
|
||||
} else if (key === yLabel) {
|
||||
yChange = true;
|
||||
searchedData[searchedDataKey][yLabel] = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
var $input = $('#edit_fieldID_' + it);
|
||||
|
||||
if ($input.hasClass('bit')) {
|
||||
sqlTypes[key] = 'bit';
|
||||
} else {
|
||||
sqlTypes[key] = null;
|
||||
}
|
||||
|
||||
it++;
|
||||
} // End data update
|
||||
// Update the chart series and replot
|
||||
|
||||
|
||||
if (xChange || yChange) {
|
||||
// Logic similar to plot generation, replot only if xAxis changes or yAxis changes.
|
||||
// Code includes a lot of checks so as to replot only when necessary
|
||||
if (xChange) {
|
||||
xCord[searchedDataKey] = selectedRow[xLabel]; // [searchedDataKey][0] contains the x value
|
||||
|
||||
if (xType === 'numeric') {
|
||||
series[0][searchedDataKey][0] = selectedRow[xLabel];
|
||||
} else if (xType === 'time') {
|
||||
series[0][searchedDataKey][0] = getTimeStamp(selectedRow[xLabel], $('#types_0').val());
|
||||
} else {
|
||||
series[0][searchedDataKey][0] = ''; // TODO: text values
|
||||
}
|
||||
|
||||
currentChart.series[0].data = series[0]; // TODO: axis changing
|
||||
|
||||
currentChart.replot();
|
||||
}
|
||||
|
||||
if (yChange) {
|
||||
yCord[searchedDataKey] = selectedRow[yLabel]; // [searchedDataKey][1] contains the y value
|
||||
|
||||
if (yType === 'numeric') {
|
||||
series[0][searchedDataKey][1] = selectedRow[yLabel];
|
||||
} else if (yType === 'time') {
|
||||
series[0][searchedDataKey][1] = getTimeStamp(selectedRow[yLabel], $('#types_1').val());
|
||||
} else {
|
||||
series[0][searchedDataKey][1] = ''; // TODO: text values
|
||||
}
|
||||
|
||||
currentChart.series[0].data = series[0]; // TODO: axis changing
|
||||
|
||||
currentChart.replot();
|
||||
}
|
||||
} // End plot update
|
||||
// Generate SQL query for update
|
||||
|
||||
|
||||
if (!isEmpty(newValues)) {
|
||||
var sqlQuery = 'UPDATE `' + CommonParams.get('table') + '` SET ';
|
||||
|
||||
for (key in newValues) {
|
||||
sqlQuery += '`' + key + '`=';
|
||||
var value = newValues[key]; // null
|
||||
|
||||
if (value === null) {
|
||||
sqlQuery += 'NULL, '; // empty
|
||||
} else if (value.trim() === '') {
|
||||
sqlQuery += '\'\', '; // other
|
||||
} else {
|
||||
// type explicitly identified
|
||||
if (sqlTypes[key] !== null) {
|
||||
if (sqlTypes[key] === 'bit') {
|
||||
sqlQuery += 'b\'' + value + '\', ';
|
||||
} // type not explicitly identified
|
||||
|
||||
} else {
|
||||
if (!isNumeric(value)) {
|
||||
sqlQuery += '\'' + value + '\', ';
|
||||
} else {
|
||||
sqlQuery += value + ', ';
|
||||
}
|
||||
}
|
||||
}
|
||||
} // remove two extraneous characters ', '
|
||||
|
||||
|
||||
sqlQuery = sqlQuery.substring(0, sqlQuery.length - 2);
|
||||
sqlQuery += ' WHERE ' + Sql.urlDecode(searchedData[searchedDataKey].where_clause);
|
||||
$.post('index.php?route=/sql', {
|
||||
'server': CommonParams.get('server'),
|
||||
'db': CommonParams.get('db'),
|
||||
'ajax_request': true,
|
||||
'sql_query': sqlQuery,
|
||||
'inline_edit': false
|
||||
}, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
$('#sqlqueryresultsouter').html(data.sql_query);
|
||||
Functions.highlightSql($('#sqlqueryresultsouter'));
|
||||
} else {
|
||||
Functions.ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // End $.post
|
||||
} // End database update
|
||||
|
||||
|
||||
$('#dataDisplay').dialog('close');
|
||||
};
|
||||
|
||||
buttonOptions[Messages.strCancel] = function () {
|
||||
$(this).dialog('close');
|
||||
};
|
||||
|
||||
$('#dataDisplay').dialog({
|
||||
autoOpen: false,
|
||||
title: Messages.strDataPointContent,
|
||||
modal: true,
|
||||
buttons: buttonOptions,
|
||||
width: $('#dataDisplay').width() + 80,
|
||||
open: function open() {
|
||||
$(this).find('input[type=checkbox]').css('margin', '0.5em');
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Attach Ajax event handlers for input fields
|
||||
* in the dialog. Used to submit the Ajax
|
||||
* request when the ENTER key is pressed.
|
||||
*/
|
||||
|
||||
$(document).on('keydown', '#dataDisplay :input', function (e) {
|
||||
if (e.which === 13) {
|
||||
// 13 is the ENTER key
|
||||
e.preventDefault();
|
||||
|
||||
if (typeof buttonOptions[Messages.strSave] === 'function') {
|
||||
buttonOptions[Messages.strSave].call();
|
||||
}
|
||||
}
|
||||
});
|
||||
/*
|
||||
* Generate plot using jqplot
|
||||
*/
|
||||
|
||||
if (searchedData !== null) {
|
||||
$('#zoom_search_form').slideToggle().hide();
|
||||
$('#togglesearchformlink').text(Messages.strShowSearchCriteria);
|
||||
$('#togglesearchformdiv').show();
|
||||
var selectedRow;
|
||||
var series = [];
|
||||
var xCord = [];
|
||||
var yCord = [];
|
||||
var xVal;
|
||||
var yVal;
|
||||
var format;
|
||||
var options = {
|
||||
series: [// for a scatter plot
|
||||
{
|
||||
showLine: false
|
||||
}],
|
||||
grid: {
|
||||
drawBorder: false,
|
||||
shadow: false,
|
||||
background: 'rgba(0,0,0,0)'
|
||||
},
|
||||
axes: {
|
||||
xaxis: {
|
||||
label: $('#tableid_0').val(),
|
||||
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
|
||||
},
|
||||
yaxis: {
|
||||
label: $('#tableid_1').val(),
|
||||
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
|
||||
}
|
||||
},
|
||||
highlighter: {
|
||||
show: true,
|
||||
tooltipAxes: 'y',
|
||||
yvalues: 2,
|
||||
// hide the first y value
|
||||
formatString: '<span class="hide">%s</span>%s'
|
||||
},
|
||||
cursor: {
|
||||
show: true,
|
||||
zoom: true,
|
||||
showTooltip: false
|
||||
}
|
||||
}; // If data label is not set, do not show tooltips
|
||||
|
||||
if (dataLabel === '') {
|
||||
options.highlighter.show = false;
|
||||
} // Classify types as either numeric,time,text
|
||||
|
||||
|
||||
xType = getType(xType);
|
||||
yType = getType(yType); // could have multiple series but we'll have just one
|
||||
|
||||
series[0] = [];
|
||||
|
||||
if (xType === 'time') {
|
||||
var originalXType = $('#types_0').val();
|
||||
|
||||
if (originalXType === 'date') {
|
||||
format = '%Y-%m-%d';
|
||||
} // TODO: does not seem to work
|
||||
// else if (originalXType === 'time') {
|
||||
// format = '%H:%M';
|
||||
// } else {
|
||||
// format = '%Y-%m-%d %H:%M';
|
||||
// }
|
||||
|
||||
|
||||
$.extend(options.axes.xaxis, {
|
||||
renderer: $.jqplot.DateAxisRenderer,
|
||||
tickOptions: {
|
||||
formatString: format
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (yType === 'time') {
|
||||
var originalYType = $('#types_1').val();
|
||||
|
||||
if (originalYType === 'date') {
|
||||
format = '%Y-%m-%d';
|
||||
}
|
||||
|
||||
$.extend(options.axes.yaxis, {
|
||||
renderer: $.jqplot.DateAxisRenderer,
|
||||
tickOptions: {
|
||||
formatString: format
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$.each(searchedData, function (key, value) {
|
||||
if (xType === 'numeric') {
|
||||
xVal = parseFloat(value[xLabel]);
|
||||
}
|
||||
|
||||
if (xType === 'time') {
|
||||
xVal = getTimeStamp(value[xLabel], originalXType);
|
||||
}
|
||||
|
||||
if (yType === 'numeric') {
|
||||
yVal = parseFloat(value[yLabel]);
|
||||
}
|
||||
|
||||
if (yType === 'time') {
|
||||
yVal = getTimeStamp(value[yLabel], originalYType);
|
||||
}
|
||||
|
||||
series[0].push([xVal, yVal, // extra Y values
|
||||
value[dataLabel], // for highlighter
|
||||
// (may set an undefined value)
|
||||
value.where_clause, // for click on point
|
||||
key, // key from searchedData
|
||||
value.where_clause_sign]);
|
||||
}); // under IE 8, the initial display is mangled; after a manual
|
||||
// resizing, it's ok
|
||||
// under IE 9, everything is fine
|
||||
|
||||
currentChart = $.jqplot('querychart', series, options);
|
||||
currentChart.resetZoom();
|
||||
$('button.button-reset').on('click', function (event) {
|
||||
event.preventDefault();
|
||||
currentChart.resetZoom();
|
||||
});
|
||||
$('div#resizer').resizable();
|
||||
$('div#resizer').on('resizestop', function () {
|
||||
// make room so that the handle will still appear
|
||||
$('div#querychart').height($('div#resizer').height() * 0.96);
|
||||
$('div#querychart').width($('div#resizer').width() * 0.96);
|
||||
currentChart.replot({
|
||||
resetAxes: true
|
||||
});
|
||||
});
|
||||
$('div#querychart').on('jqplotDataClick', function (event, seriesIndex, pointIndex, data) {
|
||||
searchedDataKey = data[4]; // key from searchedData (global)
|
||||
|
||||
var fieldId = 0;
|
||||
var postParams = {
|
||||
'ajax_request': true,
|
||||
'get_data_row': true,
|
||||
'server': CommonParams.get('server'),
|
||||
'db': CommonParams.get('db'),
|
||||
'table': CommonParams.get('table'),
|
||||
'where_clause': data[3],
|
||||
'where_clause_sign': data[5]
|
||||
};
|
||||
$.post('index.php?route=/table/zoom-search', postParams, function (data) {
|
||||
// Row is contained in data.row_info,
|
||||
// now fill the displayResultForm with row values
|
||||
var key;
|
||||
|
||||
for (key in data.row_info) {
|
||||
var $field = $('#edit_fieldID_' + fieldId);
|
||||
var $fieldNull = $('#edit_fields_null_id_' + fieldId);
|
||||
|
||||
if (data.row_info[key] === null) {
|
||||
$fieldNull.prop('checked', true);
|
||||
$field.val('');
|
||||
} else {
|
||||
$fieldNull.prop('checked', false);
|
||||
|
||||
if ($field.attr('multiple')) {
|
||||
// when the column is of type SET
|
||||
$field.val(data.row_info[key].split(','));
|
||||
} else {
|
||||
$field.val(data.row_info[key]);
|
||||
}
|
||||
}
|
||||
|
||||
fieldId++;
|
||||
}
|
||||
|
||||
selectedRow = data.row_info;
|
||||
});
|
||||
$('#dataDisplay').dialog('open');
|
||||
});
|
||||
}
|
||||
|
||||
$('#help_dialog').on('click', function () {
|
||||
displayHelp();
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue