# Calculation on Focus Out

#1

If I have 3 form fields I’d like to calculate once they have data in them and the focus leaves, how would I code out the Template.template.events({})?

2 | 2 | 2 | 6

Thank you!

#2

Use jquery focusout event

https://api.jquery.com/focusout/

``````'focusout #inputfield': function(event, template) {
//docalculation
}``````

#3

Thank you, I’ll give it a shot and come back if I still can’t figure it out.

Appreciate the help!

#4

Okay, I whipped up a simple example for you, obviously this could be improved upon but I think it should give you a basic idea of how things work.

``````<template name="form">
<p>Units: <input type="number" name="units" value="1"></p>
<p>Price: <input type="number" name="price" value="20"></p>
<p>Tax(%): <input type="number" name="tax" value="10"></p>
<p>Total: {{total}}</p>
</template>
``````
``````if (Meteor.isClient) {

Template.form.helpers({
total: function () {
return Session.get('total');
}
});

Template.form.events({
'change': function(event, template) {
var units = template.find("input[name=units]").valueAsNumber
var price = template.find("input[name=price]").valueAsNumber
var tax = template.find("input[name=tax]").valueAsNumber
var total = (units * price) + ((units * price) * (tax/100))
Session.set('total', total);
}
});
}

``````

#5

I think using Session in this case is overkill. You don’t really want to save the value locally right? You just want a dynamic value.

Here’s an example I wrote:

``````<template name="Calculator">
<input data-bind="value: a" />
<input data-bind="value: b" />
<input data-bind="value: c" />
<p data-bind="text: total"></p>
</template>

Template.Calculator.viewmodel({
a: 0,
b: 0,
c: 0,
total: function(){
return parseInt(this.a(), 10) + parseInt(this.b(), 10) + parseInt(this.c(), 10);
}
})
``````

#6

Oh wow that’s fantastic, thank you! I really appreciate you showing me how you did that, thank you!

#7

Awesome, thank you! I’m going to give this a shot

#8

@sergiotapia

This part right here is where I’m struggling.

instead of having the variables equal 0, how can I have them pull from the collection the value that was saved when either first submitted or after an update occurred? So for example, let’s say I saved a as 7 last time and b as 6, it would load the page with a: 6 b:7 c:0 and calculate. I am having the hardest time trying to pull that data from the collection.

Thanks for any help you can provide!

#9

There are many ways of doing it.

If you know the data subscription is going to be ready by the time the template is created you can just do:

``````Template.Calculator.viewmodel(
function() {
var dv = DefaultValues.findOne();
return {
a: dv.a,
b: dv.b,
c: dv.c,
total: function () {
return this.a() + this.b() + this.c();
}
}
}
);
``````

If you have many default values you can use the document when you create the view model:

``````Template.Calculator.viewmodel(
function() {
// Add all properties to the view model
return DefaultValues.findOne(); // or pluck the values
},
{
total: function () {
// We're assuming the default document will have properties a, b, and c.
return this.a() + this.b() + this.c();
}
}
);
``````

If you don’t know when the data is ready then you have the problem of maybe overwriting the user’s values. It all depends on where you’re subscribing to the data and when the subscription is ready. The following example subscribes when the template is created and updates the values as soon as the data is ready.

``````Template.Calculator.viewmodel({
a: 0,
b: 0,
c: 0,
total: function () {
return this.a() + this.b() + this.c();
},
onCreated: function (template) {
var that = this;
template.subscribe('defaultData', function(){
var dv = DefaultValues.findOne();
that.a(dv.a);
that.b(dv.b);
that.c(dv.c);
})
}
});
``````

Again, it all depends on how you’re getting the data so you might end up doing something different than these.

See Defining View Models for more information.

#11

Thank you @manuel. I’ll see how integration goes and let you know if I’m still stuck.