My Meteor app has a popover which lists tasks completed by people on a team. Team members can signal a new task completion simply opening the popover, filling out the input field and then pressing the enter key. It happens that, for some reason, the form submit event is fired more than once and then I got duplicated records in my Mongodb.
This is my code:
Template.header.onRendered(function() {
$("#sneak-preview-btn").popover({
container: 'body',
template: '<div class="popover work-journals-popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>',
animation: true,
placement : 'right',
html : true,
delay: { "show": 500, "hide": 100 },
trigger : 'manual',
content : function() {
var popTitle = "<h5>Peek last 5 activities completed by your team mates.</h5>";
var formAddEntry = "<form id='add-entry'><div class='form-group'><input id='entry' name='entry' type='text' class='form-control' placeholder='Add a new task you completed'/></div></form>";
var entriesLimit = 5;
var htmlEntryList = "";
var myEntries = WorkJournals.find({userId : Meteor.userId()}, {sort : {createdAt : -1}, limit : entriesLimit}).fetch();
if (myEntries) {
htmlEntryList ="<div class='scroll-journal-entries'><ul>";
myEntries.map(function(en) {
htmlEntryList += libGetHtmlJournalEntry(en);
});
htmlEntryList += "</ul>";
var companyUsers = Profiles.find({companyId : libGetCompanyIdFromUser(Meteor.userId())}, {fields : {userId : 1}}).fetch();
companyUsers.filter(function(user) {
if (user.userId !== Meteor.userId())
htmlEntryList += libGetHtmlJournalEntries(user.userId, entriesLimit);
});
htmlEntryList += "</div>";
}
return "<div>" + popTitle + formAddEntry + "<p>" + htmlEntryList + "</p><button id='close-sneak-preview' type='button' class='btn btn-default btn-xs pull-right'>Close</button><br>" + "</div>";
}
});
//manage lost focus
$(document).on('blur', '.popover', function(e) {
e.preventDefault();
$("#sneak-preview-btn").popover('hide');
});
//manage submit
$(document).on('submit', '#add-entry', function(e) {
e.preventDefault();
WorkJournals.insert({
companyId: Profiles.findOne({userId : Meteor.userId()}).companyId,
userId : Meteor.userId(),
entryText : $('#entry').val(),
createdAt : new Date().getTime()
});
$("#sneak-preview-btn").popover('hide');
libShowAlert('messages-heading-row', 'A completed task was added to your activity log', 'alert-nice');
});
$(document).on('click', "#close-sneak-preview", function() {
$("#sneak-preview-btn").popover('hide');
});
});
This doesn't look very Meteor to me. You have a template, yet register events with the document? Can it be that on multiple renders of your header template the $(document) events accumulate, so you end up with a whole chain of those?