Saving a telephone number to Simple Schema / Collection2 - meteor

I'm using autoform with simple schema and collection2. In my form I collect a phone number. Phone numbers where I live start with a 0. When it saves to the database the 0 is removed. How can I stop this from happening?
phone: {
type: Number,
optional: true,
autoform: {
afFieldInput: {
type: "tel"
}
}
}

Numbers are stored without a leading-zero by definition - 0123 is not a valid number. You either need to add the leading zeroes when you get data out, or store the value as a string.

Save it as a string instead type: String or format it with a leading zero whenever you display it on screen. The latter is harder if you are also storing numbers from other locales and you don't know what format they are using.

use a string and add a regex validator on it
phone: {
type: String,
regEx: /^0{1}\d{10}$/, // or something like this
}

Thanks for all the help. FYI to those who might have a similar problem, see the code below. #corvid suggested using regEx and a quick google showed a solution for Australian numbers. It seems to work well. Thanks again everyone!
Link for the regEx soltuion
phone: {
type: String,
regEx: /^\({0,1}((0|\+61)(2|4|3|7|8)){0,1}\){0,1}(\ |-){0,1}[0-9]{2}(\ |-){0,1}[0-9]{2}(\ |-){0,1}[0-9]{1}(\ |-){0,1}[0-9]{3}$/,
optional: true,
autoform: {
afFieldInput: {
type: "tel"
}
}
},

Related

Separate form validation with Meteor

I'm using collection2 and I'm trying to get it to handle validation is a specific way. I have a profile schema which looks kind of like this:
Schema.UserProfile = new SimpleSchema({
name: {
type: String,
optional: false
}
location: {
type: String,
optional: true
}
gender: {
type: String,
optional: false
}
});
Schema.User = new SimpleSchema({
username: {
type: String,
optional: true
},
emails: {
type: Array,
optional: true
},
"emails.$": {
type: Object
},
"emails.$.address": {
type: String,
regEx: SimpleSchema.RegEx.Email
},
"emails.$.verified": {
type: Boolean
},
createdAt: {
type: Date
},
profile: {
type: Schema.UserProfile,
optional: true
},
services: {
type: Object,
optional: true,
blackbox: true
},
roles: {
type: [String],
optional: true
},
heartbeat: {
type: Date,
optional: true
}
});
Meteor.users.attachSchema(Schema.User);
Now, on my registration form I'm requiring the user to select their gender and then later once they log in, users are presented with a separate form asking for their name and location. Here's the problem:
The registration form works and everything goes through with saving. When they try to save the internal form with location and name though I get an error:
Error invoking Method 'updateProfile': Gender is required [400]
I know it's happening because it's required in the schema but I've already obtained this information. How do I not require that? Or do I set up validation per form?
You have to add validation through jquery or you can use toaster for display the error on client side.
Read this also : link
I assume you use aldeed:autoform for your forms. When you use normal type in the form, all fields, even those already filled marked as mandatory have to be submitted. Two ways to fix this:
Dirty way: set hidden field with the prefilled value.
You can also set your form type as update as seen in the doc. This way, simple-schema will validate your newDoc already filled with your previous entries without screaming.
The solution number two is the one I use in most cases. This plus autoform's hooks give you enough flexibility to adapt to most use-cases you might encounter.
I don't know whether or not it is a more elegant solution, but we've stopped attaching simpleSchemas to documents in our current project.
We instead have different schemas in each collection's namespace, one for checking user input on insert, one on update, and and one to be used to fill defaultValue when inserting a new doc (which can be done either by the client or the server, in which case we don't check for input). We call .validate() or .clean() depending on what we want to do.
With clever use of the possibility to build schemas from array of schemas, we're not writing bigger schemas in the end (there's more of them though), but we have total control on when we check, and which fields are checked.
From the SimpleSchema docs:
Say you have a required key "friends.address.city" but
"friends.address" is optional. If "friends.address" is set in the
object you're validating, but "friends.address.city" is not, there is
a validation error. However, if "friends.address" is not set, then
there is no validation error for "friends.address.city" because the
object it belongs to is not present.
So the error happens because you're including profile on both forms and gender is not optional within profile. I can think of two ways to solve this:
Have additional objects under profile that are both optional and contain required fields for name/location on one (though it seems like location might be optional in both scenarios based on your code) and a required field for gender on the other. I don't particularly like this solution but it prevents needing form validation.
Use jQuery form validation (I use the package themeteorchef:jquery-validation) and make all your fields in profile optional.
It also looks like SimpleSchema accepts a function for the optional property, so you could use some custom logic there - maybe you get arguments or a context in that function that will allow you to do what you want?
Hope that helps!

Best way to exclude a Meteor value from the database?

What is the best way to exclude a field value from the data in Meteor when using Autoform, SimpleSchema, Collection2, etc? Say I have:
MySchema = new SimpleSchema({
password: {
type: String,
label: "Enter a password",
min: 8
},
confirmPassword: {
type: String,
label: "Enter the password again",
min: 8,
custom: function () {
if (this.value !== this.field('password').value) {
return "passwordMismatch";
}
}
}
});
... and I do not want to confirmPassword field persisted to the database, what is the best way to handle that? I assume using hooks, but if so where and how? Hopefully there is a way to just exclude one (or more) values without having to redefine the whole whole schema to say which to include and which to exclude. If I have 100 fields and want to exlcude 1, hopefullly the hook or whatever does not need the other 99 defiled too.
TIA
With autoform, you must use a method on the server side. Simply delete the field in the method code when you receive it at the server before inserting the document.

