Skip to content

Instantly share code, notes, and snippets.

@laughingman7743
Last active August 29, 2015 14:23
Show Gist options
  • Save laughingman7743/7ebf6181ab13a02951c0 to your computer and use it in GitHub Desktop.
Save laughingman7743/7ebf6181ab13a02951c0 to your computer and use it in GitHub Desktop.
@import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css');
.badge-danger { background-color: #d9534f !important; }
<div class="container">
<form class="form-horizontal">
<h1>Form</h1>
<ul class="nav nav-tabs" style="margin-bottom: 15px;">
<li role="presentation" class="active"><a href="#tab1" data-bind="click: clickTab1">Tab1 <span class="badge badge-danger" data-bind="errorCount: tab1.errors().length"></span></a></li>
<li role="presentation"><a href="#tab2" data-bind="click: clickTab2">Tab2 <span class="badge badge-danger" data-bind="errorCount: tab2.errors().length"></span></a></li>
<li role="presentation"><a href="#tab3" data-bind="click: clickTab3">Tab3 <span class="badge badge-danger" data-bind="errorCount: tab3.errors().length">4</span></a></li>
<li role="presentation" class="pull-right">
All Erros <span class="badge badge-danger" data-bind="errorCount: allTabErrors"></span>
</li>
</ul>
<div class="tab-content">
<!-- ko with: tab1 -->
<div role="tabpanel" class="tab-pane active" id="tab1">
<div class="form-group">
<label class="col-sm-2 control-label" for="inputEmail">Email</label>
<div class="col-sm-10" data-bind="validationElement: email">
<input type="text" id="inputEmail" class="form-control" placeholder="Email" data-bind="textinput: email"/>
<p class="text-danger" data-bind="validationMessage: email"></p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="inputPassword">Password</label>
<div class="col-sm-10" data-bind="validationElement: password">
<input type="password" id="inputPassword" class="form-control" placeholder="Password" data-bind="textinput: password"/>
<p class="text-danger" data-bind="validationMessage: password"></p>
</div>
</div>
</div>
<!-- /ko -->
<!-- ko with: tab2 -->
<div role="tabpanel" class="tab-pane" id="tab2">
<div class="form-group">
<label class="col-sm-2 control-label" for="input1">Input1</label>
<div class="col-sm-10" data-bind="validationElement: input1">
<input type="text" id="input1" class="form-control" placeholder="input1" data-bind="value: input1"/>
<p class="text-danger" data-bind="validationMessage: input1"></p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="input2">Input2</label>
<div class="col-sm-10" data-bind="validationElement: input2">
<input type="text" id="input2" class="form-control" placeholder="input2" data-bind="value: input2"/>
<p class="text-danger" data-bind="validationMessage: input2"></p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="input3">Input3</label>
<div class="col-sm-10" data-bind="validationElement: input3">
<input type="text" id="input3" class="form-control" placeholder="input3" data-bind="value: input3"/>
<p class="text-danger" data-bind="validationMessage: input3"></p>
</div>
</div>
</div>
<!-- /ko -->
<!-- ko with: tab3 -->
<div role="tabpanel" class="tab-pane" id="tab3">
<div class="form-group">
<label class="col-sm-2 control-label">Range</label>
<div class="col-sm-2" data-bind="validationElement: rangeMin">
<input type="text" id="inputRangeMin" class="form-control" placeholder="min" data-bind="textinput: rangeMin"/>
<p class="text-danger" data-bind="validationMessage: rangeMin"></p>
</div>
<span class="pull-left">
</span>
<div class="col-sm-2" data-bind="validationElement: rangeMax">
<input type="text" id="inputRangeMax" class="form-control" placeholder="max" data-bind="textinput: rangeMax"/>
<p class="text-danger" data-bind="validationMessage: rangeMax"></p>
</div>
</div>
</div>
<!-- /ko -->
</div>
<div class="form-group well well-lg" >
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary" data-bind="enable: allTabErrors() == 0">Submit</button>
<button type="button" class="btn">Cancel</button>
</div>
</div>
</form>
</div>
$(function() {
ko.bindingHandlers['errorCount'] = {
init: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var value = ko.utils.unwrapObservable(valueAccessor());
if(value == 0){
$(element).removeClass('badge-danger').text('OK');
} else {
$(element).addClass('badge-danger').text(value);
}
}
};
ko.validation.rules['rangeMinMax'] = {
validator: function (val, params) {
var min = ko.validation.utils.getValue(params[0]);
var max = ko.validation.utils.getValue(params[1]);
if (!ko.validation.utils.isEmptyVal(min) &&
!ko.validation.utils.isEmptyVal(max) &&
ko.validation.utils.isNumber(min) &&
ko.validation.utils.isNumber(max)) {
return parseInt(min, 10) < parseInt(max, 10);
} else {
return true;
}
},
message: 'message'
};
ko.validation.registerExtenders();
function tab1ViewModel() {
var self = this;
self.email = ko.observable().extend({
required: {
message: 'required'
},
email: {
message: 'invalid format'
}
});
self.password = ko.observable().extend({
required: {
message: 'required'
},
minLength: {
params: 6,
message: 'too short'
}
});
}
function tab2ViewModel() {
var self = this;
self.input1 = ko.observable();
self.input2 = ko.observable();
self.input3 = ko.observable();
self.hasValue = ko.computed(function() {
return (self.input1() || self.input2() || self.input3());
});
self.input1.extend({
required: {
message: 'required',
onlyIf: function () {
if (self.hasValue()) {
return true;
}
return false;
}
}
});
self.input2.extend({
required: {
message: 'required',
onlyIf: function () {
if (self.hasValue()) {
return true;
}
return false;
}
}
});
self.input3.extend({
required: {
message: 'required',
onlyIf: function () {
if (self.hasValue()) {
return true;
}
return false;
}
}
});
}
function tab3ViewModel() {
var self = this;
self.rangeMin = ko.observable();
self.rangeMax = ko.observable();
self.rangeMin.extend({
number: {
message: "invalid format"
},
rangeMinMax: {
params: [self.rangeMin, self.rangeMax],
message: "invalid range"
}
});
self.rangeMax.extend({
number: {
message: "invalid format"
},
rangeMinMax: {
params: [self.rangeMin, self.rangeMax],
message: "invalid range"
}
});
}
function myViewModel() {
var self = this;
self.tab1 = ko.validatedObservable(new tab1ViewModel());
self.tab2 = ko.validatedObservable(new tab2ViewModel());
self.tab3 = ko.validatedObservable(new tab3ViewModel());
self.allTabErrors = ko.computed(function() {
return parseInt(self.tab1.errors().length, 10) +
parseInt(self.tab2.errors().length, 10) +
parseInt(self.tab3.errors().length, 10);
}, self);
self.clickTab1 = function(data, event) {
event.preventDefault()
$(event.target).tab('show')
}
self.clickTab2 = function(data, event) {
event.preventDefault()
$(event.target).tab('show')
}
self.clickTab3 = function(data, event) {
event.preventDefault()
$(event.target).tab('show')
}
}
ko.validation.init({
insertMessages: false,
messagesOnModified: false,
decorateElement: true,
errorElementClass: 'has-error'
});
var viewModel = ko.validatedObservable(new myViewModel());
ko.applyBindings(viewModel);
})
name: KnockoutJS Validation Sample 7
authors:
- laughingman7743
resources:
- http://knockoutjs.com/downloads/knockout-3.3.0.js
- http://code.jquery.com/jquery-2.1.4.min.js
- http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js
- http://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.3/knockout.validation.min.js
normalize_css: no
wrap: b
panel_js: 0
panel_css: 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment