简体   繁体   中英

Accessing collection field from specific id in meteor rendered template

UPDATE : I have added additional code for clarification, which is annotated with * NEW *. I was asked to clarify what this code is doing. A series of data is inputted into a collection called posts . On the postsList template the code is outputted when the timeToEnable field is less than the current time, which allows us to delay posts based on a specified date using this javascript time picker. The issue I have resides in /client/posts/post_edit.js where I am trying to set the value of one of the pickers from data in the collection which I don't know how to retrieve in javascript but I do in html simply using {{fieldHere}} and using the postsList template helper.

Hopefully this new code and info helps.

ORIGINAL QIUESTION.


I have a form that submits 5 fields in a posts collection. I have a edit page that, auto populates the tile, and content. However I have two separate Date/Time pickers. There is a function available to me to properly set the Date/Time pickers with the specific posts data when I am on the edit page. I cant output Date/Time data the usual way using {{date}} because it is stored in a particular format 2015-05-25T17:50:00.000Z I have created separate fields in the collection that separates day, month, year for do so using datepicker function.

This function will allow me to set the Date picker.

picker.set('select', new Date(year, month, date));

My Issue resides in getting the year, month and date data, based on the id that the post I am editing is using. I can place them in html using {{title}}, however I don't know how I would identify the id, and grab that post in the collection, and allow me to use picker.set like above.

Here is my code that I think will explain best what I have so far.

client /client/posts/post_submit.js

Template.postSubmit.events({
  'submit form' : function(e){
    e.preventDefault();
    var post = {
    title: $(e.target).find('[name=title]').val(),
    postContent: $(e.target).find('[name="postContent"]').val(),
    timeToEnable: new Date(year, month, day, hours, minutes),
    timeDisplay : timeDisplay,
    year : year,
    month : month,
    day : day,
    hours : hours
  };

  ////console.log(post.timeToEnable);

  Meteor.call('postInsert', post, function(error, result) {
    // display the error to the user and abort
    if (error){
      return alert(error.reason);
    }

    // show this result but route anyway
    if (result.postExists){
      alert('This link has already been posted');
    }

      Router.go('postPage', {_id: result._id});


  });

  }

});

/client/posts/posts_list.html * NEW *

<template name="postsList">
  <div class="posts page">
    {{#each posts}}
    {{> postItem}}
    {{/each}}
  </div>
</template>

/client/posts/post_item.html * NEW *

<template name="postItem">
  {{> dashboard}}
  <article>
    <div class="post">
      <div class="post-content">
        <h1>{{title}}</h1>
        <h3>{{timeDisplay}}</h3>
        <p>{{{postContent}}}</p>
        <a href="{{pathFor 'postPage'}}">View</a>
        {{#if ownPost}}<a class="editPost" href="{{pathFor 'postEdit'}}">Edit</a>{{/if}}


      </div>
    </div>
  </article>
</template>

/client/posts/posts_list.js * NEW *

Template.postsList.helpers({
  posts: function() {
    //return Posts.find({}, {sort: {submitted: -1}});
    //
    var data = new ReactiveDict();

    data.set("now", new Date());

    return Posts.find({timeToEnable: {$lt: data.get("now")}});


  }
});

/client/posts/post_edit.html

<template name="postEdit">

  {{> dashboard}}

  <div class="container">



  <form id="editForm">


    <div class="postTitle">
      <label class="titleLabel">Press Release Title.</label>
      <div class="input">
        <input name="title" id="title" type="text" value="{{title}}" placeholder=""/>
      </div>
    </div>

    <div class="postTime">
      <label class="titleLabel">Pick A time to post</label>
      <div class="input">
        <input class="timepicker" name="" id="" type="text" value="Click for a Time to Post" placeholder=""/>
      </div>
    </div>

    <div class="postDay">
      <label class="">Pick A Date to post</label>
      <div class="input">
        <input class="datepicker" name="" id="" type="text" value="Click for a Date to Post" placeholder=""/>
      </div>
    </div>



    <div>
      <div class="textarea">
        <label class="contentLabel">Press Release content.</label>


        <!-- <input name="postContent" id="postContent" type="text" value="" placeholder="Enwave has released a..."/> -->
        <textarea name="postContent" id="postContent" type="text"></textarea>
      </div>
    </div>

    <div id="submit">


    <input type="submit" value="Submit"/>

  </div>

  <div class="deletePost">
    <a class="btn btn-danger delete" href="#">Delete post</a>

  </div>

  </form>


  </div>
</template>

This is where I want to retrieve the post fields for year, month, date. So I can set the picker to that date, all based off the specific post ID.

/client/posts/post_edit.js

This is the crucial part I need to output the fields from the collection here based on its specified id

Template.postEdit.rendered = function(){
  picker.set('select', new Date(year, month, day));
}

lib

This Route outputs code to the html when using {{title}}.

/lib/router.js

Router.route('/posts/:_id/edit', {
  name: 'postEdit',
  data: function() { return Posts.findOne(this.params._id); }
});

lib/collections/posts.js * NEW *

Posts = new Mongo.Collection('posts');

Posts.allow({
  update: function(userId, post) { return ownsDocument(userId, post); },
  remove: function(userId, post) { return ownsDocument(userId, post); },
});

Posts.deny({
  update: function(userId, post, fieldNames) {
    // may only edit the following two fields:
    return (_.without(fieldNames, 'title', 'postContent','timeToEnable','timeDisplay','year','month','day','hours').length > 0);
  }
});

Meteor.methods({
  postInsert: function(postAttributes) {
    check(Meteor.userId(), String);
    check(postAttributes, {
      title: String,
      postContent: String,
      timeToEnable: Date,
      timeDisplay:String,
      year: Number,
      month: Number,
      day: Number,
      hours: Number

    });
    var user = Meteor.user();
    var post = _.extend(postAttributes, {
      userId: user._id,
      author: user.username,
      submitted: new Date()
    });
    var postId = Posts.insert(post);
    return {
      _id: postId
    };
  }
});

server ~/server/publications.js`

Meteor.publish('posts', function() {
  return Posts.find();
});

So I would like to grab the collection fields for posts into postEdit when the template is rendered, which will set the value of day input picker.

Thanks for help in advance.

This is what ended up working for me in the end.

client /posts/post_edit.js

Template.post_edit.rendered = function(){
var year = (postObject.year);
var month = (postObject.month) -1;
var day = (postObject.day);
var hours = (postObject.hours);

var $input = $('.datepicker').pickadate();
var $inputTime = $('.timepicker').pickatime();


// Use the picker object directly.
var picker = $input.pickadate('picker');
var pickerTime = $inputTime.pickatime('picker');


picker.set('select', new Date(year, month, day));// Get on screen image
pickerTime.set('select', [hours,0]);// Get on screen image
}

lib /lib/router.js

Router.route('/posts/:_id/edit', {
  name: 'postEdit',
  data: function() {
  postObject = Posts.findOne(this.params._id);


    return postObject;

    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM