Zero to One: Building Mamoru – Weeks 5 and 6

It’s Sunday, 07/13/2014 and I’m in sunny Puerto Rico looking out over the ocean for a small vacation. Breathtaking view but I’ll keep forging ahead with the javascript etc.!

(EDIT: Posted without finishing for archiving’s sake)

After four weeks of work (I started all the way back on 06/17/2014!) I’ve realized I need to deviate from the How to Learn Javascript Properly syllabus. It’s done a great job of getting me this far and has provided much needed guidance. However, the course is targeted at budding web developers, not developers interested in creating single page applications (SPA’s) for mobile using web technology (i.e., phonegap/cordova).

For those just joining us, I’ve put in four weeks on the LJSP syllabus, and it’s time to shift gears. Here are my thoughts on how to proceed for Weeks 5 and 6!

The New Plan Overall

AngularJS instead of JQuery, Ionic on top of Cordova, and Node.js + Heroku for the backend. I’m collecting all this into a mega-post that outlines a new syllabus so that people in my position can just follow it instead of having to cobble things together like me.

The New Plan for Weeks 5 and 6

For the DOM material, read the JavaScript: The Definitive Guide chapters instead of the Professional chapters. They’re more teaching focused and less like a reference manual. Here’s my immediate todo for the foreseeable future.

  1. xRead Ch. 15 “Scripting Documents”
  2. xDo the 5 Basic Projects at Codecademy
  3. xRead Stubbornella’s Guide to CSS
  4. Finish the remaining chapter readings: Chapter 13, 16, 17-17.4 (new chapter)
  5. Read Richard’s “OOP in JavaScript: What you NEED to know” post
  6. xDo the quiz assignment
  7. Read  “Anatomy of a Typical Modern JavaScript App” from Programming Javascript Applications
  8. Watch that CSS-tricks video about positioning
  9. Google media queries and understand what they are (CSS)
  10. At some point, read The Definitive Guide to Form-Based Website Authentication (about logging users in)
  11. Read the Ionic guide and use that to determine next steps.
  12. Determine selections to read from “A Better Way to Learn AngularJS” 
  13. Do Code School’s AngularJS course
  14. Figure out Node / Heroku backend: Read 12.2 “Asynchronous I/O with Node” from Definitive; Ch. 20 “Client-Side Storage” from Definitive, review prototypal inheritance from Richard’s Objects in Detail and read Understand JavaScript Closures with Ease before starting his two-week Learn Node.js Completely and with Confidence course.

We’ve added a chapter (“Handling Events”), replaced the JQuery library with AngularJS (mainly so that we can use Ionic, an “Advanced HTML5 Hybrid Mobile App Framework” that sits on top of Cordova), and decided our backend will be Node.js running on Heroku. Likely the Node.js work will require its own two weeks after I’ve gotten the DOM and Angular down.

I might build the frontend before figuring out Node.js and Heroku, in which case I’ll end up using Ionic and Cordova to do so after the Code School AngularJS course. After we’ve got the backend operational as well, we’ll need to learn how to deploy to the Google and Apple stores. Not bad for four weeks of work!

Links for Building Mamoru Weeks 5 and 6

Stack Overflow Questions

1. How to vertically align elements within other elements using CSS – it’s much harder than it looks, and no fully generic solution exists.

2. Function.prototype.call() – trying to see if I understand the Array.prototype.map.call() code from p. 367 of Definitive.

3. Function calls vs. calling functions – the difference between passing the result of a function call vs. passing a call to a function.

4. Why document.getElementById() doesn’t return Comment Nodes – they’re not descendants of the Document node in the DOM!

5.  Asked a Programmers StackExchange question about using parseInt() vs. the Number() primitive wrapper for type conversion of inputs into numbers.

6. onkeypress vs. onkeyup vs. onkeydown – The order of events is onkeydown, onkeypress (continues firing as long as the key is held), onkeyup (when the key is released)..

Resources

0. Caniuse – lets you know if your JS/CSS/HTML5/SVG will work across various browser versions, including desktop and mobile.

1. Sizzle.js – gives you a baseline of CSS selectors and a means for accessing them that should work across all browsers, including old ones. This is the $() from JQuery.

2. Placekitten.com – http://placekitten.com/x/y where x and y are the horizontal and vertical dimensions. Serves you a placeholder image of kittens! Unfortunately it doesn’t have a default vector image scaled to dimensions for which no kitten image is available. Instead it just doesn’t serve you an image :(

3. Codeguide.co and WTFHTMLCSS – Both by Mark Otto (@mdo). A coding style guide for HTML and CSS and a list of the most common CSS headaches and their solutions.

07/13/2014 (Sun)

What I did:

1. Got organized to tackle Weeks 5 and 6 of my Mamoru-building quest!

2. Reviewed my notes for 7/11/2014 (Fri) and 6/19/2014 (Thurs)

3. Read a smidgen of Ch. 15 “Scripting Documents” from Definitive

Cool things I learned:

1. The getElementsByName() and getElementsByTagName() functions both have “elements” written with an s, but the getElementById() function does not! The getElementsByName() function may only be useful for forms, since only certain HTML fields can have names (though they need not be unique like ID’s, and, of course, don’t quite work properly in Internet Explorer). getElementsByName() is defined in the HTMLDocument class, so it is unavailable for XML documents. getElementsByTagName(“span”) returns all <span>‘s in your document, for example. The returned object is a NodeList.

2. You can select the first <p> tag in a document like so:

var firstpara = document.getElementsByTag(“P”)[0];

