Skip to content

Instantly share code, notes, and snippets.

@andrewfritz86
Created October 23, 2014 00:16
Show Gist options
  • Save andrewfritz86/8a88f59c63d06e3ef40b to your computer and use it in GitHub Desktop.
Save andrewfritz86/8a88f59c63d06e3ef40b to your computer and use it in GitHub Desktop.
Todo app main js explanation

#main.js

Hoo-boy, there aren't enough gifs for this one.

var todoApp       = {};
todoApp.taskNum   = 0;
todoApp.taskViews = {};

first, we set an empty JS object to a variable called todoApp, this is for namespacing.

Next, we set a variable called taskNum on the global namespace to 0, since we have no tasks by default.

Next, create an (initially) empty object called taskViews, to hold all our views objects.

Next, we define a few methods on our global todoApp object.

todoApp.pushView = function(newView) {

  var viewId = todoApp.taskNum; todoApp.taskNum++;
  newView.viewId = viewId;  
  todoApp.taskViews[viewId] = newView; 

Here is our createTask method, for making new tasks.

Right away, we declare two variables, and set them equal to a new Task and a new TaskView. Notice that the Task itself gets it's parameters from the data upon the submission event. Now that the task variable is pointed at a new Task object, we can create it's view object on the next line. We pass the new TaskView object our task variable (aka a Task object). Hooray! We have a new task.

On the next line, we push the TaskView object to our todoApp global namespace, and then return the task (the model) for chaining.

What is the pushView method used?

todoApp.pushView = function(newView) {

  var viewId = todoApp.taskNum; todoApp.taskNum++;
  newView.viewId = viewId;  
  todoApp.taskViews[viewId] = newView; 

First, we declare a variable viewId and set it to whatever the taskNum variable is set at from above. We then increment the taskNum variable so that we don't repeat that id.

Next, we take the view object that was passed to pushview and assign it the id we grabbed above. This creates a new attribute for the view object that gives it an id that is separate from its activerecord id, because if it hasn't been persisted yet, it won't have any kind of unique id to identify it by, and we want to be able to identify and manipulate tasks that we currently have. If we've deleted a bunch of tasks in the past, their ids will be strange due to ActiveRecord.

Finally, we push a new key/value pair into our taskViews object declared initially, with the key being the newly assigned ID, and the value being the newly created TaskView object itself.

todoApp.loadTasks = function() {
  // INDEX: GET /tasks
  $.ajax({
    url: "/tasks",
    format: "json"
  }).done(function(data){
    // create a local task (task model, view and pushed on to the task list)
    for(var i = 0; i < data.length; i++){
      todoApp.createTask(data[i]);
    }
  });
}

This method is what we use to get all our tasks loaded up and appened to the DOM when we start up our app.

We make an ajax get request to the '/tasks/ route, where we have a variable in the controller that is set to all of our tasks currently on the DB. The controller knows to render these as JSON, and sends them back to us succesfully.

In our done function, we iterate through the response and create a new task for each task on the database. This is confusing, because while we create a new TaskView and push it to our global object, we only create a new Task model object, we don't persist it (call create on it), because it's already in our DB.

$(function(){
  console.log('2. page (DOM) loaded: now running onload...');

  // caches references to repeatedly need DOM nodes
  todoApp.$body         = $("body");
  todoApp.$inputField   = $("input");
  todoApp.$submitButton = $("button");
  todoApp.$taskList     = $("ul").eq(0);

  // attach a model & view creation function to the form submission
  todoApp.$submitButton.on("click", function(event){
    event.preventDefault();
    var taskDescription = todoApp.$inputField.val();
    todoApp.$inputField.val(''); // reset the input
    todoApp.createTask({ description: taskDescription })
           .create(); // call create on the model that is returned (see above)  
  });

  // start the app!
  todoApp.loadTasks();
});

Finally, we have our onload function, and everything within it.

At the top, we declare some jQuery variables for the different parts of our DOM that we'll be referencing often.

Next, we set a click event on the submit button in our form, and prevent it's default behavior immediately so that it doesn't fire off the default post request

Then, we declare a jQuery variable called 'taskDescription', and use the jQuery 'val' method to capture whatever has been entered into our text input.

We reset the text input on the next line, as we've already captured it with our variable above.

Finally, we call our createTask method and pass it an object containing the task's description. Since our createTask returns the new task's MODEL (NOT VIEW), we can call the taskView object's create method in a chain, and persist the task, God willing.

Since javascript is asynchronous, our loadTasks function has already been called, and the DOM will have some tasks on it.

fin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment