Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // VanillaJS Todo App with full CRUD
- (function crudApp() {
- "use strict";
- // Look ma... no library!
- var itemData = {};
- var getSelector = function(targSelector) {
- for (var i = 0; i < document.querySelectorAll(targSelector).length; i++) {
- return document.querySelectorAll(targSelector)[i];
- }
- }
- var selectors = {
- 'textInput': '[data-app-todo-input]',
- 'addItem': '[data-app-add-item]',
- 'outputZone': '[data-app-list-output]',
- 'deleteAllItems': '[data-app-delete-all]',
- 'deleteItem': 'data-app-delete-item', // These are used on dynamic click events, so they don't get backets
- 'editItem': 'data-app-edit-item'
- };
- var methods = {
- 'hasAttribute': function(target, attribute) {
- return target.getAttribute(attribute);
- },
- 'addItem': function(item, properties) {
- var normalizedItem = item.toLowerCase();
- if (!itemData[normalizedItem] && properties) {
- itemData[normalizedItem] = properties;
- } else if (!itemData[normalizedItem] && !properties) {
- itemData[normalizedItem] = true;
- }
- // No overwrites for duplicate items
- else if (itemData[normalizedItem] === true) {
- alert('Duplicate entry prevented');
- }
- getSelector(selectors.textInput).value = '';
- methods.render(itemData);
- },
- 'deleteAllItems': function() {
- itemData = {};
- methods.render(itemData);
- },
- 'deleteItem': function(itemName) {
- var normalizedItemName = itemName.toLowerCase();
- if (itemData[normalizedItemName]) {
- delete itemData[normalizedItemName];
- methods.render(itemData);
- }
- },
- 'readData': function(dataset, property) {
- if (property) return dataset[property];
- else return dataset;
- },
- 'editItem': function(event, attr) {
- var itemName = event.target.getAttribute(attr).toLowerCase();
- if (itemData[itemName]) {
- var newItemName = prompt('New todo item?');
- if (newItemName) {
- methods.addItem(newItemName);
- methods.deleteItem(itemName); // Reversed from natural order for UX (no item disappear just from pressing edit)
- methods.render(itemData);
- }
- }
- },
- 'render': function(dataset) {
- methods.resetView();
- var property;
- var currentData = methods.readData(dataset);
- for (property in currentData) {
- if (currentData.hasOwnProperty(property)) {
- getSelector(selectors.outputZone).innerHTML += methods.issueTemplate(property, 'li');
- }
- }
- },
- 'resetView': function() {
- getSelector(selectors.outputZone).innerHTML = '';
- },
- 'issueTemplate': function(data, elm) {
- return '<' + elm + ' data-app-item="' + data + '">' + data + '<button ' + selectors.deleteItem + '="' + data + '">Completed</button><button ' + selectors.editItem + '="' + data + '">Edit</button></' + elm + '>';
- }
- };
- // 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)
- getSelector(selectors.outputZone).onclick = function(event) {
- if (methods.hasAttribute(event.target, 'data-app-delete-item')) {
- var deleteItemAction = new methods.deleteItem(event.target.getAttribute('data-app-delete-item'));
- } else if (methods.hasAttribute(event.target, 'data-app-edit-item')) {
- var editItemAction = new methods.editItem(event, 'data-app-edit-item');
- }
- }
- // Bind DOM events directly to functionality
- getSelector(selectors.deleteAllItems).onclick = function() {
- var deleteAllItemsAction = new methods.deleteAllItems();
- methods.render(itemData);
- };
- getSelector(selectors.addItem).onclick = function() {
- var addItemAction = new methods.addItem(getSelector(selectors.textInput).value);
- };
- getSelector(selectors.deleteItem).onclick = function() {
- var deleteItemAction = new methods.deleteItem(getSelector(selectors.textInput).value);
- methods.render(itemData);
- };
- })();
- #app
- .user-entry
- input(type="text", placeholder="Enter an item to do", data-app-todo-input)
- input(type="submit", value="Add item", data-app-add-item)
- input(type="button", value="Delete all items", data-app-delete-all)
- input(type="button", value="Delete specific item", data-app-delete-item)
- .app-output
- h1 Pure javascript todo tracker
- ul(data-app-list-output)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement