mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-06 03:45:26 +00:00
256 lines
No EOL
9.5 KiB
JavaScript
256 lines
No EOL
9.5 KiB
JavaScript
(function ($) {
|
|
|
|
class ModalHandler {
|
|
|
|
constructor(element, options) {
|
|
this.element = element;
|
|
this.options = options;
|
|
this.csrf = options.csrf;
|
|
this.observer = new MutationObserver((list) => {
|
|
this.bindFormValidation();
|
|
});
|
|
this.observer.observe(this.element[0], {
|
|
childList: true,
|
|
subtree: true
|
|
});
|
|
|
|
const submitButton = $(this.element).find(`[type='submit']`);
|
|
if (!submitButton) throw new Error("The submit button was not found inside the form!");
|
|
}
|
|
|
|
fillFormModal() {
|
|
return this.options.loadFormData();
|
|
}
|
|
|
|
invokeModalInit() {
|
|
this.options.onModalInit(this.fillFormModal());
|
|
}
|
|
|
|
delegateSubmit() {
|
|
|
|
this.bindFormValidation();
|
|
const self = this;
|
|
this.submitHandler = function(e) {
|
|
e.preventDefault(); e.stopPropagation();
|
|
self.makeRequest();
|
|
};
|
|
$(this.element).on('submit', this.submitHandler);
|
|
}
|
|
|
|
bindFormValidation() {
|
|
$(this.element).find(`input,textarea,select`).each(function(i, input) {
|
|
|
|
const $input = $(this);
|
|
function checkValidation(insertError) {
|
|
|
|
const $parent = $input.parent();
|
|
let $error = $parent.find(`.invalid-feedback`);
|
|
if ($error.length == 0) $error = $(`<span class='invalid-feedback'></span>`);
|
|
|
|
if (!input.validity.valid && input.validationMessage) {
|
|
|
|
$input.removeClass('is-valid').addClass('is-invalid');
|
|
$error.text(input.validationMessage);
|
|
|
|
if (insertError) $parent.append($error);
|
|
}
|
|
else {
|
|
$input.removeClass('is-invalid').addClass('is-valid');
|
|
$error.remove();
|
|
}
|
|
|
|
}
|
|
|
|
$(this).on('input', function(e) { checkValidation(false); });
|
|
|
|
$(this).on('invalid', function(e) {
|
|
e.preventDefault();
|
|
checkValidation(true);
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
cleanForm() {
|
|
/* remove validation fields and tracks */
|
|
$(this.element).find('input,select,textarea').each(function(i, input) {
|
|
$(this).removeClass(`is-valid`).removeClass(`is-invalid`);
|
|
});
|
|
/* reset all the values */
|
|
$(this.element)[0].reset();
|
|
}
|
|
|
|
makeRequest() {
|
|
|
|
const submitButton = $(this.element).find(`[type='submit']`);
|
|
let dataToSend = this.options.beforeSumbit();
|
|
|
|
dataToSend.csrf = this.csrf;
|
|
dataToSend = $.extend(dataToSend, this.options.submitOptions);
|
|
|
|
/* clean previous state and disable button */
|
|
submitButton.attr("disabled", "disabled");
|
|
|
|
const self = this;
|
|
const method = (this.options.method == 'post') ? $.post : $.get;
|
|
|
|
method(this.options.endpoint, dataToSend)
|
|
.done(function (response, textStatus) {
|
|
if (self.options.resetAfterSubmit) self.cleanForm();
|
|
self.options.onSubmitSuccess(response, dataToSend);
|
|
/* unbind the old closure on submit event and bind a new one */
|
|
$(self.element).off('submit', self.submitHandler);
|
|
self.delegateSubmit();
|
|
})
|
|
.fail(function (jqxhr, textStatus, errorThrown) {
|
|
self.options.onSubmitError(dataToSend, textStatus, errorThrown);
|
|
})
|
|
.always(function (d) {
|
|
submitButton.removeAttr("disabled");
|
|
});
|
|
}
|
|
|
|
delegateResetButton() {
|
|
|
|
const resetButton = $form.find(`[type='reset']`);
|
|
if (!resetButton) return;
|
|
resetButton.click(function(event) {
|
|
/* TODO: finisch the reset logic */
|
|
});
|
|
}
|
|
}
|
|
|
|
$.fn.modalHandler = function(args) {
|
|
|
|
if (this.length != 1) throw new Error("Only an element can by initialized!");
|
|
|
|
const options = $.extend({
|
|
csrf: '',
|
|
endpoint: '',
|
|
resetAfterSubmit: true,
|
|
method: 'get',
|
|
/**
|
|
* Fetch data asynchronusly from the server or
|
|
* loads data directly from the current page.
|
|
* The function must returns the fetched data.
|
|
*
|
|
* @returns Returns the fetched data.
|
|
* @example Below there is an example showing
|
|
* how to use the function when fetching data from the server
|
|
* ```
|
|
* loadFormData: async function() {
|
|
* const data = await fetch(`endpoint/to/data`);
|
|
* const user = await data.json();
|
|
* return user;
|
|
* }
|
|
* ```
|
|
*/
|
|
loadFormData: function() {},
|
|
|
|
/**
|
|
* onModalInit() is invoked when the plugin has been initialized.
|
|
* This function is used to load the fetched data from `loadFormData()`
|
|
* inside the form modal inputs.
|
|
*
|
|
* @param {object} loadedData This argument contains the fetched data obtained
|
|
* from `loadFormData()`
|
|
* @example Below there is an example showing how to use
|
|
* the function (we suppose that loadFormData() returns the following
|
|
* object: `loadedUser = {firstname: 'Foo', lastname: 'Bar', id: 1428103}`)
|
|
* ```
|
|
* onModalInit: function(loadedUser) {
|
|
* $(`#userModal form input#firstname`).val(loadedUser.firstname);
|
|
* $(`#userModal form input#lastname`).val(loadedUser.lastname);
|
|
* $(`#userModal form input#id`).val(loadedUser.id);
|
|
* }
|
|
* ```
|
|
*/
|
|
onModalInit: function(loadedData) {},
|
|
|
|
/**
|
|
* The function beforeSubmit() is invoked after the user
|
|
* submit the form. The function must return the data to
|
|
* send to the endpoint. If the chosen method is `post`
|
|
* a csrf will be add to the returned object.
|
|
*
|
|
* @example We show below a simple example how to use the function:
|
|
* ```
|
|
* beforeSubmit: function() {
|
|
* const body = {
|
|
* action: 'edit',
|
|
* JSON: JSON.stringify(serializeArrayForm($(`form`).serializeArray()))
|
|
* };
|
|
* return body;
|
|
* }
|
|
* ```
|
|
*/
|
|
beforeSumbit: function() {},
|
|
|
|
/**
|
|
* This function is invoked when the request to the endpoint
|
|
* terminates successfully (200). Before the call of this function
|
|
* a new csrf retrived from the server will be set for
|
|
* future calls.
|
|
*
|
|
* @param {object} response This object contains the response
|
|
* from the server
|
|
*
|
|
* @example Below there is an example showing a simple user case:
|
|
* ```
|
|
* onSubmitSuccess: function(response) {
|
|
* if (response.success) {
|
|
* console.log(`The user info has been edit with success!`);
|
|
* }
|
|
* }
|
|
* ```
|
|
*/
|
|
onSubmitSuccess: function(response) {},
|
|
|
|
/**
|
|
* This function is invoked when the request to the endpoint
|
|
* terminates with failure (!= 200). Before the call of this function
|
|
* a new csrf retrived from the server will be set for
|
|
* future calls.
|
|
*
|
|
* @param {object} sent This object contains the sent data to the endpoint
|
|
* @param {string} textStatus It contains the error text status obtained
|
|
* @param {object} errorThrown This object contains info about the error
|
|
*
|
|
* @example Below there is an example showing a simple user case:
|
|
* ```
|
|
* onSubmitError: function(sent, textStatus, errorThrown) {
|
|
* if (errorThrown) {
|
|
* console.error(`Ops, something went wrong!`);
|
|
* console.error(errorThrown);
|
|
* }
|
|
* }
|
|
* ```
|
|
*/
|
|
onSubmitError: function(sent, textStatus, errorThrown) {},
|
|
|
|
/**
|
|
* This function is invoked when the user click the reset input
|
|
* inside the form.
|
|
*
|
|
* @param {object} defaultData It contains the fetched data from
|
|
* `loadFormData()`.
|
|
*
|
|
* @example Below there is an example how to use the function:
|
|
* ```
|
|
* onModalReset: function(defaultData) {
|
|
* $(`input#id`).val(defaultData.id);
|
|
* $(`input#name`).val(defaultData.name);
|
|
* $(`input#address`).val(defaultData.address);
|
|
* }
|
|
* ```
|
|
*/
|
|
onModalReset: function(defaultData) {},
|
|
}, args);
|
|
|
|
const mh = new ModalHandler(this, options);
|
|
mh.invokeModalInit();
|
|
mh.delegateSubmit();
|
|
|
|
return mh;
|
|
}
|
|
}(jQuery)); |