EnVisageOnline/Main/Source/EnVisage/Scripts/Plugins/ModalDialogForm.js

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));