Native Date Renderer

Instead of displaying Skuid’s own customized renderer for dates, this field renderer displays the field value as an <input type=”date”> element, forcing a browser-native UI element to be rendered.

Note

The design and support for this input element vary from browser to browser.

Chrome

https://s3.us-west-2.amazonaws.com/developer.skuid.com/assets/v16.4.4/api-versions/v2/skuid/javascript/custom-field-renderers/examples/native-date-field/./native-date-chrome.gif

Firefox

https://s3.us-west-2.amazonaws.com/developer.skuid.com/assets/v16.4.4/api-versions/v2/skuid/javascript/custom-field-renderers/examples/native-date-field/./native-date-firefox.gif

Example Code

Download the sample page for this field renderer here, or see the example code below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
const FieldRenderer = skuid.component.FieldRenderer,
    $ = skuid.$;

// To avoid intermingling styles with the logic code below,
// let's create a `styles` object that contains the necessary CSS.
// We can then apply that later on using $(element).css().

const styles = {
    default: {
        "border": "none",
        flex: "auto",
        "background-color": "#fff",
        color: "#4a4f5a",
        "font-family": "Roboto,Helvetica,sans-serif",
        "font-size": "13px",
        "font-weight": "400",
        padding: "8px",
        width: "100%",
        "min-width": "48px",
        position: "relative",
    },
    focused: {
        "border-color": "#005cb9",
    },
    edit: {
        border: "1px solid #d1d3d5",
        "border-radius": "3px",
        "box-shadow": "0 0 2px 0 rgba(139,143,149,.12) inset, 0 2px 2px 0 rgba(139,143,149,.24) inset"
    }
};

// Date input fields require values to be in YYYY-MM-DD format.
// Assuming we're working with ISO 8601 datetime fields,
// which look like YYYY-MM-DDThh:mm:ss.sss (or some variation),
// we can parse them in a _very_ basic manner. We'll use this logic
// in both the read and edit modes, so let's define it as a function here.
const parseDate = (value) => {
    if (value) {
        return value.split("T")[0];
    }
}

return new FieldRenderer({
    readModeStrategy: "virtual",
    read: function (fieldComponent) {
        let h = fieldComponent.h,
            context = fieldComponent.cpi.getContext(),
            { field, model, row, value } = context;

        return h(
            "input",
            {
                value: parseDate(value),
                styles: styles.default,
                type: "date",
                // To render a date in the proper format, let's use an input element.
                // However, we'll need to make it `readonly` so users cannot
                // update the value without entering edit mode. Otherwise, the
                // `oninput` functions below will not work.
                afterCreate(element) {
                    element.setAttribute('readonly', true)
                },
            }
        )
    },
    editModeStrategy: "virtual",
    edit: function (fieldComponent) {
        let h = fieldComponent.h,
            context = fieldComponent.cpi.getContext(),
            { field, model, row, value } = context;

        return h(
            "input",
            {
                value: parseDate(value),
                styles: styles.default,
                type: "date",
                afterCreate(element) {
                    // While the default styles are applied in the VNode,
                    // let's also apply the edit styles after the element is created.
                    $(element).css(styles.edit);
                },
                onfocus(event) {
                    $(event.target).css(styles.focused);
                },
                oninput(event) {
                    model.updateRow(row,
                        { [field.id]: event.target.value },
                        { initiatorId: fieldComponent.id }
                    );
                },
                onblur(event) {
                    fieldComponent.cpi.onInputBlur();
                },
            },
        );
    },
});