【问题标题】:priority-web-sdk: Implementing a DATE8 fieldpriority-web-sdk:实现 DATE8 字段
【发布时间】:2017-06-24 20:14:01
【问题描述】:

我正在尝试实现一个日期类型字段。我将数据分成日、月和年的 3 个选择字段,如下所示:

    <div id="CREATEDDATE" class="item" >
        <label>Date Opened</label>
        <select 
            id="CREATEDDATEdd" 
            class="dd" 
            date="CREATEDDATE" 
            onfocus="focusdiv(event)" 
            onblur="defocusdiv(event)"
        ></select>
        <select 
            id="CREATEDDATEmm" 
            class="mm" 
            date="CREATEDDATE" 
            onfocus="focusdiv(event)" 
            onblur="defocusdiv(event)"
        ></select>
        <select 
            id="CREATEDDATEyy" 
            class="yy" 
            date="CREATEDDATE" 
            onfocus="focusdiv(event)" 
            onblur="defocusdiv(event)"
        ></select>
    </div>

updateFields 函数中,我正在测试元素的nodeName 以确定如何处理数据。如果元素是 DIV,我会通过调用 drawDate 函数来处理它,传入元素的参数和 ROW 中的值来填充选择字段。

    function updateFields(result) {
        if (result[myForm.name]) {
            var fields = result[myForm.name][1];
            for (var fieldName in fields) {
                var el = document.getElementById(fieldName);
                if (el) {
                    switch (el.nodeName){                       
                        case "INPUT":
                            el.value = fields[fieldName];
                            break;

                        case 'SELECT':                  
                            fill(el, fields[fieldName]);
                            el.value = fields[fieldName];
                            break;

                        case "DIV":
                            drawDate(el, fields[fieldName]);
                            break;
                    };
                };
            }
        }
    }

fieldChangeHandler 检查调用&lt;select&gt; 元素是否包含自定义date 属性,该属性标识我们正在更新的日期字段。

如果是这样,我们使用 dd、mm、yy &lt;select&gt; 元素中设置的值创建一个 Date 对象并运行 fieldUpdate 函数,如下所示:

    function fieldChangeHandler(event) {
        switch (event.srcElement.nodeName){                     
            case "INPUT":
                myForm.fieldUpdate(event.srcElement.id, event.target.value);
                break;

            case 'SELECT':
                if(event.srcElement.attributes["date"]){
                    var dt = new Date(0);
                    dt.setFullYear(
                        $('#'+event.srcElement.attributes["date"].nodeValue+'yy')[0].value,
                        $('#'+event.srcElement.attributes["date"].nodeValue+'mm')[0].value,
                        $('#'+event.srcElement.attributes["date"].nodeValue+'dd')[0].value
                    );
                    myForm.fieldUpdate(event.srcElement.attributes["date"].nodeValue, dt);

                } else {
                    myForm.fieldUpdate(event.srcElement.id, event.target.value);

                }
                break;                  
        };
    }

最后,我有一个drawDate 函数,它在来自updateFields 的第一次调用中填充&lt;option&gt;s。来自updateFields 的后续调用在相应的&lt;option&gt; 上设置&lt;selected&gt; 属性,以使控件与表单列中的数据保持同步:

    function drawDate(el,sel){

        var i, dt = new Date(sel);
        var monthNames = ["January", "February", "March", "April", "May", "June",
          "July", "August", "September", "October", "November", "December"
        ];

        var dd = ($('#'+el.id+'dd')[0].options.length==0);          
        for (i=1; i<32;i++) {
            if (i == dt.getDate()){
                if(dd){
                    $("#"+el.id+"dd").append('<option selected value="'+ i +'">'+ i +'</option>');
                }else{
                    $('#'+el.id+'dd')[0].options[(i-1)].selected = true;
                }

            } else {
                if(dd){
                    $('#'+el.id+"dd").append('<option value="'+ i +'">'+ i +'</option>')
                }else{
                    $('#'+el.id+'dd')[0].options[(i-1)].selected = false;
                };                  
            };
        };

        var mm = ($('#'+el.id+'mm')[0].options.length==0);          
        for (i=0; i<12;i++) {
            if (i == dt.getMonth()){
                if(mm){
                    $("#"+el.id+"mm").append('<option selected value="'+ i +'">'+ monthNames[i] +'</option>');
                }else{
                    $('#'+el.id+'mm')[0].options[(i)].selected = true;
                };

            } else {
                if(mm){
                    $('#'+el.id+"mm").append('<option value="'+ i +'">'+ monthNames[i] +'</option>');                                           
                }else{
                    $('#'+el.id+'mm')[0].options[(i)].selected = false;
                };
            };
        };

        var currentTime = new Date();
        var year = currentTime.getFullYear();
        var yy = ($('#'+el.id+'yy')[0].options.length==0);  
        var ind = 0;
        for (i=(year + 1); i>(year - 3);i--) {
            if (i == dt.getUTCFullYear()){
                if(yy){
                    $("#"+el.id+"yy").append('<option selected value="'+ i +'">'+ i +'</option>');
                }else{
                    $('#'+el.id+'yy')[0].options[ind].selected = true;
                };

            } else {
                if(yy){
                    $('#'+el.id+"yy").append('<option value="'+ i +'">'+ i +'</option>');                   
                }else{
                    $('#'+el.id+'yy')[0].options[ind].selected = false;
                };

            };
            ind ++;
        };      
    }