This works because the NodeList is ordered in the order the tags appear in the document, so the zero-index is the first instance of that tag in the document. Notice that getElementsByTag() is case-insensitive, so “P” will return <p>. This method also exists in the Elements class, allowing you to find tags that are descendants of a specific node in the document.

3. I find an explicit answer to my very first Stack Overflow question! Page 367 of Definitive says,

“HTMLDocument also defines two properties that refer to special single elements  rather than element collections. document.body is the <body> element of an HTML document, and document.head is the <head> element. These properties are always defined: if the document source does not explicitly include <head> and <body> elements, the browser creates them implicitly.”

 

7/30/2014 (Wed)

It’s been two weeks since I last worked on Mamoru! I ended up taking unexpected time off for my friend’s wedding (groomsmen duties – they are plentiful ;)), and then for my move to Japan. I’ll be staying here for about a month, and getting settled in required about a week.

I’m very glad my last post was an attack plan for the next month’s sprint! Lets me get right back in the saddle and soldier on.

What I did:

1. Reviewed my notes from 7/13/2014 (new strategy for my second 4-week sprint) and 7/11/2014 (miscellaneous CSS and initial examination of AngularJS expressions and filters).

2. Fooled around with my answer to making a clickable area larger than the visible button and changed the CSS using position: absolute to ensure the inside button graphic is actually vertically centered. Without position:absolute on the inner <div> the line margin-top: 75px for the inner <div>‘s CSS moved both <div>‘s down by 75px.

a {
text-decoration: none;
}
#hidden_button {
background: #ff33ff;
width: 300px;
height: 300px;
}

#button_graphic {
position: absolute;
width: 150px;
height: 150px;
border: 4px solid black;
border-radius: 5px;
color: #ffffff;
text-align: center;
background-color: #F38630;
margin-left: 75px;
margin-top: 75px;
}

Unfortunately, since a <div> runs across the whole width of a page, the clickable area actually extends well beyond the 300px I intended. The whole section on the right of the first <div> to the end of the browser window is clickable. Not sure how to fix that. 

3. Continued reading Chapter 15, “Scripting Documents” of Definitive. It’s loooooooong.

4. Did the Web Form project (project two) from Codecademy’s 5 Basic Projects.

Cool things I learned:

1. Vertically aligning elements inside other elements is hard with CSS. As per usual, it appears that CSS is quite hacky. I hope I will get a good grasp of the various position options (static, absolute, relative) and how to use them later, since I think that will matter a lot for styling nested elements.

2. How to use array methods on NodeLists (what getElementsByName() and getElementsByTagName() return). Definitive offers the following example:

var content = Array.prototype.map.call(document.getElementsByTagName(“p”), function(e) { return e.innerHTML; });

Here’s what I think is happening in this code. The variable content is being assigned the result of a .map() call on the NodeList of paragraph tags returned by document.getElementsByTagName(“p”). The .map() method is accessed from the Array.prototype, and its this value is set to be the paragraph tag NodeList using .call(). Since .map() applies a function that has access to item, index, array, the e in function(e) is the item of the NodeList. So the content variable ends up being comprised of the result of .innerHTML calls on each of the Element type Nodes in the NodeList made up of paragraph tags in the current document.innerHTML will return the text of a given HTML element if it has no other nodes inside it. Otherwise it will return the HTML nodes inside it. Note that the call is made without any trailing parentheses.

 

7/31/2014 (Thurs)

Only spent 1hr working yesterday, just to get back into the swing of things. Doing a full three hours today!

What I did:

1. Asked a Programmers Stack Exchange question about the Array.prototype.map.call() example from yesterday. Hoping the Programmers site is better at conceptual discussion than the StackOverflow site.

2. Read a couple interesting Programmers posts on the difficulty of hiding JavaScript code and how to write JavaScript without HTML in it by using an “MVW” pattern (Model, View, Whatever).

3. Solved an error someone on /r/learnjavascript was having – they mean to be doing a conditional test in the if statement on line five, but are using the assignment operator = instead of the comparison operator ===. Since the value on the left is not a variable, they’re getting an assignment error. Looking through others’ code like this is a nice way to warm up for my day.

4. Continued reading Ch. 15 of Definitive

Cool things I learned:

1. NodeLists (returned by document.getElementsByTagName() and document.getElementsByName()) and HTMLCollection objects (properties like document.images and document.forms) are live. If you call document.getElementsByTagName(“p”) and there are no <p> tags in your document, the .length will be 0. If a <p> tag gets added, the length of the already returned NodeList will increment to 1!

Thus, Definitive advises,

If you will be adding or removing elements from the document while iterating through a NodeList, however, you may want to make a static copy of the NodeList first:

var snapshot = Array.prototype.slice.call(nodelist, 0);

2. All these NodeList returning methods can be called on document OR on an HTML Element, in which case it will return descendants of that element matching the criteria.

3. .getElementsByClassName() also returns a live NodeList, and takes as its argument a space separated list of identifiers. Elements must match all the identifiers to be returned, but order does not matter. The class attribute of an HTML document is a space separated list of all the class identifiers provided by the CSS.

4. .querySelectorAll() is the big papa of selecting elements by their CSS selector. It returns a NodeList, but, this NodeList is not live. It takes a string of comma separated CSS selectors and returns Elements that match any of the selectors. Definitive is slightly misleading about what this method takes as an argument and what it returns. See the Mozilla Developer Network documentation for more.

5. JQuery’s implementation of .querySelectorAll() (the famous $()) is available as a standalone library called Sizzle.js. It gives you a baseline of selectors and a means for accessing them that should work across all browsers, including old ones.

