【问题标题】:Free jqGrid 4.14 Grouping header not formatting date custom totals not working免费 jqGrid 4.14 分组标题不格式化日期自定义总计不起作用
【发布时间】:2017-05-09 17:55:34
【问题描述】:

使用免费的 jqGrid 4.14 尝试设置时间记录网格搜索 SO、github 和 trirand,当然还有 google,但没有找到任何对我有用的东西。我的大部分基本功能都在工作,但是我已经做了一周的工作,需要帮​​助才能完成。将附上一张图片,显示我到目前为止所拥有的内容,并将包括我的代码/json。我无法完成的是组标题希望将组日期放在第一列中,并将相关日期的日期放在各自的列中。第二组正确显示日期,但第一个显示 /date 的数字很长。这些字段的属性和引入 json 的方式相同。需要对每个组的列和摘要行进行总计。因为时间是作为 HH:MM 字符串输入的,所以计算自定义总计,从字符串转换为秒的总和,然后再转换为字符串。如果总计超过 40 小时,则颜色应为红色。希望可以做到。

JSON:

[
    "total": 5,
    "page": 1,
    "records": 5,
    "rows": 
    {
        "CDPayCodeId": 1,
        "EndPayPeriod": "2017-05-15T00:00:00.0000000-05:00",
        "Fri": null,
        "Mon": null,
        "PersonId": 1,
        "Sat": null,
        "Sun": null,
        "Thu": null,
        "Total": null,
        "Tue": null,
        "Wed": "00:15",
        "WeekStart": "2017-04-30T00:00:00.0000000-05:00"
    }, 
    {
        "CDPayCodeId": 2,
        "EndPayPeriod": "2017-05-15T00:00:00.0000000-05:00",
        "Fri": null,
        "Mon": null,
        "PersonId": 1,
        "Sat": null,
        "Sun": null,
        "Thu": null,
        "Total": null,
        "Tue": null,
        "Wed": "06:15",
        "WeekStart": "2017-04-30T00:00:00.0000000-05:00"
    }, 
    {
        "CDPayCodeId": 1,
        "EndPayPeriod": "2017-05-15T00:00:00.0000000-05:00",
        "Fri": null,
        "Mon": "04:30",
        "PersonId": 1,
        "Sat": null,
        "Sun": null,
        "Thu": null,
        "Total": null,
        "Tue": null,
        "Wed": null,
        "WeekStart": "2017-05-14T00:00:00.0000000-05:00"
    }, 
    {
        "CDPayCodeId": 2,
        "EndPayPeriod": "2017-05-15T00:00:00.0000000-05:00",
        "Fri": null,
        "Mon": null,
        "PersonId": 1,
        "Sat": null,
        "Sun": "04:30",
        "Thu": null,
        "Total": null,
        "Tue": null,
        "Wed": null,


"WeekStart": "2017-05-14T00:00:00.0000000-05:00"
}, 
{
    "CDPayCodeId": 3,
    "EndPayPeriod": "2017-05-15T00:00:00.0000000-05:00",
    "Fri": null,
    "Mon": "04:30",
    "PersonId": 1,
    "Sat": null,
    "Sun": null,
    "Thu": null,
    "Total": null,
    "Tue": null,
    "Wed": null,
    "WeekStart": "2017-05-14T00:00:00.0000000-05:00"
} 

]

HTML

<table id="TimesheetGrid"></table>
<script>
    var PCList = '@ViewBag.PCList'
    var selectedId = '@ViewBag.PId'
</script>

JS 代码

