From 9a3090ef75ded1be2abca3fa2cca4d622a0ff243 Mon Sep 17 00:00:00 2001 From: Bhuvi100 <81316368+Bhuvi100@users.noreply.github.com> Date: Tue, 18 Oct 2022 00:11:51 +0530 Subject: [PATCH] Make search input field types match columns types (integer and float) (#17765) This PR adds type attribute as well as inputmode attribute to search value input fields which makes it easier for validation as well as for using phpMyAdmin on touch devices with virtual keyboards. Fixes #17745 Signed-off-by: Bhuvanesh T G Co-authored-by: William Desportes --- js/src/table/change.js | 33 +++++++++++++++++++ .../Controllers/Table/SearchController.php | 8 +++-- .../Table/ZoomSearchController.php | 8 +++-- libraries/classes/Types.php | 15 +++++++++ templates/table/search/input_box.twig | 13 +++++++- 5 files changed, 72 insertions(+), 5 deletions(-) diff --git a/js/src/table/change.js b/js/src/table/change.js index 2bb46e35ae..af362b5751 100644 --- a/js/src/table/change.js +++ b/js/src/table/change.js @@ -194,6 +194,19 @@ function verifyAfterSearchFieldChange (index, searchFormId) { } // Update error on dropdown change $thisInput.valid(); + } else if ($thisInput.data('type') === 'FLOAT') { + // Trim spaces + $thisInput.val($thisInput.val().trim()); + + $(searchFormId).validate({ + // update errors as we write + onkeyup: function (element) { + $(element).valid(); + } + }); + validateFloatField($thisInput, true); + // Update error on dropdown change + $thisInput.valid(); } } window.verifyAfterSearchFieldChange = verifyAfterSearchFieldChange; @@ -260,6 +273,26 @@ function validateIntField (jqueryInput, returnValueIfIsNumber) { }); } +/** + * Validate the an input contains an float value + * @param {jQuery} jqueryInput the Jquery object + * @param {boolean} returnValueIfIsNumber the value to return if the validator passes + * @return {void} + */ +function validateFloatField (jqueryInput, returnValueIfIsNumber) { + // removing previous rules + jqueryInput.rules('remove'); + + jqueryInput.rules('add', { + number: { + param: true, + depends: function () { + return returnValueIfIsNumber; + } + }, + }); +} + function verificationsAfterFieldChange (urlField, multiEdit, theType) { var evt = window.event || arguments.callee.caller.arguments[0]; var target = evt.target || evt.srcElement; diff --git a/libraries/classes/Controllers/Table/SearchController.php b/libraries/classes/Controllers/Table/SearchController.php index 85bb4c9560..437bd46e18 100644 --- a/libraries/classes/Controllers/Table/SearchController.php +++ b/libraries/classes/Controllers/Table/SearchController.php @@ -362,7 +362,9 @@ class SearchController extends AbstractController '' ); $htmlAttributes = ''; - if (in_array($cleanType, $this->dbi->types->getIntegerTypes())) { + $isInteger = in_array($cleanType, $this->dbi->types->getIntegerTypes()); + $isFloat = in_array($cleanType, $this->dbi->types->getFloatTypes()); + if ($isInteger) { $extractedColumnspec = Util::extractColumnSpec($this->originalColumnTypes[$column_index]); $is_unsigned = $extractedColumnspec['unsigned']; $minMaxValues = $this->dbi->types->getIntegerRange($cleanType, ! $is_unsigned); @@ -397,7 +399,7 @@ class SearchController extends AbstractController $value = $this->template->render('table/search/input_box', [ 'str' => '', 'column_type' => (string) $type, - 'column_data_type' => strtoupper($cleanType), + 'column_data_type' => $isInteger ? 'INT' : ($isFloat ? 'FLOAT' : strtoupper($cleanType)), 'html_attributes' => $htmlAttributes, 'column_id' => 'fieldID_', 'in_zoom_search_edit' => false, @@ -412,6 +414,8 @@ class SearchController extends AbstractController 'in_fbs' => true, 'foreign_dropdown' => $foreignDropdown, 'search_column_in_foreigners' => $searchColumnInForeigners, + 'is_integer' => $isInteger, + 'is_float' => $isFloat, ]); return [ diff --git a/libraries/classes/Controllers/Table/ZoomSearchController.php b/libraries/classes/Controllers/Table/ZoomSearchController.php index 5d87f73030..2cbdb565d0 100644 --- a/libraries/classes/Controllers/Table/ZoomSearchController.php +++ b/libraries/classes/Controllers/Table/ZoomSearchController.php @@ -452,7 +452,9 @@ class ZoomSearchController extends AbstractController '' ); $htmlAttributes = ''; - if (in_array($cleanType, $this->dbi->types->getIntegerTypes())) { + $isInteger = in_array($cleanType, $this->dbi->types->getIntegerTypes()); + $isFloat = in_array($cleanType, $this->dbi->types->getFloatTypes()); + if ($isInteger) { $extractedColumnspec = Util::extractColumnSpec($this->originalColumnTypes[$column_index]); $is_unsigned = $extractedColumnspec['unsigned']; $minMaxValues = $this->dbi->types->getIntegerRange($cleanType, ! $is_unsigned); @@ -482,7 +484,7 @@ class ZoomSearchController extends AbstractController $value = $this->template->render('table/search/input_box', [ 'str' => '', 'column_type' => (string) $type, - 'column_data_type' => strtoupper($cleanType), + 'column_data_type' => $isInteger ? 'INT' : ($isFloat ? 'FLOAT' : strtoupper($cleanType)), 'html_attributes' => $htmlAttributes, 'column_id' => 'fieldID_', 'in_zoom_search_edit' => false, @@ -496,6 +498,8 @@ class ZoomSearchController extends AbstractController 'db' => $GLOBALS['db'], 'in_fbs' => true, 'foreign_dropdown' => $foreignDropdown, + 'is_integer' => $isInteger, + 'is_float' => $isFloat, ]); return [ diff --git a/libraries/classes/Types.php b/libraries/classes/Types.php index ab15d7a7ed..b03dc86c83 100644 --- a/libraries/classes/Types.php +++ b/libraries/classes/Types.php @@ -889,6 +889,21 @@ class Types ]; } + /** + * Returns an array of float types + * + * @return string[] float types + */ + public function getFloatTypes(): array + { + return [ + 'decimal', + 'float', + 'double', + 'real', + ]; + } + /** * Returns the min and max values of a given integer type * diff --git a/templates/table/search/input_box.twig b/templates/table/search/input_box.twig index ca30bc2b8d..a066c5013a 100644 --- a/templates/table/search/input_box.twig +++ b/templates/table/search/input_box.twig @@ -79,7 +79,18 @@ {% elseif column_type starts with 'bit' %} {% set the_class = the_class ~ ' bit' %} {% endif %} -