Merge pull request #89 from Dahlgren/feature/remove-marionette-formview

Remove marionette formview library
This commit is contained in:
Björn Dahlgren 2017-10-06 00:13:22 +02:00 committed by GitHub
commit 01a9151c36
14 changed files with 46 additions and 390 deletions

View File

@ -1,39 +0,0 @@
define(function (require) {
"use strict";
var $ = require('jquery'),
_ = require('underscore'),
Backbone = require('backbone'),
Marionette = require('marionette'),
FormView = require('marionette-formview'),
Settings = require('app/models/settings'),
tpl = require('text!tpl/forms/settings.html');
return FormView.extend({
template: _.template(tpl),
fields: {
path: {
el: ".path",
required: "Please enter a valid path.",
validations: {
email: "Please enter a valid path."
}
},
type: {
el: ".type",
required: "Please choose a valid type."
},
},
initialize: function () {
var self = this;
new Settings().fetch({success: function (model, response, options) {
self.model = model;
self.runInitializers();
}});
}
});
});

View File

@ -9,7 +9,7 @@ define(function (require) {
return Backbone.Model.extend({
defaults: {
path: '',
type: 'windows',
type: '',
},
urlRoot : '/api/settings'
});

View File

@ -6,7 +6,6 @@ define(function (require) {
_ = require('underscore'),
Backbone = require('backbone'),
Marionette = require('marionette'),
FormView = require('marionette-formview'),
Ladda = require('ladda'),
IframeTransport = require('jquery.iframe-transport'),
Mission = require('app/models/mission'),

View File

@ -6,7 +6,6 @@ define(function (require) {
_ = require('underscore'),
Backbone = require('backbone'),
Marionette = require('marionette'),
FormView = require('marionette-formview'),
Ladda = require('ladda'),
IframeTransport = require('jquery.iframe-transport'),
Mission = require('app/models/mission'),

View File

@ -6,7 +6,6 @@ define(function (require) {
_ = require('underscore'),
Backbone = require('backbone'),
Marionette = require('marionette'),
FormView = require('marionette-formview'),
ListItemView = require('app/views/mods/search/list_item'),
Ladda = require('ladda'),
Mods = require('app/collections/mods'),

View File

@ -8,7 +8,7 @@ define(function (require) {
Marionette = require('marionette'),
BootstrapModal = require('backbone.bootstrap-modal'),
ServersListView = require('app/views/navigation/servers/list'),
SettingsView = require('app/forms/settings'),
SettingsView = require('app/views/settings'),
tpl = require('text!tpl/navigation.html');
return Marionette.ItemView.extend({

View File

@ -6,7 +6,6 @@ define(function (require) {
_ = require('underscore'),
Backbone = require('backbone'),
Marionette = require('marionette'),
FormView = require('marionette-formview'),
tpl = require('text!tpl/servers/form.html');
return Marionette.ItemView.extend({

View File

@ -0,0 +1,31 @@
define(function (require) {
"use strict";
var $ = require('jquery'),
_ = require('underscore'),
Backbone = require('backbone'),
Marionette = require('marionette'),
Settings = require('app/models/settings'),
tpl = require('text!tpl/settings.html');
return Marionette.ItemView.extend({
template: _.template(tpl),
modelEvents: {
'change': 'render',
},
initialize: function () {
this.model = new Settings()
this.model.fetch();
},
templateHelpers: {
isTypeChecked: function(type) {
return this.type === type ? 'checked' : '';
},
},
});
});

View File

@ -1,330 +0,0 @@
/*! marionette-formview - v1.0.1 - 2014-01-27 */
/*global Backbone,define*/
;(function (root, factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['marionette','jquery','underscore'], factory);
} else {
// Browser globals
root.Marionette.FormView = factory(root.Marionette,root.jQuery,root._);
}
}(this, function (Marionette,$,_) {
"use strict";
/**
* FormView Extension of Backbone.Marionette.ItemView
*
* @param {Object} options Options defining this FormView
* @param {Object} [options.data] Form Data. (Required if options.model is not set)
* @param {Object} [options.fields] Which Fields to include
*
*/
var FormView = Marionette.FormView = Marionette.ItemView.extend({
className : "formView",
rules : {}, //Custom Field Validation Rules
fields : {},
constructor : function(){
Marionette.ItemView.prototype.constructor.apply(this, arguments);
//Allow Passing In Fields by extending with a fields hash
if (!this.fields) throw new Error("Fields Must Be Provided");
if (!this.model) this.model = new Backbone.Model();
this.listenTo(this.model, 'change', this.changeFieldVal,this);
if (this.data) this.model.set(this.data);
//Attach Events to preexisting elements if we don't have a template
if (!this.template) this.runInitializers();
this.on('item:rendered',this.runInitializers, this);
},
changeFieldVal : function(model, fields) {
if(!_.isEmpty(fields) && fields.changes) {
var modelProperty = Object.keys(fields.changes);
this.inputVal(modelProperty, this.model.get(modelProperty));
} else if (fields.unset) {
_(this.fields).each(function(options, field) {
var elem = this.$('[data-field="'+field+'"]');
this.inputVal(elem, this.model.get(field));
},this);
}
},
populateFields : function () {
_(this.fields).each(function(options, field) {
var elem = this.$('[data-field="'+field+'"]');
this.inputVal(elem, this.model.get(field));
if (options.autoFocus) elem.focus();
},this);
},
serializeFormData : function () {
var data = {}, self = this;
_(this.fields).each(function(options, field){
data[field] = self.inputVal(field);
});
return data;
},
beforeFormSubmit : function (e) {
var errors = this.validate();
var success = _.isEmpty(errors);
if (success) {
if (_.isFunction(this.onSubmit)) return this.onSubmit.apply(this, [e]);
} else {
if (_.isFunction(this.onSubmitFail)) this.onSubmitFail.apply(this, [errors]);
e.stopImmediatePropagation();
return false;
}
},
onFieldEvent : function(evt) {
this.handleFieldEvent(evt, evt.type);
},
handleFieldEvent : function(evt, eventName) {
var el = evt.target || evt.srcElement,
field = $(el).attr('data-field'),
fieldOptions = this.fields[field];
if (fieldOptions && fieldOptions.validateOn === eventName) {
var errors = this.validateField(field);
if (!_.isEmpty(errors) && _.isFunction(this.onValidationFail)) this.onValidationFail(errors);
}
},
validate : function () {
var errors = {},
fields = _(this.fields).keys();
_(fields).each(function (field) {
var fieldErrors = this.validateField(field);
if (!_.isEmpty(fieldErrors)) errors[field] = fieldErrors;
},this);
return errors;
},
validateField : function(field) {
var fieldOptions = this.fields[field],
validations = fieldOptions && fieldOptions.validations ? fieldOptions.validations : {},
fieldErrors = [],
isValid = true;
var val = this.inputVal(field);
if (fieldOptions.required) {
isValid = this.validateRule(val,'required');
var errorMessage = typeof fieldOptions.required === 'string' ? fieldOptions.required : 'This field is required';
if (!isValid) fieldErrors.push(errorMessage);
}
// Don't bother with other validations if failed 'required' already
if (isValid && validations) {
_.each(validations, function (errorMsg, validateWith) {
isValid = this.validateRule(val, validateWith);
if (!isValid) fieldErrors.push(errorMsg);
},this);
}
if (!_.isEmpty(fieldErrors)) {
var errorObject = {
field : field,
el : this.fields[field].el,
error : fieldErrors
};
return errorObject;
}
},
inputVal : function(input, val) {
//takes field name or jQuery object
var el = input.jquery ? input : this.$('[data-field="'+input+'"]');
var self = this, mode = typeof val === 'undefined' ? 'get' : 'set';
if (el.data('fieldtype') === 'object'){
if (mode === 'get') val = {};
el.find('[data-property]').each(function(){
var elem = $(this);
var prop = elem.attr('data-property');
if (mode === 'get'){
val[prop] = self.inputVal(elem);
} else if (val){
self.inputVal(elem, val[prop]);
}
});
} else if (el.data('fieldtype') === 'array'){
if (mode === 'get') val = [];
el.find('[data-index]').each(function(){
var elem = $(this);
var index = elem.data('index');
if (mode === 'get'){
val[index] = self.inputVal(elem);
} else if (val){
self.inputVal(elem, val[index]);
}
});
} else if (el.is('input')) {
var inputType = el.attr('type').toLowerCase();
switch (inputType) {
case "radio":
el.each(function(){
var radio = $(this);
if (mode === 'get'){
if (radio.is(':checked')){
val = radio.val();
return false;
}
} else {
if (radio.val() === val){
radio.prop('checked', true);
return false;
}
}
});
break;
case "checkbox":
if (mode === 'get'){
val = el.is(':checked');
} else {
el.prop('checked', !!val);
}
break;
case "password":
if (mode === 'get'){
val = el.val();
} else {
el.val(val);
}
break;
default :
if (mode === 'get'){
val = $.trim(el.val());
} else {
el.val(val);
}
break;
}
} else {
if (mode === 'get'){
val = $.trim(el.val());
} else {
el.val(val);
}
//Handle Select / MultiSelect Etc
//@todo
}
return val;
},
validateRule : function (val,validationRule) {
var options;
// throw an error because it could be tough to troubleshoot if we just return false
if (!validationRule) throw new Error('Not passed a validation to test');
if (validationRule === 'required') return FormValidator.required(val);
if (validationRule.indexOf(':') !== -1) {
options = validationRule.split(":");
validationRule = options.shift();
}
if (this.rules && this.rules[validationRule]) {
return _(this.rules[validationRule]).bind(this)(val);
} else {
return _(FormValidator.validate).bind(this)(validationRule, val, options);
}
return true;
},
submit : function () {
this.form.submit();
},
bindFormEvents : function() {
var form = (this.$el.is('form')) ? this.$el : this.$('form').first();
this.form = form;
this.$('input')
.blur(_(this.onFieldEvent).bind(this))
.keyup(_(this.onFieldEvent).bind(this))
.keydown(_(this.onFieldEvent).bind(this))
.change(_(this.onFieldEvent).bind(this));
form.submit(_(this.beforeFormSubmit).bind(this));
},
runInitializers : function() {
this.populateFields();
this.bindFormEvents();
if (_.isFunction(this.onReady)) this.onReady();
}
});
var FormValidator = {
regex : {
//RFC 2822
email : /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i,
alpha : /^[a-zA-Z]+$/,
alphanum : /^[a-zA-Z0-9]+$/
},
validate : function(validator, val, options) {
if (_.isFunction(FormValidator[validator])) return _(FormValidator[validator]).bind(this)(val,options);
throw new Error('Validator does not exist : ' + validator);
},
matches : function(val,field) {
/*jshint eqeqeq:false*/
return val == this.inputVal(field);
},
min : function(val,minLength) {
if (val.length < minLength) return false;
return true;
},
max : function(val, maxLength) {
if (val.length > maxLength) return false;
return true;
},
numeric : function(val) {
return _.isNumber(val);
},
alpha : function(val) {
return FormValidator.regex.alpha.test(val);
},
alphanum : function (val) {
return FormValidator.regex.alphanum.test(val);
},
email : function(val) {
return FormValidator.regex.email.test(val);
},
required : function(val) {
if (val === false || _.isNull(val) || _.isUndefined(val) || (_.isString(val) && val.length === 0)) return false;
return true;
},
boolean : function(val) {
return _.isBoolean(val);
}
};
return FormView;
}));

View File

@ -7,7 +7,6 @@
class="form-control path"
name="missions"
id="missions"
data-field="missions"
>
<span class="help-block">Only supports missions packed as a PBO</span>
</div>

View File

@ -1,7 +1,7 @@
<form class="form" role="form" enctype="multipart/form-data">
<div class="form-group">
<label for="workshop" class="control-label">Steam Workshop ID</label>
<input type="number" class="form-control workshop" name="workshop" id="workshop" data-field="workshop">
<input type="number" class="form-control workshop" name="workshop" id="workshop">
<span class="help-block">
ID can be found in the URL of Workshop i.e.
<i>https://steamcommunity.com/workshop/filedetails/?id=$id</i>

View File

@ -5,7 +5,7 @@
<form class="form" role="form" action="/api/mods" method="POST">
<div class="form-group">
<label for="query" class="control-label">Search</label>
<input type="text" class="form-control query" name="query" id="query" data-field="query">
<input type="text" class="form-control query" name="query" id="query">
<span class="help-block"></span>
</div>
</form>

View File

@ -2,14 +2,14 @@
<div class="form-group">
<label for="title" class="col-sm-2 control-label">Title</label>
<div class="col-sm-10">
<input type="text" class="form-control title" data-field="title" placeholder="Title" value="<%- title %>">
<input type="text" class="form-control title" placeholder="Title" value="<%- title %>">
</div>
</div>
<div class="form-group">
<label for="port" class="col-sm-2 control-label">Port</label>
<div class="col-sm-10">
<input type="number" class="form-control port" data-field="port" placeholder="Port" value="<%- port %>">
<input type="number" class="form-control port" placeholder="Port" value="<%- port %>">
<p class="help-block">Server will use the designated port and the three following ports</p>
</div>
</div>
@ -17,21 +17,21 @@
<div class="form-group">
<label for="max-players" class="col-sm-2 control-label">Max Players</label>
<div class="col-sm-10">
<input type="number" class="form-control max-players" data-field="max-players" placeholder="Max Players" value="<%- max_players %>">
<input type="number" class="form-control max-players" placeholder="Max Players" value="<%- max_players %>">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="text" class="form-control password" data-field="password" placeholder="Password" value="<%- password %>">
<input type="text" class="form-control password" placeholder="Password" value="<%- password %>">
</div>
</div>
<div class="form-group">
<label for="admin-password" class="col-sm-2 control-label">Admin Password</label>
<div class="col-sm-10">
<input type="text" class="form-control admin-password" data-field="admin-password" placeholder="Admin Password" value="<%- admin_password %>">
<input type="text" class="form-control admin-password" placeholder="Admin Password" value="<%- admin_password %>">
</div>
</div>
@ -40,7 +40,6 @@
<div class="col-sm-10">
<textarea rows="3"
class="form-control motd"
data-field="motd"
placeholder="No MOTD will be shown"><%-motd %></textarea>
<p class="help-block">Message of the day. Shown to players when connected</p>
</div>
@ -49,7 +48,7 @@
<div class="form-group">
<label for="forcedDifficulty" class="col-sm-2 control-label">Difficulty</label>
<div class="col-sm-10">
<select class="form-control forcedDifficulty" data-field="forcedDifficulty" value="<%- (forcedDifficulty || '') %>">
<select class="form-control forcedDifficulty" value="<%- (forcedDifficulty || '') %>">
<%= ["", "Recruit", "Regular", "Veteran", "Custom"].map(function (difficulty) {
var selected = difficulty == forcedDifficulty ? 'selected' : '';
return '<option value="' + difficulty + '" ' + selected + '>' + (difficulty || 'Not set') + '</option>';
@ -81,7 +80,7 @@
<div class="form-group">
<label for="headless-clients" class="col-sm-2 control-label">Headless Clients</label>
<div class="col-sm-10">
<input type="number" class="form-control headless-clients" data-field="headless-clients" placeholder="Headless Clients" value="<%- number_of_headless_clients %>">
<input type="number" class="form-control headless-clients" placeholder="Headless Clients" value="<%- number_of_headless_clients %>">
<p class="help-block">Number of headless clients that will be launched</p>
</div>
</div>

View File

@ -2,7 +2,7 @@
<div class="form-group">
<label for="path" class="col-sm-2 control-label">Path</label>
<div class="col-sm-10">
<input type="text" class="form-control path" id="path" data-field="path" placeholder="Path to ArmA3" disabled>
<input type="text" class="form-control" placeholder="Path to ArmA" disabled value="<%- path %>">
</div>
</div>
@ -11,19 +11,19 @@
<div class="col-sm-10">
<div class="radio">
<label>
<input type="radio" name="type" data-field="type" id="type-linux" value="linux" disabled>
<input type="radio" name="type" value="linux" disabled <%- isTypeChecked('linux') %>>
Linux
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="type" data-field="type" id="type-windows" value="windows" disabled>
<input type="radio" name="type" value="windows" disabled <%- isTypeChecked('windows') %>>
Windows
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="type" data-field="type" id="type-wine" value="wine" disabled>
<input type="radio" name="type" value="wine" disabled <%- isTypeChecked('wine') %>>
Wine
</label>
</div>