Advertisement
Guest User

Untitled

a guest
Jan 12th, 2013
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (function ($) {
  2.  
  3.     _.templateSettings = {
  4.        // interpolate: /\{\{(.+?)\}\}/g   // {{ }} syntax for templating insteat of  of <%= property %>
  5.     };
  6.  
  7.     var contacts = [
  8.         { name: "Contact 1", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
  9.         { name: "Contact 2", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
  10.         { name: "Contact 3", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" },
  11.         { name: "Contact 4", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "colleague" },
  12.         { name: "Contact 5", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
  13.         { name: "Contact 6", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "colleague" },
  14.         { name: "Contact 7", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" },
  15.         { name: "Contact 8", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" }
  16.     ];
  17.  
  18.     // A model represents the data of an application; in our application this will be an individual contact, which will have attributes such as a name, a contact number, etc. You could say that an individual model represents the atomic part of the application – the smallest possible unit of functionality.
  19.  
  20.  
  21.  
  22.     var Contact = Backbone.Model.extend({
  23.         defaults: {
  24.             photo: "img/placeholder.png",
  25.             name: "",
  26.             address: "",
  27.             tel: "",
  28.             email: "",
  29.             type: ""
  30.         }
  31.     });
  32.  
  33.     // A collection is a class for managing groups of models.
  34.     var Directory = Backbone.Collection.extend({
  35.         model: Contact
  36.     });
  37.  
  38.     var ContactView = Backbone.View.extend({
  39.         tagName: "article",
  40.         className: "contact-container",
  41.         template: $("#contactTemplate").html(),
  42.         editTemplate: _.template($("#contactEditTemplate").html()),
  43.         render: function () {
  44.             var tmpl = _.template(this.template);
  45.  
  46.             //console.log(this.$el);
  47.             console.log(this.model.toJSON());
  48.  
  49.             this.$el.html(tmpl(this.model.toJSON()));
  50.             return this;
  51.         },
  52.         events: {
  53.             "click button.delete": "deleteContact",
  54.             "click button.edit": "editContact",
  55.             "change select.type": "addType",
  56.             "click button.save": "saveEdits",
  57.             "click button.cancel": "cancelEdit"
  58.         },
  59.         deleteContact: function () {
  60.            var removedType = this.model.get("type").toLowerCase();
  61.             this.model.destroy();
  62.             this.remove();
  63.             if (_.indexOf(directory.getTypes(), removedType) === -1) {
  64.                 directory.$el.find("#filter select").children("[value='" + removedType + "']").remove();
  65.             }
  66.         },
  67.         editContact: function () {
  68.             this.$el.html(this.editTemplate(this.model.toJSON()));
  69.             var newOpt = $("<option/>", {
  70.                 html: "<em>Add new...</em>",
  71.                 value: "addType"
  72.             });
  73.             this.select = directory.createSelect().addClass("type")
  74.                 .val(this.$el.find("#type").val()).append(newOpt)
  75.                 .insertAfter(this.$el.find(".name"));
  76.             this.$el.find("input[type='hidden']").remove();
  77.  
  78.            
  79.         },
  80.         saveEdits: function (e) {
  81.            e.preventDefault();
  82.             var formData = {},
  83.                 prev = this.model.previousAttributes();
  84.             $(e.target).closest("form").find(":input").not(':button').add(".photo").each(function () { // where is .not('button')
  85.                 var el = $(this);
  86.                 formData[el.attr("class")] = el.val();
  87.             });
  88.             if (formData.photo === "") {
  89.                 delete formData.photo;
  90.             }
  91.             this.model.set(formData);
  92.             this.render();
  93.             if (prev.photo === "/img/placeholder.png") {
  94.                 delete prev.photo;
  95.             }
  96.             _.each(contacts, function (contact) {
  97.                 if (_.isEqual(contact, prev)) {
  98.                     contacts.splice(_.indexOf(contacts, contact), 1, formData);
  99.                 }
  100.             });
  101.         },
  102.  
  103.         addType: function() {
  104.             if (this.select.val() === "addType") {
  105.                 this.select.remove();
  106.                 $("<input />", {
  107.                     "class": "type"
  108.                 }).insertAfter(this.$el.find(".name")).focus();
  109.             }
  110.         },
  111.         cancelEdit: function () {
  112.             this.render();
  113.         },
  114.     });
  115.  
  116.     var ContactsRouter = Backbone.Router.extend({
  117.         routes: {
  118.             "filter/:type": "urlFilter"
  119.         },
  120.         urlFilter: function (type) {
  121.             directory.filterType = type;
  122.             directory.trigger("change:filterType");
  123.         }
  124.     });
  125.  
  126.     var DirectoryView = Backbone.View.extend({
  127.         el: $("#contacts"),
  128.         initialize: function () {
  129.             this.collection = new Directory(contacts);
  130.             this.render();
  131.             this.$el.find("#filter").append(this.createSelect());
  132.             this.on("change:filterType", this.filterByType, this);
  133.             this.collection.on("reset", this.render, this);
  134.             this.collection.on("add", this.renderContact, this);
  135.             this.collection.on("remove", this.removeContact, this);
  136.         },
  137.         render: function () {
  138.             this.$el.find("article").remove();
  139.  
  140.             var that = this;
  141.             _.each(this.collection.models, function (item) {
  142.                 that.renderContact(item);
  143.             }, this);
  144.         },
  145.         renderContact: function (item) {
  146.             var contactView = new ContactView({
  147.                 model: item
  148.             });
  149.             this.$el.append(contactView.render().el);
  150.         },
  151.         getTypes: function () {
  152.             return _.uniq(this.collection.pluck("type"), false, function (type) {
  153.                 return type.toLowerCase();
  154.             });
  155.         },
  156.         createSelect: function () {
  157.             var filter = this.$el.find("#filter"),
  158.                 select = $("<select/>", {
  159.                     html: "<option value='all'>All</option>"
  160.                 });
  161.             _.each(this.getTypes(), function (item) {
  162.                 var option = $("<option/>", {
  163.                     value: item.toLowerCase(),
  164.                     text: item.toLowerCase()
  165.                 }).appendTo(select);
  166.             });
  167.             return select;
  168.         },
  169.         events: {
  170.             "change #filter select": "setFilter",
  171.             "click #add": "addContact",
  172.             "click #showForm": "showForm"
  173.         },
  174.         setFilter: function (e) {
  175.             this.filterType = e.currentTarget.value;
  176.             this.trigger("change:filterType");
  177.         },
  178.         filterByType: function () {
  179.             if (this.filterType === "all") {
  180.                 this.collection.reset(contacts);
  181.                 contactsRouter.navigate("filter/all");
  182.             } else {
  183.                 this.collection.reset(contacts, { silent: true });
  184.                 var filterType = this.filterType,
  185.                     filtered = _.filter(this.collection.models, function (item) {
  186.                         return item.get("type") === filterType;
  187.                 });
  188.                 this.collection.reset(filtered);
  189.                 contactsRouter.navigate("filter/" + filterType);
  190.             }
  191.         },
  192.         addContact: function (e) {
  193.             e.preventDefault();
  194.             var newModel = {};
  195.             $("#addContact").children("input").each(function (i, el) {
  196.                 if ($(el).val() !== "") {
  197.                     newModel[el.id] = $(el).val();
  198.               }
  199.             });
  200.             contacts.push(newModel);
  201.             if (_.indexOf(this.getTypes(), newModel.type) === -1) {
  202.                  this.collection.add(new Contact(newModel));
  203.                 this.$el.find("#filter").find("select").remove().end().append(this.createSelect());
  204.             } else {
  205.                 this.collection.add(new Contact(newModel));
  206.             }
  207.         },
  208.         removeContact: function (removedModel) {
  209.             var removed = removedModel.attributes;
  210.             if (removed.photo === "/img/placeholder.png") {
  211.                 delete removed.photo;
  212.             }
  213.             _.each(contacts, function (contact) {
  214.                 if (_.isEqual(contact, removed)) {
  215.                     contacts.splice(_.indexOf(contacts, contact), 1);
  216.                 }
  217.             });
  218.         },
  219.         showForm: function () {
  220.             this.$el.find("#addContact").slideToggle();
  221.         }
  222.  
  223.     });
  224.  
  225.     var directory = new DirectoryView();
  226.     var contactsRouter = new ContactsRouter();
  227.     Backbone.history.start();
  228.  
  229. } (jQuery));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement