Template helper not invoked on update aldeed autoform - meteor

I am using meteoric-autoform and doing an update to my values, The form is not getting populated with existing values and also the update is not happening.
I could also see that the template helper method that I have for fetching the id is not getting invoked at all.
assesmentEdit.js
Template.assesmentEdit.helpers({
assesment: function () {
alert("entered helper");
console.log(template.data.id);
var template = Template.instance();
return Assesments.findOne({_id: template.data.id});
}
});
assesmentEdit.html
<template name="assesmentEdit">
{{#ionModal customTemplate=true}}
{{# autoForm collection="Assesments" id="assesments-edit-form" type="update"}}
<div class="bar bar-header bar-stable">
<button data-dismiss="modal" type="button" class="button button-clear">Cancel</button>
<h2 class="title">Edit Assesment</h2>
<button type="submit" class="button button-positive button-clear">Save</button>
</div>
<div class="content has-header overflow-scroll">
{{> afQuickField name="name" }}
{{> afQuickField name="email"}}
{{> afQuickField name="category"}}
{{> afQuickField name="location"}}
</div>
{{/autoForm}}
{{/ionModal}}
</template>

As you can see in the docs, update forms require a doc attribute.
{{# autoForm doc=assesment collection="Assesments" id="assesments-edit-form" type="update"}}

Related

How can I style an autoform in Meteoric?

{{#autoForm schema="asdf" id="sdfg" type="method" meteormethod="meth"}}
<fieldset>
{{> afQuickField name="startLocation"}}
{{> afQuickField name="destination"}}
{{> afQuickField name="date"}}
{{> afQuickField name="departureTime"}}
{{> afQuickField name="returnTime"}}
{{> afQuickField name="seats" type="number"}}
</fieldset>
<button type="submit" class="btn btn-primary">submit<button>
{{/autoForm}}
The above code generates a form in my Meteor app, however it looks pretty bad (or at least, non-intuitive):
I don't know why this is. In the examples (1, 2) I'm looking at, the form renders in a much more sensical way. How can I get the afQuickField to show the label and the input on separate lines, or at least in another way that makes sense?

Meteor Users: add user by admin user only

I'm using the useraccounts package in my Meteor app. I want an admin to be able to add a new user (and disable signing up through the frontend). Therefore, I have added a Collection with a SimpleSchema as per the suggestion of meteor-collection2. I'm alos using AutoForm to create an 'Add user' page.
<template name="addCustomerProfile">
<div class="container">
<h1>Edit document</h1>
{{#if isReady 'updateCustomerProfile'}}
{{#autoForm collection="Users" id="userForm" type="insert" }}
<fieldset>
{{> afQuickField name='emails.0.address'}}
{{> afQuickField name='emails.0.verified'}}
{{> afQuickField name='services.password'}}
{{> afQuickField name='username'}}
{{> afQuickField name='profile.firstName'}}
</fieldset>
<button type="submit" class="btn btn-primary">Add User</button>
{{/autoForm}}
{{else}}
Nothing
{{/if}}
</div>
</template>
I can add users whenever the 'services.password' is not added to the form, but obviously no default password is set for the user in the Mongo database in that case. How can I add a field so the admin can set a default password for that user (which the user will then be able to change later on).
Why not just forbidClientAccountCreation and sendEnrollmentEmail?
Accounts.config({
forbidClientAccountCreation: true
});
Meteor.methods({
'inviteUser': function (doc) {
check(doc, YourForm);
let userId = Accounts.createUser(doc);
Accounts.sendEnrollmentEmail(userId);
}
});

Meteor Flow Router issue with update

I have a Meteor app and I'm transitioning from IronRouter to FlowRouter. So far so good, but there are aspects I don't understand yet.
I have a route as follows:
FlowRouter.route('/documents/:docId/edit', {
name: 'documentEdit',
subscriptions: function (params, queryParams) {
this.register('documentEdit', Meteor.subscribe('documentSingle', params.docId));
},
action: function (params, queryParams) {
BlazeLayout.render('layout', { top: 'header', main: 'documentEdit' });
},
});
First option:
Then I also have a template:
<template name="documentEdit">
<div class="container">
<h1>Edit document</h1>
{{#if isReady 'documentEdit'}}
{{#autoForm collection="Documents" doc=this id="documentForm" type="update" meteormethod="documentUpdateMethod"}}
<fieldset>
{{> afQuickField name='title'}}
{{> afQuickField name='content' rows=6}}
</fieldset>
<button type="submit" class="btn btn-primary">Update</button>
<a class="btn btn-link" role="button" href="{{pathFor 'documentsList'}}">Back</a>
{{/autoForm}}
{{/if}}
</div>
</template>
with a template helper as follows:
Template.documentEdit.helpers({
isReady: function(sub) {
if(sub) {
return FlowRouter.subsReady(sub);
} else {
return FlowRouter.subsReady();
}
}
});
This is as it is mentioned here, but I'm not getting the values pre-filled in the textboxes on the UI (which is normal when editing fields).
Second option:
When I do the following it works and I don't really understand why it works (found it browsing in different forums and tried it out):
<template name="documentEdit">
<div class="container">
<h1>Edit document</h1>
{{#with getDocument }}
{{#autoForm collection="Documents" doc=this id="documentForm" type="update" meteormethod="documentUpdateMethod"}}
<fieldset>
{{> afQuickField name='title'}}
{{> afQuickField name='content' rows=6}}
</fieldset>
<button type="submit" class="btn btn-primary">Update</button>
<a class="btn btn-link" role="button" href="{{pathFor 'documentsList'}}">Back</a>
{{/autoForm}}
{{/with}}
</div>
</template>
and the helper:
Template.documentEdit.helpers({
getDocument: function () {
return Documents.findOne();
}
});
So the questions are:
for the 1st option: any idea why it does not work. I would prefer that one as it's the documented way of doing things
for the 2nd option: not sure why I need (in the template helper) to do a Document.findOne() without even having to pass the id of the doc I want to edit:
You want to do template level subscriptions with Flow Router, that's one of the primary pattern changes.
So you'd do:
Setup the subscription at the template level. Autorun so it'll resubscribe on route changes.
Template.documentEdit.onCreated(function() {
var self = this;
this.autorun(function() {
var docId = FlowRouter.getParam('docId');
self.subscribe('documentSingle', docId));
};
};
Setup the template helper to pick up from the route, and grab the id and populate the helper/document.
Template.documentEdit.helpers({
getDocument: function () {
var docId = FlowRouter.getParam('docId');
var doc = Documents.findOne(docId) || {};
return doc;
}
});
Do a template level load check and if it's there render it, otherwise show loading...
<template name="documentEdit">
<div class="container">
<h1>Edit document</h1>
{{#if Template.subscriptionReady}}
{{#with getDocument }}
{{#autoForm collection="Documents" doc=this id="documentForm" type="update" meteormethod="documentUpdateMethod"}}
<fieldset>
{{> afQuickField name='title'}}
{{> afQuickField name='content' rows=6}}
</fieldset>
<button type="submit" class="btn btn-primary">Update</button>
<a class="btn btn-link" role="button" href="{{pathFor 'documentsList'}}">Back</a>
{{/autoForm}}
{{/with}}
{{else}}
Loading...
{{/if}}
</div>
</template>
Not knowing how this worked, seeing that all the tutorials I have read that deals with update used Iron router, I have spent 7 days worth of trying retrying, looking through others code, reading tutorials. Happy it now works.

Meteor Autoform Display E-mail Field

I have created an AutoForm update form that I am populating with the contents of a document. I am having a difficult time getting AutoForm to display the email address stored in the document.
<template name="edit_user_form">
{{#autoForm schema=schema id="edit_user_form" type="update" collection=Meteor.users doc=selected_user_doc}}
<fieldset>
{{> afQuickField name="profile.first_name"}}
{{> afQuickField name="profile.last_name"}}
{{> afQuickField name="emails"}}
{{> afQuickField name="status" options="allowed" noselect=true}}
{{> afQuickField name="roles" options="allowed" noselect=true}}
<div>
<button type="submit" class="btn btn-primary">Submit</button>
<button type="reset" class="btn btn-default">Reset</button>
</div>
</fieldset>
{{/autoForm}}
</template>
As a result, the Emails input field is populated with "[object Object]".
Since I am only allowing one e-mail per user, what is the correct way to tell AutoForm to populate a form field with an e-mail address? Thanks.
Yes, in meteor accounts, emails are considered an array. You can use this notation from the autoform github's issues:
{{> afQuickField name="emails.0.address"}}

meteor iron-router and dynamic template rendering

today i decided to migrate my main app from package router to iron-router.
My app was able to do dynamic template rendering :
some template are rendered programatically because it depends of some info from Mongo
That was quite easy with router package but with iron-router i fall into problems.
When i do a
Template.myTplName(data)
it always return a
TypeError: Object #<Object> has no method 'fn'
To get more logs i did this in the console :
try{
Template.myTplName(data);
} catch(e) {
console.trace();
}
And i get this :
You called Router.path for a route named undefined but that that route doesn't seem to exist. Are you sure you created it?
console.trace() utils.js:169
Utils.warn utils.js:169
IronRouter.path router.js:178
(anonymous function) helpers.js:49
apply evaluate-handlebars.js:241
invoke evaluate-handlebars.js:266
(anonymous function) evaluate-handlebars.js:330
Spark.labelBranch spark.js:1124
branch evaluate-handlebars.js:320
(anonymous function) evaluate-handlebars.js:329
_.each._.forEach underscore.js:79
template evaluate-handlebars.js:323
Handlebars.evaluate evaluate-handlebars.js:377
(anonymous function) evaluate-handlebars.js:11
(anonymous function) deftemplate.js:157
Spark.isolate spark.js:859
(anonymous function) deftemplate.js:154
Spark.createLandmark spark.js:1163
(anonymous function) deftemplate.js:135
Spark.labelBranch spark.js:1124
partial deftemplate.js:134
(anonymous function) VM28316:2
InjectedScript._evaluateOn VM28186:603
InjectedScript._evaluateAndWrap VM28186:562
InjectedScript.evaluate VM28186:481
console.trace() VM28316:2
(anonymous function) VM28316:2
InjectedScript._evaluateOn VM28186:603
InjectedScript._evaluateAndWrap VM28186:562
InjectedScript.evaluate
So in fact when i run that command, iron-router seems to try to handle it. But this template is not named in its stack so it might be a problem. But i donit want the router to manage that part.
Maybe i should change the conception of that part of the app but i would prefer not to have to.
Here is the code of the parent template:
<template name="resultsList">
{{#if selectedSearch}}
{{#if itemCount}}
<div class="row">
{{#each items}}
<div id="item_{{_id}}">{{> myitem}}</div>
{{/each}}
</div>
{{> loadMore}}
{{/if}}
</template>
Now the code of the template :
<template name="myitem">
{{#if currentUser}}
<div class="btn-toolbar">
<div class="btn-group" style="margin-left: 20px;">
{{#if hasDetail}}
<button class="btn btn-sm btn-success"><span class="glyphicon glyphicon-zoom-in"></span></
button>
{{else}}
<!-- fake button that just take the place of the detail button -->
<button class="btn btn-sm btn-link" style="cursor:default;text-decoration:none;margin-left:12px;"></button>
{{/if}}
<button {{#if starSelected}}disabled="disabled"{{/if}} class="btn btn-sm btn-info StarItem" title="A
appeler"><span class="glyphicon glyphicon-phone"></span></button>
<button {{#if visitedSelected}}disabled="disabled"{{/if}} class="btn btn-sm btn-info VisitItem" title="A
visiter"><span class="glyphicon glyphicon-road"></span></button>
<button {{#if removedSelected}}disabled="disabled"{{/if}} class="btn btn-sm btn-warning DelItem"
title="Supprimer"><span class="glyphicon glyphicon-remove icon-white"></span></button>
</div>
</div>
{{/if}}
<div class="infos">
{{{getItemInfo}}} <!-- This one will call the Template.myItem(data) -->
</div>
<div class="centerContentImage">
{{#if image}}
<img src="/img/annonces/{{_id}}" />
{{#if notCurrentUserAndHasDetail}}<button class="btn btn-info Openitem"><span class="glyphicon glyphicon-
zoom-in"></span></button>{{/if}}
{{else}}
{{else}}
<img src="/img/no_photo_icon.jpg" />
{{#if notCurrentUserAndHasDetail}}<button class="btn btn-info OpenDetailItem"><span class="glyphicon glyphicon-
zoom-in"></span></button>{{/if}}
{{/if}}
</div>
</template>
And the code of the JS :
So how can i do this ?
Thanx
ok, thanks to #ChristianFritz i looked more at the template, and in fact i found that Iron-Router provide a {{link}} helper. The problem is that my Json Object has a property named 'link', Iron-Router is not able to make the difference and it generates an error.
The Error is not really explicit
You called Router.path for a route named undefined but that that route doesn't seem to exist. Are you sure you created it?
But when using Iron Router we should have a look at the provided helpers because their naming is not using any kind of Namespace that would prevent that kind of problem.

Resources