Reputation: 3095
Problem:
I have several contenteditable elements. When a user focuses on an element, an editing
class name is added to the element. I am using Session object to do this, instead of jQuery. The problem is that everytime I focus on the element, it rerenders, and both the cursor position and focus is lost.
I am trying to use the preserve method
on the element to prevent it from getting updated when the element is being edited, but cannot get this to work. Any suggestions?
Here's my code:
// Collection
Forms = new Meteor.Collection('forms');
// Fixtures
if (Forms.find().count() === 0) {
Forms.insert({
description: "form 1"
});
Forms.insert({
description: "form 2"
});
}
if (Meteor.isClient) {
// Helpers
Template.forms.helpers({
editState: function() {
return Session.equals("fieldEditing", this._id) ? "editing" : "";
},
forms: function() {
return Forms.find();
}
});
// Preserve
Template.forms.preserve(['.editing']);
// Event handler
Template.forms.events({
'focus .form-field' : function (e, template) {
e.preventDefault();
Session.set("fieldEditing", this._id);
}
});
}
// Template
<head>
<title>testproject</title>
</head>
<body>
{{> forms}}
</body>
<template name="forms">
{{#each forms}}
<p class="{{editState}} form-field" contenteditable>
{{description}}
</p>
{{/each}}
</template>
Upvotes: 2
Views: 530
Reputation: 8865
This is caused by Spark
not considering the content of the contenteditable
node a value
that should be kept. Hence each render resets the content of the div, moving the cursor to the beginning.
I found closed issue that is similar https://github.com/meteor/meteor/issues/171 , but I don't think using {{#constant}}
regions is a great solution in your case.
I would suggest:
Note, I changed your code to the following to test easier:
if (Meteor.isClient) {
// Collection
Forms = new Meteor.Collection(null);
// Fixtures
if (Forms.find().count() === 0) {
Forms.insert({
description: "form 1"
});
Forms.insert({
description: "form 2"
});
}
// Helpers
Template.forms.helpers({
timer: function(){
return Session.get("timer");
},
forms: function() {
return Forms.find();
}
});
// Preserve
Template.forms.preserve({
".form-field":function(n){return n.id}
});
Session.set("timer",+new Date())
Meteor.setInterval(function(){
Session.set("timer",+new Date())
},2000);
}
// Template
<head>
<title>testproject</title>
</head>
<body>
{{> forms}}
</body>
<template name="forms">
{{timer}}
{{#each forms}}
<p class="form-field" contenteditable id="form-{{_id}}">
{{description}}
</p>
{{/each}}
</template>
Upvotes: 1