Tweet about this on TwitterShare on FacebookShare on Google+Share on StumbleUponShare on TumblrShare on RedditPin on PinterestEmail this to someone

This is the final part of this tutorial series. In this we will first add some functionality to ‘Add’ button where we insert new row to the table and let user to type the category information and save it.

Step 1 – Implement Add Category

A sip of Coffee with Laravel and Backbone - Book

HTML table which shows categories, belongs to ‘CategoryResultView’ so I think this is the best place to add the event handler for ‘Add’ button click. Open ‘views.coffee’ file and change as follows.

By now you know what all these changes do, but I will just skim though it. First we add event map and wire-up ‘Add’ button with a function (callback). Then inside that we need to create new Category Backbone.Model for user to edit. But before hand over it to user we need to know what he would do with that, for that we attach some events to the model. He could add category information and invoke save, or he might cancel the edit, (also once we save this and added to HTML table, later he might want to modify it or may just delete it. We have attached four event handlers for these operations, and I have declared functions without any body which will be completed later. Finally we create a edit view for user and pass the model (Category item) to it, render it and prepend to our table body, so it will add new row to the top of the table. (I think it is easier to keep on adding item when new row is added to the top instead of at the bottom, where user has to scroll every time). However we still haven’t created the ‘CategoryRowEditView‘ view. Let’s do it now.

Step 2 – Implement CategoryRowEditView

Before even creating Backbone.View to handle edit, will create a HTML template for that. Which is similar to ‘tpl-category-row‘ template but this time with some input controls. Add following to ‘views/category/index.blade.php‘ just after the ‘tpl-category-row‘ template.

I guess nothing new here, same as ‘tpl-category-row‘ but with some input controls and buttons with different captions and classes. Now back to ‘CategoryRowEditView‘. Modify ‘views.coffee‘ file to include it as below.

First we have event table, to handle ‘Save’ and ‘Cancel’ button clicks. In render() function as we did with CategoryRowDisplayView we just use the compiled template for this view and render it with the model. Note that if model has id property (i.e. when this item is already saved and in edit mode) we assign that to <tr> id attribute, else if this model is new one then will use model.cid.

When user click on save we read the user input from text boxes and update the model, and notify ‘save‘ event. If you remember we have attached event handler for these events when we created Category item in previous view (in CategoryResultView.create() function). So now this should invoke itemSave() callback of CategoryResultView. Same applies to cancel button click but the call back is ‘cancelEdit()‘. Also note that with the trigger I pass @ (this) so that our callback functions will receive a reference to this view as a parameter.

Just compile the coffee scripts and refresh your browser and will first click on ‘Search’, it will populate existing categories. Then click on ‘Add’ button, You should get something similar to below if done correctly.

Add Button Functionality

Add Button Functionality

Step 3 – Implement Save and Cancel Edit

Now will complete ‘itemSave’, cancelEdit’ callback functions of ‘CategoryResultView

As we get the edit view in the callback, first we get its model (user modified one) then call Backbone.Model.save() function to send the POST request to server with new data. We then wait till the response comes back and if it is successful, we create new CategoryRowDisplayView with this model, since now we need to replace edit row with the display row, will get the jQuery reference to ‘el‘ element of edit view and replace its content with the ‘CategoryRowDisplayView‘ render output. Finally update <tr> id with the model.id. If server returns us error then we just output it to console (of course you can show some error message to user).

In ‘cancelEdit()‘, no need to do anything if this is a new model (i.e. user decides to create new category but before saving it he cancels). We just call remove() method of Backbone.View which will remove the DOM element attached with this view.

Compile coffee scripts and refresh browser, and try to add new category save it. add new cancel without saving and see how it works.

Save and Cancel Functionality

Save and Cancel Functionality

Step 4 – Implement Delete

Finally will complete the ‘Delete’ and ‘Edit’ operations and I hope now you can understand how it works. Once again complete the ‘itemEdit()‘, ‘cancelEdit()‘, as below. Also note that since we have to attach ‘save’, ‘edit’, ‘cancel’, ‘delete’ events for the Categories that we initially received from the server, I have done that in render() method inside the collection loop, note that inside the collection loop we cannot use @ to refer the view, so keep a reference in $this before enters in to the loop and use it.

Then ‘itemDelete()‘ modified as below.
model.destroy() will send DELETE HTTP command to the server (so this item will be deleted from server side as well).

Modify ‘itemEdit()‘ and ‘cancelEdit()‘ as below.

That’s all, now you have fully functional UI with Add, Edit, Delete. Thanks for following this series so far. I’m also new to Laravel, Backbone and Coffee, so I hope there may alternative ways of achieving what I have explained in this series, but this is the way I used it in most of the time.

Source will be available at git. https://github.com/technet/laravel-backbone-coffee

A sip of Coffee with Laravel and Backbone - Book

Posts of this series
Laravel, Backbone.js + Coffeescript Tutorial Part I – Introduction
Laravel, Backbone.js + Coffeescript Tutorial Part II – Setup
Laravel, Backbone.js + Coffeescript Tutorial Part III – Install Laravel
Laravel, Backbone.js + Coffeescript Tutorial Part IV – Database
Laravel, Backbone.js + Coffeescript Tutorial Part V – Data model
Laravel, Backbone.js + Coffeescript Tutorial Part VI – REST API
Laravel, Backbone.js + Coffeescript Tutorial Part VII – REST API
Laravel, Backbone.js + Coffeescript Tutorial Part VIII – Views
Laravel, Backbone.js + Coffeescript Tutorial Part IX – Coffeescript
Laravel, Backbone.js + Coffeescript Tutorial Part X – Backbone
Laravel, Backbone.js + Coffeescript Tutorial Part XI – Backbone
Laravel, Backbone.js + Coffeescript Tutorial Part XII – Backbone
Laravel, Backbone.js + Coffeescript Tutorial Part XIII – Backbone

 

P.S – Detail answer to Cahva

I cannot say it’s a clean way of doing, but it could be done, speed up initial data load, because if your plan is to build single page application, consecutive requests have to be sent as ajax anyway, for ex: let’s say in above example you need to search categories by some criteria or you need to fetch them all again, and option you have is ajax call, or else you need to refresh the entire page. So my personal view is, instead of getting entire HTML page again + json data on that HTML page is inefficient than just fetching JSON data itself over the wire? don’t you think? What we trying to save here is only the initial data loading where we could get it with the HTML page itself. I can show you how to do that, but I don’t think it will save you in subsequent requests.

Anyway to answer your question, we can embed javascript section inside the HTML page with data from backend as below.

in the routes.php change following route as bellow.

Here we send the categories JSON string with the view itself.

Then in index.blade.php inside ‘js’ section you can write

As you can see we build this at the server side so now our app.categories collection already has data populated when it comes to the user. (You can verify by typing app.categories.dump() in browser console.

But I don’t think this will save you from anything for subsequent calls unless you want to refresh the page every time.

Also you cannot do this part using coffee script because this data render itself into HTML output at server side, as browser cannot interpret coffee yet we have to do this in pure javascript.

Another major problem of loading data at the time page renders is, let’s say you have 10,000 records in Cat table, and user normally wants to use search, but every time he comes to this page, he has to wait too long to render all data initially before he do the search, which is annoying, ‘coz he may just want to search single category or few, but you always supply and delay page load with 10,000 categories.

 

Tweet about this on TwitterShare on FacebookShare on Google+Share on StumbleUponShare on TumblrShare on RedditPin on PinterestEmail this to someone