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 = function() {
var modalHelper = this; var modalHelper = this;
var modalDiv; var modalDiv, modalIframe;
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;
});
}
function modalFunction(e) { function modalFunction(e) {
if (!event.ctrlKey && !event.metaKey) { if (!event.ctrlKey && !event.metaKey) {
@ -41,11 +24,7 @@ var ModalHelper = (function() {
if (url) { if (url) {
e.preventDefault(); e.preventDefault();
modalHelper.createModal(modalHelper.setLayoutParameter(url), function (modalDiv) { modalHelper.createModal(url, function (modalDiv) {});
modalDiv.find("form").each(function () {
formReplacer(this);
});
});
} }
} }
} }
@ -57,6 +36,8 @@ var ModalHelper = (function() {
if (ModalHelper.prototype.done !== true) { if (ModalHelper.prototype.done !== true) {
// one time initialization // one time initialization
modalDiv = jQuery('<div/>').css('hidden', true).attr('id', 'modalDiv'); 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); body.append(modalDiv);
/** replace all data-modal links and all inside modal links */ /** replace all data-modal links and all inside modal links */
@ -64,36 +45,73 @@ var ModalHelper = (function() {
modalDiv.on("click", "a", modalFunction); modalDiv.on("click", "a", modalFunction);
// close when body is clicked // close when body is clicked
body.click(function(e) { body.on("click", ".ui-widget-overlay", jQuery.proxy(modalHelper.close, modalHelper));
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();
}
});
// do not close when element is clicked modalIframe.bind("load", jQuery.proxy(modalHelper.iframeLoadHandler, modalHelper));
modalDiv.click(function(e) {
jQuery(e.target).trigger('click.rails');
if (e.target.className.indexOf("watcher_link") > -1) {
e.preventDefault();
}
e.stopPropagation();
});
ModalHelper.prototype.done = true; ModalHelper.prototype.done = true;
} else { } else {
modalDiv = jQuery('#modalDiv'); modalDiv = jQuery('#modalDiv');
modalIframe = jQuery('#modalIframe');
} }
modalHelper.modalIframe = modalIframe;
modalHelper.modalDiv = modalDiv; modalHelper.modalDiv = modalDiv;
}); });
this.loadingModal = false; 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) /** display the loading modal (spinner in a box)
* also fix z-index so it is always on top. * also fix z-index so it is always on top.
*/ */
@ -106,128 +124,56 @@ var ModalHelper = (function() {
jQuery('#ajax-indicator').hide(); jQuery('#ajax-indicator').hide();
}; };
ModalHelper.prototype.setLayoutParameter = function (url) { ModalHelper.prototype.close = function(e) {
if (url) { var modalDiv = this.modalDiv;
return url + (url.indexOf('?') != -1 ? "&layout=false" : "?layout=false"); if (!this.loadingModal) {
} if (modalDiv.data('changed') !== true || confirm(I18n.t('js.timelines.really_close_dialog'))) {
}; modalDiv.data('changed', false);
modalDiv.dialog('close');
/** 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;
if (options.url) { jQuery(this).trigger("closed");
url = options.url; }
}
if (typeof url === 'undefined') {
url = modalHelper.setLayoutParameter(form.attr('action'));
} }
};
jQuery.ajax({ ModalHelper.prototype.loading = function() {
type: 'POST', this.modalDiv.parent().hide();
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);
}
if (options.autoReplace === true) { this.loadingModal = true;
modalHelper.setModalHTML(response); this.showLoadingModal();
}
}
});
}; };
ModalHelper.prototype.setModalHTML = function(data) { /** create a modal dialog from url html data
var modalHelper = this; * @param url url to load html from.
var ta = modalHelper.modalDiv, fields; * @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 modalDiv.attr("height", calculatedHeight);
ta.html(data); modalIframe.attr("height", calculatedHeight);
// show dialog. modalDiv.dialog({
ta.dialog({
modal: true, modal: true,
resizable: false, resizable: false,
draggable: false, draggable: false,
width: '900px', width: '900px',
height: jQuery(window).height() * 0.8, height: calculatedHeight,
position: { position: {
my: 'center', my: 'center',
at: 'center' at: 'center'
} }
}); });
// hide dialog header this.loading();
//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);
});
};
/** create a modal dialog from url html data modalIframe.attr("src", url);
* @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;
}
}; };
return ModalHelper; return ModalHelper;

@ -284,6 +284,10 @@ Timeline = {
} }
); );
jQuery(this.modalHelper).on("closed", function () {
timeline.reload();
});
timelineLoader = new Timeline.TimelineLoader( timelineLoader = new Timeline.TimelineLoader(
this, this,
{ {
@ -1036,13 +1040,13 @@ Timeline = {
TimelineLoader.prototype.registerPlanningElementsByID = function (ids) { TimelineLoader.prototype.registerPlanningElementsByID = function (ids) {
this.inChunks(ids, function (planningElementIdsOfPacket, i) { this.inChunks(ids, function (planningElementIdsOfPacket, i) {
var planningElementPrefix = this.options.url_prefix + var projectPrefix = this.options.url_prefix +
this.options.planning_element_prefix; this.options.api_prefix;
// load current planning elements. // load current planning elements.
this.loader.register( this.loader.register(
Timeline.PlanningElement.identifier + '_IDS_' + i, Timeline.PlanningElement.identifier + '_IDS_' + i,
{ url : planningElementPrefix + { url : projectPrefix +
'/planning_elements.json?ids=' + '/planning_elements.json?ids=' +
planningElementIdsOfPacket.join(',')}, planningElementIdsOfPacket.join(',')},
{ storeIn: Timeline.PlanningElement.identifier } { storeIn: Timeline.PlanningElement.identifier }
@ -4176,16 +4180,6 @@ Timeline = {
text = timeline.escape(data.name); text = timeline.escape(data.name);
if (data.getUrl instanceof Function) { 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 = 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)) { if (data.is(Timeline.Project)) {
@ -4868,7 +4862,7 @@ Timeline = {
e.click(function(e) { e.click(function(e) {
if (Timeline.USE_MODALS) { if (Timeline.USE_MODALS) {
var payload = node.getData(); var payload = node.getData();
timeline.modalHelper.createModal(timeline.modalHelper.setLayoutParameter(payload.getUrl())); timeline.modalHelper.createModal(payload.getUrl());
e.stopPropagation(); 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. // also we create the url we submit the data to for the edit action.
//TODO: escape projectId and elementId. //TODO: escape projectId and elementId.
if (type === 'new') { if (type === 'new') {
non_api_url += 'new.js'; non_api_url += 'new';
} else { } else {
throw new Error('invalid action. allowed: new, show, edit'); throw new Error('invalid action. allowed: new, show, edit');
} }

Loading…
Cancel
Save