6. Text and Comments are Nodes, but are not Elements – So we can use a method to return only Elements without worrying about a blank line of space messing up our .firstChild call or subsequent efforts to traverse the NodeList. For example, .children is different from .childNodes: The first returns a NodeList of child Elements only. The second returns a NodeList that includes child Elements as well as text and comment Nodes that are children. When using .children, to traverse our Element NodeList we use things like .firstElementChild or .lastElementChild.nextElementSibling or .previousElementSibling etc.

 

8/01/2014 (Fri)

Really want to finish Ch. 15 of Definitive today. This chapter is huge and I just want to smash through it, and hopefully pick up the remaining three projects in Codecademy’s 5 Basic Projects track as well. That would be delightful.

What I did:

1. Read three posts on the /r/learnjavascript subreddit about difficulties fellow learners are encountering. Pleased to say I have internalized enough javascript knowledge by this point that those difficulties do not plague me! I’m impatient to get to the actual building stage, can’t wait to tackle this midterm quiz project.

2. Reveled in the glory of my first question on StackOverflow with multiple upvotes (9 as of today!). A pleasant surprise since it migrated from Programmers StackExchange (where it saw little action) overnight. Also a good reinforcer that I’m really retaining what I’ve learned, since even after two weeks off I was still able to evaluate some pretty complex code correctly.

3. Continued reading Ch. 15 “Scripting Documents” of Definitive.

4. Read a great StackOverflow answer that hammered home the difference between passing in the result of a function call and passing in a call to a function.

5. Asked a StackOverflow question about why document.getElementById() doesn’t return Comment Nodes. The answer? Comment nodes are not descendants of the Document node in the DOM! They (along with Text Nodes) are descendants of CharacterData, which is a child node of Node. The other child nodes of Node are Document, Element, and Attr.

6. Finished another project in the Codecademy 5 Basic Projects – the Input Validation one. Decided to skip the Date Picker one since it’s about JQuery.

7. Asked a Programmers StackExchange question about using parseInt() vs. the Number() primitive wrapper for type conversion of inputs into numbers.

Cool things I learned:

1. HTML attributes and HTMLElement object properties – HTML objects have attributes (an attribute is a name/value pair). For example, <a> has the attribute named href whose value is used as the destination for a hyperlink. Hence <a href = “wondrousthings.com”>. WIth that code you’re actually setting the value of the attribute href to the URL “wondrousthings.com”. Javascript can access attributes of HTML objects as properties of the HTMLElement object representing the HTML object in question.

2. Accessing HTMLElement object properties is simple:

HTML:

<img id=”eldarimg” src = “http://placekitten.com/50/50”> </img>

JavaScript:

var myimg = document.getElementById(“eldarimg”);
var imgurl = myimg.src;
alert(imgurl);
alert(myimg.id === “eldarimg”);

Alerting imgurl does exactly what you think it does, and the last line evaluates to true.

3. HTML object attributes must be converted to lowercase for single word attributes (e.g. “id”) or in Camel Case with first letter minuscule (e.g. “defaultChecked”). Reserved words in JavaScript mean you prefix the HTML attribute name with “html” to write its property name in JS, e.g. “for” (of <label>) becomes “htmlFor”. HTMLClass is an exception and becomes className as a JavaScript property.