$(function () {
    "use strict";
    var $grid = $("#TimesheetGrid"), recreateFilterToolbar = function () { $(this).jqGrid("destroyFilterToolbar").jqGrid("filterToolbar"); };

    var editSettings = {
        //recreateForm:true,
        jqModal: false,
        reloadAfterSubmit: false,
        closeOnEscape: true,
        savekey: [true, 13],
        closeAfterEdit: true
    };
    var addSettings = {
        //recreateForm:true,
        jqModal: false,
        reloadAfterSubmit: false,
        savekey: [true, 13],
        closeOnEscape: true,
        closeAfterAdd: true
    };
    var delSettings = {
        jqModal: false,
        reloadAfterSubmit: false,
        savekey: [true, 13],
        closeOnEscape: true,
        closeAfterAdd: true
    };
    var inLineNaveSettings = {
        add: true,
        addtext: 'Inline',
        addtitle: 'Add new record inline',
        edit: false
    };

    function SecondsFromTime(time) {
        var timeParts = time.match(/(\d{2}):(\d{2})/);
        if (timeParts !== null) {
            var timeUntil = moment.duration({
                hours: timeParts[1],
                minutes: timeParts[2],
            });
            var timeSeconds = timeUntil.as('seconds');
            return timeSeconds;
        }
    }

    function calcTotal(cellvalue, options, rowObject) {
        //var time = '12d 00:57:30';
        var secs = 0;
        var timeParts = '';
        for (var x = 1; x < 8; x++) {
            if (x === 1 && rowObject.Sun !== null) { secs = SecondsFromTime(rowObject.Sun); }
            else if (x === 2 && rowObject.Mon !== null) { secs += SecondsFromTime(rowObject.Mon); }
            else if (x === 3 && rowObject.Tue !== null) { secs += SecondsFromTime(rowObject.Tue); }
            else if (x === 4 && rowObject.Wed !== null) { secs += SecondsFromTime(rowObject.Wed); }
            else if (x === 5 && rowObject.Thu !== null) { secs += SecondsFromTime(rowObject.Thu); }
            else if (x === 6 && rowObject.Fri !== null) { secs += SecondsFromTime(rowObject.Fri); }
            else if (x === 7 && rowObject.Sat !== null) { secs += SecondsFromTime(rowObject.Sat); }
        }
        return moment().startOf('day').seconds(secs).format('H:mm');
    }

    $grid.jqGrid({
        autoencode: true,
        url: '/Timesheet/GetTaskList?PId=' + selectedId,
        editurl: '/Timesheet/UpdateTimesheet',
        mtype: "GET",
        caption: "Maintain Timesheet",
        datatype: 'json',
        loadonce: true,
        //colNames: ['', 'PayCodeId', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Total'],
        colModel: [
            { name: 'PersonId', editable: 'hidden', hidden: true },
            { name: 'EndPayPeriod', editable: 'hidden', sorttype: "date", formatter: "date", formatoptions: { newformat: "n/j/Y" } },
            { name: 'WeekStart', editable: 'hidden', sorttype: "date", formatter: "date", formatoptions: { newformat: "n/j/Y" } },
            {
                name: 'CDPayCodeId', index: 'CDPayCodeId', label: 'Pay Code', align: "center", width: 90,
                formatter: "select", autoResizable: true, sortable: false,
                edittype: "select", editoptions: { value: PCList }
            },
            { name: 'Sun', index: 'Sun', label: 'Sun', sortable: false, width: 50, autoResizable: true, summaryType: SumDay },
            { name: 'Mon', index: 'Mon', label: 'Mon', sortable: false, width: 50, autoResizable: true, summaryType: SumDay },
            { name: 'Tue', index: 'Tue', label: 'Tue', sortable: false, width: 50, autoResizable: true, summaryType: SumDay },
            { name: 'Wed', index: 'Wed', label: 'Wed', sortable: false, width: 50, autoResizable: true, summaryType: SumDay },
            { name: 'Thu', index: 'Thu', label: 'Thu', sortable: false, width: 50, autoResizable: true, summaryType: SumDay },
            { name: 'Fri', index: 'Fri', label: 'Fri', sortable: false, width: 50, autoResizable: true, summaryType: SumDay },
            { name: 'Sat', index: 'Sat', label: 'Sat', sortable: false, width: 50, autoResizable: true, summaryType: SumDay },
            {
                name: 'Total', index: 'Total', label: 'Total', sortable: false, sidth: 70, autoResizable: true,
                formatter: calcTotal
            },
            { name: "act", template: "actions", width: 60 }
        ],
        //jsonReader: { id: "PersonId" },
        height: '100%',
        shrinkToFit: true,
        autowidth: false,
        rownumbers: false,
        autoresizeOnLoad: false,
        cmTemplate: { editable: true, autoResizable: true, align: 'right' },
        iconSet: "fontAwesome",
        rowNum: 10,
        autoResizing: { compact: true },
        rowList: [5, 10, 20, "10000:All"],
        viewrecords: true,
        pager: true,
        //toppager: true,
        sortname: "SortOrder",
        sortorder: "asc",
        inlineEditing: { keys: true, defaultFocusField: "PayCode", focusField: "PayCode" },
        afterAddRow: function () {
            recreateFilterToolbar.call(this);
            $(this).trigger("reloadGrid", [{ current: true, fromServer: true }]);
        },
        afterSetRow: function () {
            recreateFilterToolbar.call(this);
            $(this).trigger("reloadGrid", [{ current: true, fromServer: true }]);
        },
        afterDelRow: function () {
            recreateFilterToolbar.call(this);
            $(this).trigger("reloadGrid", [{ current: true, fromServer: true }]);
        },
        grouping: true,
        groupingView: {
            groupField: ['EndPayPeriod', 'WeekStart'],
            groupOrder: ['asc', 'asc'],
            groupText: ['Pay Period {0}' , 'Week Start {0}'],
            //groupOrder [] // can use html if needed
            groupColumnShow: [false, false],
            groupDataSorted: true,
            //showSummaryOnHide: false,
            groupSummary: [true, true],
            hideFirstGroupCol: true,
            plusicon: 'fa-minus',
            minusicon: 'fa-plus'
        }
    }).jqGrid("gridResize");

    $grid.jqGrid("navGrid", {
        edit: editSettings,
        add: addSettings,
        del: delSettings,
        search: false,
        reloadGridOptions: { fromServer: true },
        beforeRefresh: function () {
            alert('In beforeRefresh');
            grid.jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid');
        }
    });
    $grid.jqGrid('inlineNav', inLineNaveSettings);

    $("#SelectPerson").change(function () {
        var selectedId = $("#SelectPerson").val();
        $("#TimesheetGrid").jqGrid('setGridParam', { datatype: 'json', url: '/Timesheet/GetTaskList?PId=' + selectedId }).trigger('reloadGrid');
    });

    function SumDay(val, name, record) {
        if (record[name] !== "" && record[name] !== null) {
            var totalTime = SecondsFromTime(record[name]);
            var totalTimeString = moment().startOf('day').seconds(totalTime).format('H:mm');
        }
        return totalTimeString;
    }
});