当我编辑日期时,fieldChangeHandler 函数将所选日期计算为Sat Oct 07 2017 00:00:00 GMT+0100 (GMT Daylight Time)。这是我在表单中设置的正确日期。

所选元素上的自定义date 属性包含列名:

event.srcElement.attributes["date"]
    date=​"CREATEDDATE"

所以fieldUpdate这个表单函数是用以下参数调用的:

myForm.fieldUpdate(​"CREATEDDATE", "Oct 07 2017 00:00:00 GMT+0100 (GMT Daylight Time)");

一旦我们完成了fieldUpdateupdateFields 就会被调用来刷新屏幕,但是现在:

fields["CREATEDDATE"] = "2017-10-06T00:00:00.000Z"

fieldUpdate 函数中设置CREATEDDATE 和对updateFields 的回调之间,我们似乎损失了一天...(可能是星期六!)


缩减示例。

我用新的日期更新字段:

function minimaltest()  {
    var dt = new Date(0);           
    myForm.fieldUpdate(
        "CREATEDDATE", 
        dt.setFullYear(2017, 0, 1)
    );
}

服务器回调updatefields函数:

    function updateFields(result) {
        ...
    }

但是结果中不包含我传入的日期……

result = Object {CUSTOMERS: Object}
CUSTOMERS:
Object
1:Object
CREATEDDATE:"2017-02-01T00:00:00.000Z"

然而,有趣的是,与 dt.setFullYear(2017, 0, 20) (20/01/17) 的相同调用会返回非法日期错误,就好像正在切换月份和日期组件一样。

Object {
  "type": "error",
  "code": "stop",
  "message": "Illegal date.",
  "form": "Object",
  "fatal": false
}

【问题讨论】:

  • 您最好通过创建minimal, complete and verifiable example 将代码减少到足以显示问题的程度。您的大部分逻辑都与 jQuery 和 HTML 相关联,因此很难看到发生了什么。将示例发布为可运行的 sn-p,当前代码有错误。 focusdiv 函数在哪里?
  • 公平评论。完整示例在这里:link。使用客户编号“T000043a”。我将在问题中添加一个缩减示例。
  • 您可以尝试将日期以 ISO 格式发送到 updateField。 dt = new Date('01/20/2017'); dt.toISOString();
  • 如果我这样做myForm.fieldUpdate(event.srcElement.attributes["date"].nodeValue, dt.toISOString);updateFields 返回的创建日期是零长度字符串。
  • 你能用toISOString 更改更新示例链接吗?我想调试一下,看看出了什么问题。

标签: javascript date erp


【解决方案1】:

这里的一个问题是,正在传递的日期包含英国夏令时的偏移量(/在雨中看窗外。我猜对于给定的“夏天”值)。

BST 比 Priority 预期的 UTC 时间戳晚 60 分钟,因此经过的日期是我们预期值前一天的 60 分钟或 23:00。

我们可以使用Date(Date.UTC()) 来创建UTC 日期(无偏移),而不是转换日期+偏移量toISOString,如下所示:

var dt = new Date(
    Date.UTC(
        $('#'+event.srcElement.attributes["date"].nodeValue+'yy')[0].value,
        $('#'+event.srcElement.attributes["date"].nodeValue+'mm')[0].value,
        $('#'+event.srcElement.attributes["date"].nodeValue+'dd')[0].value
    )
);

但是,当我指定天 > 12 时,我仍然收到 Illegal date 错误...


更新 2。

非法日期是由于在配置中使用美国英语 (3) 而不是英国英语 (2) 造成的。 (呸!)

var config = {
    url: 'https://erpdemo.emerge-it.co.uk',
    language: 2,
    ...
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多