4. Manipulating HTMLElement attributes using methods – you can use getAttribute()setAttribute()hasAttribute(), and removeAttribute() on HTMLElements. Note that accessing attributes as properties (#’s 2 and 3 above) does *not* allow you to remove an attribute.

var image = document.images[0];

var width = parseInt(image.getAttribute(“WIDTH”));

image.setAttribute(“class”, “thumbnail”);

(Definitive p. 376)

Note that .getAttribute() always returns a string, and .setAttribute() always takes a string, formatted in the HTML standard way – even if the word is reserved in JavaScript. The attributes are case insensitive. Use .hasAttribute() and .removeAttribute() to check for the disabled attribute on HTML form elements, for example. With .setAttribute() the first argument is the attribute name and the second is its new value. It seems like .setAttribute() can only set one attribute at a time.

5. Use console.log() not alert(“did this line work?”) to debug your code. In JSFiddle, I’ve been using an alert() statement to snoop out problem lines. The alert() won’t run if any line preceding it has a problem. This tells you nothing about the nature of the problem and makes an already difficult process much harder. While it was nice in the beginning to force me to really internalize syntax, the time has come to use the console.

Also, having the developer tools console open while working in JSFiddle gives you great feedback about errors in your code. Highly recommend! (Plus, console.log() will actually output there!)

6. parseInt(input, radix) converts a string into a number. The radix, or base system you wish to use, should always be specified. You can use this instead of the Number() primitive wrapper to do type conversion to a number. parseInt() first converts its input into a string, and then reads up until the first NaN. It converts what it has read into a number of the specified radix, truncating any decimals.

 

8/04/2014 (Mon)

Was frustrated but later felt better about today. I hate getting bogged down in the mush of a 100 page chapter and feeling like I’m not going anywhere, so I decided to ditch Ch. 15 and just make the damn quiz application. Whoops! Quickly ran into a problem I couldn’t solve (so what exactly do I do with these <form> things?) and went back to Definitive since Ch. 15 has a section on HTML forms. I’m finding it a bit better now with some immediately tangible reason for me to be reading instead of the abstract goal of building Mamoru that feels very far away. Onwards and upwards!

What I did:

1. Wrote an answer to a Stack Overflow question on .split() usage. .split() always returns an array of strings, and is a String method.

2. Reviewed my notes from 6/26/2014 to better understand objects and the “Combined Constructor/Prototype pattern” for making them.

3. Reviewed my notes from yesterday.

4. Continued reading Ch. 15, “Scripting Documents” of Definitive

5. Began working on the quiz application

Cool things I learned:

1. You have to edit the actual property on the HTMLElement Object, you can’t just edit a variable with the same value.

If you have:
HTML: <img id=”catsignal” src=”http://placekitten.com/50/50″>

JS:

var myimg = document.getElementById(“catsignal”);
var imgsrc = myimg.src;
alert(imgsrc);
imgsrc = “http://placekitten.com/250/250”;
alert(imgsrc);
myimg.src = imgsrc;

The first alert will show a /50/50 URL, the second will show a /250/250. However, it’s not until the last line, myimg.src = imgsrc; executes that the actual image changes. Changes made to imgsrc alone do not affect the HTML object.

2. The content of an HTML tag can be expressed three ways: as HTML, as plain-text, and using a tree-representation. Imagine the HTML <p> This is <i>amazing</i> oatmeal! </p>.

You might say the content of the <p> tag is “This is amazing oatmeal!” (plain-text), the HTML representation above, or, a Text node plus an Element node with a Text node child plus another Text node (tree representation).

Briefly, .innerHTML returns the content of the element as a string of HTML markup. So in our example it would return This is <i>amazing</i> oatmeal! 

To get plain-text use .textContent or .innerText. Beware that .innerText behaves strangely at times, so .textContent is the better generic choice. To use the tree representation make use of .firstChild and .nextSibling to traverse the tree accordinglyThe .nodeValue property holds the text of a Text node, and is read/write capable.

3. How to use .querySelectorAll() to retrieve particular form elements.

document.querySelectorAll(‘#shipping input[type=”radio”][name=”sex”]’);

This code will return elements that are of type “radio” with name “sex” inside forms whose id is “shipping.” (*NOTE – id is not the same as name!) So the following HTML would match (you would get the HTMLElement object of the radio button input).

<form id=”shipping”>
<input type=”radio” name=”sex” value=”male”>Male</input>
</form>

But the following would not.

<form id=”delivery”>
<input type=”radio” name=”sex” value=”male”>Male</input>
</form>

4. To get all the <input> tags in a given <form> simply chain .getElementById with .getElementsByTagName

var fields = document.getElementById(“address”).getElementsByTagName(“input”);

5. The name attribute of <input>‘s is very important – mutually exclusive radio buttons must all share the same name, and related checkboxes should share the same name as well. Having a related name allows you to pick a sub-group of elements from a <form> very quickly by accessing the <form>‘s elements property. For example.

HTML:

<p>Pick your favorite books from each genre!</p>
<form name=”books”>
<input type=”radio” name=”fantasy” value=”LoTR”>Lord of the Rings
<input type=”radio” name=”fantasy” value=”WoT”>Wheel of Time
<input type=”radio” name=”scifi” value=”Asimov”>The Foundation Series
<input type=”radio” name=”scifi” value=”Ubik”>Ubik

JavaScript:
var fantasy_books = document.forms.books.elements.fantasy;
for(var i=0; i<fantasy_books.length; i++){
console.log(fantasy_books[i]);
}

This will iterate through the two “fantasy” radio button objects but not the scifi ones.

*Note that this example uses the form name attribute, not the form id attribute as our document.querySelectorAll() and document.getElementById() examples did.

6. The .elements property of HTMLForm objects in JavaScript is an HTMLCollection of all the <input> objects in the form, with the exception of those that are of type=”img”. This is why documents.forms.books.elements.fantasy worked in the example above. .elements appears to be specific to HTMLForm objects.

7. The HTMLForm object has four other properties besides .elements. They are: .action.method.encoding.target. The .method property is an HTTP POST or GET. The .action property is the location (URI) of a program that will do something with the form’s data. The .encoding property sets the MIME type for data that will be POSTed to the server. The .target specifies where to display the response once data has been submitted to the server.

 

8/05/2014 (Tues)

Yesterday was a pretty big day! I spent well over three hours working, mainly because I felt frustrated at a perceived lack of progress. I have to remind myself over and over again that progress is still progress, no matter how slow. A post I read yesterday comparing learning programming to learning French really drove the point home. After a day you can speak like an infant. After a week you know some basic questions. After a year other speakers consider you a beginner. And even after a lifetime of study you’re not done, and there are still others who have particularly deep knowledge about specific areas. Onwards and upwards!

What I did:

1. Reviewed yesterday’s notes, and notes from 6/20/2014 – the first day I started learning javascript.

2. Corrected a misunderstanding concerning documents.forms.formName.elements vs. document.querySelectorAll(‘#formID input[type=”radio”][name=”fantasy”]’); The first uses the <form name = “eldar’s inventory”> form name attribute; whereas the second uses the <form id = “eldar’s toolbelt”> form id attribute.

3. Continued reading Ch. 15 “Scripting Documents” from Definitive. I skipped the Element Geometry and Adding/Deleting Nodes section. I will probably go back for the Adding/Deleting nodes section, but for now I’m finishing up the Forms reading.

4. Read a good StackOverflow response about onkeypress, onkeyup, and onkeydown.

Cool things I learned:

1. Forms have two special methods: submit() and reset(). The first sends the form data to the server. The second resets all form elements.

2. Form elements have the following attributes: type : e.g., “text” or “radio” or “checkbox”; form : a read-only reference to the containing form (null if the element is not inside a form); name : read-only value of the HTML name attribute; value : a read/write string corresponding to the value HTML attribute – this is what is sent to the server on submit.

3. onsubmit event handler – only triggered by an actual click on the Submit button, not by calling the .submit() method. Can return false, which allows the programmer to perform data validation before the data is submitted. All form elements have this event handler. onreset event handler works the same way.

4. More form element event handlers – focus and blur fire when a form element obtains or loses input focus. onclick fires when a button is pressed (whether by keyboard or by mouse). onchange fires once a completed change has occurred, e.g. a user has entered text and then moved the input focus elsewhere. Radio buttons and checkboxes fire both onclick and onchange events, but onchange is more widely used. You can define event handlers for these various events. This is pretty cool – this is probably how data validation on password creation boxes is done (“Your password must include a special character and a number!” e.g.).

5. Event handlers’ this – the this of an event handler refers to the form object that fired the event. So this.form refers to the form to which the element firing the event belongs. Similarly, this.form.x refers to a sibling element x of the element who fired the event.

6. Hyperlinks and buttons fire the same onclick event. Buttons made from <input> tags display whatever the value attribute is set to. Buttons made from <button> tags display the element’s content.

7. Data validation – usually done using the onsubmit event of the Form object rather than the onclick event of the Submit button.

8. Radio buttons and checkboxes – they both have a checked property, which is a boolean. When a radio button is de-selected as a result of another radio button being chosen, its onchange event does not fire. The defaultChecked property sets the checked property when the page first loads. The value attribute does not change the buttons’ appearance, but does change the string sent to the server when the form is submitted. A click on a “toggle button” (radio button or checkbox) triggers an onclick event, but only triggers an onchange event if the state changes.

9. Text input fields – the value attribute will specify the default entry in the single-line text input element. For example, a <input type=”text” value = “First name”> will load a single-line text entry field with “First name” in it. The user-submitted text becomes the new value and is submitted along with the form. Use placeholder instead if you want the text to appear slightly greyed, as a prompt for user action before the user has entered anything: <input type=”text” placeholder=”First name”>.

10. Passwords – <input type=”password”> will obscure input as the user types. This is actually pretty cool to try out for yourself. Who knew something so fancy looking could be accomplished so simply. The placeholder attribute still functions here.

11. Files – <input type=”file”> creates a button saying “Choose File” with a line of text saying “no file chosen.” The placeholder attribute does not have any effect here. The value attribute becomes the file the user chooses, and is read-only.

12. Text event handlers – text <input>‘s fire onkeypressonkeydown, and onkeyup events as the user types in them. You can return false from onkeypress or onkeydown in order to suppress certain types of input, i.e. to force the user to enter only digits.

13. The select element – gives a drop-down list of options to be selected.

<select>
<option value=”Eldar”>Eldar</option>
<option value=”Eldarina”>Eldarina</option>
<option value=”Eldarino” selected=”true”>Eldarino</option>
</select>

Setting selected to true pre-populates the dropdown with a selection once the page loads. As always, value is the string returned to the server on submit. If the <select> tag is written <select multiple=”true”> then multiple selections will be enabled by displaying the items as a list where ctrl+click (or apple+click) selects multiple options. A <select> tag does not come with a submit button.

 

8/06/2014 (Wed)

What I did:

1. Checked out Codiqa and Jetstrap, two companies run by the people who run the Ionic framework we’ll be using to build Mamoru.

2. Reviewed yesterday’s notes and my notes from 6/18/2014. It’s fun to review notes from long ago, both because I re-learn things and because it’s inspiring to see what progress I’ve made.

3. Caught an error in my notes from 6/18/2014. Technically em and rem are different for scaling font-sizes. em is relative to the direct parent element, while rem is relative to the font-size declared on the html selector in your stylesheet file. The advice from Weeks 3 and 4 to use a % for the font-size in the body selector and use em for everything else still stands when designing a SPA mobile web app.

4. Decided to skip 15.10 “Other Document Features” and go back and read 15.6 “Creating, Inserting, and Deleting Nodes”

Cool things I learned:

1. The Frameworks Business – Interestingly, Jetstrap had a link to Ionic, but Codiqa did not. Both businesses seem to follow a basic rule – take something entry-level developers will know (JQuery, Bootstrap), and make it into a WYSIWYG interface built around monthly recurring revenue. The Jetstrap pricing page is particularly interesting, with monthly prices listed in order from most expensive to least (usually it’s the other way around). Plus, the page defaults you to an annual purchase, with buttons at the top allowing you to change to a 6 month purchase or a monthly plan. The monthly prices go up accordingly. I wonder if that leads to higher conversions? The Annual / 6 mo. / Monthly tabs also tell you the % discount each method of purchasing offers. Ionic is coming out with something similar called “Ionic Creator.” This appears to be their monetization plan.

jetstrap pricing page

2. The fastest way to typecast (do type conversion) from String to Int in Javascript is using a bitwise operator like the right-shift bit shift operator. For example, if I have:

var x = “1234”;

x = x>>0;

That second line will shift the bits to the right 0 places, preserving the value of the number and coercing its type to integer. It’s faster than using Number(x), and is about the same speed as using parseInt(x), judging by the latest tests available.

3. Don’t use isNaN() to test if your variable is a number. Evidently, this function is broken. Instead, use typeof. For example:

var x = “1234”;
document.write(typeof x); //string
x = x>>0;
document.write(typeof x); //number

4. document.createElement() – Creates an element node that can be inserted as the child node of any node in the DOM. Takes the string of the HTML tag as its argument. For example, document.createElement(“p”) creates a paragraph tag. It does not insert it anywhere.

To make a text node just do var newnode = document.createTextNode(“text node content”); There’s a similar .createComment() as well.

5. Cloning a node – nodeName.cloneNode() returns a new copy of the node. Passing true recursively copies all descendants of the node. Passing false does not. document.importNode() allows you to pass a node from another document, and it will return a copy suitable for insertion into this document. Its second argument, either true or false, operates the same way as .cloneNode().

6. Inserting nodes – use .appendChild() or .insertBefore(). Call .appendChild() as a method of the parent node you want to insert into. The argument becomes the last child of that parent node. You can also call .insertBefore() on the desired parent node. Its first argument is the node to insert, and the second argument is the child node of the target parent node before which you want the new node to be inserted. Passing null for .insertBefore()‘s second argument makes it behave like .appendChild().

7. Node creation and insertion – an example.

HTML:

<title>This is the best title ever!</title>
<h1>Hello world! I’m an h1 tag!</h1>
<p>And I’m a lowly paragraph…</p>

JS:

function insertAt(parent, child, n){
if (n < 0 || n > parent.childNodes.length) {
throw new Error(“invalid index”);
}
else if (n === parent.childNodes.length) {
parent.appendChild(child);
}
else parent.insertBefore(child, parent.childNodes[n]);
}

var parent = document.getElementsByTagName(“p”)[0];
var child = document.createElement(“h2”);
child.textContent = “I hope this shows up!”;
insertAt(parent.parentNode, child, 0);

Before we execute the Javascript, we have a fairly straightforward display of HTML. The title is not visible on JSFiddle, the <h1> tag is first, and smaller and second is the <p> tag. Once we hit run, the following happens.

We declare a function (which means it gets hoisted – we could actually call it before the declaration in our code) called insertAt. It takes three arguments, parent, child, and n. The first two are the corresponding nodes (the child is the one we will be inserting, the parent is the node relative to which the insertion will happen). The n variable is the number of the childNodes index at which we wish to insert.

insertAt checks to see if n is outside the range of the parent node’s childNodes index. If it is equivalent to it, a simple call to appendChild places the child node at the last spot in the childNodes index of parent. Otherwise, a call to insertBefore inserts it in the appropriate place. *Note that if you wish to insert at spot 3, and you insert before spot 3, that insertion point becomes the new spot 3 (and the old spot 3 becomes spot 4 as everything down the line gets bumped up by one).

We have done something else interesting with the way we traversed the DOM tree to find the parent node at which we want to insert. The parent argument insertAt receives is parent.parentNode. The variable parent points to the first  (and only) <p> tag in the HTML. What insertAt actually receives as its parent argument is that <p> tag’s parent node, which is the <body> tag.

We then make an <h2> tag, and fill its text content. Can you guess where it displays as a result of our code?

8. Moving a node – calling .appendChild() or .insertBefore() on a node that already exists within the document moves it from its old position to the new one.

9. Self-calling functions with local scope – p. 384 of Definitive

/* Find the <th> elements of the table (assuming there is only one row of them) and make them clickable so that clicking on a column header sorts by that column.*/

function makeSortable(table){

var headers = table.getElementsByTagName(“th”);

for(var i = 0; i < headers.length; i++) {

(function(n) {

headers[i].onclick = function() { sortrows(table, n); };

}(i));

}

}

What is happening here? Our function makeSortable grabs all the <th> table-header elements in the table ElementObject passed to it. It then iterates through each of these <th> objects with a for loop.

In that for loop, an anonymous, self-calling nested function makes use of its local scope. Since the function is declared without a name, it is anonymous. Since it is enclosed in parentheses () it is nested. I think because it is enclosed in parentheses it also has its own local scope, which allows us to set the value of n to i from the for loop. It calls itself with the (i)); at the end.

This function contains within it another function which is an event handler for the <th> elements we scrubbed earlier. When one of those is clicked, a function calls sortrows() passing it table and n. sortrows() was a function defined one page earlier in Definitive for sorting a table of contents using javascript and the DOM.

Again, since the function is enclosed in parentheses (), we can implicitly pass it the value i to serve as its n, and that variable n has local scope. This is good because it means we won’t accidentally overwrite the value of the variable n in other uses of our sortrows() function, which takes as its arguments table, n, comparator, where table is the table to sort, n is the row’s value to use for the sorting, and comparator is the comparison function the .sort() Array method should use.

 

8/07/2014 (Thurs)

What I did:

1. Reviewed yesterday’s notes and notes from 6/23/2014. Interesting to see the continue and break control commands for manipulating loop flow again. I don’t quite recall the labelName: for() loops, but those look interesting as a way to explicitly direct flow with continue statements.

2. Problem 1 from Project Euler. I’m trying out doing one of these problems as a warmup for my day. Should get the juices flowing and give me a chance to try out the concepts I’m learning.

function addFizzBuzz(){
var total = 0;
for(var i =0; i < 1000; i++){
if(i % 3 === 0 || i % 5 === 0){
total += i;
}
}
return total;
};

function displayTotal(){
var total = addFizzBuzz();
var totalp = document.createElement(“p”);
totalp.textContent=”The total is ” + total;
document.body.appendChild(totalp);
};

displayTotal();

3. Finished Ch. 15 “Scripting Documents” from Definitive. Finally!

4. Decided to skip the last of the 5 Basic Projects since it was about drawing using the <canvas>, which does not seem relevant to me. I ended up with 1) “Project: CSS Buttons,” 2) “Web Form,” and 4) “Checking Input” completed (all previously).