【问题讨论】:

    标签: javascript jquery jqgrid free-jqgrid


    【解决方案1】:

    首先,如果您发布演示会很有帮助,它可以用来重现代码。例如,您可以使用 JSFiddle 和 JSFiddle 的 Echo service 来模拟对服务器的请求。我根据您的代码和测试数据创建了演示

    您的代码的主要问题是忽略了自定义汇总函数SumDay 的第一个参数(代码中的val)。参数的值最初是"",它将是组中先前元素的总和。您必须将该值与当前值相加并从函数返回新的总和值。固定代码如下:

    function SumDay(val, name, record) {
        var totalTime, totalTimeString;
        if (record[name] !== "" && record[name] !== null) {
            totalTime = SecondsFromTime(record[name]);
            if (val !== "") {
                totalTime += SecondsFromTime(val);
            }
            totalTimeString = moment().startOf('day').seconds(totalTime).format('HH:mm');
            val = totalTimeString;
        }
        return val;
    }
    

    我另外将.format('H:mm') 固定为.format('HH:mm'),因为您测试SecondsFromTime 中的两位数字(请参阅time.match(/(\d{2}):(\d{2})/))。

    生成的演示 https://jsfiddle.net/OlegKi/ag1160e3/ 显示如下图所示的结果:

    【讨论】:

    • 感谢您的编辑、建议和代码修复。总计现在按预期工作,但付款期标题上的日期仍显示 /date/(long number) 应与星期日期第二组标题格式相同。同样对于第二组标题,是否可以为每个单元格设置日期为“m/d”的列标题?也许删除单词 week start 和那个日期,只在列标题中加上月份和日期?我已经阅读了您的许多其他答案,这些答案对我在其他网格上有所帮助,并希望对您分享知识表示衷心的感谢。
    • @AlbertBrennan:不客气!我再次查看了代码。问题的原因:使用了许多不需要的错误选项。属性hideFirstGroupCol: true 是第一列中缺少日期格式的问题的原因。我建议您另外使用列模板来减少代码重复。查看修改后的演示jsfiddle.net/ag1160e3/1
    • @Oleg 先生,你能帮忙吗stackoverflow.com/questions/43870268/…
    • @Oleg 再次感谢您。我没有意识到这些属性会发生冲突。已经尝试了许多不同的组合来注释属性或更改值,不幸的是这不是其中之一。对于最后一个问题,您的网格是否可以在第二个甚至第一个分组上使用列标题而不是 colspan,尽管在这种情况下更喜欢第二个?我想它可以在 jQuery 中完成,但 C# 是我的主要语言,只有较少的 jQuery 经验需要我一些时间。希望网格已经做到了。再次感谢分享。
    • @AlbertBrennan:不客气!您可以在groupingView 内部使用groupSummaryPos: ["header", "header"],但您必须增加CDPayCodeId 列的宽度以保存主要的摸索信息。我为你制作了jsfiddle.net/OlegKi/ag1160e3/3 来演示另外两个回调:1)groupCollapsegroupingView 中折叠一些组和2)summaryFormatcolModel 中的回调(参见weekDateTemplate),它格式化汇总值。
    猜你喜欢
    • 2018-08-07
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-27
    • 2014-02-10
    • 1970-01-01
    相关资源
    最近更新 更多