diff --git a/adminer/include/adminer.inc.php b/adminer/include/adminer.inc.php
index 277e4fbe..4f864177 100644
--- a/adminer/include/adminer.inc.php
+++ b/adminer/include/adminer.inc.php
@@ -1062,6 +1062,7 @@ bodyLoad('" . lang('No tables.') . "\n";
} else {
+ $this->printTablesFilter();
$this->tablesPrint($tables);
}
}
@@ -1106,28 +1107,51 @@ bodyLoad('\n";
}
- /** Prints table list in menu
- * @param array result of table_status('', true)
- * @return null
- */
- function tablesPrint($tables) {
+ function printTablesFilter()
+ {
+ global $adminer;
+
+ echo "
"
+ . ""
+ . script("initTablesFilter(" . json_encode($adminer->database()) . ");")
+ . "
\n";
+ }
+
+ /**
+ * Prints table list in menu.
+ *
+ * @param array $tables Result of table_status('', true)
+ * @return null
+ */
+ function tablesPrint(array $tables) {
echo "" . script("mixin(qs('#tables'), {onmouseover: menuOver, onmouseout: menuOut});");
+
foreach ($tables as $table => $status) {
$name = $this->tableName($status);
if ($name != "") {
+ $active = $table == $_GET["select"] || $table == $_GET["edit"];
+
echo '- " . lang('select') . " "
- ;
- echo (support("table") || support("indexes")
- ? '$name"
- : "$name"
- ) . "\n";
+ . bold($active, "select")
+ . " title='" . lang('Select data') . "'>" . lang('select') . " ";
+
+ if (support("table") || support("indexes")) {
+ $active = in_array($table, [$_GET["table"], $_GET["create"], $_GET["indexes"], $_GET["foreign"], $_GET["trigger"]]);
+ $class = is_view($status) ? "view" : "structure";
+
+ echo '$name";
+ } else {
+ echo "$name";
+ }
+
+ echo "
\n";
}
}
+
echo "
\n";
+
+ return null;
}
}
diff --git a/adminer/static/default.css b/adminer/static/default.css
index e52fc067..fc77e680 100644
--- a/adminer/static/default.css
+++ b/adminer/static/default.css
@@ -31,6 +31,7 @@ input.default { box-shadow: 1px 1px 1px #777; }
input.required { box-shadow: 1px 1px 1px red; }
input.maxlength { box-shadow: 1px 1px 1px red; }
input.wayoff { left: -1000px; position: absolute; }
+input::placeholder { color: #000; opacity: 0.4; }
.center { text-align: center; }
.block { display: block; }
.version { color: #777; font-size: 67%; }
@@ -68,6 +69,7 @@ input.wayoff { left: -1000px; position: absolute; }
.links a { white-space: nowrap; margin-right: 20px; }
.logout { margin-top: .5em; position: absolute; top: 0; right: 0; }
.loadmore { margin-left: 1ex; }
+.tables-filter { padding: .8em 1em 0; }
/* .edit used in designs */
#menu { position: absolute; margin: 10px 0 0; padding: 0 0 30px 0; top: 2em; left: 0; width: 19em; }
#menu p, #logins, #tables { padding: .8em 1em; margin: 0; border-bottom: 1px solid #ccc; }
@@ -83,6 +85,7 @@ input.wayoff { left: -1000px; position: absolute; }
#schema { margin-left: 60px; position: relative; -moz-user-select: none; -webkit-user-select: none; }
#schema .table { border: 1px solid silver; padding: 0 2px; cursor: move; position: absolute; }
#schema .references { position: absolute; }
+#tables-filter { width: 100%; }
#help { position: absolute; border: 1px solid #999; background: #eee; padding: 5px; font-family: monospace; z-index: 1; }
.rtl h2 { margin: 0 -18px 20px 0; }
diff --git a/adminer/static/functions.js b/adminer/static/functions.js
index 5f62992d..c27acf4b 100644
--- a/adminer/static/functions.js
+++ b/adminer/static/functions.js
@@ -357,7 +357,78 @@ function pageClick(href, page) {
}
}
+let tablesFilterTimeout = null;
+let tablesFilterValue = '';
+function initTablesFilter(dbName) {
+ if (sessionStorage) {
+ document.addEventListener('DOMContentLoaded', function () {
+ if (dbName === sessionStorage.getItem('adminer_tables_filter_db') && sessionStorage.getItem('adminer_tables_filter')) {
+ qs('#tables-filter').value = sessionStorage.getItem('adminer_tables_filter');
+ filterTables();
+ } else {
+ sessionStorage.removeItem('adminer_tables_filter');
+ }
+
+ sessionStorage.setItem('adminer_tables_filter_db', dbName);
+ });
+ }
+
+ const filterInput = qs('#tables-filter');
+ filterInput.addEventListener('input', function () {
+ window.clearTimeout(tablesFilterTimeout);
+ tablesFilterTimeout = window.setTimeout(filterTables, 200);
+ });
+
+ document.body.addEventListener('keydown', function(event) {
+ if (isCtrl(event) && event.shiftKey && event.key.toUpperCase() === 'F') {
+ filterInput.focus();
+ filterInput.select();
+
+ event.preventDefault();
+ }
+ });
+}
+
+function filterTables() {
+ const value = qs('#tables-filter').value.toLowerCase();
+ if (value === tablesFilterValue) {
+ return;
+ }
+ tablesFilterValue = value;
+
+ let reg
+ if (value !== '') {
+ const valueExp = (`${value}`).replace(/[\\.+*?\[^\]$(){}=!<>|:]/g, '\\$&');
+ reg = new RegExp(`(${valueExp})`, 'gi');
+ }
+
+ if (sessionStorage) {
+ sessionStorage.setItem('adminer_tables_filter', value);
+ }
+
+ const tables = qsa('#tables li');
+ for (let i = 0; i < tables.length; i++) {
+ let a = qs('a[data-main="true"], span[data-main="true"]', tables[i]);
+
+ let tableName = tables[i].dataset.tableName;
+ if (tableName == null) {
+ tableName = a.innerHTML.trim();
+
+ tables[i].dataset.tableName = tableName;
+ }
+
+ if (value === "") {
+ tables[i].classList.remove('hidden');
+ a.innerHTML = tableName;
+ } else if (tableName.toLowerCase().indexOf(value) >= 0) {
+ tables[i].classList.remove('hidden');
+ a.innerHTML = tableName.replace(reg, '$1');
+ } else {
+ tables[i].classList.add('hidden');
+ }
+ }
+}
/** Display items in menu
* @param MouseEvent
diff --git a/editor/include/adminer.inc.php b/editor/include/adminer.inc.php
index be9d7436..5cf02dc9 100644
--- a/editor/include/adminer.inc.php
+++ b/editor/include/adminer.inc.php
@@ -623,6 +623,7 @@ qsl('div').onclick = whisperClick;", "")
if (!$table_status) {
echo "" . lang('No tables.') . "\n";
} else {
+ $this->printTablesFilter();
$this->tablesPrint($table_status);
}
}
@@ -632,19 +633,32 @@ qsl('div').onclick = whisperClick;", "")
function databasesPrint($missing) {
}
- function tablesPrint($tables) {
- echo "