How do send custom validation message to another schema field ?
SessionSchema = new SimpleSchema({
'seat.from': {
type: String,
max: 10,
optional: false
},
'seat.to': {
type: String,
max: 10,
optional: false
}
});
ReservationSchema = new SimpleSchema({
title: {
type: String
},
sessions: {
type: [SessionSchema],
min: 1,
optional: false,
custom: function() {
//Its an array object. validation is depends on next array so I made a validation here instead of `SessionSchema`.
return "greater-session"; // dispaly error on top of the session. I need to display error message on perticular field in `SessionSchema`.
}
}
});
SimpleSchema.messages({
"greater-session": "From seat should not lesser then previous session"
});
Autoform:
{{#autoForm id="addReservation" type="method" meteormethod="insertMyReservation" collection="Reservation"}}
{{> afQuickField name="title" autofocus=''}}
{{> afQuickField name="sessions" panelClass="group"}}
{{/autoForm}}
How do I achieve this?
I would suggest you using a custom validator for your SimpleSchema. They have access to more context information.
I would try something like this:
ReservationSchema = new SimpleSchema({
title: {
type: String
},
sessions: {
type: [SessionSchema],
min: 1,
optional: false,
custom: function() {
var sessions = this.value; // array;
var seatTo = 0; // initalize # 0
var hasError;
// loop through seach session
_.each(sessions, function(s, index) {
// if seatFrom < previous seatTo
if (s['seat.from'] < seatTo) {
hasError = true;
};
seatTo = s['seat.to']; // update seatTo for next iteration
});
if (hasError) {
return "greater-session"; // dispaly error on top of the session. I need to display error message on perticular field in `SessionSchema`.
}
}
}
});
Related
i have quickform once the submit button clicked, this method is fired
submitPost: function (app) {
check(app, {
title: String,
description: String,
category: String,
price: Number
});
var knownId = Products.insert(app);
Products.update({ _id: knownId }, { $set:{screenShots: scs, previewImage: pi, sourceCode: zip }});
}
the submit button wasn't working when i didn't give "screenShots, previewImage, and sourceCode" a default values in a collection.
Once i gave them a default value like it is shown below
previewImage: {
type: String,
defaultValue: "jjj",
},
sourceCode: {
type: String,
defaultValue: "jjj",
},
screenShots: {
type: [String],
autoValue: function() {
return [];
}
},
now the submit button in the form is working and the update method is triggered. it updates both "previewImage and sourcCode" but "screenShots" is still empty.
am not sure but i believe the problem has to do with autoValue which i should make it a default value, but how do i give an element that of type array of string a default value?
or the problem has to do with something else?
use optional: true in the schema if the value is optional, and it will pass check if it is empty.
The autoValue option is provided by the SimpleSchema package and is documented there. Collection2 adds the following properties to this for any autoValue function that is called as part of a C2 database operation:
isInsert: True if it's an insert operation
isUpdate: True if it's an update operation
isUpsert: True if it's an upsert operation (either upsert() or upsert: true)
So If you want to provide the autoValue while updating you have to use isUpdate in your schema like this.
createdAt: {
type: Date,
autoValue: function() {
if (this.isInsert) {
return new Date();
} else if (this.isUpsert) {
return {$setOnInsert: new Date()};
} else {
this.unset(); // Prevent user from supplying their own value
}
}
},
So your schema will be something like this:
previewImage: {
type: String,
defaultValue: function() {
if (this.isInsert) {
return 'fff';
} else if (this.isUpdate) {
return 'fff';
}
},
sourceCode: {
type: String,
defaultValue:function() {
if (this.isInsert) {
return 'jjj';
} else if (this.isUpdate) {
return 'jjj';
}
},
screenShots: {
type: [String],
autoValue: function() {
if (this.isInsert) {
return [];
} else if (this.isUpdate) {
return [];
}
}
},
For more info please check this
I'm trying to validate my data against a SimpleSchema before it gets submitted to the collection but for some reason I'm not able to do so with this error.
Exception while invoking method 'createVendorCategory' { stack: 'TypeError: Cannot call method \'simpleSchema\' of undefined
I have one collections with two SimpleSchemas as follows.
Vendors = new Mongo.Collection('vendors'); //Define the collection.
VendorCategoriesSchema = new SimpleSchema({
name: {
type: String,
label: "Category"
},
slug: {
type: String,
label: "Slug"
},
createdAt : {
type: Date,
label: "Created At",
autoValue: function(){
return new Date()//return the current date timestamp to the schema
}
}
});
VendorSchema = new SimpleSchema({
name: {
type: String,
label: "Name"
},
phone: {
type: String,
label: "Phone"
},
vendorCategories:{
type: [VendorCategoriesSchema],
optional: true
}
});
Vendors.attachSchema(VendorSchema);
The vendorCategory will be added after the Vendor document is created by the user.
Here is what my client side looks like.
Template.addCategory.events({
'click #app-vendor-category-submit': function(e,t){
var category = {
vendorID: Session.get("currentViewingVendor"),
name: $.trim(t.find('#app-cat-name').value),
slug: $.trim(t.find('#app-cat-slug').value),
};
Meteor.call('createVendorCategory', category, function(error) {
//Server-side validation
if (error) {
alert(error);
}
});
}
});
And here is what my server side Meteor.methods look like
createVendorCategory: function(category)
{
var vendorID = Vendors.findOne(category.vendorID);
if(!vendorID){
throw new Meteor.Error(403, 'This Vendor is not found!');
}
//build the arr to be passed to collection
var vendorCategories = {
name: category.name,
slug: category.slug
}
var isValid = check( vendorCategories, VendorSchema.vendorCategories.simpleSchema());//This is not working?
if(isValid){
Vendors.update(VendorID, vendorCategories);
// return vendorReview;
console.log(vendorCategories);
}
else{
throw new Meteor.Error(403, 'Data is not valid');
}
}
I'm guessing this is where the error is coming from.
var isValid = check( vendorCategories, VendorSchema.vendorCategories.simpleSchema());//This is not working?
Any help would be greatly appreciated.
Since you've already defined a sub-schema for the sub-object you can directly check against that:
check(vendorCategories,VendorCategoriesSchema)
I have the following SimpleSchema
Schema.Team = new SimpleSchema({
name:{
type:String
},
members: {
type: [Schema.User],
optional:true
}
});
I would like to insert (on the server) a new team document with the current user, as a reference (not as an embedded document).
I have tried:
Teams.insert({name:"theName",members:[Meteor.user()]}) // works but insert the user as an embedded doc.
Teams.insert({name:"theName",members:[Meteor.user()._id]}) // Error: 0 must be an object
I have also tried in two steps:
var id = Teams.insert({name:teamName});
Teams.update({ _id: id },{ $push: { 'users': Meteor.user()._id } });
Then I have another error I don't understand: Error: When the modifier option is true, validation object must have at least one operator
So how can I insert a document with a reference to another schema?
If you just want to store an array of userIds in your Team collection try:
Schema.Team = new SimpleSchema({
name:{
type:String
},
members: {
type: [String],
optional:true
}
});
Then
Teams.insert({ name: "theName", members: [Meteor.userId()] });
Should work. Later when you want to add an additional id you can just:
Teams.update({ _id: teamId },{ $addToSet: { members: Meteor.userId() }});
The following is probably the syntax you are after, assuming you are also using AutoForm.
If you are using collection2, you can also add an autovalue for when a team is created to automatically add the creator to that team for more convenience.
Schema.Team = new SimpleSchema({
name: {
type:String
},
members: {
type: [String],
defaultValue: [],
allowedValues: function () {
// only allow references to the user collection.
return Meteor.users.find().map(function (doc) {
return doc._id
});
},
autoform: {
// if using autoform, this will display their username as the option instead of their id.
options: function () {
return Meteor.users.find().map(function (doc) {
return {
value: doc._id,
label: doc.username // or something
}
})
}
},
autoValue: function () {
if (this.isInsert && !this.isFromTrustedCode) {
return [this.userId];
}
}
}
});
I've got a form created through AutoForm.
As far as data sources, I can fill in parts of the form and use:
AutoForm.getFormValues('form-id').insertDoc // returns the contents of the form
When I validate the form I can do:
var formValues = AutoForm.getFormValues('form-id').insertDoc;
var isValid = MyCollection.simpleSchema().namedContext("myContext").validate(formValues);
// if isValid returns true, then I enable the Submit button
Instead of filling in parts of the form, I want to manually add information into whatever object Autoform uses for validation and submission to a collection.
For example, there are data fields in the schema that simply don't need to appear in the form itself.
Take a shopping cart:
ShoppingCartSchema = {
totalPrice: {
type: Number,
optional: false
},
itemsSelected: {
type: [Object],
optional: false
}
};
The data for itemsSelected is obviously provided through user input on the form.
The data for totalPrice is something that should not be from a form input. It's generated in the code.
But totalPrice still needs to be validated as a required field before AutoForm submits the form to a collection.
So how do you add totalPrice onto the object that Autoform eventually validates?
You could use an autovalue if you wanted to.
ShoppingCartSchema = new SimpleSchema({
'items': {
type: [Object],
},
'items.$.name': {
type: String
},
'items.$.price': {
type: Number
},
totalPrice: {
type: Number,
autoValue: function () {
if (this.field('items').isSet) {
let total = this.field('items').value.reduce(function (sum, item) {
return sum + item.price;
}, 0);
if (this.isInsert) {
return total;
} else {
return { $set: total };
}
}
}
},
});
Autoform Hooks can help you manipulate the data before you save it into the Collection.
In your case .
AutoForm.hooks({
form-id: { // The Autoform ID
onSubmit: function (insertDoc, updateDoc, currentDoc) {
if (customHandler(insertDoc)) { // Your Logic here
this.done(); // This is Required
} else {
this.done(new Error("Submission failed"));
}
return false;
}
}
});
For More Information Please refer Autoform Readme
I have a simpleSchema:
imageUrl: {
type: Object,
optional: true,
autoValue: function() {
if (Meteor.isClient) return;
var imageField = this.field('imageId');
if (!imageField.isSet){
this.unset();
} else {
var imageObj = MealsImages.findOne(imageField.value);
if (imageObj){
return {thumb: imageObj.S3Url('thumb'), big: imageObj.S3Url('big')};
}
}
},
autoform: {
label: false,
type: 'hidden',
afFieldInput: {
type: "hidden"
}
}
},
For some reason, when I update the record this field always appears in $unset array:
Meteor.methods({
mealUpsert: function(doc, mealId) {
check(doc, Meals.simpleSchema());
console.log('test7');
console.log(doc);
if (mealId){
Meals.update({_id: mealId}, doc);
} else {
mealId = Meals.insert(doc);
}
return false;
}
});
Will print:
I20150830-21:49:39.560(-4)? { '$set':
...
I20150830-21:49:39.562(-4)? '$unset':
I20150830-21:49:39.562(-4)? { imageUrl: '',
...
I'm using autoform:
<template name="mealUpdateForm">
<div class="meal-content">
{{> quickForm collection="Meals" doc=this id="mealUpdateForm" meteormethod="mealUpsert" type="method-update"}}
</div>
</template>
And will never be updated or set. Any clue why field could appear in $unset list?
I think I've figured this out - you have a this.unset() in your autoValue for imageUrl. This is called whenever you omit imageId from the modifier, even if it is already present in a document you are modifying!