- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个仪表板,其中包含一些小部件,这些小部件被分组到用户可以点击的选项卡中。这些小部件具有默认的起始位置,包括高度和宽度,但如果用户移动它们或调整它们的大小(使用 gridstack.js
),我会将新的小部件数据保存到本地存储。
如果用户在选项卡之间单击,新的小部件位置将保持不变。
当用户刷新页面时,将加载默认小部件位置而不是本地存储中的数据。我尝试使用 getWidgetData()
设置新位置,但没有成功。
我已经检查了我的 grid-layout
数据的本地存储,并且存在新位置。
这里是 Codepen因为我认为 SO 需要 allow-same-origin
,因此破坏了代码段。
// Initialize zurb foundation
$(document).foundation();
$(function() {
var grid = $('.grid-stack').data('gridstack');
var options = {
cellHeight: 40,
verticalMargin: 28,
animate: false,
};
// Initialize grid-stack widgets
widgetsInit = function(options) {
$('.grid-stack').gridstack(options);
getWidgetData(); // Find and set positions from local storage
}
updateVisibleWidgetHeights = function(options) {
var targetPanel = '.tabs-panel.is-active';
$(targetPanel + ' .grid-stack .grid-stack-item').each(function(i){
$(targetPanel + ' .grid-stack').data('gridstack').resize(
$(targetPanel + ' .grid-stack .grid-stack-item')[i],
$($(targetPanel + ' .grid-stack .grid-stack-item')[i]).attr('data-gs-width'),
Math.ceil(($(targetPanel + ' .grid-stack .grid-stack-item .grid-stack-item-content')[i].scrollHeight + $(targetPanel + ' .grid-stack').data('gridstack').opts.verticalMargin) / ($(targetPanel + ' .grid-stack').data('gridstack').cellHeight() + $(targetPanel + ' .grid-stack').data('gridstack').opts.verticalMargin))
);
});
}
updateAllWidgetHeights = function(options) {
$('.grid-stack .grid-stack-item').each(function(i){
$('.grid-stack').data('gridstack').resize(
$('.grid-stack .grid-stack-item')[i],
$($('.grid-stack .grid-stack-item')[i]).attr('data-gs-width'),
Math.ceil(($('.grid-stack .grid-stack-item .grid-stack-item-content')[i].scrollHeight + $('.grid-stack').data('gridstack').opts.verticalMargin) / ($('.grid-stack').data('gridstack').cellHeight() + $('.grid-stack').data('gridstack').opts.verticalMargin))
);
});
}
getWidgetData = function() {
// // Load from local storage
var serialization = null;
if (serialization = localStorage.getItem("grid-layout")) {
_.each(JSON.parse(serialization), function (node) {
// Update each widget's properties from values in storage
$('.grid-stack-item[data-custom-id='+ node.id +']').attr({
'data-gs-x': node.x,
'data-gs-y': node.y,
'data-gs-width': node.width,
'data-gs-height': node.height,
});
});
} else {
console.log("There was no local storage data to read")
}
}
widgetsInit(options);
updateVisibleWidgetHeights();
$('.grid-stack').on('change', function (event, items) {
// Save data to local storage
var res = _.map($('.grid-stack .grid-stack-item'), function (el) {
el = $(el);
node = el.data('_gridstack_node');
return {
// Grab widget properties
id: el.attr('data-custom-id'),
x: node.x,
y: node.y,
width: node.width,
height: node.height
};
});
localStorage.setItem("grid-layout", JSON.stringify(res))
});
// On tab change update widget heights to the height of the content they contain
$(document).on('change.zf.tabs', function() {
updateVisibleWidgetHeights();
})
});
.grid-stack > .grid-stack-item > .grid-stack-item-content {
background-color: #fff;
cursor: move;
border: 1px solid #e3e3e3;
border-radius: 4px;
padding: 1rem;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.4.0/gridstack.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/css/foundation.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.4.0/gridstack.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.4.0/gridstack.jQueryUI.min.js'></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/js/foundation.min.js"></script>
<ul class="tabs" data-tabs id="example-tabs" data-deep-link="true" data-update-history="true" data-match-height="false">
<li class="tabs-title is-active"><a href="#panel1" aria-selected="true">Tab 1</a></li>
<li class="tabs-title"><a href="#panel2">Tab 2</a></li>
</ul>
<div class="tabs-content unstyled" data-tabs-content="example-tabs">
<div class="tabs-panel is-active" id="panel1">
<div class="grid-stack">
<div class="grid-stack-item" data-gs-x="0" data-gs-y="0" data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#1</div>
</div>
<div class="grid-stack-item" data-gs-x="4" data-gs-y="0" data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#2</div>
</div>
<div class="grid-stack-item" data-gs-x="8" data-gs-y="0"data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#3</div>
</div>
</div>
</div>
<div class="tabs-panel" id="panel2">
<div class="grid-stack">
<div class="grid-stack-item" data-gs-x="0" data-gs-y="0" data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#4</div>
</div>
<div class="grid-stack-item" data-gs-x="4" data-gs-y="0" data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#5</div>
</div>
<div class="grid-stack-item" data-gs-x="8" data-gs-y="0" data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#6</div>
</div>
</div>
</div>
</div>
最佳答案
您需要调查一些事情。
可用的默认示例适用于单个实例,而您有多个。
您正在一次保存和加载 gridstack
这意味着您没有跟踪元素 grid-stack-item
也没有跟踪哪个点属于对于第一个选项卡或第二个选项卡,
因此,即使您使其正常工作,它也会尝试将所有 6 个不同的小部件放置在第一个选项卡中,而不是将其加载到各自的选项卡中。
所以需要修改以下内容
$('.grid-stack').on('change', function (event, items) {
getWidgetData()
在您的 grid-stack-items
中分配 id
或 custom-data-id
属性,以便它们具有唯一标识符
将标签包装在 ID 为 tabs-cotnainer
的容器中。
在 gridstack 的事件更改上,您应该创建 json 对象,其中包含专用于它将存储的选项卡的部分中的点,如下所示。
{
"items": {
"panel1": [
{
"id": "panel1-item1",
"x": 0,
"y": 0,
"width": 4,
"height": 2
},
{
"id": "panel1-item2",
"x": 4,
"y": 0,
"width": 4,
"height": 2
},
{
"id": "panel1-item3",
"x": 8,
"y": 0,
"width": 4,
"height": 2
}
],
"panel2": [
{
"id": "panel2-item1",
"x": 0,
"y": 0,
"width": 4,
"height": 2
},
{
"id": "panel2-item2",
"x": 4,
"y": 0,
"width": 4,
"height": 2
},
{
"id": "panel2-item3",
"x": 8,
"y": 0,
"width": 4,
"height": 2
}
]
}
}
替换为以下内容
$('.grid-stack').on('change', function (event, items) {
let tabs = $('#tabs-container >ul >li');
let totalTabs = $('#tabs-container >ul >li').length;
let storagePositions = {
items: {}
};
$.each(tabs, function (index, elem) {
let panel = $(elem).find('a').attr('href').replace("#", '');
let stackItems = $('#' + panel + ' .grid-stack .grid-stack-item');
storagePositions.items[panel] = _.map(stackItems, function (el) {
el = $(el);
node = el.data('_gridstack_node');
//console.log(node);
return { // Grab widget properties
id: el.attr('data-custom-id'),
x: node.x,
y: node.y,
width: node.width,
height: node.height
};
});
});
// Save data to local storage
localStorage.setItem("grid-layout", JSON.stringify(storagePositions))
});
然后以类似的方式加载标签
getWidgetData = function () {
// // Load from local storage
var serialization = null;
let tabs = $('#tabs-container >ul >li');
let totalTabs = $('#tabs-container >ul >li').length;
if (localStorage.getItem("grid-layout") !== null) {
serialization = JSON.parse(localStorage.getItem("grid-layout"));
$.each(tabs, function (index, elem) {
let panel = $(elem).find('a').attr('href').replace('#', '');
let myGrid = $('#' + panel + ' .grid-stack').data('gridstack')
var items = GridStackUI.Utils.sort(serialization.items[panel]);
_.each(items, function (node) {
myGrid.update($('div[data-custom-id="' + node.id + '"]'),
node.x, node.y, node.width, node.height);
});
});
} else {
console.log("There was no local storage data to read")
}
}
更新后的 HTML 如下所示
<div id="tabs-container">
<ul class="tabs dashboard-tabs" data-tabs id="example-tabs" data-deep-link="true" data-update-history="true" data-match-height="false">
<li class="tabs-title is-active">
<a href="#panel1" aria-selected="true">Tab 1</a>
</li>
<li class="tabs-title">
<a href="#panel2">Tab 2</a>
</li>
</ul>
<div class="tabs-content unstyled" data-tabs-content="example-tabs">
<div class="tabs-panel is-active" id="panel1">
<div class="grid-stack">
<div class="grid-stack-item" data-custom-id="panel1-item1" data-gs-x="0" data-gs-y="0" data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#1</div>
</div>
<div class="grid-stack-item" data-custom-id="panel1-item2" data-gs-x="4" data-gs-y="0" data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#2</div>
</div>
<div class="grid-stack-item" data-custom-id="panel1-item3" data-gs-x="8" data-gs-y="0" data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#3</div>
</div>
</div>
</div>
<div class="tabs-panel" id="panel2">
<div class="grid-stack">
<div class="grid-stack-item" data-custom-id="panel2-item1" data-gs-x="0" data-gs-y="0" data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#4</div>
</div>
<div class="grid-stack-item" data-custom-id="panel2-item2" data-gs-x="4" data-gs-y="0" data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#5</div>
</div>
<div class="grid-stack-item" data-custom-id="panel2-item3" data-gs-x="8" data-gs-y="0" data-gs-width="4" data-gs-height="2">
<div class="grid-stack-item-content">#6</div>
</div>
</div>
</div>
</div>
</div>
在此处查看关于 JSFIDDLE
的完整工作演示您可以在两个选项卡中更新位置,然后尝试刷新页面,它将显示更新后的位置。
注意:只需在脚本顶部写入 localStorage.removeItem("grid-layout")
即可删除之前的值,并在第一次运行后删除此行。
关于jquery - 如何使用 gridstack.js 从本地存储设置小部件数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50913511/
我想向一些用户公开一个 Web 部件,但不是所有用户。如何在“添加 Web 部件”弹出窗口中显示或隐藏 Web 部件?我想通过代码来做到这一点,我希望使用 SharePoint 角色来实现这一点。 最
我无法创建两个以上的 StatusBar 部分: HWND hStatusBar = CreateWindowEx(0, STATUSCLASSNAME, "", WS_CHILD | WS_VISI
使用 SharePoint 2007,如何在编辑页面模式下允许将 CEWP 添加到“添加 Web 部件”对话框的选择菜单?目前,我只能添加公告、日历、链接、共享文档、任务,但我无法添加 CEWP。我可
哪个 Web 部件以及如何配置它以查看来自不同网站集的列表? 请注意,我不想查看页面,而是查看列表。例如,在单独的网站集下查看来自不同团队网站的公告。 预先感谢您的帮助。 最佳答案 Data Form
以下是我在 FeatureDeactivation 事件处理程序中添加的代码片段。我无法获得删除 System.Web.UI.WebControls.WebParts 类型的 webpart 的解决方
我一直在尝试跟踪来自以下方面的信息: Long URL clipped to stop breaking the page 和 http://msdn.microsoft.com/en-us/libr
我想创建一个自定义 Web 部件,它具有 1 个以上的筛选器 Web 部件,并且可以在运行时/设计时连接到报表查看器 Web 部件(集成模式)。 我为此搜索了很多,但找不到一种方法来让单个 Web 部
我正在尝试创建一个 Web 部件,使用户无需离开 AllItems.aspx 页面即可编辑项目。 Web 部件应具有与 EditForm.aspx 页面类似的功能。 我已经使用 ConnectionC
这些年发布的许多应用程序都有新的 GUI 部件。iTunes 或 Twitter.app 中垂直布局的最小、最大和关闭按钮(但最新的具有默认布局),Safari 和终端中的选项卡控件,GarageBa
在具有数据库依赖性的 WSS3 或 MOSS2007 中部署 Web 部件的最佳方法是什么? .wsp 是否应该包含创建数据库的代码,我应该将 .wsp 封装在另一个处理数据库创建的安装程序中,还是应
我在我们位于 http://sharepoint:12345 的 moss 服务器上创建了一个新的共享点站点并毫无问题地向其添加了 CQWP。 我有一个指向同一台服务器的域名。所以我指向了http:/
在官方 Office 2007 站点中有许多对筛选器 Web 部件的引用。当我尝试添加其中之一时,我的 Sharepoint 中的 Web 部件列表没有显示任何筛选器 Web 部件。 如果有人遇到相同
我被要求在 Sharepoint 中创建一个 Web 部件,列出用户在网站集中访问的最后 10 个文档。 我的客户想要一种快速的方式让用户访问文档,这样他们就不必翻遍文件夹结构来查找文档,因为大多数时
我需要使用 C# 以编程方式将 SharePoint Web 部件“站点用户”添加到页面。 我知道如何添加 Web 部件,但如何从 Share Point 获取“站点用户”Web 部件?我不知道如何实
我正在使用 MEF 在我的应用程序中加载插件。一切正常,但我希望在将新部件放入我的应用程序文件夹时发现它们。这可能吗? DirectoryCatalog 有一个 Changed 事件,但我不确定它是如
我有一个 Winforms 桌面应用程序正在加载具有相同接口(interface)类型的多个 MEF 部件。 问题:当我尝试加载多个相同类型时,出现以下异常: 组成保持不变。由于以下错误,更改被拒绝:
我有一个内容查询 Web 部件,它按内容类型对网站集进行查询。我已按内容类型对其进行了分组,因此我有: -- Agenda (Content Type) ----Agenda #1 ----Agend
考虑以下 SharePoint 站点层次结构: - Site Collection - Site1 - Subsite1 - AnotherSubsite1
好吧,在我的 SharePoint (2013) 网站中,我制作了一个简单的 JavaScript Web 部件,每五分钟刷新一次页面。我去调整时间,在刷新前输入等待时间的地方退格,然后不假思索地退出
我不知道 Sharepoint 脚本,我的同事也不知道 JavaScript。他使用了他在 http://www.wonderlaura.com/Lists/Posts/Post.aspx?ID=22
我是一名优秀的程序员,十分优秀!