<commit_before>
/*
 * Generic form validation
 *
 * Applies value filters and validators to fields on a form.
 * Fields annotated with a data-validators or marked required will be tested.
 *
 * Decorate inputs using:
 *      data-validators="list, of, validators"
 *      data-filters="list,of,filters"
 *
 * Returns:
 *  Object with:
 *    valid : bool that is True IFF no validator returned an error.
 *    values: Object of values of all fields.
 *    errors: Object of lists of field errors.
 */

var informal = (function() {
    var informal;

    /*
     * Deal with the lack of uniformity of input fields.
     * - checkbox only has a value if it's checked
     * - textarea?
     * - select/option and multiple?
     */
    function getValue(field) {
        var type = field.getAttribute('type') || field.nodeName;
        helper = getValue.helper[type];
        return (helper === undefined) ? field.value : helper(field);
    }
    getValue.helpers = {
        input: function (field) { return field.value; },
        checkbox: function (field) {
            return field.hasAttribute('checked') ? field.value : undefined;
        },
        radiobutton: function (field) {
        },
        textarea: function (field) {
        },
        select : function (field) {
        },
    };
    function setValue(field, value) {
        var type = field.getAttribute('type') || field.nodeName;
        helper = setValue.helper[type];
        return (helper === undefined) ? field.value = value : helper(field, value);
    }
    setValue.helpers = {
        input: function (field, value) { return field.value = value; },
        checkbox: function (field, value) { return field.checked = value == field.value; }
    };

    /**
     * Filters mutate values.
     */
    informal.filters = {

        /**
         * Filter to convert value to an integer
         */
        as_integer: function (val) {
            return parseInt(val, 10);
        },

        /**
         * Filter to convert value to a float
         */
        as_float: function (val) {
            return parseFloat(val);
        }

    };

    /**
     * Validator functions test values, and return the message to display.
     */
    informal.validators = {
        /**
         * Indicates the field must have a value.
         */
        required: function (val) {
            if (!val) { return 'This value is required.'; }
        },

        /**
         * Loose validation the value looks like an email
         */
        simple_email: function (val) {
            if(!/^.+@.+\..+$/.test(val)) {
                return 'Must be a valid email address.';
            }
        }

        past_date: function (val) {
            // bail early if blank
            if(!val) { return; }

            // and is in the future:
            if( val.isAfter( moment() )) {
                return 'Date must be in the past';
            }
        },

        future_date: function (val) {
            // bail early if blank
            if(!val) { return; }

            // and is in the future:
            if( val.isBefore( moment() )) {
                return 'Date must be in the future';
            }
        }

    };

    /**
     * Helpful wrapper for working with forms.
     * @constructor
     * @param {selector} el - The parent element of fields to be validated.
     */
    informal.Form = function (selector) {
        if(typeof selector === 'string') {
            this.el = document.querySelector(selector);
        } else {
            this.el = selector;
        }
        this.form = (this.el.nodeName == 'FORM') ? this.el : this.el.querySelector('form');
    };

    informal.Form.prototype = {

        /**
         * Selector for element to contain error messages
         */
        error_container: '.form-group',
        /**
         * Class to add to containers when they have errors
         */
        error_class: 'has-error',
        /**
         * Selector for removing error messages.
         */
        error_block_selector: '.has-error .help-block',

        /**
         * Clear all errors and values from a field's forms.
         */
        clear: function () {
            this.form.reset();
            this.clear_errors();
        },
        /**
         * Focus on the first field element.
         */
        focus: function () {
            this.$el.find('[name]').first().focus();
        },
        /**
         * Set field values from an object.
         * @param {object} obj - The object to copy properties from
         */
        load_record: function (obj) {
            var field, fields = this.el.querySelectorAll('[name]');
            for( var i=0; field = fields[i++] ; ) {
                var val = obj[field.name],
                    fmt = field.getAttribute('data-datefmt');
                if(typeof val == 'function') {
                    val = obj[field.name]();
                }
                if(fmt !== undefined) {
                    val = moment(val).format(fmt);<commit_msg>Finish field get/set value Tidy up back-ported code<commit_after>
/*
 * Generic form validation
 *
 * Applies value filters and validators to fields on a form.
 * Fields annotated with a data-validators or marked required will be tested.
 *
 * Decorate inputs using:
 *      data-validators="list, of, validators"
 *      data-filters="list,of,filters"
 *
 * Returns:
 *  Object with:
 *    valid : bool that is True IFF no validator returned an error.
 *    values: Object of values of all fields.
 *    errors: Object of lists of field errors.
 */

var informal = (function() {
    var informal;

    /*
     * Deal with the lack of uniformity of input fields.
     * - checkbox only has a value if it's checked
     * - textarea?
     * - select/option and multiple?
     */
    function getValue(field) {
        var type = field.getAttribute('type') || field.nodeName;
        helper = getValue.helper[type];
        return (helper === undefined) ? field.value : helper(field);
    }
    getValue.helpers = {
        checkbox: function (field) {
            return field.checked ? field.value : undefined;
        },
        radio: function (field) {
            return field.checked ? field.value : undefined;
        },
        select: function (field) {
            if(!field.multiple) return field.value;
            var vals = [],
                opts = field.querySelectorAll('option');
            for(var i=0; opt = opts[i++];) {
                if(opt.selected) { vals.push(opt.value); }
            }
            return vals;
        }
    };
    function setValue(field, value) {
        var type = field.getAttribute('type') || field.nodeName;
        helper = setValue.helper[type];
        return (helper === undefined) ? field.value = value : helper(field, value);
    }
    setValue.helpers = {
        checkbox: function (field, value) { field.checked = value == field.value; },
        radio: function (field, value) { field.checked = value == field.value; },
        select: function (field, value) {
            var i, opt, opts;
            if(!field.multiple) { field.value = value; return; }
            opts = field.querySelectorAll('option');
            if(value.constructor.name === 'Array') {
                for(i=0; opt = opts[i++];) {
                    opt.selected = value.indexOf(opt.value) != -1;
                }
            } else {
                for(i=0; opt = opts[i++];) {
                    opt.selected = opt.value == value;
                }
            }
        }
    };

    /**
     * Filters mutate values.
     */
    informal.filters = {

        /**
         * Filter to convert value to an integer
         */
        as_integer: function (val) {
            return parseInt(val, 10);
        },

        /**
         * Filter to convert value to a float
         */
        as_float: function (val) {
            return parseFloat(val);
        }

    };

    /**
     * Validator functions test values, and return the message to display.
     */
    informal.validators = {
        /**
         * Indicates the field must have a value.
         */
        required: function (val) {
            if (!val) { return 'This value is required.'; }
        },

        /**
         * Loose validation the value looks like an email
         */
        simple_email: function (val) {
            if(!/^.+@.+\..+$/.test(val)) {
                return 'Must be a valid email address.';
            }
        }

        past_date: function (val) {
            // bail early if blank
            if(!val) { return; }

            // and is in the future:
            if( val.isAfter( moment() )) {
                return 'Date must be in the past';
            }
        },

        future_date: function (val) {
            // bail early if blank
            if(!val) { return; }

            // and is in the future:
            if( val.isBefore( moment() )) {
                return 'Date must be in the future';
            }
        }

    };

    /**
     * Helpful wrapper for working with forms.
     * @constructor
     * @param {selector} el - The parent element of fields to be validated.
     */
    informal.Form = function (selector) {
        if(typeof selector === 'string') {
            this.el = document.querySelector(selector);
        } else {
            this.el = selector;
        }
        this.form = (this.el.nodeName == 'FORM') ? this.el : this.el.querySelector('form');
    };

    informal.Form.prototype = {

        /**
         * Selector for element to contain error messages
         */
        error_container: '.form-group',
        /**
         * Class to add to containers when they have errors
         */
        error_class: 'has-error',
        /**
         * Selector for removing error messages.
         */
        error_block_selector: '.has-error .help-block',

        /**
         * Clear all errors and values from a field's forms.
         */
        clear: function () {
            this.form.reset();
            this.clear_errors();
        },
        /**
         * Focus on the first field element.
         */
        focus: function () {
            this.el.querySelector('[name]').focus();
        },
        /**
         * Set field values from an object.
         * @param {object} obj - The object to copy properties from
         */
        load_record: function (obj) {
            var field, fields = this.el.querySelectorAll('[name]');
            for( var i=0; field = fields[i++] ; ) {
                var val = obj[field.name],
                    fmt = field.getAttribute('data-datefmt');
                if(typeof val == 'function') {
                    val = obj[field.name]();
                }
                if(fmt !== undefined) {
                    val = moment(val).format(fmt);
{'fraction_non_alphanumeric': 0.12207049271083226, 'fraction_numerical': 0.0009226794611551947, 'mean_word_length': 1.5324766355140187, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '570416', 'n_tokens_mistral': 2941, 'n_tokens_neox': 2863, 'n_words': 851}