5. Wrote most of the quiz application! Just have to do the last part where the screen removes the question text and displays the user’s score.

Cool things I learned:

1. document.body – This is how you access the <body> tag of your current document.

2. .removeChild() – Called on the parent of the node you wish to remove. So if I wanted to remove the node called stungun I would call stungun.parentNode.removeChild(stungun);

3. .replaceChild() – Takes two arguments. The first is the node to be inesrted. The second is the node to be removed. For example, n.parentNode.replaceChild(document.createTextNode(” [REDACTED] “), n);

You can also use .replaceChild() to bold text, by replacing the text node you want to be boldface with a new bold tag, and then appending the text node as a childNode to the bold tag.

4. document.parentNode – is null. document.parentNode.parentNode throws a TypeError, because null does not have the .parentNode property.

5. Document fragments – a document fragment is a handy way for holding a collection of nodes for transport or manipulation as a single entity. var frag = document.createDocumentFragment();

An example – reversing all the nodes in a <body> tag.

function reverse(n){
var frag = document.createDocumentFragment();
while (n.lastChild) {
frag.appendChild(n.lastChild);
}
n.appendChild(frag);
}
reverse(document.body);

6. Creating a variable with multiple methods –

var Insert = (function() {

if(document.createElement(“div”).insertAdjacentHTML) {

return {

before: function(e, h) {e.insertAdjacentHTML(“beforebegin”, h);},

after: function(e, h) {e.insertAdjacentHTML(“afterend”, h);},

atStart: function(e, h) {e.insertAdjacentHTML(“afterbegin”, h);},

atEnd: function(e, h) {e.insertAdjacentHTML(“beforeend”, h);}

};

}

}());

