API
Manifesto
Why
Examples
Editor

Why jDog?

History & philosophy

What is jDog? organizing code the single PAGE variable early attempts the asynchronous loading problem

Usage and Structure

PAGE is existential loading order Structure Modules Constructors Properties Functions 3rd party Libraries jQuery Extensions Custom

Complete API

What is jDog (AKA PAGE)

jDog is a javascript library to organize and structure your scripts, giving easy access from within the web console and within your code to the global variable PAGE. It is also a pattern for developing code with good structure easily and consistently. And because it's been around awhile, it is also a growing body of scripts which interact with each other consistently and reliably allowing you to build out robust new code. It's a small library that will change the way you write javaScript.

Why do you need it?

jDog makes working with the browser console the most amazing experience ever. By stuffing everything into one explorable variable, PAGE, it dramatically simplifies the process of building and then debugging your project.

Organizing code

There are many ways to organize code for a website. From the early days of the web, with pure html, images, and maybe a few CGI scripts things were relatively easy. A few key folders, some files, and a some server settings. It's very easy to organize something that is simple which does very little. Things get more complicated as you introduce more functionality. As I write this in late 2014, javascript has become a driving force in the way developers think about and organize their web projects. There are many reasons for this trend, mostly boiling down to demand from consumers and product development requirements. The bottom line is for your code to make sense, it needs to be organized, and consistently so. This is quite a challenge when you consider all of the possible ways of writing javaScript, and the many prevailing trends, existing libraries, and influential personalities who push this or that pattern or structure.

Why have a PAGE variable

The PAGE variable started out in the frustration of inheriting code from many different projects. When inheriting a project for the first time, certain important variables would be hidden inside the global window object, such as CurrentMemberId, or CampaignClass etc for example. Often javascript files would have functions and variables all meshed together, calling and modifying each other. For small projects this practice is understandable, but as the web evolved to expect ajax style interaction this practice broke down. This is especially true when trying to modify older code writing in this way. If you didn't know what to look for or have easy access to the complete code base, you can spend a lot of time just digging through the code to find what you need. Time wasted. Viewing source (back in the day) would produce some serious spaghetti. It took a long time to understand the scope of adding new features. And often, features would never get removed since doing so could break something somewhere else in unexpected ways. In short it was a mess, and there was no standard way of organizing all of the mess. For these reasons and many others I made the decision that for any new projects I would store things into a common variable called PAGE. In that way, if I hadn't worked on the project in awhile I could type PAGE in the console to peak at what was happening and get up to speed quickly.

At first the code looked something like this:

  if (typeof PAGE === "undefined") {
    PAGE = { }
  }
  PAGE.SomeProperty = 12314
But this technique got annoying since you always had to check for null. And if you had nested properties, it gets even worse.
  if (typeof PAGE !== "undefined") {

    if (PAGE.someThing && PAGE.someThing.someProperty) {
      // ... do something
    } else {
      // ... looks like it's not defined
    }

  }
This constant need for retrieving and adding nested properties (PAGE.Something.SomethingElse) prompted me to come up with a standard way of accessing nested properties inside the PAGE variable or window object. This required PAGE to be it's own library, loading very early. Though this was itself annoying, it resolved a lot of common problems with asynchronous loading. After a couple rewrites, I eventually came up with this type of syntax:

Checking if a path exists

// the old way of doing it
// this is checking against the PAGE object
var part1 = (PAGE && PAGE.Something && PAGE.Something.SomeOtherThing) ?
      PAGE.Something.SomeOtherThing.Part1 : undefined

// the way of dog
var part1 = PAGE.exists("Something.SomeOtherThing.Part1")


// the old way of doing it
// This checks against the window object
var part1 = (window.Something && window.Something.SomeOtherThing) ?
      window.Something.SomeOtherThing.Part1 : undefined

// the way of dog
var part1 = PAGE.exists("Something.SomeOtherThing.Part1", window)

// the old way of doing it
// This checks against the window object, return a default
var part1 = (window.Something && window.Something.SomeOtherThing) ?
      window.Something.SomeOtherThing.Part1 ? 123 : 123

// the way of dog
var part1 = PAGE.exists("Something.SomeOtherThing.Part1", window, 123)
Source code for checking Existence
As you can see the essence of exists is pretty simple. First, split out the path by periods. The inner obj variable gets redefined on each pass through the while loop. If it reaches an undefined or null it stops prematurely, otherwise it returns the property requested. Finally, there is an alternative variable which will return optionally if either the thing is undefined or the value is null.
var exists = function (path, base, alternate) {
  if (typeof path === "undefined" || typeof path === "object") return
  var arr = path.split(".")
    , x = 0
    , obj = base || PAGE

  if (arr.length < 1) return alternate

  while (x < arr.length) {
    obj = obj[arr[x]]
    if (obj === undefined || obj === null) return alternate
    x++
  }
  if (typeof obj !== "undefined")
    return obj
  else
    return alternate
}

