Advertisement
Guest User

Untitled

a guest
Jul 7th, 2015
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.38 KB | None | 0 0
  1. // VanillaJS Todo App with full CRUD
  2.  
  3. (function crudApp() {
  4. "use strict";
  5. // Look ma... no library!
  6. var itemData = {};
  7. var getSelector = function(targSelector) {
  8. for (var i = 0; i < document.querySelectorAll(targSelector).length; i++) {
  9. return document.querySelectorAll(targSelector)[i];
  10. }
  11. }
  12. var selectors = {
  13. 'textInput': '[data-app-todo-input]',
  14. 'addItem': '[data-app-add-item]',
  15. 'outputZone': '[data-app-list-output]',
  16. 'deleteAllItems': '[data-app-delete-all]',
  17. 'deleteItem': 'data-app-delete-item', // These are used on dynamic click events, so they don't get backets
  18. 'editItem': 'data-app-edit-item'
  19. };
  20.  
  21. var methods = {
  22.  
  23. 'hasAttribute': function(target, attribute) {
  24. return target.getAttribute(attribute);
  25. },
  26.  
  27. 'addItem': function(item, properties) {
  28. var normalizedItem = item.toLowerCase();
  29.  
  30. if (!itemData[normalizedItem] && properties) {
  31. itemData[normalizedItem] = properties;
  32. } else if (!itemData[normalizedItem] && !properties) {
  33. itemData[normalizedItem] = true;
  34. }
  35. // No overwrites for duplicate items
  36. else if (itemData[normalizedItem] === true) {
  37. alert('Duplicate entry prevented');
  38. }
  39. getSelector(selectors.textInput).value = '';
  40. methods.render(itemData);
  41. },
  42.  
  43. 'deleteAllItems': function() {
  44. itemData = {};
  45. methods.render(itemData);
  46. },
  47.  
  48. 'deleteItem': function(itemName) {
  49. var normalizedItemName = itemName.toLowerCase();
  50. if (itemData[normalizedItemName]) {
  51. delete itemData[normalizedItemName];
  52. methods.render(itemData);
  53. }
  54. },
  55.  
  56. 'readData': function(dataset, property) {
  57. if (property) return dataset[property];
  58. else return dataset;
  59. },
  60.  
  61. 'editItem': function(event, attr) {
  62. var itemName = event.target.getAttribute(attr).toLowerCase();
  63.  
  64. if (itemData[itemName]) {
  65. var newItemName = prompt('New todo item?');
  66. if (newItemName) {
  67. methods.addItem(newItemName);
  68. methods.deleteItem(itemName); // Reversed from natural order for UX (no item disappear just from pressing edit)
  69. methods.render(itemData);
  70. }
  71. }
  72. },
  73.  
  74. 'render': function(dataset) {
  75. methods.resetView();
  76. var property;
  77. var currentData = methods.readData(dataset);
  78. for (property in currentData) {
  79. if (currentData.hasOwnProperty(property)) {
  80. getSelector(selectors.outputZone).innerHTML += methods.issueTemplate(property, 'li');
  81. }
  82. }
  83. },
  84.  
  85. 'resetView': function() {
  86. getSelector(selectors.outputZone).innerHTML = '';
  87. },
  88.  
  89. 'issueTemplate': function(data, elm) {
  90. return '<' + elm + ' data-app-item="' + data + '">' + data + '<button ' + selectors.deleteItem + '="' + data + '">Completed</button><button ' + selectors.editItem + '="' + data + '">Edit</button></' + elm + '>';
  91. }
  92.  
  93. };
  94.  
  95. // This should handle both the edit and delete functionality and also click event on dynamically added elms (both come from same elm type so I use the attribute value to decide which function to implement)
  96.  
  97. getSelector(selectors.outputZone).onclick = function(event) {
  98.  
  99. if (methods.hasAttribute(event.target, 'data-app-delete-item')) {
  100. var deleteItemAction = new methods.deleteItem(event.target.getAttribute('data-app-delete-item'));
  101. } else if (methods.hasAttribute(event.target, 'data-app-edit-item')) {
  102. var editItemAction = new methods.editItem(event, 'data-app-edit-item');
  103. }
  104.  
  105. }
  106.  
  107. // Bind DOM events directly to functionality
  108.  
  109. getSelector(selectors.deleteAllItems).onclick = function() {
  110. var deleteAllItemsAction = new methods.deleteAllItems();
  111. methods.render(itemData);
  112. };
  113.  
  114. getSelector(selectors.addItem).onclick = function() {
  115. var addItemAction = new methods.addItem(getSelector(selectors.textInput).value);
  116. };
  117.  
  118. getSelector(selectors.deleteItem).onclick = function() {
  119. var deleteItemAction = new methods.deleteItem(getSelector(selectors.textInput).value);
  120. methods.render(itemData);
  121. };
  122.  
  123. })();
  124.  
  125. #app
  126. .user-entry
  127. input(type="text", placeholder="Enter an item to do", data-app-todo-input)
  128. input(type="submit", value="Add item", data-app-add-item)
  129. input(type="button", value="Delete all items", data-app-delete-all)
  130. input(type="button", value="Delete specific item", data-app-delete-item)
  131. .app-output
  132. h1 Pure javascript todo tracker
  133. ul(data-app-list-output)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement