The documentation of Planifica/meteor-wizard tells that the SimpleSchema should be created as part of the template. I have all my Simple-Schema's as part of my collection and would like to keep it that way. Anyone knows if this can be done with Planifica/meteor-wizard?
It should not matter where you define it. But in looking at the meteor-wizard docs it does look like you at least need a reference to it.
So instead of a helper that defines the schema, you just return a reference to it. So if you use the documentation example. Instead of:
Template.setupStepOne.schema = function() {
return new SimpleSchema({
...
});
}
You could use:
Template.setupStepOne.schema = CollectionName.Schema;
Just replace the CollectionName.Schema with a wherever you are storing your schema.
Install first $ meteor add planifica:wizard
Please check bellow added small program. I think it is helpful for you.
<template name="setupWizard">
{{> wizard id="setup-wizard" steps=steps}}
</template>
<template name="setupStepOne">
{{#autoForm schema=schema doc=data id="setup-step-one-form"}}
{{> afQuickField name="username"}}
{{> afQuickField name="password"}}
<button type="submit" class="btn btn-success btn-lg pull-right">Next</button>
{{/autoForm}}
</template>
<template name="setupStepTwo">
{{#autoForm schema=schema doc=data id="setup-step-two-form"}}
{{> afQuickField name="confirm"}}
<button type="submit" class="btn btn-success btn-lg pull-right">Submit</button>
{{/autoForm}}
</template>
Then configure your schema's and steps
Template.setupWizard.steps = function() {
return [{
id: 'stepOne',
title: 'Step 1. Your account',
template: 'setupStepOne',
formId: 'setup-step-one-form'
}, {
id: 'stepTwo',
title: 'Step 2. Confirm',
template: 'setupStepTwo',
formId: 'setup-step-two-form',
onSubmit: function(data, mergedData) {
Accounts.createUser(mergedData, function(err) {
if(!err) Router.go('/');
});
}
}]
}
Template.setupStepOne.schema = function() {
return new SimpleSchema({
'username': {
type: String,
label: 'Username',
min: 2,
max: 30
},
'password': {
type: String,
label: 'Password',
min: 6
}
});
}
Template.setupStepTwo.schema = function() {
return new SimpleSchema({
'password': {
type: Boolean,
label: 'Confirm your registration'
}
});
}
Related
I need your help. I have updated Autoform to version 6.0 and my forms doesn't work, I got this error:
Uncaught TypeError: ss.getQuickTypeForKey is not a function
at Object.autoFormGetInputValue [as getInputValue] (autoform-api.js:493)
at HTMLInputElement.<anonymous> (autoform-inputs.js:6)
My template .html autoform: here I have a simple insert autoform in order to insert an image reference and data.
<template name="insertArtForm">
{{#autoForm collection=artCollection doc=user id="insertArtForm" type="insert"}}
<fieldset>
{{> afQuickField name='createdBy' type='hidden' defaultValue=user._id}}
{{> afQuickField name='createdOn' type='hidden' defaultValue=today}}
<h4>ResoluciĆ³n</h4>
<div class="container">
{{> afQuickField formgroup-class="col-md-1" name='width' type='number'}}
<p class='col-md-1'>x</p>
{{> afQuickField formgroup-class="col-md-1" name='height' type='number'}}
</div>
{{> afQuickField name='name' type='text'}}
{{> afQuickField name='description' type='textarea'}}
{{> afQuickField name='prixQuote' type='text'}}
{{> afQuickField name='artURL' type='text'}}
</fieldset>
<button type="submit" class="btn btn-default" id="js-insert-art-form">Guardar</button>
{{/autoForm}}
</template>
My .js events:
Template.insertArtForm.events({
"click #js-insert-art-form": function(e){
console.log("entra en el evento");
$(".js-save-label").css("visibility","visible");
window.setTimeout(function() {
$(".js-save-label").fadeTo(500, 0).slideUp(500, function(){
$(this).remove();
});
}, 3000);
}
});
My schema:
import { Mongo } from 'meteor/mongo';
import { Index, MinimongoEngine } from 'meteor/easy:search';
import SimpleSchema from 'simpl-schema';
SimpleSchema.extendOptions(['autoform']);
/*Create and export Arts Collection*/
export const Arts = new Mongo.Collection('arts');
/*Arts index for easy:search*/
export const ArtIndex = new Index({
collection: Arts,
fields: ['name'],
engine: new MinimongoEngine(),
});
//Define Art schema
Arts.schema = new SimpleSchema({
createdBy: { //Owner
type: String,
label: "Artista",
regEx: SimpleSchema.RegEx.Id,
optional: true
}, createdOn: {
type: Date,
label: "Fecha",
optional: true
}, height: {
type: String,
label: "Alto",
optional: true
}, width: {
type: String,
label: "Ancho",
optional: true
}, name: {
type: String,
label: "Nombre de la obra",
optional: true
}, description: {
type: String,
label: "DescripciĆ³n de la obra",
optional: true
}, prixQuote: {
type: String,
label: "PrixQuote",
optional: true
}, artURL: {
type: String,
label: "URL de la obra",
optional: true
}
});
/*Attach the Arts schema for automatic validations*/
Arts.attachSchema(Arts.schema);
I'm really desperate.
I also had this issue. Be sure to have the latest node simpl-schema installed in your packages.json. I upaded to "simpl-schema": "0.2.3" and the error went away.
I am trying to use meteor-pages. In my JavaScript code I have:
Tasks = new Mongo.Collection("tasks");
Tasks.attachSchema(new SimpleSchema({
title: {
type: String,
label: "Title",
max: 200
},
complete: {
type: Boolean,
defaultValue: false,
label: " ",
autoform: {
type: "boolean-checkbox"
}
},
dueDate: {
type: Date,
label: "Due Date",
optional: true,
autoform: {
type: "pickadate"
}
}
}));
Pages = new Meteor.Pagination(Tasks, {
templateName: "tasksPaginated"
})
In my html, I have:
<template name="TaskList">
Before
{{> tasksPaginated}}
After
</template>
<template name="tasksPaginated">
{{> pages}}
{{> pagesNav}} Bottom navigation
</template>
When I try to browse to the page, I get the following error:
Exception in delivering result of invoking 'pages_tasks/CountPages':
Error
at Connection._livedata_result (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:4736:23)
at onMessage (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:3385:12)
at http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:2736:11
at Array.forEach (native)
at Function..each..forEach (http://localhost:3000/packages/underscore.js?hash=cde485f60699ff9aced3305f70189e39c665183c:149:11)
at SockJS.self.socket.onmessage (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:2735:11)
at SockJS.REventTarget.dispatchEvent (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:175:22)
at SockJS._dispatchMessage (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:1160:10)
at SockJS._didMessage (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:1218:18)
at WebSocket.that.ws.onmessage (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:1365:17)
Any ideas what I could be doing wrong?
The documentation for meteor-pages says you can initialise it like this:
this.Pages = new Meteor.Pagination("tasks");
And this will automatically pick up a template called "tasks". The other way (which I think you want) is to specify a different template, in which case your code should be :
this.Pages = new Meteor.Pagination("tasks", {itemTemplate: "tasksPaginated"});
That should solve it for you
Make sure the code
Pages = new Meteor.Pagination(Tasks, {
templateName: "tasksPaginated"
})
don't run before your Template.tasksPaginated is available globally
I am learning the ropes of Meteor and kind of lost here. I am using collections2, autoform for building my application. I want to store the collection along with user id information. So that when we retrieve the collection from the server, I want to show only the ones the user created not everything else. here is the schema.
ExercisesSchema = new SimpleSchema({
"name": {
type: String,
label: 'Name'
},
"workout.$.weight": {
type: String,
label: 'Weight'
},
"workout.$.reps": {
type: String,
label: 'Reps'
},
"notes": {
type: String,
label: 'Notes',
optional: true
}
});
on the server side I want to show only the workouts created by the user
Meteor.publish('exercises', function () {
return Exercises.find({owner: this.userId});
});
When I added the user id to the schema, it shows up in the autoform, I am not sure how to hide it, if I hide it, then possibly I can use hooks in the autoform to add the values?
In the schema you can define the ownerId as type: "hidden"
schema.js
ExercisesSchema = new SimpleSchema({
"name": {
type: String,
label: 'Name'
},
"ownerId": {
type: String,
autoform: {
type: "hidden",
}
},
"workout": {
//not sure if you need this, you didn't have it in your
type: [Object],
defaultValue: []
},
"workout.$.weight": {
type: String,
label: 'Weight'
},
"workout.$.reps": {
type: String,
label: 'Reps'
},
"notes": {
type: String,
label: 'Notes',
optional: true
}
});
And populate it with the hooks as you said.
autoFormHooks.js
AutoForm.hooks({
exerciseForm: {
formToDoc: function(doc) {
doc.ownerId = Meteor.userId();
return doc
},
}
});
An alternative to using hooks would be to use a quickFields inside of your autoForm for each field that you want to set in the doc, including ownerId. With this solution you would set the value of ownerId to currentUser.
{{#autoForm collection="Exercises" id="exerciseForm" type="insert"}}
<fieldset>
<legend>Add an Exercise</legend>
{{> afQuickField name='name'}}
{{> afQuickField name='notes'}}
{{> afQuickField name='ownerId' value=currentUserId}}
{{> afQuickField name='workout'}}
</fieldset>
<button type="submit" class="btn btn-primary">Insert</button>
{{/autoForm}}
template.js
Template.formTemplate.helpers({
currentUserId: function () {
return Meteor.userId();
}
});
You could try the before hook approach:
ExercisesSchema = new SimpleSchema({
...
"ownerId": {
type: String,
autoform: {
type: "hidden",
}
},
...
});
In your template:
{{#autoForm collection="Exercises" id="exerciseForm" type="insert"}}
<fieldset>
<legend>Add an Exercise</legend>
{{> afQuickField name='name'}}
{{> afQuickField name='notes'}}
<!-- Notice I've removed the ownerId from here. Will be added before saving to collection -->
{{> afQuickField name='workout'}}
</fieldset>
<button type="submit" class="btn btn-primary">Insert</button>
{{/autoForm}}
Then your autoform.js
var addUserHook = {
before: {
insert: function(doc) {
if(Meteor.userId()){
doc.ownerId = Meteor.userId();
}
return doc;
}
}
}
AutoForm.addHooks('exerciseForm', addUserHook);
The above adds the ownerId on the fly just when about to save to collection.
As stated in the docs on atmospherejs.com/aldeed/autoform:
For example, you might want to add the current user's ID to a
document before it is inserted. You can use "before", "formToDoc", or
"formToModifier" hooks to do this.
I am having a problem getting my Insert Autoform to work properply. I am trying to have it similar to the example http://autoform.meteor.com/insertaf and my code is below. I have already removed insecure and autopublish
client/templates/venues/venue_submit.html
<template name="venueSubmit">
<!-- {{> quickForm collection="Venues" id="venueSubmit" type="insert"}} -->
{{#if isSuccessfulvenueSubmit }}
<h2>Thanks for the Venue </h2>
{{else}}
{{#autoForm id="insertVenueForm" type="insert" collection=Collections.Venues omitFields="createdAt" resetOnSuccess=true}}
{{> afQuickField name="Venue"}}
<div class="form-group">
<button type="submit" class="btn btn-primary">Add Venue</button>
<button type="reset" class="btn btn-default">Reset Form</button>
</div>
{{/autoForm}}
{{/if}}
</template>
client/templates/venues/venue_submit.js
Schemas = {};
Template.registerHelper("Schemas", Schemas);
Schemas.Venue = new SimpleSchema({
Venue: {
type: String,
label: "Venue Name",
max: 200,
autoform: {
placeholder: "Name of the Venue"
}
},
....
});
AutoForm.debug()
var Collections = {};
Template.registerHelper("Collections", Collections);
Venues = Collections.Venues = new Mongo.Collection("Venues");
Venues.attachSchema(Schemas.Venue);
Venues.allow({
insert: function (userId, doc) {
return true;
},
remove: function (userID, doc, fields, modifier) {
return true;
},
remove: function (userId, doc) {
return true;
}
});
if (Meteor.isClient) {
Meteor.subscribe("Venues")
};
server/Publications.js
Meteor.publish('venue', function () {
return Venues.find(id);
});
The AutoForm insert type generates a document and inserts in on the client. Without the autopublish and insecure packages installed you need to make sure to subscribe to the appropriate collection on the client. It does not exist if you do not subscribe to it.
if (Meteor.isClient) {
Meteor.subscribe("Venues")
}
Your problem is that you have venue_submit.js inside the client folder, but its contents are not intended solely for the client.
You can leave venue_submit.html exactly as it is.
Change venue_submit.js to:
Template.registerHelper("Schemas", Schemas);
AutoForm.debug();
Template.registerHelper("Collections", Collections);
Meteor.subscribe("Venues");
You only need the lines here that relate to the client: the two template helpers, the AutoForm debug (which you don't need except for debugging), and the subscribe to the Venues collection.
Change server/Publications.js to include everything related to the server side:
Meteor.publish('Venues', function () {
return Venues.find({});
});
Venues.allow({
insert: function (userId, doc) {
return true;
},
remove: function (userID, doc, fields, modifier) {
return true;
},
remove: function (userId, doc) {
return true;
}
});
It includes the publish function and the permissions on the collection.
Now create lib/schema.js:
Schemas = {};
Schemas.Venue = new SimpleSchema({
Venue: {
type: String,
label: "Venue Name",
max: 200,
autoform: {
placeholder: "Name of the Venue"
}
}
});
Collections = {};
Venues = Collections.Venues = new Mongo.Collection("Venues");
Venues.attachSchema(Schemas.Venue);
Everything in lib will be available to both the client and server and the contents of this folder will be loaded first so the schema and collection definitions will be available to all the rest of the code. Note the lack of a var keyword for the Collections. Using var sets the scope to only within the file. Omitting it makes the Collections variable available throughout your code.
I'm having trouble getting Meteor.publish to update in response to a changing form field. The first call to publish seems to stick, so the query operates in that subset until the page is reloaded.
I followed the approach in this post, but am having no luck whatsoever.
Any help greatly appreciated.
In lib:
SearchResults = new Meteor.Collection("Animals");
function getSearchResults(query) {
re = new RegExp(query, "i");
return SearchResults.find({$and: [ {is_active: true}, {id_species: {$regex: re}} ] }, {limit: 10});
}
In client:
Session.set('query', null);
Template.searchQuery.events({
'keyup .query' : function (event, template) {
query = template.find('.query').value
Session.set("query", query);
}
});
Meteor.autosubscribe(function() {
if (Session.get("query")) {
Meteor.subscribe("search_results", Session.get("query"));
}
});
Template.searchResults.results = function () {
return getSearchResults(Session.get("query"));
}
On server:
Meteor.publish("search_results", getSearchResults);
Template:
Search for Animals
<body>
{{> searchQuery}}
{{> searchResults}}
</body>
<template name="searchQuery">
<form>
<label>Search</label>
<input type="text" class="query" />
</form>
</template>
<template name="searchResults">
{{#each results}}
<div>
{{_id}}
</div>
{{/each}}
</template>
Update [WRONG]
Apparently, the issue is that the collection I was working with was (correctly) generated outside of Meteor, but Meteor doesn't properly support Mongo's ObjectIds. Context here and related Stackoverflow question.
Conversion code shown there, courtesy antoviaque:
db.nodes.find({}).forEach(function(el){
db.nodes.remove({_id:el._id});
el._id = el._id.toString();
db.nodes.insert(el);
});
Update [RIGHT]
So as it turns out, it was an issue with RegExp / $regex. This thread explains. Instead of:
function getSearchResults(query) {
re = new RegExp(query, "i");
return SearchResults.find({$and: [ {is_active: true}, {id_species: {$regex: re}} ] }, {limit: 10});
}
At the moment, one needs to do this instead:
function getSearchResults(query) {
// Assumes query is regex without delimiters e.g., 'rot'
// will match 2nd & 4th rows in Tim's sample data below
return SearchResults.find({$and: [ {is_active: true}, {id_species: {$regex: query, $options: 'i'}} ] }, {limit: 10});
}
That was fun.
PS -- The ddp-pre1 branch has some ObjectId functionality (SearchResults = new Meteor.Collection("Animals", {idGeneration: "MONGO"});)
Here's my working example:
UPDATE the original javascript given was correct. The problem, as noted in the comments, turned out to be that meteor doesn't yet support ObjectIds.
HTML:
<body>
{{> searchQuery }}
{{> searchResults}}
</body>
<template name="searchQuery">
<form>
<label>Search</label>
<input type="text" class="query" />
</form>
</template>
<template name="searchResults">
{{#each results}}
<div>
{{id_species}} | {{name}} - {{_id}}
</div>
{{/each}}
</template>
Javascript:
Animals = new Meteor.Collection("Animals");
function _get(query) {
re = new RegExp(query, "i");
console.log("rerunning query: " + query);
return Animals.find({$and: [ {is_active: true}, {id_species: {$regex: re}} ] }, {limit: 10});
};
if (Meteor.isClient) {
Session.set("query", "");
Meteor.autosubscribe(function() {
Meteor.subscribe("animals", Session.get("query"));
});
Template.searchQuery.events({
'keyup .query' : function (event, template) {
query = template.find('.query').value
Session.set("query", query);
}
});
Template.searchResults.results = function () {
return _get(Session.get("query"));
}
}
if (Meteor.isServer) {
Meteor.startup(function() {
if (Animals.find().count() === 0) {
Animals.insert({name: "panda", is_active: true, id_species: 'bear'});
Animals.insert({name: "panda1", is_active: true, id_species: 'bearOther'});
Animals.insert({name: "panda2", is_active: true, id_species: 'bear'});
Animals.insert({name: "panda3", is_active: true, id_species: 'bearOther'});
}
});
Meteor.publish("animals", _get);
}