Interesting tricks of existential awareness!

// here are some cool things you can do with exists

// somewhere in my project I have defined a function

MyProject.someAmazingModule.reload = function(delay) { /* ......... */ }

// and I am not entirely sure it has loaded yet, but I don't want to wait for it

PAGE.exists("someAmazingModule.reload", MyProject, function(){})( 500 )

// what did that just do?
//
// 1. Look inside window.MyProject for someAmazingModule
// 2. look inside someAmazingModule for reload
// 3. return it and call it with 500 as the parameter
// 4. if it's not there, return and call anonymous function

The asynchronous loading problem with javascript

A good practice to employ while coding any complex project is separating concerns. Break down the functionality from the data, break apart the functionality by what it does. Break apart code that reads or writes to the database, writes cookies or localStorage. Headers, footers, tracking code etc etc. In javascript, as in other languages, this is done by saving different concerns as their own file, with a unique name for the file that corresponds to the unique name of the function or object or extension. So what's the problem? JavaScript differs from other languages however in that it is running in a browser. The browser is designed to work over a network, that could be fast or slow, where items on the page will progressively paint until everything is finished loading. If there are different files being loaded by the browser, some will load before others. This is what is known as asynchronous loading. Those who write code in compiled languages rarely have to face this problem or implement ways to resolve it. This is a huge source of grief for many developers new to javascript as they expect all things to be available now. To add even more complexity, production code often differs from development code. Keep in mind that while writing and debugging your code it wise to keep files separate, have lots of comments, but for production it is best to bundle all the necessary files together, remove all redundant information, and shrink it down and compress it. Compiled language namespace solutions use a Using statement towards the top of the file. Upon compilation, the required libraries are then hoisted into scope to be accessed by the code that needs them. In javascript it is not that simple because everything is loading asynchronously. A working solution, though a bad one, would wait for all required libraries to be loaded before running the code. The problem with this is that some files might not be needed till long after the page finishes loading. Imagine a login popup which only needs to be loaded after you click the login button. A better solution is to break down the page into areas you want loaded first, or later. A better solution would split the work of a Component into the parts that can run without external Components and the parts that require external components. In this way the processor would work on the stuff that it can now, then get to the stuff that is still being loaded later. Thanks to the power of javascript you can do this very thing, as the scope in the closure allows full access to variables long after they are first loaded. One of the advantages of jDog over Module loading scripts is the emphasis on Constructors and other non Module type objects. Later on I will expound upon the differences, but for this topic, Constructors are Functions that output Objects which can have Methods and properties. If you understand Object Oriented Architecture, Constructors can be thought of as a Class. In JavaScript, Constructors have even more functionality.

How jDog tackles the asynchronous problem

If jDog does anything well, it is tackling the asynchronous loading problem with web based javascript. The primary technique is quite simple. PAGE.wait

The Order of things

When working with asynchronous code, you never can be absolutely sure of the load order. For PAGE (jdog) to work properly, it should be added before any other PAGE items. Also, though it's not dependant on jQuery, it certainly interacts with jQuery faster if jQuery is loaded before PAGE. Normally I load jQuery through google's hosted library. This speeds up the page loading since the source is coming from a different domain.

Ideal Order

	1) PAGE.loader.js          // add this to the PAGE bundle, or directly on HTML
	2) PAGE.base.js            // add this to the PAGE bundle
	3) jQuery                  // add this to the page bundle
	4) (any page extensions)   // add this to the PAGE bundle
	5) (any page constructors or functions or properties)
	6) (any page modules)

Structure of your PAGE

To a large degree the structure of your page is up to you. jdog is not a framework like angular or similar libraries that requires a rigid structure or pattern to develop around. jdog is framework independent. This means you have more freedom to adapt other javascript libraries since there are no dependency conflicts to contend with. It really is up to you to structure your code the best way you can. jdog is a library management tool. Javascript is a very expressive language which allows for many different types of patterns. In my practice the following ways of grouping code have been beneficial.
Modules
These are the instantiated objects in the page
Constructors
These are functions that Construct Objects (either Modules, or the sub parts to Modules)
Functions
Stateless scripts that affect Modules or their parts
Properties
Global variables which allow easy communication from backend
Extensions
Scripts which extend the functionality of the PAGE library
Module Extenders
Bits of code that expand the functionality of modules
External Libraries
Any of a million javascript libraries

What do I mean by Module?

A Module is an Object that exists on your page with public properties and methods. Modules are stateful Singletons. Whereas a Function takes parameters and runs some script, Modules are the thing itself. They rarely if ever get removed, instead their properties change states. This is the home for active code running on the page, and should be the first place to look in order to understand the structure of what is happening. So for example if you are working on the home page of a site, then you can assume that PAGE.Modules.home will be there. Always start with PAGE in console, and just explore the Modules object first.

