PageRenderTime 55ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/city_aware/templates/staff/event_categories_table.html

https://github.com/hack4reno2011/Rock-Star-Scientists
HTML | 215 lines | 199 code | 16 blank | 0 comment | 0 complexity | b47934cdd8f72fb8576ff2f933d76ca4 MD5 | raw file
  1. {% extends "foundation.html" %}
  2. {% load url from future %}
  3. {% block headers %}
  4. <style type="text/css">
  5. </style>
  6. <script>
  7. var inputMenu = "<div id='barCell'><span class='inputBar'><label>Name:<input type='text'></input></label><button id='add'>Add</button></span></div>";
  8. var sortMenu = "<button id='sortByName'>Sort by Name</button><button id='sortById'>Sort by ID</button>";
  9. var noIdItem = '<div class="label"><%= name %><div class="options"><button class="delete">delete</button></div></div>';
  10. var noIdRow = '<td><%= id %></td><td class="rowName"><%= name %></td><td><button class="delete">delete</button></td>';
  11. var editRow = '<td><%= id %></td><td><input class="labelInput" value="<%= name %>"></input></td><td><button class="delete">delete</button></td>';
  12. var screenOverlay = '<div class="overlay"><div id="box"><p>Are you sure you want to delete <%=name%>?</p><button class="confirmDel">Delete</button><button class="cancelDel">Cancel</button></div></div>';
  13. var data = [];
  14. var overlayIn = 200,
  15. overlayOut = 200;
  16. function callOverlay(question, callback) {
  17. $("#overlay").fadeIn(overlayIn);
  18. $("#overlayQuestion").html(question);
  19. $("#overlayYes").unbind().click(callback);
  20. }
  21. $(function() {
  22. $("#overlay").click(function(e) {
  23. if (e.target === this) {
  24. $(this).fadeOut(overlayOut);
  25. }
  26. });
  27. $("#overlayNo").click(function() {
  28. $("#overlay").fadeOut(overlayOut);
  29. });
  30. var Item = Backbone.Model.extend({
  31. defaults: {'name': "Unknown"},
  32. urlRoot: '/api/eventcategories/',
  33. });
  34. var List = Backbone.Collection.extend({
  35. model: Item,
  36. url: '/api/eventcategories/',
  37. parse: function(data) {
  38. return data.objects;
  39. },
  40. comparator: function(item) {
  41. return item.get('id');
  42. }
  43. });
  44. var ItemView = Backbone.View.extend({
  45. tagName: 'tr',
  46. className: 'label',
  47. events: {
  48. 'click button.delete': 'remove',
  49. 'dblclick td.rowName': "editLabel",
  50. },
  51. initialize: function() {
  52. _.bindAll(this, 'render', 'unrender', 'remove', 'editLabel', 'saveLabel', 'actualDestroy');
  53. this.model.bind('change', this.render);
  54. this.model.bind('remove', this.unrender);
  55. },
  56. render: function() {
  57. $(this.el).html(_.template(noIdRow, this.model.toJSON()));
  58. return this;
  59. },
  60. editLabel: function() {
  61. //change the template to editing mode
  62. $(this.el).html(_.template(editRow, this.model.toJSON()))
  63. //TODO should only save on change
  64. $('input.labelInput', this.el).focusout(this.saveLabel).change(this.saveLabel).bind("keypress", function(e) {if (e.keyCode == 13) {this.saveLabel};});
  65. },
  66. saveLabel: function() {
  67. //TODO confirm new text, delete if empty
  68. var newText = $('input.labelInput', this.el).val();
  69. this.model.set({'name': newText});
  70. this.model.save();
  71. //TODO rerender no matter what happened: avoid duplication with save call
  72. $(this.el).html(_.template(noIdRow, this.model.toJSON()));
  73. },
  74. unrender: function() {
  75. $(this.el).remove();
  76. },
  77. remove: function() {
  78. //this.model.destroy();
  79. //TODO no need for custom callbacks?
  80. console.log("preparing to destroy:", this.model);
  81. $(this.el).html(_.template(noIdRow, this.model.toJSON()));
  82. //TODO make backbone function
  83. callOverlay("Are you sure you want to delete the category '" + this.model.get('name') + "'?", this.actualDestroy);
  84. //this.model.destroy();
  85. //this.model.destroy({error: function(model, response) {
  86. // console.log("DELETE error:", response);
  87. // },
  88. // success: function(model, response) {
  89. // //apparently, reports success on 301 ?!?!
  90. // console.log("DELETE success:", model, response);
  91. // }
  92. //});
  93. },
  94. actualDestroy: function() {
  95. console.log("will actually destroy!");
  96. $("#overlay").fadeOut(overlayOut);
  97. this.model.destroy();
  98. },
  99. });
  100. //TODO why global?
  101. var iList = (new List()).add(data);
  102. var AppView = Backbone.View.extend({
  103. el: $('#tableCell'),
  104. events: {
  105. 'click button#refresh': "refreshList",
  106. 'click button#add': "newItem",
  107. 'click button#sortByName': "sortByName",
  108. 'click button#sortById': "sortById",
  109. },
  110. initialize: function() {
  111. _.bindAll(this, 'render', 'addItem', 'appendItem', 'sortByName', 'renderList', 'sortById', 'newItem', 'refreshList');
  112. this.collection = iList.bind('add', this.appendItem);
  113. this.sortOrder = -1;
  114. this.render();
  115. this.collection = iList.bind('reset', this.renderList);
  116. this.collection.fetch(); //fires 'reset'
  117. //this.collection.fetch({add: true}); //otherwise list will 'reset'
  118. //this.collection.fetch({add: true, data: {offset: 50}}); //otherwise list will 'reset'
  119. //this.collection.sort(); //should fire 'reset'
  120. },
  121. render: function() {
  122. $(this.el).append(_.template(inputMenu, {})).append(_.template(sortMenu, {})).append("<table class='backSupported'><thead><tr class='header'><th>id</th><th>Category</th><th>Options</th></tr></thead><tbody></tbody></table>");
  123. this.renderList();
  124. },
  125. renderList: function() {
  126. $('tbody', this.el).empty();
  127. // _.each?
  128. for (var i = 0; i < this.collection.models.length; i++) {
  129. this.appendItem(this.collection.models[i]);
  130. }
  131. },
  132. addItem: function() {
  133. this.collection.add(new Item({'name': "new bus stop"}));
  134. },
  135. appendItem: function(item) {
  136. var itemView = new ItemView({
  137. model: item
  138. });
  139. $('tbody', this.el).append(itemView.render().el);
  140. },
  141. sortByName: function() {
  142. this.sortOrder = -this.sortOrder;
  143. this.collection.comparator = buildNameComparator(this.sortOrder);
  144. this.collection.sort();
  145. },
  146. sortById: function() {
  147. this.sortOrder = -this.sortOrder;
  148. this.collection.comparator = buildIdComparator(this.sortOrder);
  149. this.collection.sort();
  150. },
  151. newItem: function() {
  152. var newText = $('input', this.el).val();
  153. if (newText) {
  154. //TODO not empty?
  155. var randItem = new Item({'name': newText});
  156. randItem.save({}, {success: buildSuccessReponse(this.collection)});
  157. var newText = $('input', this.el).val("");
  158. }
  159. },
  160. refreshList: function() {
  161. this.collection.fetch(); //fires 'reset'
  162. },
  163. });
  164. function buildIdComparator(sortOrder) {
  165. return function(country) {
  166. return sortOrder * country.get('id');
  167. }
  168. }
  169. function buildNameComparator(sortOrder) {
  170. return function(item) {
  171. return _.map(item.get("name").toLowerCase().split(""), function(letter) {
  172. return String.fromCharCode(sortOrder * (letter.charCodeAt(0)));
  173. });;
  174. }
  175. }
  176. function buildSuccessReponse(collection) {
  177. return function(model, response) {
  178. collection.add(model);
  179. collection.sort();
  180. }
  181. }
  182. var app = new AppView();
  183. });
  184. </script>
  185. {% endblock %}
  186. {% block content %}
  187. <p><a href="{% url 'staff_home' %}">&lt&lt&lt Return to Staff Homepage</a></p>
  188. <h4>Add an event category:</h4>
  189. <div id="tableCell"></div>
  190. <div id="overlay" style="display:none">
  191. <div id="overlayPrompt">
  192. <span id="overlayQuestion"></span>
  193. <div id="overlayButtons">
  194. <button id="overlayYes" >Yes</button>
  195. <button id="overlayNo" >No</button>
  196. </div>
  197. </div>
  198. </div>
  199. {% endblock %}