<commit_before>var edx = edx || {};

(function($, _, Backbone, gettext) {
    'use strict';

    edx.student = edx.student || {};
    edx.student.account = edx.student.account || {};

    edx.student.account.FormView = Backbone.View.extend({
        tagName: 'form',

        el: '',

        tpl: '',

        fieldTpl: '#form_field-tpl',

        events: {},

        errors: [],

        formType: '',

        $form: {},

        fields: [],

        // String to append to required label fields
        requiredStr: '*',

        initialize: function( data ) {
            this.model = data.model;
            this.preRender( data );

            this.tpl = $(this.tpl).html();
            this.fieldTpl = $(this.fieldTpl).html();
            this.buildForm( data.fields );

            this.listenTo( this.model, 'error', this.saveError );
        },

        /* Allows extended views to add custom
         * init steps without needing to repeat
         * default init steps
         */
        preRender: function( data ) {
            /* Custom code goes here */
            return data;
        },

        render: function( html ) {
            var fields = html || '';

            $(this.el).html( _.template( this.tpl, {
                fields: fields
            }));

            this.postRender();

            return this;
        },

        postRender: function() {
            var $container = $(this.el);

            this.$form = $container.find('form');
            this.$errors = $container.find('.submission-error');
        },

        buildForm: function( data ) {
            var html = [],
                i,
                len = data.length,
                fieldTpl = this.fieldTpl;

            this.fields = data;

            for ( i=0; i<len; i++ ) {
                if ( data[i].errorMessages ) {
                    data[i].errorMessages = this.escapeStrings( data[i].errorMessages );
                }

                html.push( _.template( fieldTpl, $.extend( data[i], {
                    form: this.formType,
                    requiredStr: this.requiredStr
                }) ) );
            }

            this.render( html.join('') );
        },

        /* Helper method to toggle display
         * including accessibility considerations
         */
        element: {
            hide: function( $el ) {
                if ( $el ) {
                    $el.addClass('hidden')
                       .attr('aria-hidden', true);
                }
            },

            show: function( $el ) {
                if ( $el ) {
                    $el.removeClass('hidden')
                       .attr('aria-hidden', false);
                }
            }
        },

        escapeStrings: function( obj ) {
            _.each( obj, function( val, key ) {
                obj[key] = _.escape( val );
            });

            return obj;
        },

        forgotPassword: function( event ) {
            event.preventDefault();

            this.trigger('password-help');
        },

        getFormData: function() {

            var obj = {},
                $form = this.$form,
                elements = $form[0].elements,
                i,
                len = elements.length,
                $el,
                $label,
                key = '',
                errors = [],
                test = {};

            for ( i=0; i<len; i++ ) {

                $el = $( elements[i] );
                $label = $form.find('label[for=' + $el.attr('id') + ']');
                key = $el.attr('name') || false;

                if ( key ) {
                    test = this.validate( elements[i] );
                    if ( test.isValid ) {
                        obj[key] = $el.attr('type') === 'checkbox' ? $el.is(':checked') : $el.val();
                        $el.removeClass('error');
                        $label.removeClass('error');
                    } else {
                        errors.push( test.message );
                        $el.addClass('error');
                        $label.addClass('error');
                    }
                }
            }

            this.errors = _.uniq( errors );

            return obj;
        },

        saveError: function( error ) {
            this.errors = ['<li>' + error.responseText + '</li>'];
            this.setErrors();
        },

        setErrors: function() {
            var $msg = this.$errors.find('.message-copy'),
                html = [],
                errors = this.errors,
                i,
                len = errors.length;

            for ( i=0; i<len; i++ ) {
                html.push( errors[i] );
            }

            $msg.html( html.join('') );

            this.element.show( this.$errors );
        },

        submitForm: function( event ) {
            var data = this.getFormData();

            event.preventDefault();

            if ( !_.compact(this.errors).length ) {
                this.model.set( data );
                this.model.save();
                this.toggleErrorMsg( false );
            } else {
                this.toggleErrorMsg( true );
            }
        },

        toggleErrorMsg: function( show ) {
            if ( show ) {
                this.setErrors();
            } else {
                this.element.hide( this.$errors );
            }
        },

        validate: function( $el ) {
            return edx.utils.validate( $el );
        }
    });

})(jQuery, _, Backbone, gettext);
<commit_msg>Updated so is submission prevented by JS due to errors it scrolls to the error messages<commit_after>var edx = edx || {};

