PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/js/app.js

https://bitbucket.org/tariel/contacts
JavaScript | 208 lines | 151 code | 42 blank | 15 comment | 8 complexity | c6ed335fab03ae5f40ea1455ebd20fb3 MD5 | raw file
  1. /*
  2. http://net.tutsplus.com/tutorials/javascript-ajax/build-a-contacts-manager-using-backbone-js-part-1/
  3. http://net.tutsplus.com/tutorials/javascript-ajax/build-a-contacts-manager-using-backbone-js-part-2/
  4. */
  5. (function ($) {
  6. var contacts = [
  7. { name: "Contact 1", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
  8. { name: "Contact 2", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
  9. { name: "Contact 3", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" },
  10. { name: "Contact 4", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "colleague" },
  11. { name: "Contact 5", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
  12. { name: "Contact 6", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "colleague" },
  13. { name: "Contact 7", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" },
  14. { name: "Contact 8", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" }
  15. ];
  16. var Contact = Backbone.Model.extend({
  17. defaults: {
  18. photo: "img/placeholder.png",
  19. name: "",
  20. address: "",
  21. tel: "",
  22. email: "",
  23. type: ""
  24. }
  25. });
  26. // Define directory collection
  27. var Directory = Backbone.Collection.extend({
  28. model: Contact
  29. });
  30. var ContactView = Backbone.View.extend({
  31. tagName: "article",
  32. className: "contact-container",
  33. template: _.template($("#contactTemplate").html()),
  34. render: function () {
  35. this.$el.html(this.template(this.model.toJSON()));
  36. return this;
  37. },
  38. events: {
  39. "click button.delete": "deleteContact"
  40. },
  41. deleteContact: function () {
  42. var removedType = this.model.get("type").toLowerCase();
  43. // remove model
  44. this.model.destroy();
  45. // remove view
  46. this.remove();
  47. if (_.indexOf(directory.getTypes(), removedType) === -1) {
  48. directory.$el.find("#filter select").children("[value='" + removedType + "']").remove();
  49. }
  50. }
  51. });
  52. // Master view
  53. var DirectoryView = Backbone.View.extend({
  54. el: $("#contacts"),
  55. initialize: function () {
  56. this.collection = new Directory(contacts);
  57. this.render();
  58. this.$el.find('#filter').append(this.createSelect());
  59. this.on("change:filterType", this.filterByType, this);
  60. this.collection.on("reset", this.render, this);
  61. this.collection.on("add", this.renderContact, this);
  62. this.collection.on("remove", this.removeContact, this);
  63. },
  64. render: function () {
  65. this.$el.find("article").remove();
  66. _.each(this.collection.models, function (item) {
  67. this.renderContact(item);
  68. }, this);
  69. },
  70. renderContact: function (item) {
  71. var contactView = new ContactView({
  72. model: item
  73. });
  74. // $el property is cached jQuery object
  75. // that Backbone creates automatically
  76. this.$el.append(contactView.render().el);
  77. },
  78. getTypes: function () {
  79. return _.uniq(this.collection.pluck("type"), false, function (type) {
  80. return type.toLowerCase();
  81. });
  82. },
  83. // Build types filter list
  84. createSelect: function () {
  85. var select = $("<select/>", {
  86. html: "<option>All</option>"
  87. });
  88. _.each(this.getTypes(), function (item) {
  89. var option = $("<option/>", {
  90. value: item.toLowerCase(),
  91. text: item.toLowerCase()
  92. }).appendTo(select);
  93. });
  94. return select;
  95. },
  96. // Define ui events
  97. events: {
  98. "change #filter select": "setFilter",
  99. "click #add": "addContact",
  100. "click #showForm": "showForm"
  101. },
  102. // Define filter handler
  103. setFilter: function (e) {
  104. this.filterType = e.currentTarget.value;
  105. this.trigger("change:filterType");
  106. },
  107. filterByType: function () {
  108. if (this.filterType === "all") {
  109. this.collection.reset(contacts);
  110. contactsRouter.navigate("filter/all");
  111. } else {
  112. this.collection.reset(contacts, { silent: true });
  113. var filterType = this.filterType,
  114. filtered = _.filter(this.collection.models, function (item) {
  115. return item.get("type") === filterType;
  116. });
  117. this.collection.reset(filtered);
  118. contactsRouter.navigate("filter/" + filterType);
  119. }
  120. },
  121. // Define method for adding contacts
  122. addContact: function (e) {
  123. e.preventDefault();
  124. var newModel = {};
  125. $("#addContact").children("input").each(function (i, el) {
  126. if ($(el).val() !== "") {
  127. newModel[el.id] = $(el).val();
  128. }
  129. });
  130. contacts.push(newModel);
  131. if (_.indexOf(this.getTypes(), newModel.type) === -1) {
  132. this.collection.add(new Contact(newModel));
  133. this.$el.find("#filter").find("select").remove().end().append(this.createSelect());
  134. } else {
  135. this.collection.add(new Contact(newModel));
  136. }
  137. },
  138. removeContact: function (removedModel) {
  139. var removed = removedModel.attributes;
  140. if (removed.photo === "/img/placeholder.png") {
  141. delete removed.photo;
  142. }
  143. _.each(contacts, function (contact) {
  144. if (_.isEqual(contact, removed)) {
  145. contacts.splice(_.indexOf(contacts, contact), 1);
  146. }
  147. });
  148. },
  149. showForm: function () {
  150. this.$el.find("#addContact").slideToggle();
  151. }
  152. });
  153. // Define routes
  154. var ContactsRouter = Backbone.Router.extend({
  155. routes: {
  156. "filter/:type": "urlFilter"
  157. },
  158. urlFilter: function (type) {
  159. directory.filterType = type;
  160. directory.trigger("change:filterType");
  161. }
  162. });
  163. var directory = new DirectoryView();
  164. var contactsRouter = new ContactsRouter();
  165. Backbone.history.start();
  166. } (jQuery));