Skip to content

Commit

Permalink
Upgrading to can 3.0.
Browse files Browse the repository at this point in the history
Adding equality operator fix from #36.
  • Loading branch information
ccummings committed Oct 11, 2016
1 parent 6efc35b commit f2fd07c
Show file tree
Hide file tree
Showing 13 changed files with 107 additions and 83 deletions.
18 changes: 10 additions & 8 deletions can-validate/can-validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@
*
*/

import can from 'can';
import ns from 'can-util/namespace';
import Construct from 'can-construct';
import canDev from 'can-util/js/dev/';

// add methods to can
var Validate = can.Construct.extend({
var Validate = Construct.extend({

/*
* @description The current validator ID to use when can.validate methods are called.
Expand Down Expand Up @@ -96,7 +98,7 @@ var Validate = can.Construct.extend({
isValid: function () {
//!steal-remove-start
if (!this._validatorId) {
can.dev.warn('A validator library is required for can.validate to work properly.');
canDev.warn('A validator library is required for can.validate to work properly.');
}
//!steal-remove-end
return this.validator().isValid.apply(this, arguments);
Expand All @@ -118,7 +120,7 @@ var Validate = can.Construct.extend({
once: function () {
//!steal-remove-start
if (!this._validatorId) {
can.dev.warn('A validator library is required for can.validate to work properly.');
canDev.warn('A validator library is required for can.validate to work properly.');
}
//!steal-remove-end
return this.validator().once.apply(this, arguments);
Expand All @@ -139,16 +141,16 @@ var Validate = can.Construct.extend({
var validateArgs = arguments;
//!steal-remove-start
if (!this._validatorId) {
can.dev.warn('A validator library is required for can.validate to work properly.');
canDev.warn('A validator library is required for can.validate to work properly.');
}
if (typeof arguments[0] !== 'object') {
can.dev.warn('Attempting to pass single value to validate, use can.validator.once instead.');
canDev.warn('Attempting to pass single value to validate, use can.validator.once instead.');
}
//!steal-remove-end
return this.validator().validate.apply(this, validateArgs);
}
}, {});

can.validate = Validate;
ns.validate = Validate;

export default can;
export default Validate;
25 changes: 14 additions & 11 deletions can-validate/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</head>
<body>
<div id="app" class="container">
<script src="../../node_modules/steal/steal.js" main="can/view/autorender/"></script>
<script src="../../node_modules/steal/steal.js" main="can-view-autorender"></script>
<script type='text/stache' id="demo" can-autorender>
<h1>can.validate Demo</h1>

Expand All @@ -31,16 +31,16 @@ <h3 class="panel-title">Validation Test</h3>
<form>
<label for="test1">MyVal <span class="text-danger"></span></label>
<div class="input-group" {{data 'field' 'myVal'}}>
<input class="form-control" id="test1" type="text" can-value="myVal">
<input class="form-control" id="test1" type="text" {($value)}="myVal">
<span class="input-group-btn">
<button type="button" class="btn btn-default" can-click="validateField">Validate</button>
<button type="button" class="btn btn-default" ($click)="validateField">Validate</button>
</span>
</div>
<label for="test2">MyNum <span class="text-danger"></span></label>
<div class="input-group" {{data 'field' 'myNum'}}>
<input class="form-control" id="test2" type="text" can-value="myNum">
<input class="form-control" id="test2" type="text" {($value)}="myNum">
<span class="input-group-btn">
<button type="button" class="btn btn-default" can-click="validateField">Validate</button>
<button type="button" class="btn btn-default" ($click)="validateField">Validate</button>
</span>
</div>
</form>
Expand All @@ -50,7 +50,9 @@ <h3 class="panel-title">Validation Test</h3>
</script>
</div>
<script type='text/javascript'>
steal('can','can-validate/', 'can-validate/shims/validatejs.shim', function(can){
steal('jquery/dist/jquery.js', 'can-validate/', 'can-view-model', 'can-util/dom/data/', 'can-validate/shims/validatejs.shim', 'can-stache-bindings', function($, canValidate, setViewModel, domData){
window.getViewModel = setViewModel;
canValidate = canValidate.default;
var validations = {
myVal: {
required: true,
Expand All @@ -67,16 +69,17 @@ <h3 class="panel-title">Validation Test</h3>
}
};

can.$('#demo').viewModel({
setViewModel(document.getElementById('demo'), {
myVal: 'testing testing',
myNum: 100,
errors: [],
validateField: function (ctx, $el) {
validateField: function (ctx, el) {
var $el = $(el);
var $parent = $el.parents('.input-group'),
$label = can.$('label[for=' + $parent.find('.form-control').attr('id') + ']'),
val = $parent.data('field');
$label = $('label[for=' + $parent.find('.form-control').attr('id') + ']'),
val = domData.get.call($parent[0], 'field');

var errors = can.validate.once(this.attr(val), validations[val], 'myObjIsAwesome');
var errors = canValidate.once(this.attr(val), validations[val], 'myObjIsAwesome');
if (errors) {
$parent.addClass('has-error');
$label.find('.text-danger').text(errors[0]);
Expand Down
19 changes: 9 additions & 10 deletions can-validate/map/validate/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</head>
<body>
<div id="app" class="container">
<script src="../../../node_modules/steal/steal.js" main="can/view/autorender/"></script>
<script src="../../../node_modules/steal/steal.js" main="can-view-autorender/"></script>
<script type='text/stache' id="demo" can-autorender>
<h1>can.Map Validate Plugin Demo</h1>

Expand All @@ -32,19 +32,19 @@ <h3 class="panel-title">Validation Test</h3>
In the following examples, this happens when the field&rsquo;s value changes.</p>
<div class="form-group">
<label for="test1">MyVal required?</label>
<input class="form-control" id="test" type="checkbox" can-value="myMap.isRequired">
<input class="form-control" id="test" type="checkbox" {($value)}="myMap.isRequired">
</div>
<div class="form-group">
<label for="test1">MyVal</label>
<input class="form-control" id="test1" type="text" can-value="myMap.myVal">
<input class="form-control" id="test1" type="text" {($value)}="myMap.myVal">
</div>
<div class="form-group">
<label for="test2">MyNum</label>
<input class="form-control" id="test2" type="text" can-value="myMap.myNum">
<input class="form-control" id="test2" type="text" {($value)}="myMap.myNum">
</div>
<div class="input-group">
<p>You can also validate all properties at once</p>
<button type="button" class="btn btn-primary" can-click="doValidate">Validate All</button>
<button type="button" class="btn btn-primary" ($click)="doValidate">Validate All</button>
</div>
</div>
<ul class="list-group">
Expand All @@ -62,10 +62,9 @@ <h3 class="panel-title">Validation Test</h3>
</script>
</div>
<script type='text/javascript'>
steal.import('can', 'can-validate', 'can/map/define/', 'can-validate/map/validate/', 'can-validate/shims/validatejs.shim')
.then(function(modules){
var can = modules[0];
var TestMap = can.Map.extend({
steal('can-map', 'can-validate', 'can-view-model', 'can-map-define', 'can-validate/map/validate/', 'can-validate/shims/validatejs.shim', 'can-stache-bindings',
function(Map, canValidate, setViewModel){
var TestMap = Map.extend({
define: {
myNum: {
value: 'heyo',
Expand Down Expand Up @@ -93,7 +92,7 @@ <h3 class="panel-title">Validation Test</h3>
}
});

can.$('#demo').viewModel({
setViewModel(document.getElementById('demo'), {
myMap: new TestMap({isRequired: true}),
myFailMap: new TestMap({testString: 'hello'}),
doValidate: function () {
Expand Down
49 changes: 27 additions & 22 deletions can-validate/map/validate/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,14 @@
*
*/

import can from 'can';
import 'can-validate/can-validate';

var proto = can.Map.prototype;
import canMap from 'can-map';
import canCompute from 'can-compute';
import canValidate from 'can-validate/can-validate';
import canEach from 'can-util/js/each/';
import isEmptyObject from 'can-util/js/is-empty-object/';
import deepAssign from 'can-util/js/deep-assign/';

var proto = canMap.prototype;
var oldSet = proto.__set;
var ErrorsObj;
var defaultValidationOpts;
Expand All @@ -70,7 +74,7 @@ var resolveComputes = function (itemObj, opts) {
var processedObj = {};

// Loop through each validation option
can.each(opts, function (item, key) {
canEach(opts, function (item, key) {
var actualOpts = item;
if (typeof item === 'function') {
// create compute and add it to computes array
Expand Down Expand Up @@ -102,9 +106,9 @@ var getPropDefineBehavior = function (behavior, attr, define) {
};

// Default Map for errors object. Useful to add instance helpers
ErrorsObj = can.Map.extend({}, {
ErrorsObj = canMap.extend({}, {
hasErrors: function () {
return !can.isEmptyObject(this.attr());
return !isEmptyObject(this.attr());
}
});

Expand Down Expand Up @@ -134,12 +138,12 @@ var initProperty = function (key, value) {
mapValidateCache = getValidateFromCache.call(this);

// If validate options don't exist in cache for current prop, create them
if (mapValidateCache[key] && !can.isEmptyObject(mapValidateCache[key])) {
if (mapValidateCache[key] && !isEmptyObject(mapValidateCache[key])) {
validateOpts = mapValidateCache[key];
propIniting = false;
} else {
// Copy current prop's validation properties to cache
validateOpts = can.extend({}, getPropDefineBehavior('validate', key, this.define));
validateOpts = deepAssign({}, getPropDefineBehavior('validate', key, this.define));
// Need to build computes in the next step
propIniting = true;
}
Expand All @@ -148,7 +152,7 @@ var initProperty = function (key, value) {
if (typeof validateOpts !== 'undefined') {
//create validation computes only when initing the map
if (propIniting) {
validateOpts = can.extend({},
validateOpts = deepAssign({},
defaultValidationOpts,
validateOpts,
// Find any functions, converts them to computes and returns
Expand Down Expand Up @@ -177,11 +181,11 @@ proto.init = function () {
oldInit.apply(this, arguments);
}
};
can.extend(can.Map.prototype, {
deepAssign(canMap.prototype, {
_initValidation: function () {
var self = this;
var validateCache = getValidateFromCache.call(this);
can.each(this.define, function (props, key) {
canEach(this.define, function (props, key) {
if (props.validate && !validateCache[key]) {
initProperty.call(self, key, self[key]);
}
Expand Down Expand Up @@ -211,18 +215,18 @@ can.extend(can.Map.prototype, {
var self = this;

// Loop through validate options
can.each(this.define, function (value, key) {
canEach(this.define, function (value, key) {
if (value.validate) {
processedOpts[key] = resolveComputes({key: key, value: self.attr(key)}, validateOpts[key]);
}
});
var errors = can.validate.validate(this.serialize(), processedOpts);
var errors = canValidate.validate(this.serialize(), processedOpts);

// Process errors if we got them
// TODO: This creates a new instance every time.
this.attr('errors', new ErrorsObj(errors));

return can.isEmptyObject(errors);
return isEmptyObject(errors);
},
/**
* @function _validateOne Validate One
Expand All @@ -235,16 +239,17 @@ can.extend(can.Map.prototype, {
*
* @param {object} item A key/value object
* @param {object} opts Object that contains validation config.
+ @param {object} otherItems Object that contains other attributes in the map
* @return {boolean} True if method found that the property can be saved; if
* validation fails and the property must validate (`mustValidate` property),
* this will be `false`.
*/
_validateOne: function (item, opts) {
_validateOne: function (item, opts, otherItems) {
var errors;
var allowSet = true;

// run validation
errors = can.validate.once(item.value, can.extend({}, opts), item.key);
errors = canValidate.once(item.value, deepAssign({}, opts), item.key, otherItems);

// Process errors if we got them
if (errors && errors.length > 0) {
Expand Down Expand Up @@ -287,11 +292,11 @@ can.extend(can.Map.prototype, {
var self = this;

// Loop through each validation option
can.each(opts, function (item, key) {
canEach(opts, function (item, key) {
processedObj[key] = item;
if (typeof item === 'function') {
// create compute and add it to computes array
var compute = can.compute(can.proxy(item, self));
var compute = canCompute(Function.prototype.bind.call(item, self));
computes.push({key: key, compute: compute});
processedObj[key] = compute;
}
Expand All @@ -300,10 +305,10 @@ can.extend(can.Map.prototype, {
// Using the computes array, create necessary listeners
// We do this afterwards instead of inline so we can have access
// to the final set of validation options.
can.each(computes, function (item) {
canEach(computes, function (item) {
item.compute.bind('change', function () {
itemObj.value = self.attr(itemObj.key);
self._validateOne(itemObj, processedObj);
self._validateOne(itemObj, processedObj, self.attr());
});
});

Expand All @@ -325,7 +330,7 @@ proto.__set = function (prop, value, current, success, error) {
// If validate opts are set and initing, validate properties only if validateOnInit is true
if ((validateOpts && !mapIniting) || (validateOpts && mapIniting && validateOpts.validateOnInit)) {
// Validate item
allowSet = this._validateOne({key: prop, value: value}, validateOpts);
allowSet = this._validateOne({key: prop, value: value}, validateOpts, this.attr());
}
}

Expand Down
11 changes: 6 additions & 5 deletions can-validate/map/validate/validate.test.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
/* jshint asi: false */
import can from 'can';
import 'can/map/define/';
import Map from 'can-map';
import 'can-map-define';
import 'can-validate';
import 'can-validate/map/validate/';
import 'can-validate/shims/validatejs.shim';
import isEmptyObject from 'can-util/js/is-empty-object/';
import 'chai';
import 'steal-mocha';
var expect = chai.expect;
var validatedMap;
var secondaryMap;

var ValidatedMap = can.Map.extend({
var ValidatedMap = Map.extend({
define: {
myNumber: {
value: 100,
Expand Down Expand Up @@ -40,7 +41,7 @@ describe('Validate can.Map define plugin', function () {
validatedMap = new ValidatedMap();
});
it('does not validate', function () {
expect(can.isEmptyObject(validatedMap.errors)).to.equal(true);
expect(isEmptyObject(validatedMap.errors)).to.equal(true);
});
});
});
Expand Down Expand Up @@ -95,7 +96,7 @@ describe('Validate can.Map define plugin', function () {
});
it('control map validates successfully', function () {
secondaryMap.attr('computedProp', '');
expect(can.isEmptyObject(secondaryMap.attr('errors'))).to.equal(true);
expect(isEmptyObject(secondaryMap.attr('errors'))).to.equal(true);
});
it('other map validates, sets error', function () {
validatedMap.attr('computedProp', '');
Expand Down
Loading

0 comments on commit f2fd07c

Please sign in to comment.