It’s cool how the return block is compound: it returns a different function call based on what the method name is — but, the method name is not an argument a function receives. Rather, it’s the literal function call the programmer writes. I.e., it’s Insert.atEnd(elementName, “text”); not Insert(atEnd, “text”). And the reason it’s not elementName.Insert(atEnd, “text”) is because the Insert variable we’re creating is not a property of Element. To do it that way we’d need to add it to the Element prototype.

I’m still not sure what the ()); at the end does. Insert operates like a function that has different kinds of methods that can be called, like Insert.before(element, “text to insert”); This replaces the elementName.insertAdjacentHTML(position, text); method that is the default one, with “more logical names” according to Definitive p. 386. The code above is a snippet of the larger function, which also includes implementing the four insertAdjacentHTML functions for browsers that don’t already have them.

If you make the last line look like }); instead of }()); then it says that Insert is undefined and not a function. So including the () seems necessary. Originally I thought this would work like elementName.Insert.before(“text to insert”); but instead it is Insert.before(elementName, “text”); – which makes sense since it is built off elementName.insertAdjacentHTML(pos, text);

7. HTML Parser – Definitive tells me this will be useful (p. 386-7) so I’ll copy it down here, but it seems pretty straightforward.

function parseHTML(html) {

var container = document.createElement(“div”);

var frag = document.createDocumentFragment();

container.innerHTML = html;

while(container.firstChild) {

frag.appendChild(container.firstChild);

}

return frag;

}

