From 52547a000da2633008100a0db132a6ccc25ef2ba Mon Sep 17 00:00:00 2001 From: Caroline Horn Date: Tue, 31 Jan 2017 13:00:54 -0500 Subject: [PATCH 1/9] Day 1 complete --- 01 - JavaScript Drum Kit/index-START.html | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/01 - JavaScript Drum Kit/index-START.html b/01 - JavaScript Drum Kit/index-START.html index 4070d32767..59ff7b07ae 100644 --- a/01 - JavaScript Drum Kit/index-START.html +++ b/01 - JavaScript Drum Kit/index-START.html @@ -58,6 +58,25 @@ From e930898d0bcdfe5576a2bada63cfd0b59b8c9ca7 Mon Sep 17 00:00:00 2001 From: Caroline Horn Date: Tue, 31 Jan 2017 13:29:21 -0500 Subject: [PATCH 2/9] Day 2 done --- 02 - JS + CSS Clock/index-START.html | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/02 - JS + CSS Clock/index-START.html b/02 - JS + CSS Clock/index-START.html index 2712384201..8a60531709 100644 --- a/02 - JS + CSS Clock/index-START.html +++ b/02 - JS + CSS Clock/index-START.html @@ -10,7 +10,7 @@
-
+
@@ -61,12 +61,36 @@ background:black; position: absolute; top:50%; + transform-origin: 100%; + transform: rotate(90deg); + transition: all 0.05s cubic-bezier(.1, 2.7,.58,1); } From 26d3b0564c3f9bbacc5051eb3940c7c247cfa046 Mon Sep 17 00:00:00 2001 From: Caroline Horn Date: Tue, 31 Jan 2017 13:47:35 -0500 Subject: [PATCH 3/9] Day 3 done --- 03 - CSS Variables/index-START.html | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/03 - CSS Variables/index-START.html b/03 - CSS Variables/index-START.html index ca2b59d077..8ff7b79286 100644 --- a/03 - CSS Variables/index-START.html +++ b/03 - CSS Variables/index-START.html @@ -21,6 +21,21 @@

Update CSS Variables with JS

