232 lines
6.8 KiB
JavaScript
232 lines
6.8 KiB
JavaScript
|
$(document).ready(function () {
|
||
|
// Enable share links
|
||
|
$(".share-links").each(function (idx, link) {
|
||
|
link = $(link);
|
||
|
link.attr("data-bs-toggle", "tooltip");
|
||
|
if (!link.attr("data-bs-placement")) link.attr("data-bs-placement", "left");
|
||
|
if (!link.attr("title"))
|
||
|
link.attr("title", _("Copy the share URL of this page."));
|
||
|
$(link).click(function (event) {
|
||
|
event.preventDefault();
|
||
|
copy_to_clipboard($(link).attr("href"));
|
||
|
});
|
||
|
});
|
||
|
|
||
|
// Enable tooltip
|
||
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
||
|
|
||
|
$(".copyable")
|
||
|
.click(function (event) {
|
||
|
copy_to_clipboard($(event.target).html().trim());
|
||
|
})
|
||
|
.css("cursor", "copy");
|
||
|
|
||
|
// Enable 3-states switches
|
||
|
$("input.form-3s-switch").each(function (idx, input) {
|
||
|
input = $(input);
|
||
|
input.click(function (event) {
|
||
|
event.preventDefault();
|
||
|
let value = input.attr("value");
|
||
|
if (value == "1") value = null;
|
||
|
else if (value == "0") value = "1";
|
||
|
else value = "0";
|
||
|
input.val(value);
|
||
|
input.prop("checked", value !== null);
|
||
|
input.trigger("change");
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Copy a value to clipboard
|
||
|
* @param {string} value The value to copy to clipboard
|
||
|
*/
|
||
|
function copy_to_clipboard(value) {
|
||
|
var txt = $("<textarea>");
|
||
|
txt.html(value);
|
||
|
$(document.body).append(txt);
|
||
|
txt.select();
|
||
|
document.execCommand("copy");
|
||
|
txt.remove();
|
||
|
alertify.notify(_("Copied!"), "success", 5);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load and show a form in a modal
|
||
|
* @param {object} opts Options:
|
||
|
* {
|
||
|
* form_url: [URL of the form content],
|
||
|
* title: [modal title],
|
||
|
* validate_url: [The url to send the form data to],
|
||
|
* method: [send method (optional, default: POST)],
|
||
|
* json: [
|
||
|
* if true, send form data as JSON in the body of the request, otherwise,
|
||
|
* send them as x-www-form-urlencoded data
|
||
|
* ],
|
||
|
* loading_message: [loading message (optional)],
|
||
|
* validate_error: [default error to display on form validation error, optional],
|
||
|
* size: [modal size, see BootstrapDialog.SIZE_* (optional)],
|
||
|
* validate_form_method: [method to used to validate & serialize form data (optional)],
|
||
|
* onshown: [a callback to call on modal shown (optional)],
|
||
|
* done: [a callback to call on form submission success (optional)],
|
||
|
* done_url: [The url to redirect the user to after a successful form submission (optional)],
|
||
|
* }
|
||
|
*/
|
||
|
function show_form_modal(opts) {
|
||
|
const loading = alertify.notify(
|
||
|
opts.loading_message || _("Loading form, please wait...", "success")
|
||
|
);
|
||
|
$.get(opts.form_url, null, function (modal_content) {
|
||
|
loading.dismiss();
|
||
|
BootstrapDialog.show({
|
||
|
title: opts.title,
|
||
|
size: opts.size || BootstrapDialog.SIZE_LARGE,
|
||
|
message: $(modal_content),
|
||
|
onshown: opts.onshown,
|
||
|
buttons: [
|
||
|
{
|
||
|
label: _("Validate"),
|
||
|
cssClass: "btn-primary",
|
||
|
action: function (dialog) {
|
||
|
var form = dialog.getModalBody().find("form");
|
||
|
var data = (opts.validate_form_method || validate_form)(form);
|
||
|
if (data == false) return;
|
||
|
if (form.find("input.is-invalid").length != 0) return false;
|
||
|
|
||
|
$.ajax({
|
||
|
url: opts.validate_url,
|
||
|
type: opts.method || "POST",
|
||
|
data: opts.json ? JSON.stringify(data) : data,
|
||
|
contentType: `${
|
||
|
opts.json
|
||
|
? "application/json"
|
||
|
: "application/x-www-form-urlencoded"
|
||
|
}; charset=utf-8`,
|
||
|
dataType: "json",
|
||
|
}).always(function (data) {
|
||
|
if (
|
||
|
handle_ajax_return(
|
||
|
data,
|
||
|
(default_error =
|
||
|
opts.validate_error ||
|
||
|
_(
|
||
|
"An unknown error occurred. If problem persist, please contact support."
|
||
|
))
|
||
|
)
|
||
|
)
|
||
|
if (opts.done_url) window.location = opts.done_url;
|
||
|
if (typeof opts.done == "function") opts.done(data);
|
||
|
});
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Validate and serialize form's data
|
||
|
* @param {jQuery} form The form element to validate and serialize
|
||
|
* @returns object|false The serialized form's data on success or false
|
||
|
*/
|
||
|
function validate_form(form) {
|
||
|
form.find(".is-invalid").removeClass("is-invalid");
|
||
|
if (!form[0].checkValidity()) {
|
||
|
$(form[0].elements).each(function (idx, element) {
|
||
|
if (!element.checkValidity()) $(element).addClass("is-invalid");
|
||
|
});
|
||
|
return false;
|
||
|
}
|
||
|
var data = {};
|
||
|
jQuery.each(form.serializeArray(), function (idx, item) {
|
||
|
item.value = item.value.trim();
|
||
|
if (item.value) data[item.name] = item.value;
|
||
|
});
|
||
|
console.log(data);
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Handle AJAX return to display errors/messages and return true or false in case of success or error
|
||
|
*
|
||
|
* Note: this function is designed to be called from jqXHR.always() by passing its data parameter.
|
||
|
*
|
||
|
* @param {object} data Data as received by jQuery jqXHR.always() method as first parameter
|
||
|
* @param {string|null} default_error Default error message on failure without error message in return
|
||
|
* @param {string|null} success_message Optional message to display on success
|
||
|
* @returns bool
|
||
|
*/
|
||
|
function handle_ajax_return(
|
||
|
data,
|
||
|
default_error = null,
|
||
|
success_message = null
|
||
|
) {
|
||
|
data =
|
||
|
"done" in data && "fail" in data && "always" in data
|
||
|
? data.responseJSON ?? {}
|
||
|
: data;
|
||
|
if (data.errors)
|
||
|
$(data.errors).each(function (idx, error) {
|
||
|
alertify.notify(error, "error");
|
||
|
});
|
||
|
|
||
|
if (data.messages)
|
||
|
$(data.messages).each(function (idx, message) {
|
||
|
alertify.notify(message, "success", 5);
|
||
|
});
|
||
|
|
||
|
if (data && data.success) {
|
||
|
if (success_message) alertify.notify(success_message, "success");
|
||
|
return true;
|
||
|
}
|
||
|
if (!data.errors)
|
||
|
alertify.notify(
|
||
|
default_error ??
|
||
|
_(
|
||
|
"An unknown error occurred. If problem persist, please contact support."
|
||
|
),
|
||
|
"error"
|
||
|
);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// AlertifyJS default settings
|
||
|
alertify.defaults = {
|
||
|
// dialogs defaults
|
||
|
modal: true,
|
||
|
movable: true,
|
||
|
resizable: true,
|
||
|
closable: true,
|
||
|
maximizable: true,
|
||
|
pinnable: true,
|
||
|
pinned: true,
|
||
|
padding: true,
|
||
|
overflow: true,
|
||
|
maintainFocus: true,
|
||
|
transition: "fade",
|
||
|
|
||
|
// notifier defaults
|
||
|
notifier: {
|
||
|
// auto-dismiss wait time (in seconds)
|
||
|
delay: 0,
|
||
|
// default position
|
||
|
position: "top-right",
|
||
|
},
|
||
|
|
||
|
// language resources
|
||
|
glossary: {
|
||
|
// ok button text
|
||
|
ok: _("OK"),
|
||
|
// cancel button text
|
||
|
cancel: _("Cancel"),
|
||
|
},
|
||
|
theme: {
|
||
|
// class name attached to prompt dialog input textbox.
|
||
|
input: "ajs-input form-control",
|
||
|
// class name attached to ok button
|
||
|
ok: "ajs-ok btn btn-primary",
|
||
|
// class name attached to cancel button
|
||
|
cancel: "ajs-cancel btn btn-default",
|
||
|
},
|
||
|
};
|