Material Date

This sample integrates following already existing javascript material date picker https://github.com/FreddyFY/material-datepicke and shows how to use an external javascript and css to get respondent input and validate the input with multi-language support and styling based on the current ngSurvey theme chosen by the survey manager.

class MaterialDateWidget extends NGSWidget {
    /* 
        Sample that shows how to integrate an external javascript 
        based extension as a ngsurvey widget with label support.
        
        This sample integrates the material date picker
        https://github.com/FreddyFY/material-datepicker

        Shows how to use external javascript and css to get respondent input
        and validate the input with multilanguage support
    */

    /*  Html template that will generate before widget's class is created
        All id's will be suffixed by the uniqueId
        provided during creation of the widget */
    static get template() {
        return `<input class="ngs-question__answer-field ngs-question__answer-field-material-date" type="text" id="materialpicker001">`;
    }

    /* Style that will be assigned to this widget, note that all 
      elements class names will be scoped using the widget unique id */  
    static get style() {
        return `.ngs-question__answer-field-material-date {max-width:100px;}`
    }

    /* Allows the answer to be set required or not
       from the answer settings page to make
       the widget answer required during survey
    */
    static get required() {
        return true;
    }

    /* Properties that can be set in from the form designer for each
     answer using this widget as an answer type in the answer properties*/
    static get propertiesDef() {
        return [{
                id: 'color',
                label: 'color',
                defaultValue: 'var(--ngs-accent-color)',
                type: 'text'
            },
            {
                id: 'orientation',
                label: 'Orientation',
                defaultValue: 'portrait',
                type: 'list',
                list: [{
                        name: 'portrait',
                        value: 'portrait'
                    },
                    {
                        name: 'landscape',
                        value: 'landscape'
                    }
                ]
            }
        ];
    }

    /* External javascript code dependencies that will be loaded
     before the widget gets created */
    static get jsDependencies() {
        return [{
                id: 'moments',
                url: 'https://momentjs.com/downloads/moment-with-locales.min.js'
            },
            {
                id: 'materialdate',
                url: 'https://cdn.rawgit.com/FreddyFY/material-datepicker/master/dist/material-datepicker.min.js'
            }
        ];
    }

    /* External css code dependencies that will be loaded
       before the widget gets created */
    static get cssDependencies() {
        return [{
                id: 'googlefonts',
                url: 'https://fonts.googleapis.com/icon?family=Material+Icons'
            },
            {
                id: 'materialdatecss',
                url: 'https://cdn.rawgit.com/FreddyFY/material-datepicker/master/dist/material-datepicker.css'
            }
        ];
    }

    init() {
        var widget = this;
        // Get the input element from the template
        // its important to always suffix any id 
        // of the template with the uniqueid of the widget
        this.inputField = this.getWidgetElementById('materialpicker001');

        this.getLanguage$(lang => {
            // Setup the date picker, its important to always suffix any id 
            // of the template with the uniqueid of the widget
            this.materialPicker001 = new MaterialDatepicker('#materialpicker001' + this.uniqueId, {
                lang: lang.languageCode,
                color: this.properties.color,
                orientation: this.properties.orientation,
                onNewDate: function(date) {
                    // If the user has selected a date post the value to the form
                    widget.setAnswer(widget.inputField.value);
                }
            });

            if (this.materialPicker001) {

                // Get the current render mode to know how we should
                // setup the state here make it disabled if the 
                // widget is in read only mode 
                this.isDisabled$(disabled => {
                    this.inputField.disabled = disabled;
                });

                // Set the inital value when the widget gets created
                if (this.answerContext.initialValue) {
                    this.inputField.value = this.answerContext.initialValue;
                } else if (this.inputField.value) {
                    this.setAnswer(this.inputField.value);
                }

                // If the user changes the text make sure to save the value
                // in the form   
                this.inputField.addEventListener('input', (event) => {
                    this.textChange(this.inputField.value, this);
                });
            }
        });
    }

    // Post the value to the form
    textChange(value, widget) {
        widget.setAnswer(this.inputField.value);
    }

    // Will be called by the form
    // to see if the value is valid
    // If not valid must return '' (no error message shown) or the error message to show
    // If its valid return null 
    isValid() {
        var date = new Date(this.inputField.value);
        if ((this.inputField.value && !(date instanceof Date && !isNaN(date.valueOf())))) {
            return 'InvalidDateDataTypeMessage';
        } else {
            return null;
        }
    }
}

Last updated

(c) 2024 Data Illusion Zumbrunn. All rights reserved. Reproduction strictly forbidden.