From d7cf6cd4eb61496ae2d6075da0c9fd3113163b5c Mon Sep 17 00:00:00 2001 From: Caroline Horn Date: Tue, 31 Jan 2017 14:41:08 -0500 Subject: [PATCH 4/9] day 4 done --- 04 - Array Cardio Day 1/index-START.html | 74 ++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/04 - Array Cardio Day 1/index-START.html b/04 - Array Cardio Day 1/index-START.html index eec0ffc31d..e8b1862609 100644 --- a/04 - Array Cardio Day 1/index-START.html +++ b/04 - Array Cardio Day 1/index-START.html @@ -29,31 +29,97 @@ const people = ['Beck, Glenn', 'Becker, Carl', 'Beckett, Samuel', 'Beddoes, Mick', 'Beecher, Henry', 'Beethoven, Ludwig', 'Begin, Menachem', 'Belloc, Hilaire', 'Bellow, Saul', 'Benchley, Robert', 'Benenson, Peter', 'Ben-Gurion, David', 'Benjamin, Walter', 'Benn, Tony', 'Bennington, Chester', 'Benson, Leana', 'Bent, Silas', 'Bentsen, Lloyd', 'Berger, Ric', 'Bergman, Ingmar', 'Berio, Luciano', 'Berle, Milton', 'Berlin, Irving', 'Berne, Eric', 'Bernhard, Sandra', 'Berra, Yogi', 'Berry, Halle', 'Berry, Wendell', 'Bethea, Erin', 'Bevan, Aneurin', 'Bevel, Ken', 'Biden, Joseph', 'Bierce, Ambrose', 'Biko, Steve', 'Billings, Josh', 'Biondo, Frank', 'Birrell, Augustine', 'Black, Elk', 'Blair, Robert', 'Blair, Tony', 'Blake, William']; - // Array.prototype.filter() + // Array.prototype.filter() -- loops over each item in array and decide to keep or not // 1. Filter the list of inventors for those who were born in the 1500's + const fifteen = inventors.filter(function(inventor) { + if(inventor.year >= 1500 && inventor.year < 1600) { + return true; // keep it + } + }) - // Array.prototype.map() + // shorthand: + // const fifteen = inventors.filter(inventor => inventor.year >= 1500 && inventor.year < 1600); + + console.table(fifteen); + + // Array.prototype.map() -- takes in an array, does something with it, then returns new array of same length // 2. Give us an array of the inventors' first and last names + const fullNames = inventors.map(inventor => inventor.first + ' ' + inventor.last); + console.log(fullNames); - // Array.prototype.sort() + // Array.prototype.sort() -- sorts by giving 1 or -1 // 3. Sort the inventors by birthdate, oldest to youngest + const ordered = inventors.sort(function(a, b){ + if (a.year > b.year) { + return 1; + } else { + return -1; + } + }); + + // shorthand: + // ordered = inventors.sort((a, b) => (a.year > b.year ? 1 : -1)); + + console.table(ordered); - // Array.prototype.reduce() + // Array.prototype.reduce() -- builds something on each item // 4. How many years did all the inventors live? + const totalYears = inventors.reduce((total, inventor) => { + return total + (inventor.passed - inventor.year); + }, 0) + + console.log(totalYears); + // 5. Sort the inventors by years lived + const oldest = inventors.sort(function(a,b) { + const lastGuy = a.passed - a.year; + const nextGuy = b.passed - b.year; + return lastGuy > nextGuy ? -1 : 1; + }) + + console.table(oldest); + // 6. create a list of Boulevards in Paris that contain 'de' anywhere in the name // https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris + /* + const category = document.querySelector('.mw-category'); + const links = Array.from(category.querySelectorAll('a')); + + const de = links + .map(link => link.textContent) + .filter(streetName => streetName.includes('de')); + */ + // 7. sort Exercise // Sort the people alphabetically by last name + const alpha = people.sort((lastOne, nextOne) => { + const [alast, afirst] = lastOne.split(', '); + const [blast, bfirst] = nextOne.split(', '); + return alast > blast ? -1 : 1; + }) + + console.log(alpha); + // 8. Reduce Exercise // Sum up the instances of each of these const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck' ]; + const transportation = data.reduce(function(obj, item) { + if(!obj[item]) { + obj[item] = 0; + } + + obj[item]++; + return obj; + }, {}) + + console.log(transportation); + From 4ea13ef78202d2327ba86c4e82928960ac6d918a Mon Sep 17 00:00:00 2001 From: Caroline Horn Date: Wed, 1 Feb 2017 17:55:06 -0500 Subject: [PATCH 5/9] Days 5,6,7 done --- 05 - Flex Panel Gallery/index-START.html | 43 ++++++++++++++++++++++++ 06 - Type Ahead/index-START.html | 36 ++++++++++++++++++++ 07 - Array Cardio Day 2/index-START.html | 39 +++++++++++++++++++++ 3 files changed, 118 insertions(+) diff --git a/05 - Flex Panel Gallery/index-START.html b/05 - Flex Panel Gallery/index-START.html index e1d643ad5c..0c2f98ebea 100644 --- a/05 - Flex Panel Gallery/index-START.html +++ b/05 - Flex Panel Gallery/index-START.html @@ -24,9 +24,16 @@ .panels { min-height:100vh; overflow: hidden; + display: flex; } .panel { + flex: 1; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + background:#6B0F9C; box-shadow:inset 0 0 0 5px rgba(255,255,255,0.1); color:white; @@ -54,6 +61,18 @@ margin:0; width: 100%; transition:transform 0.5s; + flex: 1 0 auto; + display: flex; + justify-content: center; + align-items: center; + } + + .panel > *:first-child { + transform: translateY(-100%); + } + + .panel > *:last-child { + transform: translateY(100%); } .panel p { @@ -67,9 +86,18 @@ } .panel.open { + flex: 5; font-size:40px; } + .panel.open.active > *:first-child { + transform: translateY(0); + } + + .panel.open.active > *:last-child { + transform: translateY(0); + } + .cta { color:white; text-decoration: none; @@ -108,6 +136,21 @@ diff --git a/06 - Type Ahead/index-START.html b/06 - Type Ahead/index-START.html index 1436886918..c59cc00b79 100644 --- a/06 - Type Ahead/index-START.html +++ b/06 - Type Ahead/index-START.html @@ -17,6 +17,42 @@ diff --git a/07 - Array Cardio Day 2/index-START.html b/07 - Array Cardio Day 2/index-START.html index 969566ff78..4176dc2a9d 100644 --- a/07 - Array Cardio Day 2/index-START.html +++ b/07 - Array Cardio Day 2/index-START.html @@ -26,15 +26,54 @@ // Some and Every Checks // Array.prototype.some() // is at least one person 19 or older? +/* + const isAdult = people.some(function(person){ + const currentYear = (new Date().getFullYear()); + + if(currentYear - person.year >= 19) { + return true; + } + }) +*/ + + const isAdult = people.some(person => { + const currentYear = (new Date().getFullYear()); + return currentYear - person.year >= 19; + }) + + console.log({isAdult}); + // Array.prototype.every() // is everyone 19 or older? + const allAdults = people.every(person => { + const currentYear = (new Date().getFullYear()); + return currentYear - person.year >= 19; + }) + + console.log({allAdults}); + + // Array.prototype.find() // Find is like filter, but instead returns just the one you are looking for // find the comment with the ID of 823423 + const comment = comments.find(comment => comment.id === 823423); + + console.log(comment); + // Array.prototype.findIndex() // Find the comment with this ID // delete the comment with the ID of 823423 + const index = comments.findIndex(comment => comment.id === 823423); + //comments.splice(index, 1); + const newComments = [ + ...comments.slice(0, index), + ...comments.slice(index + 1) + ] + + console.table(comments); + console.table(newComments); + From 23e2fa4f98233a4f8bccc8a6d8ded501a9d64619 Mon Sep 17 00:00:00 2001 From: Caroline Horn Date: Wed, 1 Feb 2017 18:12:36 -0500 Subject: [PATCH 6/9] day 9 done --- 09 - Dev Tools Domination/index-START.html | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/09 - Dev Tools Domination/index-START.html b/09 - Dev Tools Domination/index-START.html index 196fffd719..ff9f89891c 100644 --- a/09 - Dev Tools Domination/index-START.html +++ b/09 - Dev Tools Domination/index-START.html @@ -20,26 +20,57 @@ // Regular // Interpolated + console.log('Hello I am a %s string!', 'poop'); // Styled + console.log('%c I am some great text', 'font-size: 24px'); // warning! + console.warn('Oh NO'); // Error :| + console.error('Crap!'); // Info + console.info('Fun fact!'); // Testing + console.assert(1 === 2, 'That is wrong!'); // clearing + //console.clear(); // Viewing DOM Elements + const p = document.querySelector('p'); + console.dir(p); // Grouping together + dogs.forEach(dog => { + console.groupCollapsed(`${dog.name}`); + console.log(`This is ${dog.name}`); + console.log(`${dog.name} is ${dog.age *7} dog years old`); + console.groupEnd(`${dog.name}`); + }) // counting + console.count('Wes'); + console.count('Wes'); + console.count('Wes'); + console.count('Me'); + console.count('Wes'); + console.count('Wes'); + console.count('Me'); + console.count('Me'); + console.count('Wes'); // timing + console.time('fetching data'); + fetch('https://api.github.com/users/cchaos') + .then(data => data.json()) + .then(data => { + console.timeEnd('fetching data'); + console.log(data); + }); From f0535bca5d7065726817208ce5cf212335c3977f Mon Sep 17 00:00:00 2001 From: Caroline Horn Date: Thu, 2 Feb 2017 10:39:10 -0500 Subject: [PATCH 7/9] up to day 15 done --- .../index-START.html | 27 ++++++++ 13 - Slide in on Scroll/index-START.html | 21 ++++++ .../index-START.html | 30 +++++++++ 15 - LocalStorage/index-START.html | 64 ++++++++++++++++++- 4 files changed, 141 insertions(+), 1 deletion(-) diff --git a/10 - Hold Shift and Check Checkboxes/index-START.html b/10 - Hold Shift and Check Checkboxes/index-START.html index eb7ed310bb..078b5d7bea 100644 --- a/10 - Hold Shift and Check Checkboxes/index-START.html +++ b/10 - Hold Shift and Check Checkboxes/index-START.html @@ -104,6 +104,33 @@ diff --git a/13 - Slide in on Scroll/index-START.html b/13 - Slide in on Scroll/index-START.html index 0b9fb8fccb..56266b402a 100644 --- a/13 - Slide in on Scroll/index-START.html +++ b/13 - Slide in on Scroll/index-START.html @@ -58,6 +58,27 @@

