Merge pull request #1186 from Th3M3/th3m3/improve_group-select

improve group selection
This commit is contained in:
DL6ER
2020-04-06 16:05:25 +02:00
committed by GitHub
10 changed files with 217 additions and 1841 deletions

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,73 @@ 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(".bs-actionsbox")
.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 +245,7 @@ function addAdlist() {
"Successfully added adlist",
address
);
table.ajax.reload(null, false);
$("#new_address").val("");
$("#new_comment").val("");
table.ajax.reload();
@@ -304,6 +320,7 @@ function editAdlist() {
"Successfully " + done + " adlist ",
address
);
table.ajax.reload(null, false);
} else {
utils.showAlert(
"error",
@@ -350,7 +367,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);
}

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,73 @@ 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(".bs-actionsbox")
.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 +293,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 +354,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 +410,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);

View File

@@ -129,6 +129,26 @@ 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.selectAllText = "All";
pickerDEFAULTS.deselectAllText = "None";
pickerDEFAULTS.countSelectedText = function(num, total) {
if (num === total) {
return "All selected (" + num + ")";
}
return num + " selected";
};
}
window.utils = (function() {
return {
showAlert: showAlert,
@@ -136,6 +156,7 @@ window.utils = (function() {
disableAll: disableAll,
enableAll: enableAll,
validateIPv4CIDR: validateIPv4CIDR,
validateIPv6CIDR: validateIPv6CIDR
validateIPv6CIDR: validateIPv6CIDR,
bsSelect_defaults: bsSelect_defaults
};
})();

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,75 @@ 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(".bs-actionsbox")
.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 +379,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 +471,7 @@ function editDomain() {
"Successfully " + done + " " + domain_regex,
domain
);
table.ajax.reload(null, false);
} else
utils.showAlert(
"error",
@@ -509,7 +525,8 @@ function deleteDomain() {
table
.row(tr)
.remove()
.draw(false);
.draw(false)
.ajax.reload(null, false);
} else {
utils.showAlert(
"error",

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>

View File

@@ -260,4 +260,9 @@ code.breakall
.pointer {
cursor: pointer;
}
.bootstrap-select.bs-container.align-right {
left: unset !important;
right: 10px;
}

View File

@@ -1 +0,0 @@
span.multiselect-native-select{position:relative}span.multiselect-native-select select{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px -1px -1px -3px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;left:50%;top:30px}.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li.multiselect-group label{margin:0;padding:3px 20px 3px 20px;height:100%;font-weight:700}.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.radio,.multiselect-container>li>a>label.checkbox{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container label.checkbox,.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}.form-inline .multiselect-container li a label.checkbox input[type=checkbox],.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;margin-right:0}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long