priority-web-sdk:实现 DATE8 字段

priority-web-sdk: Implementing a DATE8 field

我正在尝试实现日期类型字段。我将数据分成 3 个 select 字段,分别代表日、月和年,如下所示:

    <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 中的值以填充 select 字段。

    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 检查调用 <select> 元素是否包含自定义 date 属性,该属性标识我们正在更新的日期字段。

如果是,我们使用在 dd、mm、yy <select> 元素和 运行 fieldUpdate 函数中设置的值创建一个 Date 对象,如下所示:

    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 的第一次调用时填充 <option>s。来自 updateFields 的后续调用在适当的 <option> 上设置 <selected> 属性,以保持控件与表单列中的数据同步:

    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 函数计算 selected 日期为 Sat Oct 07 2017 00:00:00 GMT+0100 (GMT Daylight Time)。这是我在表格中设置的正确日期。

selected 元素上的自定义 date 属性包含列名称:

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

因此使用以下参数调用表单 fieldUpdate 函数:

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

完成 fieldUpdate 后,将调用 updateFields 刷新屏幕,但现在:

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) returns 出现非法日期错误,好像月和日组件正在切换。

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

这里的一个问题是传递的日期包含英国夏令时的偏移量(/在下雨时 window。我猜是给定值 "summer")。

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,
    ...
};