Knockout Validation length is always 0 - javascript

I am new to using knockout and I am trying to get the validation plug-in to work. However, I tried ViewModel.errors().length == 0 but it is always zero
when i check the isValid - I always get true.
Here is the rest of my code, please help.
define(['knockout','knockout-validation', 'services/changeup', 'services/currencies', 'plugins/router'], function (ko, validation, changeup, currencies, router) {
ko.validation.configure({
insertMessages: true,
decorateElement: true,
errorElementClass: 'error',
errorMessageClass: 'help-inline '
});
var ctor = function () {
this.amount = ko.observable().extend({ required: true, number: true});
this.currency = ko.observable().extend({ required: true});
this.requestedAmount = ko.observable();
this.requestedCurrency = ko.observable().extend({ required: true, notEqual: this.currency, message: 'please'});
this.comment = ko.observable().extend({ required: true, minLength: 3});
this.currencies = currencies;
};
ctor.errors = ko.validation.group(ctor);
ctor.prototype.activate = function (activationData) {
};
ctor.prototype.save = function () {
var valid = ctor.isValid();
console.log(valid);
if (ctor.isValid()){
ctor.errors.showAllMessages();
}
else {
var dto = ko.toJS(this);
delete dto.currencies;
changeup.createRequest(dto).then(function(request){
console.log(request, 'a');
router.navigate('dashboard');
});
}
};
ctor.prototype.cancel = function (activationData) {
};
return ctor;
});

ko validation group should be attached with this not with the function itself so your code wil be like :-
var ctor = function () {
this.amount = ko.observable().extend({ required: true, number: true});
this.currency = ko.observable().extend({ required: true});
this.requestedAmount = ko.observable();
this.requestedCurrency = ko.observable().extend({ required: true, notEqual: this.currency, message: 'please'});
this.comment = ko.observable().extend({ required: true, minLength: 3});
// this.currencies = currencies;
this.errors = ko.validation.group(this);
};
And save function will be:-
ctor.prototype.save = function () {
var valid = this.isValid();
console.log(valid);
if (!this.isValid()){ //use this
this.errors.showAllMessages();
}
else {
var dto = ko.toJS(this);
delete dto.currencies;
changeup.createRequest(dto).then(function(request){
console.log(request, 'a');
router.navigate('dashboard');
});
}
};
Fiddle Demo

Related

ValidateJS Async REST Call

