I’m new to Meteor and working on a “learning” project. I’m adapting a tutorial app for my own purposes (thank you George McKnight for the meteorshop video and repo!).
I’ve added peppelg:bootstrap-3-modal
and aldeed:autoform
to my project and I’ve setup this template:
<template name="productModalEdit">
<div class="modal fade" role="dialog">
<div class="modal-dialog" >
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Edit Product</h4>
</div>
<div class="modal-body">
{{#autoForm id="afUpdateProduct" doc=selectedProductDoc type="method-update" singleMethodArgument=false meteormethod="editProduct" collection=Collections.Products}}
<fieldset>
{{> afQuickField name='name'}}
{{> afQuickField name='desc' rows=4}}
{{> afQuickField name='price'}}
{{> afQuickField name='thumb'}}
{{> afQuickField name='catName'}}
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-primary" id="save">Save Product</button>
<button type="reset" class="btn btn-default">Reset Form</button>
</div>
{{/autoForm}}
</div>
</div>
</div>
</div>
</template>
There’s actually an almost duplicate template for inserting, so I call different templates for insert vs. update. There are two different meteor methods that correspond with each operation.
I have the following client javascript:
// helper to get the product categories out of the database
Template.productModalNew.helpers({
categories:function(){
return SubCategories.find().map(function (doc) {
return doc.name;
})
}
});
// add or update events for the product modal form template
Template.productModalNew.events({
'click #save': function(e) {
e.preventDefault();
Modal.hide('productModalNew');
}
});
Template.productModalEdit.helpers({
categories:function(){
return SubCategories.find().map(function (doc) {
return doc.name;
})
},
selectedProductDoc: function () {
return Products.findOne(Session.get("selectedProductId"));
}
});
// add or update events for the product modal form template
Template.productModalEdit.events({
'click #save': function(e) {
e.preventDefault();
Modal.hide('productModalNew');
}
});
Schemas = {};
Schemas.Product = new SimpleSchema({
name: {
type: String,
index: 1,
unique: true
},
desc: {
type: String,
optional: true
},
price: {
type: Number,
decimal: true,
optional: true
},
catName: {
type: String,
optional: true
},
thumb: {
type: String,
optional: true
}
});
var Collections = {};
Products = Collections.Products = new Mongo.Collection("Products");
Products.attachSchema(Schemas.Product);
// make sure the templates know about these helpers
Template.registerHelper("Schemas", Schemas);
Template.registerHelper("Collections", Collections);
// data access rules
// TODO: add some real rules to these
Products.allow({
insert: function () {
return true;
},
update: function () {
return true;
},
remove: function () {
return true;
}
});
Meteor.subscribe('products');
And this is the server code:
Meteor.methods({
addProduct:function(product){
var prod_id = Products.insert(product);
return prod_id;
},
editProduct:function(product, doc_id) {
Products.update({_id:doc_id},product);
}
});
This all seems to be right out of the documentation, and almost everything works, except for the actual method calls. I’m not reaching the methods when I do a form submit. The weird thing is I had this working and somehow I’ve broken it.
Since I had it working I did remove the autopublish
package, but I’m pretty sure I have the publish/subscribe thing all sorted out properly.
Is there anything obvious here that I have wrong? I’ve tried to use AnyForm.debug() to no avail. Obviously I don’t know how to do that correctly, and the documentation for it is “thin”, from what I’ve found so far.
Also, when I try to use collection="Products"
rather than collection=Collections.Products
things stop working (the form doesn’t render any fields). That would seem to be a clue that my Collections aren’t being recognized properly, but I have no idea why that would be.
Any pointers would be greatly appreciated. I’ve been over the AutoForm documentation about a dozen times and I’m getting nowhere fast with that path. If I’ve left out any important parts of the code please let me know and I’ll gladly get it in here.