183 lines
5.3 KiB
JavaScript
183 lines
5.3 KiB
JavaScript
/* ===========================================================
|
|
* ModalDialogForm.js v0.0.1
|
|
* ===========================================================
|
|
* Copyright 2016 Prevu
|
|
* ========================================================== */
|
|
|
|
(function ($) {
|
|
|
|
"use strict";
|
|
/* ModalDialogForm CLASS DEFINITION
|
|
* ====================== */
|
|
|
|
var C_CHANGABLE_CONTROLS_SELECTOR = 'input[type=checkbox],input[type=radio],input[type=text],select,textarea';
|
|
|
|
var ModalDialogForm = function (element, options) {
|
|
this.init(element, options);
|
|
};
|
|
|
|
ModalDialogForm.prototype = {
|
|
constructor: ModalDialogForm,
|
|
init: function (element, options) {
|
|
var plugin = this;
|
|
this.options = options;
|
|
this.$container = $(element);
|
|
this.$data = {
|
|
formDataChanged: false,
|
|
formCloseEventHandler: null
|
|
};
|
|
|
|
this.validateIncomingParams();
|
|
|
|
if (this.options.initCallback && (typeof this.options.initCallback === 'function')) {
|
|
this.options.initCallback(this);
|
|
}
|
|
},
|
|
validateIncomingParams: function () {
|
|
// Add validation of incoming params here, if needed. Throw exception, if something is wrong
|
|
},
|
|
getContainerId: function () {
|
|
if (!this.$container)
|
|
return;
|
|
|
|
return $(this.$container).attr('id');
|
|
},
|
|
attachToFormEvents: function () {
|
|
var plugin = this;
|
|
var containerId = this.getContainerId();
|
|
if (!containerId) {
|
|
throw "Unable to sign to modal form 'on close' event: container has no 'id' attribute";
|
|
}
|
|
|
|
if (!this.$data) {
|
|
this.$data = {};
|
|
}
|
|
|
|
var containerSelector = '#' + containerId;
|
|
this.$data.formCloseEventHandler = function (e) {
|
|
return plugin.onFormClosingQuery(e, plugin);
|
|
}
|
|
|
|
$(document).on('hide.bs.modal', containerSelector, this.$data.formCloseEventHandler);
|
|
},
|
|
detachFromFormEvents: function () {
|
|
if (this.$data && this.$data.formCloseEventHandler && (typeof this.$data.formCloseEventHandler === 'function')) {
|
|
var containerId = this.getContainerId();
|
|
if (!containerId) {
|
|
throw "Unable to unasign from modal form 'on close' event: container has no 'id' attribute";
|
|
}
|
|
|
|
var containerSelector = '#' + containerId;
|
|
$(document).off('hide.bs.modal', containerSelector, this.$data.formCloseEventHandler);
|
|
this.$data.formCloseEventHandler = null;
|
|
}
|
|
},
|
|
startTrackingControlChanges: function () {
|
|
var plugin = this;
|
|
$(this.$container).find(C_CHANGABLE_CONTROLS_SELECTOR).on("change.modalDialogForm", function () {
|
|
plugin.setDataChanged(true);
|
|
});
|
|
},
|
|
finishTrackingControlChanges: function () {
|
|
$(this.$container).find(C_CHANGABLE_CONTROLS_SELECTOR).off("change.modalDialogForm");
|
|
},
|
|
onFormClosingQuery: function (e, plugin) {
|
|
|
|
var containerId = plugin.getContainerId();
|
|
|
|
if ($(e.target).attr('id') != containerId) {
|
|
plugin.$container.focus();
|
|
return true; // close modal form
|
|
}
|
|
|
|
if (plugin.isDataChanged()) {
|
|
bootbox.confirm(plugin.options.confirmMessage, function (result) {
|
|
if (result) {
|
|
plugin.resetDataChanges();
|
|
plugin.detachFromFormEvents();
|
|
plugin.finishTrackingControlChanges();
|
|
plugin.$container.modal('hide');
|
|
}
|
|
});
|
|
|
|
plugin.$container.focus();
|
|
return false; // DO NOT close modal form
|
|
}
|
|
|
|
plugin.$container.focus();
|
|
plugin.detachFromFormEvents();
|
|
plugin.finishTrackingControlChanges();
|
|
return true; // close modal form
|
|
},
|
|
setDataChanged: function (isChanged) {
|
|
if (!this.$data) {
|
|
this.$data = {};
|
|
}
|
|
this.$data.formDataChanged = isChanged;
|
|
},
|
|
resetDataChanges: function () {
|
|
if (!this.$data) {
|
|
this.$data = {};
|
|
}
|
|
this.$data.formDataChanged = false;
|
|
},
|
|
isDataChanged: function () {
|
|
return this.$data ? this.$data.formDataChanged : false;
|
|
},
|
|
show: function () {
|
|
this.startTrackingControlChanges();
|
|
this.attachToFormEvents();
|
|
this.resetDataChanges();
|
|
this.$container.modal('show');
|
|
if (this.options.parseValidators)
|
|
$.validator.unobtrusive.parseDynamicContent(this.$container.find('form'));
|
|
},
|
|
hide: function () {
|
|
this.resetDataChanges();
|
|
this.$container.modal('hide');
|
|
},
|
|
setData: function (data) {
|
|
if (data) {
|
|
this.$data = data;
|
|
}
|
|
else {
|
|
this.$data = null;
|
|
}
|
|
},
|
|
destroy: function () {
|
|
console.log('Modal form destroy');
|
|
var e = $.Event('destroy');
|
|
this.$container.trigger(e);
|
|
|
|
if (e.isDefaultPrevented()) return;
|
|
|
|
this.detachFromFormEvents();
|
|
this.$container.removeData('modalDialogForm');
|
|
}
|
|
};
|
|
/* MODAL DIALOG FORM PLUGIN DEFINITION
|
|
* ======================= */
|
|
|
|
$.fn.modalDialogForm = function (option, args) {
|
|
return this.each(function () {
|
|
var $this = $(this),
|
|
data = $this.data('modalDialogForm'),
|
|
options = $.extend({}, $.fn.modalDialogForm.defaults, $this.data(), typeof option == 'object' && option);
|
|
|
|
if (!data) $this.data('modalDialogForm', (data = new ModalDialogForm(this, options)));
|
|
if (typeof option == 'string')
|
|
data[option].apply(data, [].concat(args));
|
|
});
|
|
};
|
|
|
|
$.fn.modalDialogForm.defaults = {
|
|
confirmMessage: "Form contains data changes, do you really want to close the form?",
|
|
initCallback: null,
|
|
parseValidators: false
|
|
};
|
|
|
|
$.fn.modalDialogForm.Constructor = ModalDialogForm;
|
|
|
|
}(jQuery));
|
|
|