Now that we can show posts, let's create a form to make new posts. It's important to realize that we're just going to create a form. There's no user account and no authentication, just a form that anyone could use to make new posts. We'll start with the template, which we'll put in the index.ejs
file:
<script type="text/template" id="postFormView"> <a href="/">All Posts</a><br /> <input type="text" id="postTitle" placeholder="post title" /> <br /> <textarea id="postText"></textarea> <br /> <button id="submitPost"> Post </button> </script>
It's a very basic form, but it will do. So now, we need to create our view; use the following code:
var PostFormView = Backbone.View.extend({ tagName: 'form', template: _.template($("#postFormView").html()), initialize: function (options) { this.posts = options.posts; }, events: { 'click button': 'createPost' }, render: function () { this.el.innerHTML = this.template(); return this; }, createPost: function (e) { var postAttrs = { content: $("#postText").val(), title: $("#postTitle").val(), pubDate: new Date() }; this.posts.create(postAttrs); postRouter.navigate("/", { trigger: true }); return false; } });
It's pretty big, but you should be able to understand most of it. We start by making the view a <form>
element through the tagName
property. We fetch the template we just created in the template
property. In the initialize
method, we take a Posts
collection as an option and assign it as a property, much like we did in the router. In the events
property, we listen for a click event on the button. When that happens, we call the createPost
method. Rendering this view is pretty simple. Actually, the real complexity here is in the createPost
method, but even that is pretty simple. We create a postAttrs
object that has all the properties of our post: the content and the text from the form and a date that we add.
After creating this postAttrs
object, we pass it to the Posts
collection's create
method. This is a convenience method, really, that creates the Post
model instance, saves it to the server, and adds it to the collection. If we wanted to do this "manually", we'd do something similar to the following lines of code:
var post = new Post(commentAttrs); this.posts.add(post); post.save();
Every Backbone model constructor takes an object, which is a hash of attributes. We can add that model to the collection using the add
method. Then, every model instance has a save
method, which sends the model to the server.
Note
In this case, it's important to add the model to the collection before saving it, because our model class doesn't know the server route to POST to on its own. If we wanted to be able to save model instances that aren't in a collection, we'd have to give the model class a urlRoot
property:
urlRoot: "/posts",
Finally, we navigate back to the home page.
The next step is to add a new route to the router. In the routes
property of the router class, add the following line:
'posts/new': 'newPost'
Then, we add the newPost
method, which is very simple:
newPost: function () { var pfv = new PostFormView({ posts: this.posts }); this.main.html(pfv.render().el); },
That's all! Like I said, this isn't how you'd really do blog posting in a proper blog, but it shows us how to send model data back to the server.