I'm currently delving into the realms of Session and reactive data sources within the Meteor JS framework. They prove to be quite useful for managing global UI states. However, I've encountered a challenge in scoping them to a specific instance of a template.
My Objective
I have multiple contenteditable elements on a single webpage, each accompanied by an "Edit" button. On clicking the Edit button, the respective element should be focused on with "Save" and "Cancel" buttons displayed alongside.
Upon clicking "Cancel", any changes should be discarded, and the template instance should refresh with the original content.
The Code Implementation So Far
// Helper
Template.form.helpers({
editState: function() {
return Session.get("editState");
}
});
// Rendered
Template.form.rendered = function(e){
var $this = $(this.firstNode);
var formField = this.find('.form-field');
if (Session.get("editState")) formField.focus();
};
// Event map
Template.form.events({
'click .edit-btn' : function (e, template) {
e.preventDefault();
Session.set("editState", "is-editing");
},
'click .cancel-btn' : function (e, template) {
e.preventDefault();
Session.set("editState", null);
},
});
// Template
<template name="form">
<div class="{{editState}}">
<p class="form-field" contenteditable>
{{descriptionText}}
</p>
</div>
<a href="#" class="edit-btn">Edit</a>
<a href="#" class="save-btn">Save</a>
<a href="#" class="cancel-btn">Cancel</a>
</template>
// CSS
.edit-btn
.cancel-btn,
.save-btn {
display: inline-block;
}
.cancel-btn,
.save-btn {
display: none;
}
.is-editing .cancel-btn,
.is-editing .save-btn {
display: inline-block;
}
The Dilemma
When dealing with multiple instances of the Form
template, the .form-field
gets focused on every instance, rather than just the one being edited. How can I ensure that only the currently edited element is focused upon?