The reason you don’t have to iterate through container‘s childNodes list is because .appendChild() will automatically remove and replace a node if it is within the same document. So each time container.firstChild !== null that child node gets moved to frag.

8. link.innerHTML – this is the area the hyperlink will cover. <a href = “whatever.com”> this is the innerHTML </a> 

 

8/8/2014 (Fri)

Yesterday was a big deal for me. I had a mental block preventing me from understanding how to capture a user’s input from a webpage and transfer it over to my javascript. Then I realized what it meant to use the .onclick() method and was happily able to document.getElementById() for my button, set that to a var, and then use .onclick() on it to call a function that kicked the whole thing off.

I had a pretty short day today, spending most of it on dissertation work.

What I did:

1. Did problem 2 from Project Euler.

2. Began investigating an odd bug with my midterm quiz application. I use the value attribute of my submit button to track the question number. As it increments, the displayed question and choices change, and the logic knows which answer is now correct. Starting with the attribute hardcoded in the HTML to 1 somehow makes the second question display, even though no javascript should be being executed yet since no button has been clicked (it’s an .onclick() event that kicks everything off). Not sure what to make of it.

Cool things I learned:

1. Debugging can be painful. Spent most of my time debugging Problem 2 from Project Euler, only to discover that my mistake was not writing the number 4,000,000 correctly.

2. Looked at another solution someone else had done for Problem 2 in Project Euler (also in javascript) and marveled at how much better their code was. It did all the necessary tests at the same time it was creating the fibonacci sequence, and it used memoization to reduce recursion whenever possible. It was very elegant!

This makes me think that my code will probably go through two phases: a solution that works, and then making that solution more elegant. Kind of like shaving.

8/11/2014 (Mon)

What I did:

1. Read Stubornella’s Guide to CSS

2. Bugfixes for my midterm quiz project.

3. Finished my midterm quiz project!

Cool things I learned:

1. CSS has a built-in “cascade.” That’s where the Cascade in Cascading Style Sheets comes from. A browser will apply the most complicated style it recognizes, so place your styles for a given selector in order of most basic to most complex.

Stubornella calls this “relying on the cascade.” Example:

.foo{
  background-color: #ccc; /* older browsers will use this */
  background-color: rgba(0,0,0,0.2); /* browsers that understand rgba will use this */
}

2. Copying and pasting that code example from Stubornella magically worked. It appears to use a <pre></pre> tag, so from now on I’ll use that to format my own code examples! Google tells me the <pre> tag stands for pre-formatted and maintains nested indentations, which is why it is used to display computer code.

3. Use browser prefixes – again order from oldest to newest, and put the most current standard as the last. The browser goes as deep as it can in the cascade, so you want the best stuff at the bottom.

Example:

