BB: Validation Plugin

by kyllle

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.validation/0.11.5/backbone-validation.js"></script>
<h1>Backbone Validation Ref</h1>

<script type="text/template" class="tmpl-person">
    <form action="" class="form-fields">
        <div>
            <label>Name</label>
            <input type="text" class="text-input" name="name" />
            <span class="feedback"></span>
            <ul class="error">This is a required field</ul>
        </div>
        <div>
            <label>Age</label>
            <input type="text" class="text-input" name="age" />
            <span class="feedback"></span>
            <ul class="error">This is a required field</ul>
        </div>
        <div>
            <label>Address</label>
            <input type="text" class="text-input" name="address" />
            <span class="feedback"></span>
            <ul class="error">This is a required field</ul>
        </div>
    </form>
    <br>
    <button class="btn  js-action--validate-all">Validate All - ['name', 'age', 'address']</button>
    <button class="btn  js-action--validate-keys">Validate keys - ['name', 'age']</button>
    <button class="btn  js-action--validate-key">Validate keys - ['address']</button>
</script>

SCSS

@import url(http://fonts.googleapis.com/css?family=Roboto:300,400,500);

* {
  -webkit-font-smoothing: antialiased;
  box-sizing: border-box;
}

body {
    font-family: Roboto;
    padding: 16px;
    line-height: 1.5;
    font-weight: normal;
    color: #ccc;
    background: #292929;
    font-size: 18px;
}

h1, h2, h3 {
    font-weight: normal;
}

.pg-heading {
    margin-bottom: 0;
}

h1 {
	margin-bottom: 20px;
	font-size: 28px;
}

a {
    color: #95baf6;
    transition: opacity .3s;
}

a:hover {
    opacity: 0.75;
}

div {
	margin-bottom: 8px;
}

input,
button{
    border: none;
    height: 40px;
    outline: none;
    padding: 0 8px;
}

button {
	margin-right: 8px;
  margin-bottom: 8px;
	height: 50px;
}

input {
	width: 100%;
}

label {
	display: block;
}

button {
    padding: 0 16px;
    background: #2196F3;
    color: white;
    transition: background .3s;
		font-size: 18px;
		border-radius: 4px;
}

button:hover {
    background: #1E88E5;
}

button:active {
    background: #1976D2;
}

input[type=text] {
    transition: border-color .3s;
    border: 1px solid white;    
}

input ~ .error {
    color: red;
		display: none;
}

input.invalid ~ .error {
	display: block;
}

Babel + JSX

console.clear();

const Model = Backbone.Model.extend({

	validation: {
  	name: [{
    	required: true,
			minLength: 3,
			msg: 'Name must be at least 3 characters long'
    }, {
			required: true,
			maxLength: 20,
			msg: 'Name can be no longer than 20 characters long'
		}, {
			required: true,
			msg: 'Name already exists',
			fn: 'checkForDuplicateName'
		}],
    age: {
      range: [1, 80],
      msg: 'Age must be between 1 and 80',
      required: true
    },
    address: [{
    	minLength: 1,
    	msg: 'Address too short',
      required: false
    },{
    	maxLength: 5,
    	msg: 'Address too long',
      required: false
    	}]
  },
	
  //loop though personsCollection, returns error if name exists already
  checkForDuplicateName(name) {
  	if (newCollection.findWhere({'name': name})){return 'error'}
	}
  
});

const Collection = Backbone.Collection.extend({});

const View = Backbone.View.extend({

	template: Handlebars.compile( $('.tmpl-person').html() ),
	className: 'view',
	
  events: {
		'click .js-action--validate-keys': 'actionValidateKeysClicked',
		'click .js-action--validate-key': 'actionValidateKeyClicked',
 		'click .js-action--validate-all': 'actionValidateAllClicked',
	},
	
	initialize() {
		Backbone.Validation.bind(this);

		this.listenTo(this.model, {
			'validated': this.onModelValidated,
			'validated:valid': this.onModelValid,
			'validated:invalid': this.onModelInvalid,
			'invalid': this.onInvalid
		});
    
	},
	
	render() {
		this.$el.html(this.template(this.model.toJSON()));
		return this;
	},
    
  //validates ALL input using boolean:true as an arg
  actionValidateAllClicked(event) {
  	event.preventDefault();
  	var keys = true;
  	this.actionValidateKeysClickedMain(keys);
  },
 	
  //only validates NAME and AGE by calling actionValidateKeysClickedMain with those args (as array)
  actionValidateKeysClicked(event) {
  	event.preventDefault();
    var keys = ['name', 'age'];
  	this.actionValidateKeysClickedMain(keys);
  },
  
 ...