Slide in on Scroll

}; } + const sliderImages = document.querySelectorAll('.slide-in'); + + function checkSlide(e) { + sliderImages.forEach(sliderImage => { + // halfway through the image + const slideInAt = (window.scrollY + window.innerHeight) - sliderImage.height / 2; + // bottom of image + const imageBottom = sliderImage.offsetTop + sliderImage.height; + const isHalfShown = slideInAt > sliderImage.offsetTop; + const isNotScrolledPast = window.scrollY < imageBottom; + + if(isHalfShown && isNotScrolledPast) { + sliderImage.classList.add('active'); + } else { + sliderImage.classList.remove('active'); + } + }); + } + + window.addEventListener('scroll', debounce(checkSlide)); + diff --git a/27 - Click and Drag/index-START.html b/27 - Click and Drag/index-START.html index b8609315f7..d40a9dc45e 100644 --- a/27 - Click and Drag/index-START.html +++ b/27 - Click and Drag/index-START.html @@ -35,6 +35,39 @@ diff --git a/Books/index.html b/Books/index.html new file mode 100644 index 0000000000..e4d8c258db --- /dev/null +++ b/Books/index.html @@ -0,0 +1,21 @@ + + + + + Minimal JS front-end App Example + + + +

Public Library

+

An Example of a Minimal JavaScript front-end App

+

This app supports the following operations:

+ +
  • +
  • +
  • +
  • +
  • +
  • +
    + + \ No newline at end of file diff --git a/Books/listBooks.html b/Books/listBooks.html new file mode 100644 index 0000000000..eba4bd652d --- /dev/null +++ b/Books/listBooks.html @@ -0,0 +1,22 @@ + + + + + Minimal JS front-end App Example + + + + + + +

    Public Library: List all books

    + + + +
    ISBNTitleYear
    + + + \ No newline at end of file diff --git a/Books/src/ctrl/initialize.js b/Books/src/ctrl/initialize.js new file mode 100644 index 0000000000..bd09a0ad77 --- /dev/null +++ b/Books/src/ctrl/initialize.js @@ -0,0 +1,2 @@ +// instantiate the namespaces for Public Library +var pl = { model:{}, view:{}, ctrl:{} }; \ No newline at end of file diff --git a/Books/src/model/Book.js b/Books/src/model/Book.js new file mode 100644 index 0000000000..50765076ee --- /dev/null +++ b/Books/src/model/Book.js @@ -0,0 +1,99 @@ +function Book( slots ) { + this.isbn = slots.isbn; + this.title = slots.title; + this.year = slots.year; +}; + +// +// A class-level property Book.instances representing the collection of all Book instances managed by the application in the form of a map. +Book.instances = {}; + +// +// A static class-level method Book.convertRow2Obj for converting a row into a corresponding object of type Book. +Book.convertRow2Obj = function (bookRow) { + var book = new Book( bookRow); + return book; +}; + +// +// A class-level method Book.loadAll for loading all managed Book instances from the persistent data store. +Book.loadAll = function () { + var i=0, key="", keys=[], bookTableString="", bookTable={}; + try { + if (localStorage["bookTable"]) { + bookTableString = localStorage["bookTable"]; + } + } catch (e) { + alert("Error when reading from Local Storage\n" + e); + } + if (bookTableString) { + bookTable = JSON.parse( bookTableString); + keys = Object.keys( bookTable); + console.log( keys.length +" books loaded."); + for (i=0; i < keys.length; i++) { + key = keys[i]; + Book.instances[key] = Book.convertRow2Obj( bookTable[key]); + } + } +}; + +// +// A class-level method Book.saveAll for saving all managed Book instances to the persistent data store. +Book.saveAll = function () { + var bookTableString="", error=false, + nmrOfBooks = Object.keys( Book.instances).length; + try { + bookTableString = JSON.stringify( Book.instances); + localStorage["bookTable"] = bookTableString; + } catch (e) { + alert("Error when writing to Local Storage\n" + e); + error = true; + } + if (!error) console.log( nmrOfBooks + " books saved."); +}; + +// +// A class-level method Book.add for creating and storing a new Book record. +Book.add = function (slots) { + var book = new Book( slots); + Book.instances[slots.isbn] = book; + console.log("Book " + slots.isbn + " created!"); +}; + +// +// A class-level method Book.update for updating an existing Book record. +Book.update = function (slots) { + var book = Book.instances[slots.isbn]; + var year = parseInt( slots.year); + if (book.title !== slots.title) { book.title = slots.title;} + if (book.year !== year) { book.year = year;} + console.log("Book " + slots.isbn + " modified!"); +}; + +// +// A class-level method Book.destroy for deleting a Book instance. +Book.destroy = function (isbn) { + if (Book.instances[isbn]) { + console.log("Book " + isbn + " deleted"); + delete Book.instances[isbn]; + } else { + console.log("There is no book with ISBN " + isbn + " in the database!"); + } +}; + +// +// A class-level method Book.createTestData for creating a few example book records to be used as test data. +Book.createTestData = function () { + Book.instances["006251587X"] = new Book({isbn:"006251587X", title:"Weaving the Web", year:2000}); + Book.instances["0465026567"] = new Book({isbn:"0465026567", title:"GΓΆdel, Escher, Bach", year:1999}); + Book.instances["0465030793"] = new Book({isbn:"0465030793", title:"I Am A Strange Loop", year:2008}); + Book.saveAll(); +}; + +// +// A class-level method Book.clearData for clearing the book datastore. +Book.clearData = function () { + if (confirm("Do you really want to delete all book data?")) { + localStorage["bookTable"] = "{}"; + } +}; \ No newline at end of file diff --git a/Books/src/view/listBooks.js b/Books/src/view/listBooks.js new file mode 100644 index 0000000000..0ae6e91292 --- /dev/null +++ b/Books/src/view/listBooks.js @@ -0,0 +1,17 @@ +pl.view.listBooks = { + setupUserInterface: function () { + var tableBodyEl = document.querySelector("table#books>tbody"); + var i=0, keys=[], key="", row={}; + // load all book objects + Book.loadAll(); + keys = Object.keys( Book.instances); + // for each book, create a table row with a cell for each attribute + for (i=0; i < keys.length; i++) { + key = keys[i]; + row = tableBodyEl.insertRow(); + row.insertCell(-1).textContent = Book.instances[key].isbn; + row.insertCell(-1).textContent = Book.instances[key].title; + row.insertCell(-1).textContent = Book.instances[key].year; + } + } +}; \ No newline at end of file diff --git a/MVC/App.js b/MVC/App.js new file mode 100644 index 0000000000..a9968d8ead --- /dev/null +++ b/MVC/App.js @@ -0,0 +1,5 @@ +$(function () { + var model = new TaskModel(), + view = new TaskView(model), + controller = new TaskController(model, view); + }); diff --git a/MVC/EventDispatcher.js b/MVC/EventDispatcher.js new file mode 100644 index 0000000000..1425c14ee1 --- /dev/null +++ b/MVC/EventDispatcher.js @@ -0,0 +1,18 @@ +var Event = function (sender) { + this._sender = sender; + this._listeners = []; +} + +Event.prototype = { + + attach: function (listener) { + this._listeners.push(listener); + }, + + notify: function (args) { + for (var i = 0; i < this._listeners.length; i += 1) { + this._listeners[i](this._sender, args); + } + } + +}; \ No newline at end of file diff --git a/MVC/TaskController.js b/MVC/TaskController.js new file mode 100644 index 0000000000..57ed2eb9d6 --- /dev/null +++ b/MVC/TaskController.js @@ -0,0 +1,65 @@ +var TaskController = function (model, view) { + this.model = model; + this.view = view; + + this.init(); +}; + +TaskController.prototype = { + + init: function () { + this.createChildren() + .setupHandlers() + .enable(); + }, + + createChildren: function () { + // no need to create children inside the controller + // this is a job for the view + // you could all as well leave this function out + return this; + }, + + setupHandlers: function () { + + this.addTaskHandler = this.addTask.bind(this); + this.selectTaskHandler = this.selectTask.bind(this); + this.unselectTaskHandler = this.unselectTask.bind(this); + this.completeTaskHandler = this.completeTask.bind(this); + this.deleteTaskHandler = this.deleteTask.bind(this); + return this; + }, + + enable: function () { + + this.view.addTaskEvent.attach(this.addTaskHandler); + this.view.completeTaskEvent.attach(this.completeTaskHandler); + this.view.deleteTaskEvent.attach(this.deleteTaskHandler); + this.view.selectTaskEvent.attach(this.selectTaskHandler); + this.view.unselectTaskEvent.attach(this.unselectTaskHandler); + + return this; + }, + + + addTask: function (sender, args) { + this.model.addTask(args.task); + }, + + selectTask: function (sender, args) { + this.model.setSelectedTask(args.taskIndex); + }, + + unselectTask: function (sender, args) { + this.model.unselectTask(args.taskIndex); + }, + + completeTask: function () { + this.model.setTasksAsCompleted(); + }, + + deleteTask: function () { + this.model.deleteTasks(); + } + +}; \ No newline at end of file diff --git a/MVC/TaskModel.js b/MVC/TaskModel.js new file mode 100644 index 0000000000..0f8860eceb --- /dev/null +++ b/MVC/TaskModel.js @@ -0,0 +1,62 @@ +var TaskModel = function() { + this.tasks = []; + this.selectedTasks = []; + + this.addTaskEvent = new Event(this); + this.removeTaskEvent = new Event(this); + this.setTasksAsCompletedEvent = new Event(this); + this.deleteTasksEvent = new Event(this); + + }; + +TaskModel.prototype = { + + addTask: function(task) { + this.tasks.push({ + taskName: task, + taskStatus: 'uncompleted' + }); + this.addTaskEvent.notify(); + }, + + getTasks: function() { + return this.tasks; + }, + + setSelectedTask: function(taskIndex) { + this.selectedTasks.push(taskIndex); + }, + + unselectTask: function(taskIndex) { + this.selectedTasks.splice(taskIndex, 1); + }, + + setTasksAsCompleted: function() { + var selectedTasks = this.selectedTasks; + for (var index in selectedTasks) { + this.tasks[selectedTasks[index]].taskStatus = 'completed'; + } + + this.setTasksAsCompletedEvent.notify(); + + this.selectedTasks = []; + + }, + + + deleteTasks: function() { + var selectedTasks = this.selectedTasks.sort(); + + for (var i = selectedTasks.length - 1; i >= 0; i--) { + this.tasks.splice(this.selectedTasks[i], 1); + } + + // clear the selected tasks + this.selectedTasks = []; + + this.deleteTasksEvent.notify(); + + } + + +}; \ No newline at end of file diff --git a/MVC/TaskView.js b/MVC/TaskView.js new file mode 100644 index 0000000000..214f7f3f6c --- /dev/null +++ b/MVC/TaskView.js @@ -0,0 +1,152 @@ +var TaskView = function (model) { + this.model = model; + this.addTaskEvent = new Event(this); + this.selectTaskEvent = new Event(this); + this.unselectTaskEvent = new Event(this); + this.completeTaskEvent = new Event(this); + this.deleteTaskEvent = new Event(this); + + this.init(); +}; + +TaskView.prototype = { + + init: function () { + this.createChildren() + .setupHandlers() + .enable(); + }, + + createChildren: function () { + // cache the document object + this.$container = $('.js-container'); + this.$addTaskButton = this.$container.find('.js-add-task-button'); + this.$taskTextBox = this.$container.find('.js-task-textbox'); + this.$tasksContainer = this.$container.find('.js-tasks-container'); + + return this; // allows for the method chaining inside the previous init() call + }, + + setupHandlers: function () { + + // setting up the event handlers and changing the scope of the this keyword inside that handler + + this.addTaskButtonHandler = this.addTaskButton.bind(this); + this.selectOrUnselectTaskHandler = this.selectOrUnselectTask.bind(this); + this.completeTaskButtonHandler = this.completeTaskButton.bind(this); + this.deleteTaskButtonHandler = this.deleteTaskButton.bind(this); + + /** + Handlers from Event Dispatcher + */ + this.addTaskHandler = this.addTask.bind(this); + this.clearTaskTextBoxHandler = this.clearTaskTextBox.bind(this); + this.setTasksAsCompletedHandler = this.setTasksAsCompleted.bind(this); + this.deleteTasksHandler = this.deleteTasks.bind(this); + + return this; + }, + + enable: function () { + + this.$addTaskButton.click(this.addTaskButtonHandler); + this.$container.on('click', '.js-task', this.selectOrUnselectTaskHandler); + this.$container.on('click', '.js-complete-task-button', this.completeTaskButtonHandler); + this.$container.on('click', '.js-delete-task-button', this.deleteTaskButtonHandler); + + /** + * Event Dispatcher + */ + this.model.addTaskEvent.attach(this.addTaskHandler); + this.model.addTaskEvent.attach(this.clearTaskTextBoxHandler); + this.model.setTasksAsCompletedEvent.attach(this.setTasksAsCompletedHandler); + this.model.deleteTasksEvent.attach(this.deleteTasksHandler); + + return this; + }, + + addTaskButton: function () { + this.addTaskEvent.notify({ + task: this.$taskTextBox.val() + }); + }, + + completeTaskButton: function () { + this.completeTaskEvent.notify(); + }, + + deleteTaskButton: function () { + this.deleteTaskEvent.notify(); + }, + + selectOrUnselectTask: function () { + + var taskIndex = $(event.target).attr("data-index"); + + if ($(event.target).attr('data-task-selected') == 'false') { + $(event.target).attr('data-task-selected', true); + this.selectTaskEvent.notify({ + taskIndex: taskIndex + }); + } else { + $(event.target).attr('data-task-selected', false); + this.unselectTaskEvent.notify({ + taskIndex: taskIndex + }); + } + + }, + + show: function () { + this.buildList(); + }, + + buildList: function () { + var tasks = this.model.getTasks(); + var html = ""; + var $tasksContainer = this.$tasksContainer; + + $tasksContainer.html(''); + + var index = 0; + for (var task in tasks) { + + if (tasks[task].taskStatus == 'completed') { + html += "
    "; + } else { + html += "
    "; + } + + $tasksContainer.append(html + '
    '); + + index++; + } + + }, + + + + /* -------------------- Handlers From Event Dispatcher ----------------- */ + + clearTaskTextBox: function () { + this.$taskTextBox.val(''); + }, + + addTask: function () { + this.show(); + }, + + setTasksAsCompleted: function () { + this.show(); + + }, + + deleteTasks: function () { + this.show(); + + } + + /* -------------------- End Handlers From Event Dispatcher ----------------- */ + + +}; \ No newline at end of file diff --git a/MVC/index.html b/MVC/index.html new file mode 100644 index 0000000000..e503fc7632 --- /dev/null +++ b/MVC/index.html @@ -0,0 +1,33 @@ + + + + + Javascript MVC + + + + + + +
    + + + + +
    + + + + +
    + + + + + + + + + + + \ No newline at end of file