gridstack-8.x-2.5/js/admin/gridstack.admin.ui.js
js/admin/gridstack.admin.ui.js
/**
* @file
* Provides GridStack admin utilities.
*/
(function ($, Drupal, _, GridStack, _db, window) {
'use strict';
Drupal.gridstack = Drupal.gridstack || {};
_.each(['base', 'models', 'collections', 'views'], function (key) {
Drupal.gridstack[key] = Drupal.gridstack[key] || {};
});
/**
* GridStack UI public methods.
*
* @namespace
*/
Drupal.gridstack.ui = {
nodesData: [],
nestedData: [],
domData: [],
loadCollection: function (el, oldData, isNested) {
oldData = oldData === 'undefined' ? false : oldData;
var $el = $(el);
var data = Drupal.gridstack.base[oldData ? 'oldData' : 'newData']($el, isNested);
var nodes = GridStack.Utils.sort(data);
var gridStack = Drupal.gridstack.collections.Boxes.extend({
model: Drupal.gridstack.models.Box
});
var collections = _.map(nodes, function (node, i) {
node.index = (i + 1);
return new Drupal.gridstack.models.Box(node);
}, this);
return new gridStack(collections);
},
loadGridStack: function (o) {
var me = this;
o = o || {};
o.saveCallback = o.saveCallback || {
callback: me.save.bind(me)
};
return new Drupal.gridstack.views.GridStack(o);
},
save: function (collection, options) {
var me = this;
var breakpoint = options.breakpoint || null;
var icon = options.icon || null;
var mergedData = [];
var nodesData = [];
var nestedData = [];
var updateIcon = options.updateIcon || false;
collection.each(function (box, i) {
if (box instanceof Drupal.gridstack.models.Box) {
var nodes = box.getDataToSave();
var nested = box.get('nested') || [];
var nestedNodes = box.getDataNestedToSave();
nodesData.push(nodes);
nestedData[i] = nested.length ? nestedNodes : [];
// Flatten main and nested boxes with complete data for icon.
if (updateIcon) {
var boxAttributes = box.attributes;
mergedData.push(_.omit(boxAttributes, 'nested'));
if (nested.length) {
_.omit(nested, 'nested');
mergedData = mergedData.concat(nested);
}
}
}
});
me.nodesData = nodesData;
me.nestedData = nestedData;
// Ensures empty value is respected to add and remove existing grids.
var storedValue = me.nodesData.length ? JSON.stringify(me.nodesData) : '';
$('[data-drupal-selector="' + options.storage + '"]').val(storedValue);
var nestedValue = me.nestedData.length ? JSON.stringify(me.nestedData) : '';
$('[data-drupal-selector="' + options.nestedStorage + '"]').val(nestedValue);
// Collect data needed to generate icon.
if (updateIcon && icon && icon === breakpoint) {
me.domData = Drupal.gridstack.icon.save(options, mergedData);
}
}
};
/**
* GridStack icon public methods.
*
* @namespace
*/
Drupal.gridstack.icon = {
build: function (form, rebuild) {
var me = this;
var $form = $(form);
var iconBreakpoint = $form.data('icon') || 'lg';
var $main = $('#gridstack-' + iconBreakpoint, form);
if (!$main.length) {
return;
}
// Sets canvas dimensions.
var canvas = $('#gridstack-canvas', form)[0];
var cw = parseInt($main.css('width'));
var ch = parseInt($main.css('height'));
var url = '';
canvas.width = cw;
canvas.height = ch;
canvas.style.width = cw + 'px';
canvas.style.height = ch + 'px';
// Rebuild icon if required.
if (rebuild) {
url = me.draw(canvas);
}
return url;
},
draw: function (canvas) {
var me = this;
var url;
var data = Drupal.gridstack.ui.domData || [];
if (!data.length) {
return;
}
_.each(data, function (node) {
var ctx = canvas.getContext('2d');
var x = node.left;
var y = node.top;
var id = node.title;
ctx.beginPath();
ctx.fillStyle = node.color;
// Uniform colors.
if (node.color !== 'transparent') {
ctx.fillStyle = '#18bc9c';
}
ctx.fillRect(x, y, node.width, node.height);
ctx.restore();
// Text.
me.drawBoxById(ctx, id, node);
});
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement.
url = canvas.toDataURL('image/png');
$('#gridstack-icon').val(url);
// Update icon preview.
$('#gridstack-screenshot').empty().css('background-image', 'url(' + url + ')');
return url;
},
drawBoxById: function (ctx, id, node) {
var h = node.height;
var x = node.left + 20;
var y = h > 120 ? (node.top + 70) : (node.top + 45);
ctx.beginPath();
ctx.font = '92px sans-serif';
ctx.textBaseline = 'middle';
ctx.textAlign = 'left';
ctx.fillStyle = 'white';
ctx.fillText(id, x, y);
},
save: function (options, mergedData) {
options = _.extend(Drupal.gridstack.base.options, options);
var $main = $('#gridstack-' + options.icon);
var grids = {};
var margin = options.verticalMargin > 2 ? options.verticalMargin : 15;
var halfMargin = margin / 2;
var spacing = options.verticalMargin > 5 ? 0 : 5;
var noMargin = options.noMargin;
var domData = _.map(mergedData, function (node) {
if (_.isUndefined(node.id)) {
return grids;
}
var $box = $('.box[data-gs-bid="' + node.id + '"]', $main);
if (_.isUndefined($box) || _.isUndefined($box[0])) {
return grids;
}
var rect = $box[0].firstElementChild.getBoundingClientRect();
var currentIndex = $box.index() + 1;
var left = parseInt($box.css('left')) + halfMargin;
var top = parseInt($box.css('top'));
var $nested = $('.gridstack--nested:first', $box);
var $nestedBox = $('> .box', $nested);
var nested = false;
var title = $nestedBox.length ? '' : currentIndex;
var color = '#18bc9c';
var width = rect.width;
if ($nestedBox.length) {
color = 'transparent';
width += halfMargin;
}
if ($box.parent('.gridstack--nested').length) {
var $gsNested = $box.parent('.gridstack--nested');
var $parentBox = $gsNested.closest('.box');
var parentBoxIndex = $parentBox.index() + 1;
currentIndex = $box.index() + 1;
left += parseInt($parentBox.css('left'));
top += parseInt($parentBox.css('top'));
nested = true;
if (!_.isUndefined(parentBoxIndex) && !_.isUndefined(currentIndex)) {
title = parentBoxIndex + ':' + currentIndex;
}
else {
title = '';
}
color = 'rgba(24, 288, 156, .4)';
if ($nestedBox.length) {
color = '#18bc9c';
}
}
else {
// Check is using CSS framework, and so reduce with by its margins.
// Also if nomargin is enabled, icon still needs some margins.
if (options.isNested || noMargin) {
width -= margin;
}
}
if (options.verticalMargin === 0 && $box.data('gsColumn') !== 12) {
width -= halfMargin;
}
grids = {
left: left,
top: top,
width: width,
height: rect.height - spacing,
margin: margin,
id: !_.isUndefined(node) ? node._id : 0,
index: currentIndex,
nested: nested,
title: title,
color: color
};
return grids;
}, this);
return domData;
}
};
})(jQuery, Drupal, _, GridStack, dBlazy, this);