I am trying to create a validator which makes a REST call to my server and grabs a value the database. A few problems, when my validator is enabled it only validates that input and not the rest of the constraints. Also, I keep getting this error for the Id length [validate.js] Attribute id has a non numeric value for length, I do not receive this error when I am not using the async validator.
Here is my validator:
validate.validators.myAsyncValidator = function(input, options, key, attributes) {
return new validate.Promise(function(resolve, reject) {
if (!validate.isEmpty(input.value)) {
axios.get('/data-management/verify-data', {
params: {
id: input.value,
filter: options[0]
}
})
.then(function(response) {
if (response.data !== options[1]) resolve(" already exists!");
})
.catch(function(error) {
resolve(": Error, try again.");
});
}
}); };
Here are my constraints:
var constraints = {
email: {
presence: true,
email: true
},
password: {
presence: true,
format: {
// We don't allow anything that a-z and 0-9
pattern: "^[a-zA-Z0-9!##$&()\\-`.+,/\"]*$",
// but we don't care if the username is uppercase or lowercase
flags: "i",
message: "Must contain at least 1 Uppercase, 1 Lowercase, 1 Number, and 1 Special Character"
},
length: {
minimum: 6,
message: "Must be at least 6 characters"
}
},
"confirm-password": {
presence: true,
equality: {
attribute: "password",
message: "^The passwords does not match"
}
},
district: {
presence: true
},
id: {
presence: true,
length: {
minimum: 5,
maximum: 20,
message: "Must be between 6-20 characters"
},
format: {
// We don't allow anything that a-z and 0-9
pattern: "[a-z0-9]+",
// but we don't care if the username is uppercase or lowercase
flags: "i",
message: "can only contain a-z and 0-9"
},
myAsyncValidator: ["signup", false]
}};
And me hooking up my constraints to my form:
var inputs = document.querySelectorAll("input, textarea, select");
for (var i = 0; i < inputs.length; ++i) {
inputs.item(i).addEventListener("change", function(ev) {
// var errors = validate.async(form, constraints).then(function(data) {
// console.log("data");
// });
var obj = this;
var n = this.name;
validate.async(form, constraints).then(function() {
}, function(errors) {
showErrorsForInput(obj, errors[n.valueOf()]);
});
});
}
function handleFormSubmit(form, input) {
// validate the form against the constraints
// var errors = validate.async(form, constraints).then(function(data) {
// console.log("data2");
// });
validate.async(form, constraints).then(function() {
}, function(errors) {
showErrors(form, errors || {});
if (!errors) {
showSuccess();
}
});
I can provide the functons showErrors(), showSuccess(), and showErrorsForInput() if needed.
Thanks!
Found a solution. Checked the ID constraints first, once they were gone, I checked for rest of the constraints. Also added a tokenizer to remove the length error I was receiving.
Here is the updated code:
validate.validators.checkExists = function(input, options) {
return new validate.Promise(function(resolve, reject) {
if (!validate.isEmpty(input.value)) {
axios.get('/data-management/verify-data', {
params: {
id: input.value,
filter: options[0]
}
})
.then(function(response) {
if (response.data !== options[1]) resolve("already exists!");
else resolve();
})
.catch(function(error) {
reject(": Error, try again.");
});
} else resolve();
});
};
// These are the constraints used to validate the form
var constraints = {
email: {
presence: true,
email: true
},
password: {
presence: true,
format: {
pattern: "^[a-zA-Z0-9!##$&()\\-`.+,/\"]*$",
flags: "i",
message: "Must contain at least 1 Uppercase, 1 Lowercase, 1 Number, and 1 Special Character"
},
length: {
minimum: 6,
message: "must be at least 6 characters"
}
},
"confirm-password": {
presence: true,
equality: {
attribute: "password",
message: "^The passwords does not match"
}
},
firstName: {
presence: true
},
lastName: {
presence: true
},
district: {
presence: {
message: "must be selected"
}
}
};
var idConstraints = {
id: {
presence: true,
length: {
minimum: 5,
tokenizer: function(input) {
try {
return input.value;
} catch (e) {
return " ";
}
}
},
checkExists: ["signup", false]
}
};
// Hook up the form so we can prevent it from being posted
var form = document.querySelector("form#signup");
form.addEventListener("submit", function(ev) {
ev.preventDefault();
handleFormSubmit(form);
});
// Hook up the inputs to validate on the fly
var inputs = document.querySelectorAll("input, textarea, select");
for (var i = 0; i < inputs.length; ++i) {
inputs.item(i).addEventListener("change", function(ev) {
var obj = this;
var n = this.name;
validate.async(form, idConstraints).then(function() {
var moreErrors = validate(form, constraints) || {};
showErrorsForInput(obj, moreErrors[n.valueOf()]);
}, function(errors) {
showErrorsForInput(obj, errors[n.valueOf()]);
});
});
}
function handleFormSubmit(form) {
validate.async(form, idConstraints).then(function() {
var errors = validate(form, constraints);
showErrors(form, errors || {});
}, function(errors) {
showErrors(form, errors || {});
if (!errors) {
showSuccess();
}
});
}

Meteor Method.call issue in jquery-validation

I have a form to change password. I need to validate the old password. But jquery addMethod is always return false in Meteor.call. How to make it workable. Or is there any way? My bellow code will be more details about my issue.
$.validator.addMethod( 'checkPassword', ( oldpassword ) => {
var digest = Package.sha.SHA256(oldpassword);
Meteor.call('checkPassword', digest, function(err, result) {
var res = result.error != null; // even if this is "true", error message is visible.
return res;
});
});
$( "#changepassword" ).validate({
rules: {
oldpassword: {
required: true,
checkPassword: true
}
},
messages: {
oldpassword: {
required: "Please enter your Old Password",
checkPassword: "Password doesnt match!!!" //this message is visible all the time.
} }
});
Here is my method call
Meteor.methods({
checkPassword: function(digest){
if (Meteor.isServer) {
if (this.userId) {
var user = Meteor.user();
var password = {digest: digest, algorithm: 'sha-256'};
var result = Accounts._checkPassword(user, password);
return result;
}
}
}
});
here the meteor package

Sequelize get virtual field

for sync reasons I would like to create a hash of certain fields of a row as a virtual field.
My sequelize model looks like this:
var crypto = require('crypto');
module.exports = function(sequelize, DataTypes) {
return sequelize.define('transactions', {
id: {
type: DataTypes.INTEGER,
primaryKey: true
},
randomfieldone: {
type: DataTypes.BIGINT,
allowNull: true,
},
randomfieldtwo: {
type: 'NUMERIC',
allowNull: false,
},
hash: {
type: DataTypes.VIRTUAL,
set: function (val) {
var string = this.randomfieldone+''+this.randomfieldtwo;
var hash = crypto.createHash('md5');
hash.update(string);
hash.digest('hex');
this.setDataValue('hash', hash);
}
}
},{
timestamps: false
});
};
When I try to output that, I get 'undefined'.
I would like to be able to access it like any other 'real' field.
console.log(row.hash)
What am I doing wrong here?
I am use
hash: {
type: DataTypes.VIRTUAL,
set: function (val) {
var string = this.get("randomfieldone")+''+this.get("randomfieldtwo");
var hash = crypto.createHash('md5');
hash.update(string);
hash.digest('hex');
this.setDataValue('hash', hash);
}
}
Ok I solved it:
var md5 = require('MD5');
getterMethods: {
hash: function () {
var string = this.id+''+this.randomfieldone +''+this.randomfieldtwo;
var hash = md5(string);
return hash;
}
}
if you set getter function for a property in schema, the property will be included when the instance is converted to object or json.

KO validation: model.errors is undefined

I have this model
var MarketResearch = function (data) {
var self = this;
self.Validate = function() {
if (!self.isValid()) {
self.errors.showAllMessages();
return false;
}
return true;
};
this.id = data ? data.id : 0;
this.city = ko.observable(data ? data.city : '').extend({ required: true });
this.since = ko.observable(data ? data.since : '').extend({ required: true });
this.title = ko.observable(data ? data.title : '').extend({ required: true });
}
Here is the view:
function onDocumentReady() {
koValidationConfig()
// initializeDataPickers(market);
// createCkEditor('market_editor');
ko.applyBindings(market, document.getElementById("market-form"));
}
var market = new MarketResearch(null);
function onSaveMarketClicked() {
market.errors.showAllMessages();
}
function koValidationConfig() {
ko.validation.rules.pattern.message = 'Invalid.';
ko.validation.configure({
// registerExtenders: true,
messagesOnModified: true,
insertMessages: true,
decorateInputElement: true,
});
ko.validation.registerExtenders();
}
I have some required fields here. When I put nothing in the fields it displays "this field is required" and colors the form elements.
But market.errors is always undefined, so I can't check if the form is valid!
market.errors.showAllMessages();
Doesn't work too.
Ko.validation is defined, I checked.
What's wrong?
ko.validation adds an errors property to observables, not models. You also need to use .extend on an observable to enable validation.

Node.js ORM2 check if field already exists

What is the best method to check if field value already exists.
This is my model:
// Set global
var moment = require('moment');
var _ = require('lodash');
// Create model
module.exports = function (orm, db) {
var Profile = db.define('profile',
// Field Properties
{
username: {type: 'text', required: true, unique: true},
name: {type: 'text', required: true},
email: {type: 'text', required: true},
password: {type: 'text', required: true},
birthday: {type: 'date', required: true},
gender: {type: 'enum', values: ["male", "female"], required: true},
join_date: {type: 'date'}
},
{
// Model hooks. Manual: https://github.com/dresende/node-orm2/wiki/Model-Hooks
hooks: {
beforeValidation: function() {
// Set join date to current date
this.join_date = new Date();
}
},
// Model Validations. Manual: https://github.com/dresende/node-orm2/wiki/Model-Validations
validations: {
username: [orm.enforce.security.username({length: 4}, 'Invalid username')],
email: [orm.enforce.patterns.email('Please enter a valid email')],
password: [orm.enforce.security.password('6', 'Invalid password')],
birthday: [orm.enforce.patterns.match(/\d{2}-\d{2}-\d{4}/, null, 'Invalid birthday')]
},
// Model methods. Extra functions and stuff
methods: {
}
});
};
And this is my register controller:
module.exports = function (req, res, next) {
// Get post params
var params = _.pick(req.body, 'formAction', 'username', 'password', 'email', 'confirm_password',
'birthday', 'gender', 'terms');
// If we try to register
if (params['formAction'] == 'register') {
// Manual validations
// Check if we agreed with the terms
if (params['terms'] != 1) {
res.send({error: 'You must agree to the terms of service'});
return false;
}
// Check if password was confirmed
if (params['password'] && params['password'] != params['confirm_password']) {
res.send({error: 'Please confirm your password'});
return false;
}
// Check if username already exists
// Try to register
req.models.profile.create({username: params['username'],
password: params['password'],
email: params['email'],
birthday: params['birthday'],
gender: params['gender'],
name: params['username']}, function (err, items) {
// Check to see if we have error
error = helpers.getError(err);
// Return error
if (error)
res.send({error: error});
});
}
// Show login form
else
res.sendfile(settings.path + '/public/register.html');
};
How can i check if username already exists in db? Now if i try to create i get DUP_KEY error from database.
Thanks,
Radu
Looks like adding a hook and using next() worked out
beforeCreate: function (next) {
obj = this;
Profile.exists({email: this.email}, function (err, exists) {
if (exists) {
return next(new Error("Email already exists"));
}
else
{
Profile.exists({username: obj.username}, function (err, exists) {
console.log(exists);
if (exists) {
return next(new Error("Username already exists"));
}
else
return next();
});
}
});
}

Categories