(function($, _, Backbone, gettext) {
    'use strict';

    edx.student = edx.student || {};
    edx.student.account = edx.student.account || {};

    edx.student.account.FormView = Backbone.View.extend({
        tagName: 'form',

        el: '',

        tpl: '',

        fieldTpl: '#form_field-tpl',

        events: {},

        errors: [],

        formType: '',

        $form: {},

        fields: [],

        // String to append to required label fields
        requiredStr: '*',

        initialize: function( data ) {
            this.model = data.model;
            this.preRender( data );

            this.tpl = $(this.tpl).html();
            this.fieldTpl = $(this.fieldTpl).html();
            this.buildForm( data.fields );

            this.listenTo( this.model, 'error', this.saveError );
        },

        /* Allows extended views to add custom
         * init steps without needing to repeat
         * default init steps
         */
        preRender: function( data ) {
            /* Custom code goes here */
            return data;
        },

        render: function( html ) {
            var fields = html || '';

            $(this.el).html( _.template( this.tpl, {
                fields: fields
            }));

            this.postRender();

            return this;
        },

        postRender: function() {
            var $container = $(this.el);

            this.$form = $container.find('form');
            this.$errors = $container.find('.submission-error');
        },

        buildForm: function( data ) {
            var html = [],
                i,
                len = data.length,
                fieldTpl = this.fieldTpl;

            this.fields = data;

            for ( i=0; i<len; i++ ) {
                if ( data[i].errorMessages ) {
                    data[i].errorMessages = this.escapeStrings( data[i].errorMessages );
                }

                html.push( _.template( fieldTpl, $.extend( data[i], {
                    form: this.formType,
                    requiredStr: this.requiredStr
                }) ) );
            }

            this.render( html.join('') );
        },

        /* Helper method to toggle display
         * including accessibility considerations
         */
        element: {
            hide: function( $el ) {
                if ( $el ) {
                    $el.addClass('hidden')
                       .attr('aria-hidden', true);
                }
            },

            show: function( $el ) {
                if ( $el ) {
                    $el.removeClass('hidden')
                       .attr('aria-hidden', false);
                }
            }
        },

        escapeStrings: function( obj ) {
            _.each( obj, function( val, key ) {
                obj[key] = _.escape( val );
            });

            return obj;
        },

        forgotPassword: function( event ) {
            event.preventDefault();

            this.trigger('password-help');
        },

        getFormData: function() {

            var obj = {},
                $form = this.$form,
                elements = $form[0].elements,
                i,
                len = elements.length,
                $el,
                $label,
                key = '',
                errors = [],
                test = {};

            for ( i=0; i<len; i++ ) {

                $el = $( elements[i] );
                $label = $form.find('label[for=' + $el.attr('id') + ']');
                key = $el.attr('name') || false;

                if ( key ) {
                    test = this.validate( elements[i] );
                    if ( test.isValid ) {
                        obj[key] = $el.attr('type') === 'checkbox' ? $el.is(':checked') : $el.val();
                        $el.removeClass('error');
                        $label.removeClass('error');
                    } else {
                        errors.push( test.message );
                        $el.addClass('error');
                        $label.addClass('error');
                    }
                }
            }

            this.errors = _.uniq( errors );

            return obj;
        },

        saveError: function( error ) {
            this.errors = ['<li>' + error.responseText + '</li>'];
            this.setErrors();
        },

        setErrors: function() {
            var $msg = this.$errors.find('.message-copy'),
                html = [],
                errors = this.errors,
                i,
                len = errors.length;

            for ( i=0; i<len; i++ ) {
                html.push( errors[i] );
            }

            $msg.html( html.join('') );

            this.element.show( this.$errors );

            // Scroll to error messages
            $('html,body').animate({
                scrollTop: this.$errors.offset().top
            },'slow');
        },

        submitForm: function( event ) {
            var data = this.getFormData();

            event.preventDefault();

            if ( !_.compact(this.errors).length ) {
                this.model.set( data );
                this.model.save();
                this.toggleErrorMsg( false );
            } else {
                this.toggleErrorMsg( true );
            }
        },

        toggleErrorMsg: function( show ) {
            if ( show ) {
                this.setErrors();
            } else {
                this.element.hide( this.$errors );
            }
        },

        validate: function( $el ) {
            return edx.utils.validate( $el );
        }
    });

})(jQuery, _, Backbone, gettext);

{'fraction_non_alphanumeric': 0.13777777777777778, 'fraction_numerical': 0.0007111111111111111, 'mean_word_length': 1.0943782576321668, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 7, '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': '4547346', 'n_tokens_mistral': 3025, 'n_tokens_neox': 2825, 'n_words': 599}