Files
Facilitor/APPL/FAC/fac_edit_widget_page.js
2025-05-14 07:56:00 +00:00

614 lines
21 KiB
JavaScript

/*
$Revision$
$Id$
File: fac_edit_widget_page.js
Description: clientside functions for fac_edit_widget_page.asp
*/
/* Config */
var MAX_COLS_PER_ROW = 6;
var TOTAL_GRID_WIDTH = 12;
var MAX_RAP_HEIGHT = 1500;
/* Are filled onload */
var WIDGET_TITLE_HEIGHT;
var WIDGET_OUTER_X;
var WIDGET_OUTER_Y;
/* Are filled as soon as possible (onload if not hidden) */
var TOOLTIP_Y;
var ADD_ICON_Y;
var dragOptions,
drOptions,
resizeColumnOptions,
resizeRowOptions;
function initOptions()
{
dragOptions = {
addClasses: false,
containment: ".widget-body",
opacity: 0.75,
revert: true,
revertDuration: 0,
stack: ".widget-col-wrapper"
}
drOptions = {
addClasses: false,
tolerance: "pointer"
}
resizeColumnOptions = {
containment: ".widget-body",
create: resizeCreateColumn,
handles: "e",
start: resizeStartColumn
}
resizeRowOptions = {
// containment: ".widget-body",
minHeight: WIDGET_OUTER_Y + WIDGET_TITLE_HEIGHT,
create: resizeCreateRow,
handles: "s",
start: resizeStartRow
}
}
function clean_markers()
{
var $markers = $(".wgt-marker");
$markers.removeClass("wgt-marker");
$markers.not(".widget-col-wrapper").remove();
}
function delete_widget()
{
var $widgets_in_this_row = $(this).siblings(".widget-col-wrapper");
var delete_width = parseInt($(this).attr("data-width"), 10);
destroyEditMode();
var widgets = $widgets_in_this_row.length;
switch (widgets) {
case 0:
$(this).closest(".widget-container").remove(); // Enige widget in deze rij; verwijder hele rij
break;
case 1:
updateColWidth($widgets_in_this_row, TOTAL_GRID_WIDTH);
break;
default: // 2+
// Verwijderde breedte verdelen over de overgebleven widgets
var add_width;
for (var i = 0; i < Math.min(widgets, MAX_COLS_PER_ROW) && delete_width > 0; i++)
{
add_width = Math.ceil(delete_width / (widgets - i));
delete_width -= add_width;
updateColWidth($widgets_in_this_row.eq(i), add_width, true);
}
$(this).closest(".widget-container").addClass("editable");
break;
}
$(this).remove();
startEditMode();
}
function onDrop(e, ui)
{
if (!ui.draggable.length)
return;
var contentCls = ".widget-col, .empty-col";
var $orgWidget = $(contentCls, ui.draggable);
var $newWidget = $(contentCls, e.currentTarget);
var org_key = $orgWidget.closest(".widget-col-wrapper").attr("data-key");
var new_key = $newWidget.closest(".widget-col-wrapper").attr("data-key");
$orgWidget.closest(".widget-col-wrapper").attr("data-key", new_key);
$newWidget.closest(".widget-col-wrapper").attr("data-key", org_key);
$newWidget.replaceWith($orgWidget[0].outerHTML);
$orgWidget.replaceWith($newWidget[0].outerHTML);
$(".widget-col-wrapper").attr("style", ""); // jQuery draggable zet er een z-index op, maar die wil ik niet
}
function resizeColSize($elem, i)
{
var changed = 0;
$elem.removeClass(function (j, cls)
{
var currentClass = cls.match(/item-width-\d{1,2}/)[0];
var currentSize = parseInt($elem.attr("data-width"), 10);
var minSize = 1;
var maxSize = TOTAL_GRID_WIDTH - $elem.nextAll(".widget-col-wrapper").length;
changed = i > 0 ? Math.min(maxSize - currentSize, i) : Math.max(minSize - currentSize, i);
var newSize = currentSize + changed;
if (changed != i)
console.error("zou niet meer voor moeten komen.");
if (changed != 0) {
$elem.addClass("item-width-" + newSize)
.attr("data-width", newSize);
return currentClass; // delete old class
}
})
return Math.abs(changed);
}
function resizeCreateColumn(e, ui)
{
$("> div.ui-resizable-e", e.target).each(function () {
// Create and style resize-icons (East)
$(this).append(I("fa-ellipsis-v fa-lg", { fastyle: "far" }));
});
}
var lastColWidth;
var stepSize;
function resizeStartColumn(e, ui)
{
lastColWidth = ui.originalSize.width;
// Recalc grid to 'snap' to
var $this = $(this);
var $container = $this.closest(".widget-container");
var $nextColumn = $this.nextAll(".widget-col-wrapper:first");
var widgetContainerWidth = $container.width();
stepSize = (widgetContainerWidth - 100) / TOTAL_GRID_WIDTH;
$resizable_cols.resizable("option", "grid", [stepSize]);
/* Zet styling in resize-mode */
$this.add($nextColumn).addClass("resizing-col-wrapper");
// Recalc min & max width
var minWidthInSteps = 1;
var maxWidthInSteps = parseInt($(this).attr("data-width"), 10) // Eigen breedte
+ parseInt($nextColumn.attr("data-width"), 10) // Breedte van volgende wgt
- minWidthInSteps; // Min-breedte van volgende wgt (altijd 1)
var widgetMinWidth = Math.floor(minWidthInSteps * stepSize - 1);
var widgetMaxWidth = Math.ceil(maxWidthInSteps * stepSize + 1);
$(this).resizable("option", "minWidth", widgetMinWidth);
$(this).resizable("option", "maxWidth", widgetMaxWidth);
}
function resizeColumn(e, ui)
{
var storeLastColWidth = 1;
if (parseFloat($(this).css("width")) <= 0)
{
$(this).css("width", lastColWidth);
storeLastColWidth = 0;
}
var $next = $(this).nextAll(".widget-col-wrapper:first");
var widgetContainerWidth = $(e.target).closest(".widget-container").width();
stepSize = (widgetContainerWidth - 100) / TOTAL_GRID_WIDTH;
var moveXcols = Math.round(Math.abs(ui.size.width - lastColWidth) / stepSize);
if (ui.size.width > lastColWidth) // Moved right
{
resizeColSize($next, -moveXcols);
resizeColSize($(this), moveXcols);
}
else if (ui.size.width < lastColWidth) // Moved left
{
resizeColSize($(this), -moveXcols);
resizeColSize($next, moveXcols);
}
if (storeLastColWidth)
lastColWidth = ui.size.width;
}
function resizeStopColumn(e, ui)
{
var $resizedColumns = $(this).nextAll(".resizing-col-wrapper:first").addBack();
/* Resize plattegronden */
$resizedColumns.filter("[data-widget-type='FLR']").each(function () {
var new_x = parseInt(stepSize * $(this).attr("data-width")) - WIDGET_OUTER_X;
var img = $(this).find(".widget-type-flr > img")[0];
resize_flr(img, new_x);
});
/* Zet styling in normal-mode */
$resizedColumns.removeClass("resizing-col-wrapper").attr("style", ""); // jQuery resizable zet er een width op, maar doen wij zelf
/* Reload widget on resize */
var $widget_iframes = $resizedColumns.find(".widget-col iframe");
$widget_iframes.each(function () {
$(this).attr("src", $(this).attr("src"));
});
}
function resizeCreateRow(e, ui)
{
$("> div.ui-resizable-s", e.target).each(function () {
var $fix_h = $('<input type="checkbox" class="fix">');
if ($(this).closest(".widget-container").find(".widget-col-wrapper").filter("[data-height]").length)
$fix_h.prop("checked", true); // Minimaal 1 hoogte gedefinieerd
$(this).append(L("fac_widget_fix_height"))
.append($fix_h)
.append(I("fa-ellipsis-h fa-lg", { fastyle: "far" }));
});
}
function resizeStartRow(e, ui)
{
var hasAnyTitle = $(this).find(".widget-title").length;
var minH = WIDGET_OUTER_Y + (hasAnyTitle ? WIDGET_TITLE_HEIGHT : 0);
$(this).resizable("option", "minHeight", minH);
}
function checkRowClearance(container, rowMaxHeight)
{
var $container = $(container);
if (!$container.hasClass("widget-container")) // indien onload dan is dit de IFRAME of IMG
$container = $container.closest(".widget-container");
/* Set default waardes */
if (!TOOLTIP_Y)
TOOLTIP_Y = parseFloat($container.find(".widget-tooltip:last").height());
if (!ADD_ICON_Y)
ADD_ICON_Y = parseFloat($container.find(".empty-col").css("font-size")) * 4; // * 4 want het plus icoon heeft de fa-4x class
var rowHeight = typeof rowMaxHeight === "undefined" ? 0 : rowMaxHeight;
if (!rowHeight)
$container.find("[class^=widget-type-").each(function () {
if ($(this).hasClass(".widget-type-mk") || $(this).hasClass(".widget-type-mi"))
rowHeight = Math.max(rowHeight, $(this).find("table").height());
else
rowHeight = Math.max(rowHeight, $(this).height());
});
var allWidgetsHaveTitles = $container.find("[class^=widget-type-]:first-child").length == 0;
var titleOffset = allWidgetsHaveTitles ? WIDGET_TITLE_HEIGHT : 0;
rowHeight += titleOffset;
$container.find(".empty-col > i").removeAttr("style");
// Voorkomt de tooltip als deze niet meer past
$container.toggleClass("low-clearance", (TOOLTIP_Y > rowHeight));
if (ADD_ICON_Y > rowHeight) // Als de plus niet meer in het vierkantje past, maken we hem kleiner
$container.find(".empty-col > i").css("font-size", String(rowHeight) + "px");
}
function resizeRow(e, ui)
{
$(e.target).find(".widget-col-wrapper").each(function () {
var thisWidgetHasTitle = $(this).find(".widget-title").length;
var wgt_h = parseInt(ui.size.height - (WIDGET_OUTER_Y + (thisWidgetHasTitle ? WIDGET_TITLE_HEIGHT : 0)), 10);
$(this).find(".widget-size-value").text(wgt_h);
});
resizeRowContents.apply(e.target, [true, false, ui.size.height]);
}
function resizeRowContents(fixed_height, auto, height)
{
fixed_height = fixed_height || false;
var $container = $(this);
var new_h = height || 0;
if (typeof height === "undefined")
$container.find("[class^=widget-type-]").each(function () {
new_h = Math.max(new_h, parseInt($(this).height(), 10));
});
else
new_h = height - WIDGET_OUTER_Y; /* == (afgerond) height incl widget-title */
if (auto) // Alleen bij resizeStop
{
if (fixed_height)
$container.find(".widget-col-wrapper").each(function() { $(this).attr("data-height", new_h); });
else
{
$container.css("height", "auto") // Haal ingestelde hoogte weg
$container.find(".widget-col-wrapper").each(function() { $(this).removeAttr("data-height"); });
}
}
$container.find("[class^=widget-type-]").each(function () {
var $widget = $(this);
var new_height = height ? new_h - ($widget.prev(".widget-title").length ? WIDGET_TITLE_HEIGHT : 0) : new_h;
switch ($(this).closest(".widget-col-wrapper").attr("data-widget-type"))
{
case "FAC": // Facilitor URL
case "FAQ": // Kennisbank
case "NWS": // Nieuwspagina
case "RAP": // Rapportage
// iFrame
$widget.find("iframe").css("max-height", (fixed_height ? new_height : ""));
var win = $widget.find("iframe")[0].contentWindow;
if (win.FcltMgr)
win.FcltMgr.resized();
if (auto && !fixed_height && $container.height() > MAX_RAP_HEIGHT) // Anders wordt die (default) wel heel erg groot bij het uitvinken
{
$widget.find("iframe").css("max-height", "100vh");
if (win.FcltMgr)
win.FcltMgr.resized();
}
break;
case "RAW": // HTML code
if (fixed_height)
$widget.find("iframe").css("max-height", new_height);
else
resize_raw($(this).find("iframe")[0]);
break;
case "URL": // Externe URL
/* Geen access, dan mag je hem zelf mooi zetten. Dynamisch hier dus niet mogelijk */
$widget.find("iframe")[0].height = (fixed_height ? new_height : ""); // Default 150px dus
break;
case "IMG": // Plaatje
$widget.find("img").css("max-height", (fixed_height ? new_height : ""));
break;
case "FLR": // Plattegrond
if (auto)
{
var img = $widget.find("img")[0];
resize_flr(img, null, fixed_height ? new_height : -1);
$(this).closest(".widget-col-wrapper").nextAll(".ui-resizable-s").find(".fix").prop("checked", true);
}
break;
case "MK": // Menukop
case "MI": // Menuitem
if (fixed_height)
$widget.css("max-height", new_height);
else
{
var actual_h = resize_menu($widget);
$widget.css("max-height", actual_h);
}
$widget.find("img").css("max-height", (fixed_height ? new_height : ""));
break;
default:
console.error("Unknown widget-type (" + $(this).closest(".widget-col-wrapper").attr("data-widget-type") + ")");
break;
}
checkRowClearance($container, new_h);
})
}
function resize_menu(some_wrapping_div)
{
return $(some_wrapping_div).find(".widget-type-mk > table, .widget-type-mi > table").height();
}
function resizeStopRow(e, ui)
{
$(e.target).find(".fix").prop("checked", true);
resizeRowContents.apply($(e.target), [true, true, ui.size.height]);
}
function updateColWidth($col_wrapper, new_width, relative)
{
var old_width = parseInt($col_wrapper.attr("data-width"));
if (relative)
new_width += old_width;
var sizeChanged = relative || new_width != old_width;
$col_wrapper.removeClass(function (i, cls) { return cls.match(/item-width-\d{1,2}/) })
.addClass("item-width-" + new_width)
.attr("data-width", new_width);
if (sizeChanged)
{ /* Reload widget on resize */
var $widget_iframe = $col_wrapper.find("iframe");
$widget_iframe.attr("src", $widget_iframe.attr("src"));
}
}
function upsert_widget_onpage_callback(params)
{
if (params.delete) // Verwijderen
{
delete_widget.apply($(".wgt-marker"));
clean_markers();
return;
}
else if (!params.key) // Annuleren
{
clean_markers();
return;
}
// else Aanpassen
// Voor synchroniciteit in een eigen interne functie;
function do_upsert_widget_onpage($container, $widget)
{
var $marker = $container.find(".wgt-marker");
if ($marker.hasClass("widget-col-wrapper")) // Edit van bestaande widget
{
var width = $marker.attr("data-width");
// Gebruik dan de width die de bestaande widget op de pagina heeft
updateColWidth($widget, width);
$marker.replaceWith($widget);
}
else // Invoegen van nieuwe widget
{
$marker.replaceWith($widget);
checkRowClearance($container);
if ($container.children(".widget-col-wrapper").length >= MAX_COLS_PER_ROW)
$container.removeClass("editable");
// resize cols met de nieuwe erbij
var cols = $container.children(".widget-col-wrapper").length;
var totalWidth = TOTAL_GRID_WIDTH;
$container.children(".widget-col-wrapper").each(function ()
{
newWidth = Math.round(totalWidth / cols);
updateColWidth($(this), newWidth);
cols--;
totalWidth -= newWidth;
});
}
startEditMode();
}
$.get("./fac_widget.asp?mode=edit&wgt_key=" + params.key, function (data)
{
if (!data)
return;
destroyEditMode();
var $wgt_wrapper = $(".wgt-marker").closest(".widget-container");
if ($wgt_wrapper.find(".big-tooltip").length) // Nieuwe rij
{
clean_markers();
var $new_row = $("<div class=\"widget-container editable\"></div>");
$.get("./fac_widget.asp?mode=edit&wgt_key=-1", function (new_row_cols) { // -1 voor de vulling van een lege rij
$new_row.append(new_row_cols);
$wgt_wrapper.before($new_row);
do_upsert_widget_onpage($new_row, $(data));
});
}
else // Bestaande rij
do_upsert_widget_onpage($wgt_wrapper, $(data));
});
}
var $resizable_cols = $();
var $resizable_rows = $();
var $draggables = $();
var $droppables = $();
function startEditMode()
{
function init_resizable_cols() {
$resizable_cols = $();
$(".widget-container").each(function() {
$resizable_cols = $resizable_cols.add($(this).children(".widget-col-wrapper").not(":last"));
});
$resizable_cols.resizable(resizeColumnOptions);
$resizable_cols.on("resize", resizeColumn)
.on("resizestop", resizeStopColumn);
}
function init_resizable_rows() {
$resizable_rows = $(".widget-container").not(":last");
$resizable_rows.resizable(resizeRowOptions);
$resizable_rows.on("resize", resizeRow)
.on("resizestop", resizeStopRow);
$(".fix").on("change", function() {
resizeRowContents.apply($(this).closest(".widget-container")[0], [$(this).prop("checked"), !$(this).prop("checked")]);
});
}
function init_draggables() {
$draggables = $(".widget-col-wrapper").not(".widget-new-wrapper");
$draggables.draggable(dragOptions);
}
function init_droppables() {
$droppables = $(".widget-col-wrapper").not(".widget-new-wrapper");
$droppables.droppable(drOptions)
$droppables.on("drop", onDrop);
}
$(".edit-widget").on("click", function() {
clean_markers();
$(this).closest(".widget-col-wrapper").addClass("wgt-marker");
var wgt_key = parseInt($(this).closest(".widget-col-wrapper").attr("data-key"), 10);
FcltMgr.openModalDetail("../mgt/fac_widget_onpage.asp?mode=edit&id=" + wgt_key, L("fac_widget"), { callback: upsert_widget_onpage_callback });
});
$(".delete-widget").on("click", function() {
FcltMgr.confirm(L("fac_widget_del_txt"), delete_widget.bind($(this).closest(".widget-col-wrapper")));
});
$(".empty-col-wrapper").on("click", function() {
clean_markers();
$(this).prev(".filler-col-wrapper").before("<div class='wgt-marker'></div>");
FcltMgr.openModalDetail("../mgt/fac_widget_onpage.asp?mode=edit&id=-1", L("fac_widget"), { callback: upsert_widget_onpage_callback });
});
init_resizable_cols();
init_resizable_rows();
init_draggables();
init_droppables();
}
function destroyEditMode()
{
$(".widget-icon").off();
$(".empty-col-wrapper").off();
$resizable_cols.resizable("destroy");
$resizable_cols.off();
$resizable_cols = $();
$(".fix").off();
$resizable_rows.resizable("destroy");
$resizable_rows.off();
$resizable_rows = $();
$draggables.draggable("destroy");
$draggables = $();
$droppables.droppable("destroy")
$droppables.off();
$droppables = $();
}
$(function ()
{
function _pixelTotal(computedStyle, cssProperties) {
var result = 0;
for (x in cssProperties)
result += parseFloat(computedStyle[cssProperties[x]]);
return result
}
var $dummyWrapper = $("<div>", { "class": "widget-col-wrapper item-width-1" });
var $dummy = $("<div>", { "class": "widget-col" }).appendTo($dummyWrapper);
var $dummyTitle = $("<div>", { "class": "widget-title" }).appendTo($dummy);
$("<div>", { "class": "widget-type-fac" }).appendTo($dummy);
$dummyWrapper[0].style.cssText = "position: absolute; left: -9999px; top: -9999px";
$(".widget-container:last").append($dummyWrapper);
var dummyStyle = window.getComputedStyle($dummy[0]);
var titleStyle = window.getComputedStyle($dummyTitle[0]);
WIDGET_TITLE_HEIGHT = _pixelTotal(titleStyle, ["height"]);
WIDGET_OUTER_X = _pixelTotal(dummyStyle, ["marginLeft", "marginRight", "borderLeftWidth", "borderRightWidth"]);
WIDGET_OUTER_Y = _pixelTotal(dummyStyle, ["marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"]);
$dummyWrapper.remove();
$dummyTitle = null;
$dummy = null;
$dummyWrapper = null;
// Deze hoeft maar 1x
$(".widget-new-wrapper").on("click", function () {
$(this).siblings(".empty-col-wrapper").eq(0).trigger("click");
});
$(".widget-container").each(function()
{
if ($(this).children(".widget-col-wrapper").length < MAX_COLS_PER_ROW)
{
$(this).addClass("editable");
}
});
initOptions();
startEditMode();
$(".widget-type-mk, .widget-type-mi").each(function () {
checkRowClearance(this);
});
})