Add better select menu allowing users to filter inside the dropdown as well as add new entries in place.

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2020-05-13 21:18:54 +02:00
parent 2f0b8bfdc8
commit bdca8104e5
6 changed files with 46 additions and 22 deletions

View File

@@ -30,14 +30,18 @@
<label for="select">Known clients:</label>
<select id="select" class="form-control" placeholder="">
<option disabled selected>Loading...</option>
</select><br>
<input id="ip-custom" type="text" class="form-control" disabled placeholder="Client IP address (IPv4 or IPv6, CIDR subnetting available, optional)" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off">
</select>
</div>
<div class="form-group col-md-6">
<label for="new_comment">Comment:</label>
<input id="new_comment" type="text" class="form-control" placeholder="Client description (optional)">
</div>
</div>
<div class="row">
<div class="col-md-12">
<p>You can select an existing client or add a custom one by typing into the field above and confirming your entry with <kbd>&#x23CE;</kbd>. Clients can be described either by their IP addresses (IPv4 and IPv6 are supported), IP subnets (CIDR notation, like <code>192.168.2.0/24</code>) or by their MAC addresses. Note that client recognition by MAC addresses only work for devices at most one networking hop away from your Pi-hole.</p>
</div>
</div>
</div>
<div class="box-footer clearfix">
<button type="button" id="btnAdd" class="btn btn-primary pull-right">Add</button>

View File

@@ -17,25 +17,36 @@ function reload_client_suggestions() {
{ action: "get_unconfigured_clients", token: token },
function (data) {
var sel = $("#select");
var customWasSelected = sel.val() === "custom";
sel.empty();
// In order for the placeholder value to appear, we have to have a blank
// <option> as the first option in our <select> control. This is because
// the browser tries to select the first option by default. If our first
// option were non-empty, the browser would display this instead of the
// placeholder.
sel.append($("<option />"));
// Add data obtained from API
for (var key in data) {
if (!Object.prototype.hasOwnProperty.call(data, key)) {
continue;
}
var text = key;
// Add MAC address
var text = key.toUpperCase();
// Check if this is a valid MAC address (skip mock devices)
if (!utils.validateMAC(text)) {
continue;
}
// Append host name if available
if (data[key].length > 0) {
text += " (" + data[key] + ")";
}
sel.append($("<option />").val(key).text(text));
}
sel.append($("<option />").val("custom").text("Custom, specified below..."));
if (customWasSelected) {
sel.val("custom");
}
},
"json"
);
@@ -57,6 +68,12 @@ $(document).ready(function () {
$("#btnAdd").on("click", addClient);
reload_client_suggestions();
$("select").select2({
tags: true,
placeholder: "Select client...",
allowClear: true
});
utils.bsSelect_defaults();
get_groups();
@@ -64,12 +81,6 @@ $(document).ready(function () {
$("#ip-custom").val("");
$("#ip-custom").prop("disabled", $("#select option:selected").val() !== "custom");
});
// Disable autocorrect in the search box
var input = document.querySelector("input[type=search]");
input.setAttribute("autocomplete", "off");
input.setAttribute("autocorrect", "off");
input.setAttribute("autocapitalize", "off");
input.setAttribute("spellcheck", false);
});
function initTable() {
@@ -231,6 +242,13 @@ function initTable() {
}
});
// Disable autocorrect in the search box
var input = document.querySelector("input[type=search]");
input.setAttribute("autocomplete", "off");
input.setAttribute("autocorrect", "off");
input.setAttribute("autocapitalize", "off");
input.setAttribute("spellcheck", false);
table.on("order.dt", function () {
var order = table.order();
if (order[0][0] !== 0 || order[0][1] !== "asc") {
@@ -248,9 +266,6 @@ function initTable() {
function addClient() {
var ip = $("#select").val();
var comment = $("#new_comment").val();
if (ip === "custom") {
ip = $("#ip-custom").val();
}
utils.disableAll();
utils.showAlert("info", "", "Adding client...", ip);

View File

@@ -208,7 +208,7 @@ if ($_POST['action'] == 'get_groups') {
$QUERYDB = getQueriesDBFilename();
$FTLdb = SQLite3_connect($QUERYDB);
$query = $FTLdb->query('SELECT DISTINCT ip,network.name FROM network_addresses AS name LEFT JOIN network ON network.id = network_id ORDER BY ip ASC;');
$query = $FTLdb->query('SELECT DISTINCT hwaddr,name FROM network;');
if (!$query) {
throw new Exception('Error while querying FTL\'s database: ' . $db->lastErrorMsg());
}
@@ -216,7 +216,7 @@ if ($_POST['action'] == 'get_groups') {
// Loop over results
$ips = array();
while ($res = $query->fetchArray(SQLITE3_ASSOC)) {
$ips[$res['ip']] = $res['name'] !== null ? $res['name'] : '';
$ips[$res['hwaddr']] = $res['name'] !== null ? $res['name'] : '';
}
$FTLdb->close();
@@ -227,8 +227,8 @@ if ($_POST['action'] == 'get_groups') {
// Loop over results, remove already configured clients
while (($res = $query->fetchArray(SQLITE3_ASSOC)) !== false) {
if (isset($ips[$res['ip']])) {
unset($ips[$res['ip']]);
if (isset($ips[$res['hwaddr']])) {
unset($ips[$res['hwaddr']]);
}
}

View File

@@ -209,6 +209,7 @@
<link rel="stylesheet" href="style/vendor/AdminLTE.min.css">
<link rel="stylesheet" href="style/vendor/animate.css">
<link rel="stylesheet" href="style/vendor/select2.min.css">
<noscript><link rel="stylesheet" href="style/vendor/js-warn.css"></noscript>
<script src="scripts/vendor/jquery.min.js"></script>
@@ -216,6 +217,7 @@
<script src="style/vendor/bootstrap/js/bootstrap.min.js"></script>
<script src="scripts/vendor/adminlte.min.js"></script>
<script src="scripts/vendor/bootstrap-notify.min.js"></script>
<script src="scripts/vendor/select2.min.js"></script>
<?php if(in_array($scriptname, array("groups.php", "groups-clients.php", "groups-domains.php", "groups-adlists.php"))){ ?>
<script src="style/vendor/bootstrap/js/bootstrap-select.min.js"></script>

2
scripts/vendor/select2.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
style/vendor/select2.min.css vendored Normal file

File diff suppressed because one or more lines are too long