modals now use iframe. bugfixes.

pull/232/head
Nils Kenneweg 11 years ago
parent 9279b55ebd
commit a76caf0b55
  1. 230
      app/assets/javascripts/modal.js
  2. 22
      app/assets/javascripts/timelines.js
  3. 2
      app/assets/javascripts/timelines_modal.js

@ -13,24 +13,7 @@ var ModalHelper = (function() {
var ModalHelper = function() {
var modalHelper = this;
var modalDiv;
function formReplacer(form) {
var submitting = false;
console.log(pform);
form = jQuery(form);
form.submit(function (e) {
console.log("Form submit!");
if (!submitting) {
submitting = true;
modalHelper.showLoadingModal();
modalHelper.submitBackground(form, {autoReplace: true});
}
return false;
});
}
var modalDiv, modalIframe;
function modalFunction(e) {
if (!event.ctrlKey && !event.metaKey) {
@ -41,11 +24,7 @@ var ModalHelper = (function() {
if (url) {
e.preventDefault();
modalHelper.createModal(modalHelper.setLayoutParameter(url), function (modalDiv) {
modalDiv.find("form").each(function () {
formReplacer(this);
});
});
modalHelper.createModal(url, function (modalDiv) {});
}
}
}
@ -57,6 +36,8 @@ var ModalHelper = (function() {
if (ModalHelper.prototype.done !== true) {
// one time initialization
modalDiv = jQuery('<div/>').css('hidden', true).attr('id', 'modalDiv');
modalIframe = jQuery('<iframe/>').attr('id', 'modalIframe').attr('width', '100%').attr('height', '100%');
modalDiv.append(modalIframe);
body.append(modalDiv);
/** replace all data-modal links and all inside modal links */
@ -64,36 +45,73 @@ var ModalHelper = (function() {
modalDiv.on("click", "a", modalFunction);
// close when body is clicked
body.click(function(e) {
if (modalDiv.data('changed') !== undefined && (modalDiv.data('changed') !== true || confirm(I18n.t('js.timelines.really_close_dialog')))) {
modalDiv.data('changed', false);
modalDiv.dialog('close');
} else {
e.stopPropagation();
}
});
body.on("click", ".ui-widget-overlay", jQuery.proxy(modalHelper.close, modalHelper));
// do not close when element is clicked
modalDiv.click(function(e) {
jQuery(e.target).trigger('click.rails');
modalIframe.bind("load", jQuery.proxy(modalHelper.iframeLoadHandler, modalHelper));
if (e.target.className.indexOf("watcher_link") > -1) {
e.preventDefault();
}
e.stopPropagation();
});
ModalHelper.prototype.done = true;
} else {
modalDiv = jQuery('#modalDiv');
modalIframe = jQuery('#modalIframe');
}
modalHelper.modalIframe = modalIframe;
modalHelper.modalDiv = modalDiv;
});
this.loadingModal = false;
};
ModalHelper.prototype.iframeLoadHandler = function () {
try {
var modalDiv = this.modalDiv, modalIframe = this.modalIframe, modalHelper = this;
var content = modalIframe.contents();
var body = content.find("body");
if (body.html() !== "") {
this.hideLoadingModal();
this.loadingModal = false;
//add closer
modalDiv.parent().prepend('<div id="ui-dialog-closer" />').click(jQuery.proxy(this.close, this));
jQuery('.ui-dialog-titlebar').hide();
modalDiv.data('changed', false);
//tweak body.
body.find("#top-menu").hide();
body.find("#main-menu").hide();
body.find("#footnotes_debug").hide();
body.find("#footer").hide();
body.find("#content").css("margin", "0px").css("padding", "0px");
body.find("#main").css("padding-bottom", "0px");
body.css("min-width", "0px");
body.find(":input").change(function () {
modalDiv.data('changed', true);
});
jQuery(this).trigger("loaded");
modalDiv.parent().show();
/*modalIframe.attr("height", "0px");
//tweak height
var height = Math.max(content.height() + 20, modalDiv.height());
modalDiv.attr("height", height);
modalIframe.attr("height", height);*/
modalIframe.attr("height", modalDiv.height());
} else {
this.showLoadingModal();
}
} catch (e) {
this.loadingModal = false;
this.hideLoadingModal();
this.close();
}
};
/** display the loading modal (spinner in a box)
* also fix z-index so it is always on top.
*/
@ -106,128 +124,56 @@ var ModalHelper = (function() {
jQuery('#ajax-indicator').hide();
};
ModalHelper.prototype.setLayoutParameter = function (url) {
if (url) {
return url + (url.indexOf('?') != -1 ? "&layout=false" : "?layout=false");
}
};
/** submit a form in the background.
* @param form: form element
* @param url: url to submit to. can be undefined if so, url is taken from form.
* @param callback: called with results
*/
ModalHelper.prototype.submitBackground = function(form, options, callback) {
var modalHelper = this;
var data = form.serialize(), url;
ModalHelper.prototype.close = function(e) {
var modalDiv = this.modalDiv;
if (!this.loadingModal) {
if (modalDiv.data('changed') !== true || confirm(I18n.t('js.timelines.really_close_dialog'))) {
modalDiv.data('changed', false);
modalDiv.dialog('close');
if (options.url) {
url = options.url;
}
if (typeof url === 'undefined') {
url = modalHelper.setLayoutParameter(form.attr('action'));
jQuery(this).trigger("closed");
}
}
};
jQuery.ajax({
type: 'POST',
url: url,
data: data,
error: function(obj, error) {
if (typeof callback === "function") {
callback(obj.status, obj.responseText);
}
},
success: function(response) {
if (typeof callback === "function") {
callback(null, response);
}
ModalHelper.prototype.loading = function() {
this.modalDiv.parent().hide();
if (options.autoReplace === true) {
modalHelper.setModalHTML(response);
}
}
});
this.loadingModal = true;
this.showLoadingModal();
};
ModalHelper.prototype.setModalHTML = function(data) {
var modalHelper = this;
var ta = modalHelper.modalDiv, fields;
/** create a modal dialog from url html data
* @param url url to load html from.
* @param callback called when done. called with modal div.
*/
ModalHelper.prototype.createModal = function(url, callback) {
var modalHelper = this, modalIframe = this.modalIframe, modalDiv = this.modalDiv, counter = 0;
if (modalHelper.loadingModal) {
return;
}
ta.data('changed', false);
var calculatedHeight = jQuery(window).height() * 0.8;
// write html to div
ta.html(data);
modalDiv.attr("height", calculatedHeight);
modalIframe.attr("height", calculatedHeight);
// show dialog.
ta.dialog({
modalDiv.dialog({
modal: true,
resizable: false,
draggable: false,
width: '900px',
height: jQuery(window).height() * 0.8,
height: calculatedHeight,
position: {
my: 'center',
at: 'center'
}
});
// hide dialog header
//TODO: we need a default close button somewhere
ta.parent().prepend('<div id="ui-dialog-closer" />');
jQuery('.ui-dialog-titlebar').hide();
fields = ta.find(":input");
fields.change(function(e) {
ta.data('changed', true);
});
};
this.loading();
/** create a modal dialog from url html data
* @param url url to load html from.
* @param callback called when done. called with modal div.
*/
ModalHelper.prototype.createModal = function(url, callback) {
var modalHelper = this;
if (modalHelper.loadingModal) {
return;
}
modalHelper.loadingModal = true;
try {
modalHelper.showLoadingModal();
// get html for url.
jQuery.ajax({
type: 'GET',
url: url,
dataType: 'html',
error: function(obj, error) {
modalHelper.hideLoadingModal();
modalHelper.loadingModal = false;
},
success: function(data) {
try {
modalHelper.setModalHTML(data);
modalHelper.hideLoadingModal();
if (typeof callback === 'function') {
callback(modalHelper.modalDiv);
}
} catch (e) {
console.log(e);
} finally {
modalHelper.loadingModal = false;
}
}
});
} catch (e) {
console.log(e);
modalHelper.loadingModal = false;
}
modalIframe.attr("src", url);
};
return ModalHelper;

@ -284,6 +284,10 @@ Timeline = {
}
);
jQuery(this.modalHelper).on("closed", function () {
timeline.reload();
});
timelineLoader = new Timeline.TimelineLoader(
this,
{
@ -1036,13 +1040,13 @@ Timeline = {
TimelineLoader.prototype.registerPlanningElementsByID = function (ids) {
this.inChunks(ids, function (planningElementIdsOfPacket, i) {
var planningElementPrefix = this.options.url_prefix +
this.options.planning_element_prefix;
var projectPrefix = this.options.url_prefix +
this.options.api_prefix;
// load current planning elements.
this.loader.register(
Timeline.PlanningElement.identifier + '_IDS_' + i,
{ url : planningElementPrefix +
{ url : projectPrefix +
'/planning_elements.json?ids=' +
planningElementIdsOfPacket.join(',')},
{ storeIn: Timeline.PlanningElement.identifier }
@ -4176,16 +4180,6 @@ Timeline = {
text = timeline.escape(data.name);
if (data.getUrl instanceof Function) {
text = jQuery('<a href="' + data.getUrl() + '" class="tl-discreet-link" target="_blank" data-modal/>').append(text).attr("title", text);
text.click(function(event) {
if (Timeline.USE_MODALS && !event.ctrlKey && !event.metaKey && data.is(Timeline.PlanningElement)) {
timeline.modalHelper.createPlanningModal(
'show',
data.project.identifier,
data.id
);
event.preventDefault();
}
});
}
if (data.is(Timeline.Project)) {
@ -4868,7 +4862,7 @@ Timeline = {
e.click(function(e) {
if (Timeline.USE_MODALS) {
var payload = node.getData();
timeline.modalHelper.createModal(timeline.modalHelper.setLayoutParameter(payload.getUrl()));
timeline.modalHelper.createModal(payload.getUrl());
e.stopPropagation();
}
});

@ -26,7 +26,7 @@ ModalHelper.prototype.createPlanningModal = function(type, projectId, elementId,
// also we create the url we submit the data to for the edit action.
//TODO: escape projectId and elementId.
if (type === 'new') {
non_api_url += 'new.js';
non_api_url += 'new';
} else {
throw new Error('invalid action. allowed: new, show, edit');
}

Loading…
Cancel
Save