0

我正在尝试将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 值之外,另外两个小部件与上述小部件类似。

问题: 这段代码面临的问题是,我不能多次执行拖放操作,并且它没有下降到我们想要放置它的正确位置。

如果需要更多信息,请告诉我。

4

0 回答 0