Meteor simple-schema: how to get the value of another field that isn't set

I'd like to know the value of another field even when that field hasn't been set in this update, but is part of the document and was set in the past. Is this possible using aldeed:simple-schema?
No. Unless the other field is included in the modifier you have to lookup the document using Collection.findOne and get the field value from that.
Simple you can use for instance:
AutoForm.getFieldValue('profileInformation.dateOfBirth');
age: {
type: String,
optional: true,
defaultValue : function(){
return AutoForm.getFieldValue('profileInformation.dateOfBirth');
}
}

Datatype validation error - MeteorJS/Autoform/SimpleSchema/Embedded Simple Schema

I am using Simple Schema,collection hooks and Autoform packages in Meteor and I am trying to update a Embedded object in my schema in the after update collection hook. I feel I might doing something silly, but was just unable to solve this problem. I am getting the exeption while saving: Exception while invoking method '/providers/update' Error: 0 must be an integer
My schema:
Schemas.Providers = new SimpleSchema({
email: {
type: String,
label: 'Email Address',
autoValue: function() {
if (this.isInsert || this.isUpdate) {
return Meteor.user().emails[0].address;
}
},
autoform: {
afFieldInput: {
type: 'email'
}
}
},
officelocation: {
type: String,
label: 'Location of Office',
optional:true
},
location: {
type: [LocationSchema],
optional:true
}});
The collection hook that works:
Providers.after.update(function (userId, doc) {
var oldDoc = this.previous;
Providers.direct.update({_id: doc._id},{$set: {location:{
type:'Point',
coordinates:[0,0]
}}});
});
The collection hook that does not work.. Ideally I should not be updating after the collection update, but wanted to make sure this works:
Providers.after.update(function (userId, doc) {
var oldDoc = this.previous;
var array=[];
var iArray=doc.officelocation.split(",");
array.push(Number(iArray[1]));
array.push(Number(iArray[0]))
Providers.direct.update({_id: doc._id},{$set: {location:[{
type:'Point',
coordinates:array
}]}});
});
Looking at what you are trying to store, use parseInt instead of Number that you are using. It will return an integer that mongo can store.
The issue is not with the method that you are using. It is with the way you are storing data in mongo. Show us how your LocationSchema looks like.
Detail:
Mongo uses a different number format that what javascript uses. In javascript, a Number can be an integer, a float, a decimal or anything that you want. Mongo has very strict demands when it comes to integer or floats.
Overall, what it means is that if you want to store an accurate decimal number in mongo (which I suspect what you are trying to do), you have to either store it as a string (you loose the ability to do direct mongo operation such as $inc $gt etc) or divide it into two parts and store separably. The third option is to store it as a float which isn't accurate an is only useful if you want some kind of approximate value.

Formatting strings using attributes in kendo grid

I was wondering if it would be possible to format strings (in this case the string displayed in the field OrderDate) using the "attributes:{}" thing ( I do not know how I should call that. A tag? A property?)
NOTE: This is inside a kendogrid which gets JSON data from a remote server.
NOTE 2 : The attributes:{style:text-align:center;"} works just fine.
field : "OrderDate",
title : "Orderdatum",
attributes:{style:"text-align:center;"},
width : 170,
If there is anything else that I need to provide you with, do say so.
Thanks in advance everyone! And if this looks like I haven't searched or something, then I can assure you I have.
I thought this might help people get an idea of how it looks. What I want to achieve in my case is that IF the data is 3-3-2009 (the selected cell/row) that it shows as 03-03-2009. Is it possible to achieve it using attributes ?
Again, thanks in advance.
Edit 2:
This link tells me it is not possible to do it in CSS3. So my guess now is that I accidently have created a duplicate question. So let me rephrase my quesion: How can I format the string, not necessarily using attributes, so it looks how I explained I want it to look?
Edit 3:
I was supposed to include this.
As you can see what I get is a string and not a number.
schema: {
type : "json",
data : "SalesOrders.SalesOrder",
model: {
fields: {
OrderNo : {type: "string"},
OrderDate : {type: "string"},
DeliveryWeek : {type: "number"},
OrderTotal : {type: "number"},
OBJECTID : {type: "number"},
},
Yet again, thanks for your time to read my question.
In this scenario, you are unable to format the string using CSS3 (Like totally impossibru...)
Therefore, you need to format your JSON object once its loaded, before its passed into the grid for display.
Formatting of data (This link give you some idea on how you format the datasource)
http://www.telerik.com/forums/datasource-number-format
Formatting dates (This link give you idea on how to format dates)
http://docs.telerik.com/kendo-ui/getting-started/framework/globalization/dateformatting
If you are not comfortable with kendo formatting of dates (Yes, I hate it), you can use the sweet momentJS
http://momentjs.com/
BTW (EDITED)
Kendo grid date column not formatting
this is a quicker and cleaner way of using "template" attribute for formatting
We can combine the functionality (described in the following Kendo UI documentation) to reformat the date during the DataBound event:
http://docs.telerik.com/kendo-ui/getting-started/framework/globalization/dateformatting
http://docs.telerik.com/kendo-ui/api/web/grid#events-dataBound
[update]
Here's some generic code to convey the idea:
<div id="grid"></div>
<script>
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{ field: "age" }
],
dataSource: [
{ name: "Jane Doe", age: 30 },
{ name: "John Doe", age: 33 }
],
dataBound: function(e) {
console.log("put your Date conversion logic here in the dataBound event");
}
});

Resources