Undefined ReactiveVar - meteor

I am trying to implement JQuery slider in one of my forms, and I use a ReactiveVar to track it's value
Code:
Template.requestPaymentForm.created = function() {
this.requestAmountValue = new ReactiveVar(0);
};
Template.requestPaymentForm.helpers({
selectedRequestAmount: function() {
var value = Template.instance().requestAmountValue.get() / 100;
return value;
},
...
Template.requestPaymentForm.events({
'slide #requestAmountSlider': function(event, template) {
var sliderValue = template.$("#requestAmountSlider").slider("option","value");
template.requestAmountValue.set(sliderValue);
},
});
HTML
<template name='requestPaymentForm'>
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Request Payment</h4>
</div>
{{#autoForm collection="Payments" id="insertPaymentForm" type="method" meteormethod="createPayment"}}
<div class="modal-body">
<div class="amounts">
<span class="selected amount">Amount: {{formatMoney selectedRequestAmount}}</span>
<span class="available amount">Available: {{formatMoney availableForRequest}}</span>
</div>
<br>
<div id="requestAmountSlider"></div><br>
{{> afFieldInput name='amount'}}
</div>
<div class="modal-footer">
<button id="submitRequestPaymentForm" type="submit" class="btn btn-default btn-primary">Submit</button>
</div>
{{/autoForm}}
</div>
</template>
However, when I render this template, I get an error
TypeError: Cannot read property 'get' of undefined
at Object.Template.requestPaymentForm.helpers.selectedRequestAmount
Any idea as to why this is?
Much appreciated

This is a bug from Autoform plugin. All the initialization from your Template.requestPaymentForm.created is forfeited, and overwritten by Autoform .created . Thus, it said that the variable is undefined in helper.
I encounter the same problem and I am waiting for autoform team to fix this issue. My fix is adding a check in helper and assign value if it is null.Hope this helps.

Related

Meteor: No context for #each loop event handlers

I'm using an #each loop with an unmanaged local collection to generate a sequence of input fields for a form. However, when I try to use this._id in the event handler it is undefined. In fact, the context being passed to the event handler is for the window. Any help to find what is going wrong and how I should be getting the proper context as this within my event handler is much appreciated.
The code is:
<h4 class="page-header">Children on this account</h4>
{{#each children}}
<div id={{_id}} class="form-group col-md-12 child-form-instance">
<div class="form-group col-sm-5 col-xs-12">
<input type="text" name="childFirstName" class="form-control" placeholder="Child's First Name">
</div>
<div class="form-group col-sm-5 col-xs-10">
<input type="text" name="childLastName" class="form-control" placeholder="Child's Last Name" value="{{_id}}">
</div>
<div class="form-group col-xs-2">
<button type="button" class="btn btn-danger remove-child" aria-label="remove child">
<span class="glyphicon glyphicon-trash"></span>
</button>
</div>
</div>
{{/each}}
<div class="form-group">
<input type="button" id="addChild" class="btn btn-success" value="Add child">
</div>
and the js:
var children = new Mongo.Collection(null);
Template.signup.onRendered( () => {
Modules.client.signupValidateSubmit({
form: "#signup",
template: Template.instance()
});
children.remove({});
children.insert({}); //create one empty child
});
Template.signup.events({
'submit form': ( event ) => event.preventDefault(),
'click #addChild': () => {
children.insert({});
console.log(children.find().fetch());
},
'click .remove-child': () => {
console.log(this);
}
});
Template.signup.helpers({
children () {
return children.find();
}
});
Everything is working fine with the addChild button, and the _ids are getting properly assigned in the DOM, but the remove-child class is logging the window context.
You are using ES6 arrow functions which will lexically bind this with the parent scope. As a consequence, you don't get the scope of children.
In order to solve the issue, just change the template event to:
Template.signup.events({
// ...
'click .remove-child': function (event, template) {
console.log(this);
}
// ...
});

Meteor Bootstrap 3 Form does not Submit

I'm working with meteor#1.1.10 and twbs:bootstrap#3.3.5
I can get a modal window to spawn, close, and register a button has been clicked. I cannot get it to read any information from a form though. It just closes. I included a console message and it never shows up to either the browser or the command prompt.
Is there a way to do this without including another package? I've included my modal HTML template and Javascript. I'm hoping it's just something missed in the code.
Below is the HTML:
<template name="emodal">
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Spends Email Details</h4>
</div>
<div class="modal-body">
<form class="emailspends">
<label for="input">Recipient:</label>
<input type="text" name="emailto" required>
<label for="input">Character Name:</label>
<input type="text" name="charname" required>
<input type="submit" id="sendemail" class="email" value="Email Spends" data-dismiss="modal">
</form>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
</template>
Below is the Javascript:
Template.emodal.events({
"submit .emailspends": function (event) {
console.log(Meteor.user().emails[0].address);
// Prevent default browser form submit
event.preventDefault();
// Get value from form element
//var emailto = event.target.emailto.value;
var emailto = event.target.emailto.value;
var charname = event.target.charname.value;
var title = "Experience spends for " + charname;
Meteor.call('sendEmail', emailto,
'zbottorff#uwalumni.com', title,
'Yup, modal testies.');
// Clear form
event.target.emailto.value = "";
event.target.charname.value = "";
}
});
Update: Realized I should include this, but I did make sure I could get a submit-able template without it being in a modal window. Now I want to turn it into a modal and it's not submitting.
Bah! I found it just after I posted this.
I had too many parts to my submit button. I removed the "Class" and "id" parts, changed my Javascript to look for a 'submit form' event instead. Voala! Got the bugger to work.

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.

Ui-bootstrap-modal with ui-bootstrap-tpls-0.13 and bootstrap 3.3.2, angular 1.3.14 not working

As mentioned in the title, the modal does not show up.
The content of the form is loaded via formly and the content of the template seems to load, but it only shows the modal very thin, with the overlay but not the content.
I have a main controller in which I have:
$scope.add = function(){
$modal.open({
templateUrl: 'app/js/templates/popupAddCarForm.html',
controller: 'FormsController',
controllerAs: 'vm',
backdrop: 'static',
resolve: {
formData: function(){
return {
fields: getFormFields(),
model: {}
}
}
}
});
};
My html is like so:
<script type="text/ng-template" id="popupAddCarForm">
<div class="modal">
<div class="modal-dialog">
<div class="modal-header">
<h3 class="modal-title">Adauga masina</h3>
</div>
<div class="modal-body">
<form name="vm.addCarForm">
<formly-form model="vm.formData.model" fields="vm.formData.fields">
</formly-form>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-default" type="submit" >Adauga</button>
</div>
</div>
</div>
And my form controller like so:
davidintercar.controller('FormsController',
function($modalInstance, formData) {
var vm = this;
//debugger;
vm.formData = formData;
vm.originalFields = angular.copy(vm.formData.fields);
}
);
The result is like so:
LATER EDIT:
In order to rid ourselfes of other doubts, here is the code from the demo:
app.controller('ModalInstanceCtrl', function ($modalInstance, formData) {
var vm = this;
debugger;
// function assignment
vm.ok = ok;
vm.cancel = cancel;
// variable assignment
vm.formData = formData;
vm.originalFields = angular.copy(vm.formData.fields);
// function definition
function ok() {
$modalInstance.close(vm.formData.model);
}
function cancel() {
$modalInstance.dismiss('cancel');
};
});
Link: angular-formly.com/#/example/integrations/ui-bootstrap-modal
LATER, LATER EDIT:
Plunker: http://plnkr.co/edit/8wgL4t2oXsFFeLBKGGW8?p=preview
Folder Structure:
--app
----js
------controller
------services
------templates
------view
----app.js
intex.html
My popupAddCarForm.html is in the templates directory, but as you see in the plunker, it does not render my loaded content, even in the same directory although a separate template file.
The modal template don't need to have the modal and modal-dialog layer - they will be generated by bootstrap.
<script type="text/ng-template" id="popupAddCarForm.html">
<div class="modal-header">test
<h3 class="modal-title">Adauga masina</h3>
</div>
<div class="modal-body">
<form name="vm.addCarForm">
<formly-form model="vm.formData.model" fields="vm.formData.fields">
</formly-form>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-default" type="submit" >Adauga</button>
</div>
</script>

Template helper not invoked on update aldeed autoform

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"}}

Resources