improve multiselect

Signed-off-by: Th3M3 <the_me@outlook.de>
This commit is contained in:
Th3M3
2020-03-15 21:43:16 +01:00
parent 0a81dadf2f
commit fd983a2b68
10 changed files with 218 additions and 1841 deletions
+58 -39
View File
@@ -26,6 +26,7 @@ function get_groups() {
$(document).ready(function() {
$("#btnAdd").on("click", addAdlist);
utils.bsSelect_defaults();
get_groups();
});
@@ -47,6 +48,8 @@ function initTable() {
],
drawCallback: function() {
$('button[id^="deleteAdlist_"]').on("click", deleteAdlist);
// Remove visible dropdown to prevent orphaning
$("body > .bootstrap-select.dropdown").remove();
},
rowCallback: function(row, data) {
$(row).attr("data-id", data.id);
@@ -88,61 +91,74 @@ function initTable() {
$("td:eq(3)", row).empty();
$("td:eq(3)", row).append(
'<div id="selectHome_' +
data.id +
'">' +
'<select id="multiselect_' +
data.id +
'" multiple="multiple"></select></div>'
'<select class="selectpicker" id="multiselect_' + data.id + '" multiple></select>'
);
var selectEl = $("#multiselect_" + data.id, row);
// Add all known groups
for (var i = 0; i < groups.length; i++) {
var extra = "";
var data_sub = "";
if (!groups[i].enabled) {
extra = " (disabled)";
data_sub = 'data-subtext="(disabled)"';
}
selectEl.append(
$("<option />")
$("<option " + data_sub + "/>")
.val(groups[i].id)
.text(groups[i].name + extra)
.text(groups[i].name)
);
}
// Select assigned groups
selectEl.val(data.groups);
// Initialize multiselect
selectEl.multiselect({
includeSelectAllOption: true,
buttonContainer: '<div id="container_' + data.id + '" class="btn-group"/>',
maxHeight: 200,
onDropdownShown: function() {
var el = $("#container_" + data.id);
var top = el[0].getBoundingClientRect().top;
var bottom = $(window).height() - top - el.height();
if (bottom < 200) {
el.addClass("dropup");
// Initialize bootstrap-select
selectEl
// fix dropdown if it would stick out right of the viewport
.on("show.bs.select", function() {
var winWidth = $(window).width();
var dropdownEl = $("body > .bootstrap-select.dropdown");
if (dropdownEl.length > 0) {
dropdownEl.removeClass("align-right");
var width = dropdownEl.width();
var left = dropdownEl.offset().left;
if (left + width > winWidth) {
dropdownEl.addClass("align-right");
}
}
if (bottom > 200) {
el.removeClass("dropup");
})
.on("changed.bs.select", function() {
// enable Apply button
if ($(ApplyBtn).prop("disabled")) {
$(ApplyBtn)
.addClass("btn-success")
.prop("disabled", false)
.on("click", function() {
editAdlist.call(selectEl);
});
}
})
.on("hide.bs.select", function() {
// Restore values if drop-down menu is closed without clicking the Apply button
if (!$(ApplyBtn).prop("disabled")) {
$(this)
.val(data.groups)
.selectpicker("refresh");
$(ApplyBtn)
.removeClass("btn-success")
.prop("disabled", true)
.off("click");
}
})
.selectpicker()
.siblings(".dropdown-menu")
.find(".btn-group")
.parent()
.prepend(
'<button type="button" id=btn_apply_' +
data.id +
' class="btn btn-block btn-sm" disabled>Apply</button>'
);
var offset = el.offset();
$("body").append(el);
el.css("position", "absolute");
el.css("top", offset.top + "px");
el.css("left", offset.left + "px");
},
onDropdownHide: function() {
var el = $("#container_" + data.id);
var home = $("#selectHome_" + data.id);
home.append(el);
el.removeAttr("style");
}
});
selectEl.on("change", editAdlist);
var ApplyBtn = "#btn_apply_" + data.id;
var button =
'<button class="btn btn-danger btn-xs" type="button" id="deleteAdlist_' +
@@ -230,6 +246,7 @@ function addAdlist() {
"Successfully added adlist",
address
);
table.ajax.reload(null, false);
$("#new_address").val("");
$("#new_comment").val("");
table.ajax.reload();
@@ -304,6 +321,7 @@ function editAdlist() {
"Successfully " + done + " adlist ",
address
);
table.ajax.reload(null, false);
} else {
utils.showAlert(
"error",
@@ -350,7 +368,8 @@ function deleteAdlist() {
table
.row(tr)
.remove()
.draw(false);
.draw(false)
.ajax.reload(null, false);
} else {
utils.showAlert("error", "", "Error while deleting adlist with ID " + id, response.message);
}
+59 -41
View File
@@ -65,6 +65,7 @@ $(document).ready(function() {
$("#btnAdd").on("click", addClient);
reload_client_suggestions();
utils.bsSelect_defaults();
get_groups();
$("#select").on("change", function() {
@@ -90,6 +91,8 @@ function initTable() {
],
drawCallback: function() {
$('button[id^="deleteClient_"]').on("click", deleteClient);
// Remove visible dropdown to prevent orphaning
$("body > .bootstrap-select.dropdown").remove();
},
rowCallback: function(row, data) {
$(row).attr("data-id", data.id);
@@ -126,61 +129,74 @@ function initTable() {
$("td:eq(2)", row).empty();
$("td:eq(2)", row).append(
'<div id="selectHome_' +
data.id +
'">' +
'<select id="multiselect_' +
data.id +
'" multiple="multiple"></select></div>'
'<select class="selectpicker" id="multiselect_' + data.id + '" multiple></select>'
);
var selectEl = $("#multiselect_" + data.id, row);
// Add all known groups
for (var i = 0; i < groups.length; i++) {
var extra = "";
var data_sub = "";
if (!groups[i].enabled) {
extra = " (disabled)";
data_sub = 'data-subtext="(disabled)"';
}
selectEl.append(
$("<option />")
$("<option " + data_sub + "/>")
.val(groups[i].id)
.text(groups[i].name + extra)
.text(groups[i].name)
);
}
// Select assigned groups
selectEl.val(data.groups);
// Initialize multiselect
selectEl.multiselect({
includeSelectAllOption: true,
buttonContainer: '<div id="container_' + data.id + '" class="btn-group"/>',
maxHeight: 200,
onDropdownShown: function() {
var el = $("#container_" + data.id);
var top = el[0].getBoundingClientRect().top;
var bottom = $(window).height() - top - el.height();
if (bottom < 200) {
el.addClass("dropup");
// Initialize bootstrap-select
selectEl
// fix dropdown if it would stick out right of the viewport
.on("show.bs.select", function() {
var winWidth = $(window).width();
var dropdownEl = $("body > .bootstrap-select.dropdown");
if (dropdownEl.length > 0) {
dropdownEl.removeClass("align-right");
var width = dropdownEl.width();
var left = dropdownEl.offset().left;
if (left + width > winWidth) {
dropdownEl.addClass("align-right");
}
}
if (bottom > 200) {
el.removeClass("dropup");
})
.on("changed.bs.select", function() {
// enable Apply button
if ($(ApplyBtn).prop("disabled")) {
$(ApplyBtn)
.addClass("btn-success")
.prop("disabled", false)
.on("click", function() {
editClient.call(selectEl);
});
}
})
.on("hide.bs.select", function() {
// Restore values if drop-down menu is closed without clicking the Apply button
if (!$(ApplyBtn).prop("disabled")) {
$(this)
.val(data.groups)
.selectpicker("refresh");
$(ApplyBtn)
.removeClass("btn-success")
.prop("disabled", true)
.off("click");
}
})
.selectpicker()
.siblings(".dropdown-menu")
.find(".btn-group")
.parent()
.prepend(
'<button type="button" id=btn_apply_' +
data.id +
' class="btn btn-block btn-sm" disabled>Apply</button>'
);
var offset = el.offset();
$("body").append(el);
el.css("position", "absolute");
el.css("top", offset.top + "px");
el.css("left", offset.left + "px");
},
onDropdownHide: function() {
var el = $("#container" + data.id);
var home = $("#selectHome" + data.id);
home.append(el);
el.removeAttr("style");
}
});
selectEl.on("change", editClient);
var ApplyBtn = "#btn_apply_" + data.id;
var button =
'<button class="btn btn-danger btn-xs" type="button" id="deleteClient_' +
@@ -278,7 +294,7 @@ function addClient() {
if (response.success) {
utils.showAlert("success", "glyphicon glyphicon-plus", "Successfully added client", ip);
reload_client_suggestions();
table.ajax.reload();
table.ajax.reload(null, false);
} else {
utils.showAlert("error", "", "Error while adding new client", response.message);
}
@@ -339,10 +355,11 @@ function editClient() {
if (response.success) {
utils.showAlert(
"success",
"glyphicon glyphicon-plus",
"glyphicon glyphicon-pencil",
"Successfully " + done + " client",
ip_name
);
table.ajax.reload(null, false);
} else {
utils.showAlert(
"error",
@@ -394,7 +411,8 @@ function deleteClient() {
table
.row(tr)
.remove()
.draw(false);
.draw(false)
.ajax.reload(null, false);
reload_client_suggestions();
} else {
utils.showAlert("error", "", "Error while deleting client with ID " + id, response.message);
+20 -1
View File
@@ -129,6 +129,24 @@ function validateIPv6CIDR(ip) {
return ipv6validator.test(ip);
}
function bsSelect_defaults() {
// set bootstrap-select defaults
var pickerDEFAULTS = $.fn.selectpicker.Constructor.DEFAULTS;
pickerDEFAULTS.noneSelectedText = "none selected";
pickerDEFAULTS.selectedTextFormat = "count > 1";
pickerDEFAULTS.actionsBox = true;
pickerDEFAULTS.width = "fit";
pickerDEFAULTS.container = "body";
pickerDEFAULTS.dropdownAlignRight = "auto";
pickerDEFAULTS.countSelectedText = function(num, total) {
if (num === total) {
return "All selected (" + num + ")";
}
return num + " selected";
};
}
window.utils = (function() {
return {
showAlert: showAlert,
@@ -136,6 +154,7 @@ window.utils = (function() {
disableAll: disableAll,
enableAll: enableAll,
validateIPv4CIDR: validateIPv4CIDR,
validateIPv6CIDR: validateIPv6CIDR
validateIPv6CIDR: validateIPv6CIDR,
bsSelect_defaults: bsSelect_defaults
};
})();
+59 -41
View File
@@ -55,6 +55,7 @@ $(document).ready(function() {
$("#add2black, #add2white").on("click", addDomain);
utils.bsSelect_defaults();
get_groups();
});
@@ -77,6 +78,8 @@ function initTable() {
],
drawCallback: function() {
$('button[id^="deleteDomain_"]').on("click", deleteDomain);
// Remove visible dropdown to prevent orphaning
$("body > .bootstrap-select.dropdown").remove();
},
rowCallback: function(row, data) {
$(row).attr("data-id", data.id);
@@ -153,63 +156,76 @@ function initTable() {
if (table.column(5).visible()) {
$("td:eq(4)", row).empty();
$("td:eq(4)", row).append(
'<div id="selectHome_' +
data.id +
'">' +
'<select id="multiselect_' +
data.id +
'" multiple="multiple"></select></div>'
'<select class="selectpicker" id="multiselect_' + data.id + '" multiple></select>'
);
var selectEl = $("#multiselect_" + data.id, row);
// Add all known groups
for (var i = 0; i < groups.length; i++) {
var extra = "";
var data_sub = "";
if (!groups[i].enabled) {
extra = " (disabled)";
data_sub = 'data-subtext="(disabled)"';
}
selectEl.append(
$("<option />")
$("<option " + data_sub + "/>")
.val(groups[i].id)
.text(groups[i].name + extra)
.text(groups[i].name)
);
}
// Select assigned groups
selectEl.val(data.groups);
// Initialize multiselect
selectEl.multiselect({
includeSelectAllOption: true,
buttonContainer: '<div id="container_' + data.id + '" class="btn-group"/>',
maxHeight: 200,
onDropdownShown: function() {
var el = $("#container_" + data.id);
var top = el[0].getBoundingClientRect().top;
var bottom = $(window).height() - top - el.height();
if (bottom < 200) {
el.addClass("dropup");
// Initialize bootstrap-select
selectEl
// fix dropdown if it would stick out right of the viewport
.on("show.bs.select", function() {
var winWidth = $(window).width();
var dropdownEl = $("body > .bootstrap-select.dropdown");
if (dropdownEl.length > 0) {
dropdownEl.removeClass("align-right");
var width = dropdownEl.width();
var left = dropdownEl.offset().left;
if (left + width > winWidth) {
dropdownEl.addClass("align-right");
}
}
if (bottom > 200) {
el.removeClass("dropup");
})
.on("changed.bs.select", function() {
// enable Apply button
if ($(ApplyBtn).prop("disabled")) {
$(ApplyBtn)
.addClass("btn-success")
.prop("disabled", false)
.on("click", function() {
editDomain.call(selectEl);
});
}
var offset = el.offset();
$("body").append(el);
el.css("position", "absolute");
el.css("top", offset.top + "px");
el.css("left", offset.left + "px");
},
onDropdownHide: function() {
var el = $("#container_" + data.id);
var home = $("#selectHome_" + data.id);
home.append(el);
el.removeAttr("style");
}
});
selectEl.on("change", editDomain);
})
.on("hide.bs.select", function() {
// Restore values if drop-down menu is closed without clicking the Apply button
if (!$(ApplyBtn).prop("disabled")) {
$(this)
.val(data.groups)
.selectpicker("refresh");
$(ApplyBtn)
.removeClass("btn-success")
.prop("disabled", true)
.off("click");
}
})
.selectpicker()
.siblings(".dropdown-menu")
.find(".btn-group")
.parent()
.prepend(
'<button type="button" id=btn_apply_' +
data.id +
' class="btn btn-block btn-sm" disabled>Apply</button>'
);
}
var ApplyBtn = "#btn_apply_" + data.id;
// Highlight row (if url parameter "domainid=" is used)
if ("domainid" in GETDict && data.id === parseInt(GETDict.domainid)) {
$(row)
@@ -364,7 +380,7 @@ function addDomain() {
domainEl.val("");
commentEl.val("");
wildcardEl.prop("checked", false);
table.ajax.reload();
table.ajax.reload(null, false);
} else {
utils.showAlert("error", "", "Error while adding new " + domain_regex, response.message);
}
@@ -456,6 +472,7 @@ function editDomain() {
"Successfully " + done + " " + domain_regex,
domain
);
table.ajax.reload(null, false);
} else
utils.showAlert(
"error",
@@ -509,7 +526,8 @@ function deleteDomain() {
table
.row(tr)
.remove()
.draw(false);
.draw(false)
.ajax.reload(null, false);
} else {
utils.showAlert(
"error",
+2 -2
View File
@@ -223,8 +223,8 @@
<script src="scripts/vendor/bootstrap-notify.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-multiselect.js"></script>
<link rel="stylesheet" href="style/vendor/bootstrap/css/bootstrap-multiselect.css">
<script src="style/vendor/bootstrap/js/bootstrap-select.min.js"></script>
<link rel="stylesheet" href="style/vendor/bootstrap/css/bootstrap-select.min.css">
<script src="style/vendor/bootstrap/js/bootstrap-toggle.min.js"></script>
<link rel="stylesheet" href="style/vendor/bootstrap/css/bootstrap-toggle.min.css">
<script src="scripts/vendor/moment.min.js"></script>