background: #1e5799; /* Old browsers */
background: -moz-linear-gradient(top, #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#1e5799), color-stop(50%,#2989d8), color-stop(51%,#207cca), color-stop(100%,#7db9e8)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* IE10+ */
background: linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* W3C */

4. Calling a function vs. asking for a function’s return value – I had a particularly nasty bug in my midterm quiz project. My javascript seemed to execute by itself without me wanting it to, immediately after the page loaded. This was a problem as it incremented my question number and text, putting new text on the screen before the user had even done anything. I was adjusting by artificially decrementing the starting index by 1, but I finally figured it out.

I structured my code so that none of the functions should run until the user clicks the “go” button, since that is when they submit the first answer, I can check it for correctness and adjust the score accordingly, and load and display the next question along with its choices. The problem was that this process was happening automatically, without the user ever answering question one.

The culprit:

go.onclick = checkAnswer(go.value);

The solution:

go.onclick = checkAnswer();

Originally I was holding the current question index in my go button’s value attribute, so I thought I needed to pass it, hence the function call assigned to the .onclick event.

However, this ended up actually calling the function and assigning its return value to the .onclick event, which of course was useless for me since it didn’t return anything! This is why pressing the button did not do anything.

My workaround was to make the current question index a global variable and simply access it from the checkAnswer function instead of having it be passed as an argument. Since values stored in the DOM are accessible from my script file anyway, I could always store the current question index somewhere in the DOM and access it when checkAnswer is called instead of using a global variable too.

5. Forcing re-used radio buttons to be unselected when question text changes – The radio button input form I was using for my answer choices is the same form for every question. Only the question text changes. The problem is that after a user makes an answer choice on the first question, the subsequent questions all come with that answer pre-selected.

I wanted none of the radio buttons to be selected each time the question changed. Manually adding the checked = “false” attribute to each of the radio buttons did nothing, since that attribute would get overwritten once one of them was selected on the first question.

The solution:

document.forms.answers.choices[i].checked = false;

As I iterated through the radio buttons to change their nextSibling in the DOM (this is how I changed answer choice text) I also made sure to make them all unchecked again. Works like a charm!

 

8/12/2014 (Tues)

Since I finished the midterm quiz ahead of schedule I’m a bit lost. Should I do more reading — Chs. 13 (“JavaScript in Web Browsers”), 16 (“Scripting CSS”) and 17.1-4 (“Handling Events”) from Definitive and the OOP post from JavascriptIsSexy — or just jump straight into Ionic? If I decide to go into Ionic, should I really do AngularJS first or just go into Ionic and learn what Angular I need to along the way? And how will I store data about users — what is my ‘database’ going to look like?

Maybe I don’t need the full Ionic/Angular framework. Maybe I can just use the CSS of Ionic to get the styling I want, and build the rest of the business logic / view control logic (e.g. event handlers) myself. The UI is simple after all, and apparently for DOM manipulation Ionic uses something called jqLite, which is part of jQuery anyways.

It also seems like Angular and Ionic don’t use OOP, so maybe I can skip the OOP post from JavascriptIsSexy.

Also – should I make the ”かんたんらくてん” Chrome plugin I’ve been thinking about? It would strip out all the unnecessary ads and spam around the actual product, so that when you clicked on a product it actually gives you the product. It’s an interesting hack to make and it would let me solidify my JS a bit and learn more CSS.

What I did:

1. Read “Where does the Ionic framework fit in?” from the Ionic framework site. It looks like Ionic will help me get native-like styling and UI components running quickly. It also looks like it only supports iOS 6 and Android 4.1 or later.

2. Read “My perspective of working with the Ionic framework” from Raymond Camden over at Adobe. According to Raymond,

“So speaking as an Angular noob, I felt comfortable using Ionic with it…Of course, if you know nothing of Angular, you may want to spend a few minutes looking at it before you use Ionic, but you certainly do not need to be an expert.”

3. Read Christopher Coenraets’ post about making a sample employee directory with Ionic. The graphic at the beginning was very helpful for understanding the landscape of mobile development frameworks.

frameworks

4. Read the Ionic section from this mobile framework roundup at Modus Create. I particularly liked their quote from the perspective of a Product Manager:

“The initial barrier to get started with AngularJS is very low, without needing to know the entire framework in order to build an easy app. However, beginners faced with more advanced tasks in a complex application will face an increasingly steep learning curve. Also, Angular is built with testing in mind. Make use of it early in the game.”

It looks like Angular will not be terribly difficult to use, but that its testing component is something I need to make use of from the get go.

Cool things I learned:

1. Ugh. So in addition to Ionic, there is a “sister tool” called ng-Cordova which appears to be some kind of CLI wrapper for Phonegap/Cordova. There are just too many names flying around now. I just want to build a simple app!

2. Ionic only supports iOS 6 and Android 4.1 or higher, so it looks like I will be cutting some of the market out if I use it. However, I’ll still get 98% of the iOS users, which is where the money-spending consumers (in the States) are. According to the same article, I will also be getting two-thirds of the Android install base. Numbers as of April 2014.

3. The mobile frameworks graphic above from Chris Coenraets was quite helpful, but I notice that it only specifies UI, Architecture, and DOM manipulation. The backend appears to be missing in both the Full Stack or Custom Stack (mix and match) approach. So I suppose that part of the stack always has to be handled on your own. For me I think that’s Node.js + Heroku, but I’m not sure what to do for a database. I’m hoping Heroku provides that too.

4. It looks like Angular will not be terribly difficult to use, but that its testing component is something I need to be aware of from the get go, and that its learning curve increases steeply (or so one source says). I’m concerned about over-engineering this problem (Ionic! Angular! ng-Cordova!) when a simpler solution would work.

 

bobo