我正在尝试将gridstack库用于仪表板,该库允许将控件拖放到客户端的小部件并调整其大小。我正在尝试使用包装 javascript 库并防止直接使用 gridstack 库,唯一的原因是每当我需要切换到另一个 javascript 库时;像一些需求,gridstack 不直接支持;那么我不需要对每个使用它的地方进行更改。
这是我的代码。
HTML:
<html>
<head>
<script type="text/javascript" src="../js/jquery-1.11.1.js"></script>
<script type="text/javascript" src="../js/jquery-ui-1.10.4.js"></script>
<script type="text/javascript" src="../js/jquery-migrate-1.2.1.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../js/underscore-min.js"></script>
<script type="text/javascript" src="../js/gridstack.js"></script>
<script type="text/javascript" src="../js/jquery.grid.final.js"></script>
<link rel="stylesheet" type="text/css" href="../css/jquery-ui.theme.css"></link>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../css/gridstack.css"></link>
<link rel="stylesheet" type="text/css" href="../css/gridstack-extra.css"></link>
<link rel="stylesheet" type="text/css" href="../css/dashboard.css"></link>
<style type="text/css">
.widget-wrapper {
height: 100%;
}
.grid-stack {
background: #f5f5f5;
width: 80%;
}
.resize-helper {
border: 2px dotted red;
opacity: 0.2;
}
.grid-stack-item {
}
.widget {
border: 1px solid red;
}
#dashboardContainer > .grid-stack-item[data-gs-x='1'] {
left: 33.33%;
}
#dashboardContainer > .grid-stack-item[data-gs-x='2'] {
left: 66.66%;
}
#dashboardContainer > .grid-stack-item[data-gs-width='1'] {
width: 33.33%;
}
#dashboardContainer > .grid-stack-item[data-gs-width='2'] {
width: 66.66%;
}
#dashboardContainer > .grid-stack-item[data-gs-width='3'] {
width: 100%;
}
</style>
<script type="text/javascript">
$(function () {
var options = {
cellHeight: 100,
verticalMargin: 20,
width: 3,
// float: true,
handleClass: 'widget-header',
imageDir : "../img/",
resizable: {
handles: "e",
grid: [330, 50],
helper: "resize-helper"
},
ajaxCallbacks: {
saveColumns: {
url: '../url1.html',
data: {
dashboardId : '3'
}
},
widgetSettings: {
// url: 'http://www.ibm.com/',
data: {}
},
getWidgetsByColumn: {
url: 'getWIdgetsByColumn.json',
data: {
id : '2'
}
},
getWidget: {
// url: 'getWidget.json',
url: 'loadWidget.jsp',
data: {
dashboardId : '1'
}
}
}
};
$('#dashboardContainer').gridDashboard(options);
});
</script>
</head>
<body>
<div id="dashboardContainer" style="width: 80%; background-color: #f0f0f0;"></div>
</body>
Java 脚本文件:
(function($) { // Create closure.
// Constructor for dashboard object.
$.fn.gridDashboard = function(options) {
// Public properties of dashboard.
var dashboard = {};
dashboard.element = this.empty();
dashboard.ready = false;
dashboard.columns = Array();
dashboard.widgets = Array();
// End of public properties of dashboard.
//this method is a IE 7 and 8 hack to force repaing of dashboard in case of visual change on reorder/minimize/maximize
dashboard._forceRepaint = function() {
if ($.browser.msie && $.browser.version <= 8) {
dashboard.element.addClass('js').removeClass('js');
}
};
// Used to determine whether two resort events are resulting from the same UI event.
var currentReSortEvent = null;
// Merge in the caller's options with the defaults.
var opts = $.extend({}, $.fn.gridDashboard.defaults, options);
this.gridstack(opts);
var grid = this.data('gridstack');
var img = document.createElement("IMG");
img.src = opts.imageDir + "maximize.gif";
// Execution 'forks' here and restarts in init(). Tell the user we're busy with a throbber.
var throbber = $(opts.throbberMarkup).appendTo(dashboard.element);
getJSON(opts.ajaxCallbacks.getWidgetsByColumn.url, opts.ajaxCallbacks.getWidgetsByColumn.data, init);
return dashboard;
// End of constructor and private properties for dashboard object.
/**
* Private methods of dashboard.
*/
// Ajax callback for getWidgetsByColumn.
function init(widgets, status, jqXHR) {
throbber.remove();
// var markup = '<div class="empty-placeholder">' + opts.emptyPlaceholderInner + '</div>';
// Create widget containers per column.
for (var c = 0; c < opts.columns; c++) {
var col = {
initialWidgets : Array(),
element: dashboard.element
};
var rowIndex = 0;
for ( var id in widgets[c]) {
col.initialWidgets[id] = dashboard.widgets[id] = widget({
id : id,
element : $('<div class="widget"></div>').appendTo(col.element), // Append widget to column (sortable)
});
grid.addWidget(dashboard.widgets[id].element, c, rowIndex, 1, 1, false, null, null, null, null, id);
rowIndex++;
}
}
$("<div class='clearfix'></div>").appendTo(dashboard.element);
}
function getJSON(url, params, callback) {
if (url) {
$.ajax({
dataType : "json",
url : url,
data : params,
success : callback,
error : function(jqXHR) {
// Check login session active or not.
}
});
}
}
/**
* widget object Private sub-class of dashboard Constructor starts
*/
function widget(widget) {
// Merge default options with the options defined for this widget.
widget = $.extend({}, $.fn.gridDashboard.widget.defaults, widget);
/**
* Public methods of widget.
*/
// End public methods of widget.
/**
* Public properties of widget.
*/
// Default controls. External script can add more with widget.addControls()
widget.controls = {
settings : {
description : 'Configure this widget',
callback : widget.toggleSettings
},
minimize : {
description : 'Show & hide this widget',
callback : widget.toggleMinimize
},
fullscreen : {
description : 'Open widget to full screen mode',
callback : widget.enterFullscreen
},
close : {
description : 'Remove this widget',
callback : widget.remove
}
};
// End public properties of widget.
/**
* Private properties of widget.
*/
// We're gonna 'fork' execution again, so let's tell the user to hold with us till the AJAX callback gets invoked.
// var throbber = $(opts.throbberMarkup).appendTo(widget.element);
var params = $.extend({}, opts.ajaxCallbacks.getWidget.data, {
id : widget.id
});
// Get actual widget content.
getJSON(opts.ajaxCallbacks.getWidget.url, params, init);
return widget;
// End of private properties of widget.
/**
* Private methods of widget.
*/
// Ajax callback for widget initialization.
function init(data, status, jqXHR) {
var newWidget = ("new-widget" == widget.id);
$.extend(widget, data);
widget.element.attr('id', 'widget-' + widget.id).addClass(
widget.classes);
// throbber.remove();
// Build and add the widget's DOM element.
$(widgetHTML()).appendTo(widget.element);
}
// Builds inner HTML for widgets.
function widgetHTML() {
var html = '';
html += '<div class="widget-wrapper">';
html += ' <div class="widget-controls"></div>';
html += ' <div class="widget-header">' + widget.title
+ '</div>';
html += ' <div class="widget-content">' + widget.content
+ '</div>';
html += '</div>';
return html;
}
}
};
// Public static properties of dashboard. Default settings.
$.fn.gridDashboard.defaults = {
columns : 3,
emptyPlaceholderInner : 'There are no widgets in this column of your dashboard.',
fullscreenHeaderInner : '<img alt="Close this widget" src="images/close.gif" /> Return to Dashboard',
throbberMarkup : '<div class="throbber"><img alt="Loading, please wait" src="../img/throbber.gif" /><p>Loading...</p></div>',
animationSpeed : 200,
callbacks : {},
widgetCallbacks : {}
};
// Default widget settings.
$.fn.gridDashboard.widget = {
defaults : {
minimized : false,
settings : false,
fullscreen : false
}
};
})(jQuery); // end of closure
getWIdgetsByColumn.json:
[{"104_2":0,"104_1":0},{},{"104_3":0}]
意味着,两个小部件应位于仪表板容器的第一列,一个小部件位于仪表板容器的第三列。
小部件内容将从服务器端加载。加载小部件.jsp:
<%@ page import="java.io.File" %>
<%@ page import="java.io.FileInputStream" %>
<%! String jsonOutput = ""; %>
<%
String id = request.getParameter("id");
FileInputStream fis = null;
try {
File file = new File("C:/apache-tomcat-7.0.54/webapps/SampleApp/gridstack/getWidget-" + id + ".json");
fis = new FileInputStream(file);
byte[] content = new byte[fis.available()];
fis.read(content);
out.write(new String(content));
out.flush();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (fis != null) {
try { fis.close(); } catch (Exception ex) { ex.printStackTrace(); }
}
}
%>
每个仪表板小部件都加载了 json 内容。这是小部件 JSON 的示例代码。
getWidget-104_1.json
{"width":"100%","height":"300px",
"title":"Widget Title",
"content":"<table width=\"100%\" cellpadding=\"2\" cellspacing=\"0\" border=\"0\"><tr><td align='center'>\r\n\r\n\r\n <select name=\"select_104_1\" style=\"width:100%;\" id=\"select_104_1\" >\r\n<option value=\"100\" selected=\"selected\" >Sample_Option_1<\u002foption>\r\n<option value=\"108\" >Sample_Option_3<\u002foption>\r\n<option value=\"104\" >Test_Option<\u002foption>\r\n<\u002fselect>\r\n\r\n<\u002ftr><tr><td valign=\"top\" style=\"height:100%\">\r\n <div id='chart_104_1' style='width:100%;'><\u002fdiv>\n \r\n<\u002ftd><\u002ftr><\u002ftable>\r\n",
"id":"104_1"}
除了 id 值之外,另外两个小部件与上述小部件类似。
问题: 这段代码面临的问题是,我不能多次执行拖放操作,并且它没有下降到我们想要放置它的正确位置。
如果需要更多信息,请告诉我。