Constructors

Constructors are functions that create Objects. They are Stateless, in that they themselves remain constant, generating Objects based on the parameters being passed in. All things considered, while Modules are required, Constructors are not. But the benefit of building out functionality as a Constructors instead of just as a part of a Module is that Constructors are easier to test. Because they are stateless, you can generate many objects from them, testing different combinations, and disposing of the objects when you are done. The same cannot be said for Modules.

Functions

Functions are stateless bits of code that do something for you without needing to generate objects. They might be used to modify objects, or numbers, or strings, or any other kind of quick work. Functions are the easiest thing to test, since there is an input and an output.

Properties

Properties are a repository for holding all of the global variables for a site. I generally put things like the User object. Since they are global, any Function, Constructor, or Module can read from them, or even write to them. They have no methods to themselves. They are mute that way.

Third Party Libraries

Third Party libraries can be added in different ways. Generally, external libraries add to the window object, and as such can be 'waited' for like everything else. To load the script from PAGE, you would use PAGE.load
PAGE.load("/Scripts/folder/ExternalSpinnerExample.js")
if you have the script bundled, (as you should), you only need to reference it when it's loaded in the normal way, with the exception that you include the 'window' object as the root.
PAGE.wait("window.ExternalSpinnerExample", function(ExternalSpinnerExample) {
  ExternalSpinnerExample()
})
or
PAGE.wait(
  "window.ExternalSpinnerExample"
  , ref
  , function(ref) {
  ref.ExternalSpinnerExample
})

jQuery is a special little library

I don't claim to love many javascript libraries, but I do love jQuery. It's a special case, so much so in fact that PAGE built in integration for it. Normally for jQuery you would need the following to ensure that jQuery and the DOM are ready to play together.
$(document).ready(function() {
  // lets do some good
})
But I love and use jQuery often, and really don't want to have to type this every time I want to use jQuery with jDog.
$(document).ready(function() {
  PAGE.add("Modules.demo", (function() {
    // lets do some good
  }()))
})
And though new HTML5 tricks bring fuel to the argument that it is no longer required for DOM manipulation, there are so many wonderful libraries using jQuery, why not make it easy? So I created both add$ and addWait$:
// for simple adding
PAGE.add$("Modules.home", (function() {

  var exports = {
    $btn : $("button[name='Submit']")
    , $name : $("input[name='Name']")
  }

  exports.$btn.click(function() {
    alert("clicked the button : value = " + exports.$btn.val())
  })

  return exports

}()))


// for simple waiting then adding
PAGE.addWait$(
  "Modules.home"
  , [
    "window.jQuery.fn.select2"
    , "Modules.dataService.read"
  ]
  , (function(ref) {

  var exports = {
    $btn : $("button[name='Submit']")
    , $name : $("input[name='Name']")
  }

  exports.$btn.click(function() {
    alert("clicked the button : value = " + exports.$btn.val())
  })

  return exports

}()))
The above code will first wait until jQuery is 'ready', ie, jQuery is loaded, and the DOM is ready, then it will add your module. Ideally you would only need this for Modules, since only modules interact directly with the DOM. Constructors and Functions only get instantiated after Modules, therefore it is fair to assume that jQuery is loaded.

Extensions

Extensions are scripts that extend the PAGE library itself. Here is an example of one:
PAGE.extend(function(puppy, dog, log) {

  dog.GetTime = function() {
    // your code
  }

})
As for convention, puppy is the instance, dog is the prototype, and log is any logging to console. It's easy to remember, that's why it's like that. If you must know, instance properties for PAGE act the same as prototype properties to PAGE. What's nice is to keep them separated. In this way, prototype methods and properties can be hidden, and the output of typing PAGE is much cleaner.

Custom

It's perfectly common for javascript to have all sorts of interesting patterns. Javascript is one of the most expressive languages, and as such people try different ways of writing it. Here is some interesting code to ponder:
// setup a base component
PAGE.add("Components.Base", function(obj) {

  // this utilizes what is called the module pattern
  // an object is brought in and extended

  obj.someProperty  = obj.someProperty  || 123
  obj.someProperty2 = obj.someProperty2 || { blah : true }

  obj.doSomething = function() {
    // your code
  }

  return obj

})

// create a component based on the Base component
PAGE.add("Components.Input", function(/* lots of stuff here */) {

  // with this pattern we must ensure the Components.Base is fully loaded
  var base = PAGE.exists("Components.Base") || function(obj){ return obj }

  var dog = base({

    someProperty : 514
    , DoThis : function() {
      // blah blah
    }

  })

  return dog

})