How to reset a form in Meteor - meteor

I need to reset a popup form where the values are all filled from session variables:
Template.customerinfo.name = -> Session.get('activeCustomer').name
Right now I'm doing it manually:
Template.customerinfo.events
'click #cancelButton': ->
Client.getById('inputName').val(Session.get('activeCustomer').name)
Meteor.render would be even messier because I would have to pluck the current form/template, create a new one with Meteor.render and then insert it into the DOM.
Is there a way to tell meteor to reset a form or template and pull the values from their sources?

In your Handlebars template, i.e. after you do a Meteor.call() or collection insert / update, put this jQuery call. It returns the 1st form in the DOM, then calls the DOM reset().
$('.add-post-form')[0].reset();
In your HTML:
<form class="form-horizontal add-post-form" role="form">
// Your form HTML.
</form>
Also, see:
http://www.w3schools.com/jsref/met_form_reset.asp

just use event.target.name.value = "";

Just have a condition in which the template (or variable) will render, and then change that condition. For example in the HTML have:
<Template name="customerinfo">
{{#if somevariable}}
{{name}}
{{/if}}
</template>
And in the JS, have...
var somevariable = true;
and these helpers:
Template.customerinfo.name = function(){
return Session.get('activeCustomer').name;
}
Template.customerinfo.somevariable = function(){
return somevariable
}
Since the template will get rendered only when somevariable is true, when you need to re-render the form, execute the function resetForm():
resetForm = function(){
somevariable = false;
somevariable = true;
}

i think you can add a hide reset button to reset your form.
css
.hide { display: none; }
handlebars tmpl
<template name="btn-reset-hide">
<input type="reset" class="btn-reset-hide">
</template>
{{> btn-reset-hide}}
js
resetForm = (tmpl) ->
if tmpl?
($ tmpl.find '.btn-reset-hide').trigger 'click'
else
($ '.btn-reset-hide').trigger 'click'
call resetForm()

Related

Best way to prevent a template helper to be rerun when it is unnecessary?

I'm trying to prevent a template helper to be rerun when it is unnecessary. I made a simple application to illustrate this behavior:
Let's say I want to display some items that contain only a title and a description.
<template name="Tests">
{{#each items}}
{{> TestsItems}}
{{/each}}
</template>
<template name="TestsItems">
<div class="title">{{title}}</div>
<div class="description">{{description}}</div>
</template>
I have autopublish enabled.
Template.Tests.helpers({
items: function () {
return Items.find();
}
});
Template.TestsItems.helpers({
description: function () {
// I'm using this helper to do some updates
// on a jQuery plugin when the description field change.
// see example 1: https://github.com/avital/meteor-ui-new-rendered-callback/
console.log("The description is run");
return this.description;
}
});
When a new update is made on the title field only, you can see that the description helper is rerun. What I'm trying to achieve is to only rerun this helper when there is a new value for the description field and not every time a field has changed in the document.
As {{#constant}} and {{#isolate}} are deprecated, how can I get this behavior in the latest Meteor versions?
Note 1: Create a new subtemplate including the description does not fix the problem.
I would avoid side effects in template helpers. Instead I would use an autorun:
Template.TestItems.rendered = function () {
var _id = this.data._id;
this.autorun(function () {
// Select only the description field, so that we only
// trigger a re-run if the description field changes
var description = Items.findOne(_id, {fields: {description: 1}}).description;
// update the JQuery plugin
});
}

Meteor templates accessing subtemplate helper functions

Is it possible for a parent Meteor template to access a subtemplate directly? Ideally, I'd like to use templates a widgets with an API. I was hoping for something like this:
mypage.html
<template name="myPage">
<div class="widgetContainer"></div>
<button>submit</button>
</template>
mypage.js
Template.myPage.rendered = function(){
this.myWidgetInstance = UI.render(Template.myWidget)
UI.insert(this.myWidgetInstance, $('.widgetContainer')[0]);
}
Template.myPage.events({
'click button': function(e, template){
// I don't want this logic to live inside of mywidget.js.
// I also don't want this template to know about the <input> field directly.
var val = template.data.myWidgetInstance.getMyValue();
}
});
mywidget.html
<template name="myWidget">
<input></input>
</template>
mywidget.js
Template.myWidget.getValue = function(){
return this.$('input').val();
}
The above doesn't work because myWidgetInstance.getMyValue() doesn't exist. There doesn't appear to be a way for external code to access template helper functions on an instance.
Is anyone using Meteor templates in the way I'm trying to use them above? Or is this better suited for a separate jQuery widget? If so, it'd be a shame because I still want my widget template to benefit from the features Meteor provides.
It is possible to access subtemplate helper function.
Your example will work once you apply few fixes:
fix 1 : getValue() instead of getMyValue()
Template.myPage.events({
'click button': function(e, template){
// I don't want this logic to live inside of mywidget.js.
// I also don't want this template to know about the <input> field directly.
var val = template.myWidgetInstance.getValue();
console.log(val);
}
});
fix 2 : $('input').val(); instead this.$('input').val();
Template.myWidget.getValue = function(){
return $('input').val();
}
fix 3 : <input> should have no close tag.
<template name="myWidget">
<input type="text" value="sample value">
</template>

Meteor.js: how to swap partial templates in and out of the main page

Just starting with meteor.
Looking for a way to have a single "main page", which would contain an area, in which different partial templates could be swapped in and out, at a click of a Next/Previous buttons.
I understand how to include partial templates statically by using {{> step_1_Template}} syntax.
What I need, is to have the Next/Previous buttons permanently on the main page, and, when the Next button is clicked - remove the {{> step_1_Template}} and insert the {{> step_2_Template}}.
How is this done?
My knee-jerk reaction is that you should just use iron-router. However, that may only make sense if you are swapping out templates based on routes. If you are sticking with the same route and only changing the partials then you can accomplish this with session variables.
When the user clicks the 'next' button you can set a session variable like:
Template.myTemplate.created = function() {
Session.setDefault('currentStep', 1);
};
Template.myTemplate.events({
'click #next': function() {
var step = Session.get('currentStep');
return Session.set('currentStep', step + 1);
}
});
Then you can add a helper like:
Template.myTemplate.helpers({
isStep: function(n) {
return Session.equals('currentStep', n);
}
});
Finally your template can select the proper partial based on the session:
<template name='myTemplate'>
{{#if isStep 1}}
{{> step_1_Template}}
{{/if}}
{{#if isStep 2}}
{{> step_2_Template}}
{{/if}}
</template>

Edit in place Meteor view without using Session

I want to include a template (or use a helper, I don't care) that could be clicked to edit in place. This view MUST be reusable, and so can't rely on the Session variable or any other variables that aren't contained by the view instance.
In the display mode it would look like this:
<div class="editable">{{content}}</div>
which would change to the edit mode when you clicked on it, which would look like this:
<input type="text" value="{{content}}" />
and you could revert back to display mode (persisting it's changes appropriately) by either hitting enter or pressing a button.
It seems meteor doesn't make this incredibly easy, since my first attempts with html:
<template name="editable">
{{#if editing}}
<input type="text" value={{this}} />
{{else}}
<div class="edit-thing">{{this}}</div>
{{/if}}
</template>
// In the appropriate display template.
{{> editable stuff}}
and js:
Template.user.stuff = "yo yo yo";
Template.editable.events({
'click .edit-thing': function(e) {
this.isEditing = true;
}
});
Template.editable.helpers({
editing: function() {
return !!this.isEditing;
}
});
have had problems with not being reactive, which using the Deps library didn't solve. (This version just wouldn't change when you clicked it, since this.isEditing isn't reactive and doesn't trigger a change in the editing helper.)
Ask for more information if you like! Thanks!
That's a typical use case for Deps, did you remember to use both depend and changed? The js code may look like this:
Template.editable.created = function() {
this.data.isEditing = false;
this.data.isEditingDep = new Deps.Dependency();
};
Template.editable.events({
'... whatever to start edit mode ...': function(e, t) {
t.data.isEditing = true;
t.data.isEditingDep.changed();
},
'... whatever to close edit mode ...': function(e, t) {
t.data.isEditing = false;
t.data.isEditingDep.changed();
},
});
Template.editable.editing = function() {
this.isEditingDep.depend();
return this.isEditing;
};

in Meteor, how do i update a property on only one instance of a template?

If I have an {{# each}} binding in Meteor, and I want to update a property on only one instance of the template inside the #each. How would I do that? I've tried setting a value on the "template" object inside the events map, but that doesn't seem to be reactive. I've also tried binding to a Session property, but that will cause every instance to update instead of just the one I want...
for example:
{{#each dates}}
{{> dateTemplate}}
{{/each}}
<template name="dateTemplate">
{{date}}
<span style="color: red;">{{errorMsg}}</span> <--- how do i update errorMsg?
</template>
Template.dateTemplate.events({
'click': function(event, template) {
template.errorMsg = 'not valid'; <--- this doesn't do anything
}
});
EDIT TO ADDRESS ANSWER BELOW:
Template.dateTemplate.events({
'click': function(event, template) {
template.errorMsg = function() { return 'not valid';} <--- this also doesn't do anything
}
});
You don't have to use handlebars for this, because its not something that needs reactivity to pass the message through, reactive variables work best with db data, or data that would be updated by another client over the air.
You could use JQuery (included by default) to update it, it can also get a bit fancier:
<template name="dateTemplate">
{{date}}
<span style="color: red;display: none" class="errorMessage"></span>
</template>
Template.dateTemplate.events({
'click': function(event, template) {
$(template.find('.errorMessage')).html('Your Error Message').slideDown();
}
});
Ive edited it so the error is hidden by default, and slides down with an animation
I'm experimenting handling this by passing a different reactive object to each instance of the template. Then the template can bind to the reactive object (which is unique per instance) and we don't have any extra boilerplate.
It ends up looking like this:
Initial render:
Template.firstTemplateWithPoll(ContextProvider.getContext())
Template.secondTemplateWithPoll(ContextProvider.getContext())
// (I actually pass getContext an identifier so I always get the same context for the same template)
JS:
Template.poll.events = {
'click .yes' : function() {
this.reactive.set('selection', 'yes');
},
'click .no' : function() {
this.reactive.set('selection', 'no');
}
};
Template.poll.selection = function(arg) {
return this.reactive.get('selection');
}
Template:
<template name="poll">
<blockquote>
<p>
Your selection on this poll is {{selection}}
</p>
</blockquote>
<button class='yes'>YES</button>
<button class='no'>NO</button>
</template>
template.errorMsg should be a function that returns your error.
Template.dateTemplate.events({
'click': function(event, template) {
template.errorMsg = function() { return 'not valid'; };
}
});

Resources