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

app.views = app.views || {};
app.views.utility = app.views.utility || {};

app.views.utility.Form = (function() {

	'use strict';

	return app.abstracts.BaseView.extend({

		// A template is required to display anything.
		template: null,

		events: {
			'change :input': 'process',
			'submit form': 'process',
			'click .form-field-action': 'onFormFieldAction',
		},

		inputs: [],

		initialize: function() {

			_.bindAll(this, 'process');
			this.process = _.throttle(this.process, 500, { leading: false });
			this.prepareInputs();
		},

		prepareInputs: function() {

			var inputs = _.result(this, 'inputs') || [];
			this.inputs = _.map(inputs, this.prepareInput, this);
		},

		prepareInput: function(input) {

			input = _.clone(input);
			input.id = input.id || input.name;
			var value = this.getInputValueOverride(input.name);
			if (!_.isUndefined(value)) {
				input.value = value;
			} else if (input.value) {
				input.value = _.result(input, 'value');
			} else {
				input.value = input.default;
			}
			switch (input.type) {
				case 'select':
					input.options = _.result(input, 'options') || [];
					input.options = _.map(input.options, function(option) {
						return {
							key: option.key,
							label: _.result(option, 'label'),
							selected: input.value === option.key,
						};
					});
					break;
			}
			input.visible = input.visible !== false;
			return input;
		},

		serializeData: function() {

			var data = app.abstracts.BaseView.prototype.serializeData.apply(this, arguments);
			data.inputs = this.inputs;
			return data;
		},

		onFormFieldAction: function(evt) {

			var $target = $(evt.target);
			var name = $target.attr('data-input');
			if (!name) return;
			var input = this.getInputByName(name);
			if (!input) return;
			var action = _.findWhere(input.actions || [], { name: $target.attr('data-action') });
			if (!action || !action.fn) return;
			var fn = _.bind(action.fn, this);
			var formData = this.getFormData();
			var value = formData[name];
			var $input = this.$(':input[name="' + name + '"]');

			fn(value, function(error, newValue) {

				if (error) {
					return app.mainView.showMessage(error);
				}

				if (newValue) {
					$input.val(newValue).trigger('change');
				}
			});
		},

		showErrors: function(validationErrors) {

			if (!_.isEmpty(validationErrors)) {
				_.each(validationErrors, function(validationError) {
					var $field = this.$(':input[name="' + validationError.field + '"]');
					var $row = $field.parents('.form-row').first();
					var $error = $row.find('.form-error');
					$field.addClass('error');
					$error.append($('<div/>', {
						class: 'form-error-message',
						text: validationError.error,
					}));
				}, this);
			}
		},

		clearErrors: function() {

			this.$('.form-error-message').remove();
			this.$('.form-row.error').removeClass('error');
			this.$(':input.error').removeClass('error');
		},

		getFormData: function() {

			return this.$('form').serializeJSON();
		},

		allRequiredFieldsFilledIn: function() {

			var formData = this.getFormData();
			return _.every(this.inputs, function(input) {
				return input.required !== true || !!formData[input.name];
			});
		},

		process: function(evt) {

			if (evt && evt.preventDefault) {
				evt.preventDefault();
			}

			this.clearErrors();

			var data = this.getFormData();

			// Set defaults.
			_.each(this.inputs, function(input) {
				if (_.isUndefined(data[input.name]) && !_.isUndefined(input.default)) {
					data[input.name] = input.default;
				}
			});

			this.validate(data, _.bind(function(error, validationErrors) {

				if (error) {
					return app.mainView.showMessage(error);<commit_msg>Provide missing form data during processing.<commit_after>var app = app || {};

app.views = app.views || {};
app.views.utility = app.views.utility || {};

app.views.utility.Form = (function() {

	'use strict';

	return app.abstracts.BaseView.extend({

		// A template is required to display anything.
		template: null,

		events: {
			'change :input': 'process',
			'submit form': 'process',
			'click .form-field-action': 'onFormFieldAction',
		},

		inputs: [],

		initialize: function() {

			_.bindAll(this, 'process');
			this.process = _.throttle(this.process, 500, { leading: false });
			this.prepareInputs();
		},

		prepareInputs: function() {

			var inputs = _.result(this, 'inputs') || [];
			this.inputs = _.map(inputs, this.prepareInput, this);
		},

		prepareInput: function(input) {

			input = _.clone(input);
			input.id = input.id || input.name;
			var value = this.getInputValueOverride(input.name);
			if (!_.isUndefined(value)) {
				input.value = value;
			} else if (input.value) {
				input.value = _.result(input, 'value');
			} else {
				input.value = input.default;
			}
			switch (input.type) {
				case 'select':
					input.options = _.result(input, 'options') || [];
					input.options = _.map(input.options, function(option) {
						return {
							key: option.key,
							label: _.result(option, 'label'),
							selected: input.value === option.key,
						};
					});
					break;
			}
			input.visible = input.visible !== false;
			return input;
		},

		serializeData: function() {

			var data = app.abstracts.BaseView.prototype.serializeData.apply(this, arguments);
			data.inputs = this.inputs;
			return data;
		},

		onFormFieldAction: function(evt) {

			var $target = $(evt.target);
			var name = $target.attr('data-input');
			if (!name) return;
			var input = this.getInputByName(name);
			if (!input) return;
			var action = _.findWhere(input.actions || [], { name: $target.attr('data-action') });
			if (!action || !action.fn) return;
			var fn = _.bind(action.fn, this);
			var formData = this.getFormData();
			var value = formData[name];
			var $input = this.$(':input[name="' + name + '"]');

			fn(value, function(error, newValue) {

				if (error) {
					return app.mainView.showMessage(error);
				}

				if (newValue) {
					$input.val(newValue).trigger('change');
				}
			});
		},

		showErrors: function(validationErrors) {

			if (!_.isEmpty(validationErrors)) {
				_.each(validationErrors, function(validationError) {
					var $field = this.$(':input[name="' + validationError.field + '"]');
					var $row = $field.parents('.form-row').first();
					var $error = $row.find('.form-error');
					$field.addClass('error');
					$error.append($('<div/>', {
						class: 'form-error-message',
						text: validationError.error,
					}));
				}, this);
			}
		},

		clearErrors: function() {

			this.$('.form-error-message').remove();
			this.$('.form-row.error').removeClass('error');
			this.$(':input.error').removeClass('error');
		},

		getFormData: function() {

			return this.$('form').serializeJSON();
		},

		allRequiredFieldsFilledIn: function() {

			var formData = this.getFormData();
			return _.every(this.inputs, function(input) {
				return input.required !== true || !!formData[input.name];
			});
		},

		process: function(evt) {

			if (evt && evt.preventDefault) {
				evt.preventDefault();
			}

			this.clearErrors();

			var data = this.getFormData();

			// Add missing data from inputs.
			_.each(this.inputs, function(input) {
				if (_.isUndefined(data[input.name]) && !_.isUndefined(input.value)) {
					data[input.name] = input.value;
				}
			});

			this.validate(data, _.bind(function(error, validationErrors) {

				if (error) {
					return app.mainView.showMessage(error);
{'fraction_non_alphanumeric': 0.18161165308031538, 'fraction_numerical': 0.0008018174528932247, 'mean_word_length': 3.1393805309734515, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '2231989', 'n_tokens_mistral': 2984, 'n_tokens_neox': 2401, 'n_words': 469}