I have two separate schemas that use the same field. I've tried to create schemaComponents so that I can update both schemas in one location however I get an error Error: Invalid definition for school.$ field. when I use it. I'm not sure what I'm doing wrong here, I was under the impression this was allowed.
Path: SchemaComponents.js
SchemaComponents = {
schools: {
type: [String],
optional: true,
autoform: {
options: [
{label: "School One", value: 'SchoolOne'},
{label: "School Two", value: 'SchoolTwo'},
{label: "School Three", value: 'SchoolThree'},
]
}
}
};
Path: StudentSchema.js
import from '../components/SchemaComponents.js';
StudentSchema = new Mongo.Collection("studentSchema");
var Schemas = {};
Schemas.StudentSchema = new SimpleSchema({
school: SchemaComponents.schools,
});
StudentSchema.attachSchema(Schemas.StudentSchema);
Path: TeacherSchema.js
import from '../components/SchemaComponents.js';
TeacherSchema = new Mongo.Collection("teacherSchema");
var Schemas = {};
Schemas.TeacherSchema = new SimpleSchema({
school: SchemaComponents.schools,
});
TeacherSchema.attachSchema(Schemas.TeacherSchema);
You defined SchemaComponent as a simple object and not as a SimpleSchema object. To reuse your schools definition do:
let schoolsSchema = new SimpleSchema({
schools: {
type: [String],
optional: true,
autoform: {
options: [
{label: "School One", value: 'SchoolOne'},
{label: "School Two", value: 'SchoolTwo'},
{label: "School Three", value: 'SchoolThree'},
]
}
}
});
Then you can do:
Schemas.TeacherSchema = new SimpleSchema({
school: {
type: schoolsSchema
}
});
Related
I have two separate schemas that use the same components. I've tried to create schemaComponents so that I can update both schemas in one location however I get an error ReferenceError: SchemaComponents is not defined when I use it. I'm not sure what I'm doing wrong here, I was under the impression this was allowed.
Path: SchemaComponents.js
SchemaComponents = {
schools: {
type: [String],
optional: true,
autoform: {
options: [
{label: "School One", value: 'SchoolOne'},
{label: "School Two", value: 'SchoolTwo'},
{label: "School Three", value: 'SchoolThree'},
]
}
}
};
Path: StudentSchema.js
StudentSchema = new Mongo.Collection("studentSchema");
var Schemas = {};
Schemas.StudentSchema = new SimpleSchema({
school: SchemaComponents.schools,
});
StudentSchema.attachSchema(Schemas.StudentSchema);
Path: TeacherSchema.js
TeacherSchema = new Mongo.Collection("teacherSchema");
var Schemas = {};
Schemas.TeacherSchema = new SimpleSchema({
school: SchemaComponents.schools,
});
TeacherSchema.attachSchema(Schemas.TeacherSchema);
I might be thinking about this the wrong way, so please feel free to correct my thinking.
I'm using simpleSchema and I have a section of code which is used in more than one schema. Is there a way to create an individual component and import it into each schema, so that when I need to update the component I don't have to update it in multiple locations?
Path: resuableComponent
type: String,
optional: true,
autoform: {
type: "select",
options: function () {
return [
{label: "School logo 1", value: 'url'},
{label: "School logo 2", value: 'url'},
{label: "School logo 3", value: 'url'},
];
},
}
Path: studentCollection.js
Schemas.Student = new SimpleSchema({
studentUserId: {
type: String,
},
school: {
type: String,
optional: false
},
**resuableComponent**
});
Path: teacherCollection.js
Schemas.Teacher = new SimpleSchema({
teacherUserId: {
type: String,
},
school: {
type: String,
optional: false
},
**resuableComponent**
});
You could move the reusable objects into a different file that should be visible on both client and server if you are using SimpleSchema.
Example based on your question:
lib/schema-components.js :
SchemaComponents = {
school: {
type: String,
optional: false
},
// ...
// more reusable components here
};
someCollectionFile.js :
Schemas.Student = new SimpleSchema({
studentUserId: {
type: String
},
school: SchemaComponents.school,
// ...
});
I have this schema:
AdsSchema = new SimpleSchema({
title: {
type: String,
label: "Title"
},
_cityId: {
type: String,
label: "City ID"
},
_categoryId: {
type: String,
label: "Category ID"
},
insertedDateTime: {
type: Date,
label: "Inserted Date Time",
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
}
}
},
insertedBy: {
type: String,
label: "Inserted By"
defalutValue: Meteor.user().username
},
price: {
type: Number,
label: "Price"
},
image: {
type: Object,
label: "Image",
optional: true
},
email: {
type: String,
label: "Email"
},
phoneNumber: {
type: String,
label: "Phone Number",
optional: true
},
desc: {
type: String,
label: "Description",
autoform: {
afFieldInput: {
type: "textarea",
rows: 10
}
}
},
quickOrNot: {
type: Boolean,
label: "Quick Or Not",
}
});
I use quickForm for insert to mongoDB, whit following code:
{{> quickForm schema="AdsSchema" collection="Ads" id="insBaseAds" type="insert"}}
and autoForm generate for me a form with all of schema's fields.
but I want only limit fields to show to user on autform, for example these fields:
title, price, image, email, phoneNumber, desc
and I fill some fields my self, for example these fields:
_cityId: "test",
_categoryId: "test",
insertBy: "test"
how can I use quickForm?
You can use afQuickfields
{{>afQuickFields fields="title, price, image, email, phoneNumber, desc"}}
else you can use type 'hidden' in schema
_cityId: {
type: String,
label: "City ID",
autoform:{
type:"hidden"
}
}
I have been working on extending the Meteor.users schema which work fine but after I create the first user in a Meteor.startup() and tried logging in I get a "User Not Found" error. Even though i can see the user in the mongo shell. Here is my schema:
Schemas.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,
optional: true
},
"firstName":{
type: String,
max: 50,
min:2
},
'middleName':{
type: String,
optional: true,
max: 50
},
"lastName":{
type: String,
max: 50,
min:2
},
"gender": {
type: String,
autoform: {
afFieldInput: {type: "select-radio-inline",},
options:
[
{label: "Male", value: "Male"},
{label: "Female", value: "Female"}
]
}
},
"branch": {
type: String,
optional: true,
autoform: {
type: "select",
options: function () {
return CompanyBranches.find().map(function (c) {
return {label: c.companyName+' - '+c.addressCity, value: c._id};
});
}
}
},
"active":{
type: String,
allowedValues: ["Yes","No"],
autoform: {
options: [
{label: "Yes", value: "Yes"},
{label: "No", value: "No"}
],
afFieldInput: {
type: "select-radio-inline"
}
}
},
services: {
type: Object,
optional: true,
blackbox: true
},
roles: {
type: [String],
optional: true,
autoform: {
options: [
{label: "Dashboard", value: "Dashboard"},
{label: "Branches", value: "Branches"},
{label: "User Profile", value: "User Profile"},
{label: "Case Managers", value: "Case Managers"},
{label: "Insurance Company", value: "Insurance Company"},
{label: "Tasks", value: "Tasks"},
{label: "Calendar", value: "Calendar"},
{label: "Contacts", value: "Contacts"},
{label: "Cases", value: "Cases"},
{label: "Requests", value: "Requests"},
{label: "Accounts", value: "Accounts"},
{label: "Reports", value: "Reports"},
{label: "Search", value: "Search"},
{label: "HR", value: "HR"}
],
afFieldInput: {
type: "select-checkbox-inline"
}
}
}
});
Meteor.users.attachSchema(Schemas.User);
This is my Meteor Startup function:
Meteor.startup(function () {
if ( Meteor.users.find().count() === 0 ) {
Accounts.createUser({
username: "leocrawf#gmail.com",
email:"leocrawf#gmail.com",
password: "leoten",
firstName: "Leocrawf",
lastName: "Stewart",
gender:"Male",
active: "Yes"
}, function (error) {
if (error) {
console.log("Cannot create user");
}
});
}
});
on the server i am doing this in the Accounts.onCreateUser():
Accounts.onCreateUser(function(options, user) {
user = options || {};
user.username = options.username;
user.firstName = options.firstName;
user.lastName = options.lastName;
user.active = options.active;
user.gender = options.gender;
// Returns the user object
return user;
});
When I query the mongo shell i get this:
meteor:PRIMARY> db.users.find().pretty()
{
"_id" : "pFurR8iDYWJcX9rus",
"username" : "leocrawf#gmail.com",
"firstName" : "Leocrawf",
"lastName" : "Stewart",
"gender" : "Male",
"active" : "Yes",
"services" : {
"resume" : {
"loginTokens" : [
{
"when" : ISODate("2016-02-05T23:13:38.364Z"),
"hashedToken" : "vs5xVlKL59yVTO/fbKbSnar38I8ILAruj2W1YecQ2Io="
}
]
}
}
}
It doesn't look like you're setting up the profile correctly when creating the user:
Instead of:
Accounts.createUser({
username: "leocrawf#gmail.com",
email:"leocrawf#gmail.com",
password: "leoten",
firstName: "Leocrawf",
lastName: "Stewart",
gender:"Male",
active: "Yes"
},
Try:
Accounts.createUser({
username: "leocrawf#gmail.com",
email: "leocrawf#gmail.com",
password: "leoten",
profile: {
firstName: "Leocrawf",
lastName: "Stewart",
gender: "Male",
active: "Yes"
}
},
Also I recommend active: true instead of active: "Yes" to use a boolean instead of a string. It doesn't look like you've defined active or gender in your schema either btw.
I am using autoform and collection2 package and making a form in meteor. As of now i put some hard-coded option for country-state-city dropdown and insert-update is working fine. Now I want for the first time only country dropdown is enable other two are disable. Based on Country selection the states dropdown will populate and enable. Then based on State selection City Should Populate.
I don't want to do this manually. Is there any way to do this using autoform / collection2 features??? My code sample is as follows:
Collection2 Schema:
country:{
type: String,
label : "Country",
autoform: {
afFieldInput: {
type: "select"
},
options: function () {
return [
{label: 'Country1', value: 'Country1'},
{label: 'Country2', value: 'Country2'},
{label: 'Country3', value: 'Country3'},
{label: 'Country4', value: 'Country4'}
];
}
}
},
state:{
type: String,
label : "State",
autoform: {
afFieldInput: {
type: "select"
},
options: function () {
return [
{label: 'State1', value: 'State1'},
{label: 'State2', value: 'State2'},
{label: 'State3', value: 'State3'},
{label: 'State4', value: 'State4'}
];
}
}
},
city:{
type: String,
label : "City",
autoform: {
afFieldInput: {
type: "select"
},
options: function () {
return [
{label: 'City1', value: 'City1'},
{label: 'City2', value: 'City2'},
{label: 'City3', value: 'City3'},
{label: 'City4', value: 'City4'}
];
}
}
},
HTML ::
{{> afQuickField name='country' template="bootstrap3-horizontal" label-class="col-sm-4" input-col-class="col-sm-8"}}
{{> afQuickField name='state' template="bootstrap3-horizontal" label-class="col-sm-4" input-col-class="col-sm-8"}}
{{> afQuickField name='city' template="bootstrap3-horizontal" label-class="col-sm-4" input-col-class="col-sm-8"}}
Any Help??
I think this is somewhat the idea you have, https://jsfiddle.net/bdhacker/eRv2W/
// Countries
var country_arr = new Array("Afghanistan", "Albania", "Algeria", "American Samoa", "Angola", "Anguilla", "Antartica"...
// States
var s_a = new Array();
s_a[0] = "";
s_a[1] = "Badakhshan|Badghis|Baghlan|Balkh|Bamian|Farah|Faryab|Ghazni|Ghowr|Helmand|Herat|Jowzjan|Kabol|Kandahar|Kapisa|Konar|Kondoz|Laghman|Lowgar|Nangarhar|Nimruz|Oruzgan|Paktia|Paktika|Parvan|Samangan|Sar-e Pol|Takhar|Vardak|Zabol";...
you can extract the data from this and adjust to your app. Hope it helps
i think you can set the inputs of state and city to be disabled
country:{
type: String,
label : "Country",
autoform: {
afFieldInput: {
type: "select"
},
options: function () {
return [
{label: 'Country1', value: 'Country1'},
{label: 'Country2', value: 'Country2'},
{label: 'Country3', value: 'Country3'},
{label: 'Country4', value: 'Country4'}
];
}
}
},
state:{
type: String,
label : "State",
autoform: {
afFieldInput: {
type: "select",
disabled:true
},
options: function () {
return [
{label: 'State1', value: 'State1'},
{label: 'State2', value: 'State2'},
{label: 'State3', value: 'State3'},
{label: 'State4', value: 'State4'}
];
}
}
},
city:{
type: String,
label : "City",
autoform: {
afFieldInput: {
type: "select",
disabled:true
},
options: function () {
return [
{label: 'City1', value: 'City1'},
{label: 'City2', value: 'City2'},
{label: 'City3', value: 'City3'},
{label: 'City4', value: 'City4'}
];
}
}
},
and use Template event to enable the options
Template.YOURTEMPLATENAME.events({
'change input[name="country"]' :function(){
if ($('input[name="country"]').value() != ''){
$('input[name="state"]').attr('disabled','');
}else {
$('input[name="state"]').attr('disabled','disabled');
}
},
'change input[name="state"]' :function(){
if ($('input[name="state"]').value() != ''){
$('input[name="city"]').attr('disabled','');
}else {
$('input[name="city"]').attr('disabled','disabled');
}
}
});