Meteor JS: How to insert a document into the collection, but only on the client side?

I am new to Meteor and am creating a simple application to learn the structure. The application that I create allows you to place words on the image of a kitten.

Desired behavior:

The user clicks anywhere on the kitten and a content item appears allowing the user to enter text. A click outside the element saves the element and remains in place.

The problem I am facing:

If I have two browser windows open in the application, and I click on one kitten in one window, an empty field appears in both windows. Ideally, an empty field will appear only in the window that I clicked on. As soon as the word is saved, the inside should be visible in both windows.

My question is:

Is there a way to insertdocument to the collection only on the client side and then use it upsertlater to add the document to the servo-controlled collection?

Here is what I tried:

I created a stub method that exists only on the client side to insert a document. The problem with this is that when I click on the image, an empty field appears for a second, and then disappears again.

Here is the code:

images-tags.js

if (Meteor.isClient) {
  var isEditing;

  Template.image.image_source = function () {
    return "http://placekitten.com/g/800/600";
  };

  Template.tag.rendered = function(){
    var tag = this.find('.tag');
    if (isEditing && !tag.innerText) {
      tag.focus();
    }
  }

  Template.image.events({
    'click img' : function (e) {
      if (isEditing) {
        isEditing = false;
      } else {
        isEditing = true;
        var mouseX = e.offsetX;
        var mouseY = e.offsetY;

        // Tags.insert({x:mouseX, y:mouseY});

        // Insert tag on the client-side only.
        // Upsert later when the field is not empty.
        Meteor.call('insertTag', {x:mouseX, y:mouseY});
      }
    },

    'click .tag' : function (e) {
      isEditing = true;
    },

    'blur .tag' : function (e) {
      var currentTagId = this._id;
      var text = e.target.innerText;

      if(text) {
        Tags.upsert(currentTagId, {$set: {name: text}});
      } else {
        Tags.remove(currentTagId);
      }
    }
  });

  Template.image.helpers({
    tags: function() {
      return Tags.find();
    }
  });

  // Define methods for the collections
  Meteor.methods({
    insertTag: function(attr) {
      Tags.insert({x:attr.x, y:attr.y});
    }
  });
}

// Collections
Tags = new Meteor.Collection('tags');

image-tags.html

<head>
  <title>Image Tagger</title>
</head>

<body>
  {{> image}}
</body>

<template name="image">
  <figure>
    <img src="{{image_source}}" />
    <figcaption class="tags">
        {{#each tags}}
          {{> tag}}
        {{/each}}
      </figcaption>
  </figure>
</template>


<template name="tag">
  <div class="tag" contenteditable style="left: {{x}}px; top: {{y}}px;">
    {{name}}
  </div>
</template>
+4
source share
2 answers

You should save the temporary tag (and probably your isEditingvar) to Session:

Session.set("isEditing", true);
Session.set("newTag", {x:mouseX, y:mouseY});

, null . Session , . leaderboard .

Edit:

<figcaption class="tags">
  {{#each tags}}
    {{> tag}}
  {{/each}}
  {{#with newTag}}
    {{> tag}}
  {{/with}}
</figcaption>

Template.image.newTag = function() {
  return Session.get("newTag");
}
+4

, , : .

, - "" "" "" ( /eiditing/...) . :

  • , "" ""

, , . , .

,

0

All Articles