
jo is a lightweight JavaScript framework designed for HTML5 apps.
$ and other arcane looking symbols in place of proper identifiersDave Balmer: davebalmer.wordpress.com, follow @balmer on Twitter, or email dbalmerjr@gmail.com
Available from GitHub as a git repo or a zip file.
If you want to jam an existing web page into an application framework, jo probably isn't for you. jo is designed to create applications. While it will play nicely with a mixture of new and old web development techniques, it uses HTML5 as a development stack and does not require direct DOM manipulation.
| JavaScript Application | ||||||
| jo | PhoneGap (optional) | |||||
|---|---|---|---|---|---|---|
| joView | joEvent | joDataSource | ||||
| CSS3 | Canvas | DOM | Events | XHR | SQLite | Device OS |
All documentation for the framework is based on
Markdown
and provides a simple, natural and flexible way to document the code. This simple set
of perl scripts has become its own tool called joDoc.
Currently joDoc is included with jo, but in the future it will have its own codebase.
jo is a JavaScript framework for HTML5 capable browsers and devices. It's pretty easy to build on your own, but it does have a few build requirements to do so.
cd jo
make -B
If you do not have make installed, you may want to install and update your
copy of XCode which is freely available form Apple. The -B is required, because
we want to force make to build everything without checking dependancies.
Note: the Makefiles will be getting smarter very soon.
You should install cygwin, which gives you a pretty full unix-like environment
to develop in. Note that you'll have to download make and perl as well if
you want the whole enchilada.
If you're not up for building the library yourself, there's nothing wrong with downloading the latest stable release, all built and ready to plug in from: joApp.com
Important files in the directory tree are:
js/jo_min.js
This is the jo library bundled and minified, ready to drop into your project. You
will need to build the library to make this file (as well as the un-minified
version jo.js which is useful for debugging).
css/aluminum
This is a CSS3 bundle ready to skip your app with. Also serves as a good example of modern HTML5 styling capabilities. Looks pretty bad in IE up through version 8.
css/basic
This is a very basic CSS file which will work on browsers or devices which aren't up to speed with the good stuff. Nothing fancy, just functional.
docs/html/index.html
This file (and others) are built by joDoc when you run make. If you do not build
your files from this source, don't worry. You can always get the docs from the
latest stable release at: joApp.com
Copyright 2010 Dave Balmer, Jr. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY DAVE BALMER, JR. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVE BALMER, JR. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Dave Balmer, Jr.
The complete jo library is small, so in most cases you'll just want to pull it all in, like this:
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/aluminum/aluminum.css">
</head>
<body>
<!-- any static page content goes here -->
<script src="js/jo_min.js"></script>
<!-- any application JavaScript files go here -->
</body>
</html>
If you're using jo to create all the UI for your application, you won't need any content
or tags in your index.html file.
Since the framework is highly dependent on CSS, your mileage may vary across platforms. In particular, Internet Explorer before 9 will have limited eye candy and no animated transitions.
Since jo is geared for HTML5 applications, I recommend you test your apps with Safari, Chrome, FireFox or Opera (in that order or preference).
jo has some initialization which should only be done when your browser is ready to have its DOM fiddled with, so you may want to wrap your code in a function that's called when your page loads, or your device signals that your app is ready to go.
The simplest UI would be something like:
jo.load();
joAlert("Hello!");
Something more interesting would look like:
jo.load();
// setup a stack and a sample card
var stack = new joStack();
var okbutton = new joButton("OK");
// set a responder to the OK button
okbutton.selectEvent.subscribe(function() {
stack.hide();
});
// create our card
var card = new joCard([
new joTitle("Hello"),
new joCaption("Hello World!"),
new joFiller([
okbutton
])
]);
// put the card on our view stack
stack.push(card);
Of course, it is recommended you use more robust OOP coding patterns to make a proper application. While there's nothing illegal about putting everything in global space in a single JavaScript file, but if you're looking to build something big or more easy to maintain, I recommend you check out "JavaScript: the Good Parts" by Doug Crockford (O'Reilly Press).
The following is a class hierarchy for the framework, organized by general function.
Instead of a complex set of pseudo-class methods, jo uses a few simple coding patterns: singleton, base class, subclass, and module. All of these are found in modern JavaScript implementations. A good reference to have while developing your app is JavaScript: The Good Parts by Douglas Crockford (O'Reilly Press)
The pattern for creating a singleton is really just an object literal. For example:
MyApp = {
init: function() {
// some sort of initialization code goes here
},
mymethod: function() {
// some custom method
},
// properties can also be declared inline
myproperty: true
};
Prototypal inheritance does well with "fat" base classes which do most everything you anticipate a subclass would want. This type of inheritance benefits greatly from shallow/wide prototypes for a number of reasons. A base class looks something like:
MyClass = function(x) {
// constructor
this.x = x;
};
MyClass.prototype = {
mymethod: function() {
// some method
},
myothermethod: function() {
// another method
}
};
Strictly speaking, JavaScript doesn't have classes and subclasses. But it does know how to make copies of an object, and keeps track of "inheritance" through its prototype chain. A subclass in jo looks something like this:
MySubclass = function(x, y) {
//constructor
this.y = y;
// call to our "superclass" constructor
MyClass.call(this, x);
};
MySubclass.extend(MyClass, {
mynewmethod: function() {
// this subclass has its own new method
}
});
A couple things to note. jo augments the Function object in JavaScript to
have an extend() method. This is just some syntactic sugar which makes it
easier to extend an object, giving us a pseudo-subclass with syntax that's
not too awkward. The advantage here is we're using JavaScript's natural
object model behind the scenes. We're not creating any extra fluff, just
automating the process somewhat.
Note that objects created using prototypal inheritance also get the benefit of
using JavaScript's built-in instanceof operator which works up the
prototype chain. For example:
// given this new subclass
var someobject = new MySubclass(1, 2);
// both of these tests are "true"
joLog(someobject instanceof MySubclass);
joLog(someobject instanceof MyClass);
You may also notice a "call to super" comment in our MySubclass constructor.
This is a convenient coding pattern which makes it easier to create subclasses,
with methods that augment the superclass' functionality. Like this:
MySubclass.extend(MyClass, {
mynewmethod: function() {
// this subclass has its own new method
},
mymethod: function() {
this.x += 5;
// call super's mymethod() with this object's context
MyClass.prototype.mymethod.apply(this, arguments);
}
});
It may look slightly odd at first, but this approach gives us more of the benefits of subclassing you'd find in other languages without having to step outside of JavaScript's natural object model.
jo uses a variant on this OOP pattern quite extensively for notifications between objects.
When you think about JavaScript, most of the interesting things that happen are asynchronous: XHR calls, loading scripts, accessing at database, making device-specific system calls; even user interactions are all asynchronous in nature.
Instead of trying to hide from this often complex-looking stuff, jo embraces it and provides a scheme to wrap all these different use cases in a consistent interface using joSubject.
This excellent, lightweight mobile application library by Nitobi neutralizes device differences and provides a stable webkit application shell. jo is designed to work with PhoneGap out of the box, and it's highly recommended.
Another tool by Nitobi, LawnChair is a client-side storage solution which stores JSON objects (in SQLite or whatever the device supports). It looks promising, and the jo core has a special subclass of joDataSource called joLawn which folds Nitobi's library into the jo event model.
jo makes extensive use of CSS for its widgets. As a result, it's extremely easy to skin and adapt your user interface for different devices. The project will have a community-driven theme collection to help reduce development time by choosing a stylesheet that most closely matches your application (or device native controls).
One feature jo exploits is the fact that modern browser engines treat unknown
tags as -- tags. So instead of mucking up your application's DOM and CSS space with
a horde of div tags with different CSS classes, it uses namespaced tags which
are outside of your document's typical CSS name space (except body).
<jodialog>
<jofieldset>
<joinput></joinput>
<jobutton></jobutton>
</jofieldset>
</jodialog>
One side benefit of this is that it is possible to load styled HTML content from another source and not have that content's CSS corrupt your application's user interface.
joDoc is a plain text code documentation scheme for JavaScript. It was created out of frustration felt working with various documentation systems available.
/**
myClass
=======
This is my class. It rocks, and this is its _description_, which also
rocks.
Extends
-------
- someOtherClass
Methods
-------
- setName(name)
Where `name` is a `String`.
Use
---
// here is some sample code which shows how to use this class
var x = new myClass(name);
> Note: use of the `name` reserved word is probaly a bad idea.
*/
You can put your comments for your code either:
in your source code (anywhere and in as many pieces as you want) denoted with
/** ... */ multiline-comment blocks
separate markdown (*.mdown) files, probably (tho not necessarily) named to
match your JavaScript files
Can't get much more flexible than that.
JavaScript is an extremely expressive language which is often difficult to describe in terms of meta data and fields. Often, important information that needs to be documented just doesn't fit into a neat, tidy spot.
jsdoc in its various incarnations and some of its spawn like yuidoc take the approach that "what is good for Java is good for JavaScript". All these flavors are based on javadoc formatting, and have been in use for some time.
Aside from the regimented markup being a bit odd to read (admit it, even Java developers don't love it), it suffers from an inflexibility with regard to all the coding patterns available with JavaScript. Basically, it fails due for the same reason that all JavaScript libraries which attempt to subvert JavaScript's natural object model fail. These solutions, while influential in the idea that some form consistent coding approach could help us make better code, are not in the spirit of embracing JavaScript.
Why then do so many developers continue to use a documentation tool which was born of the same well-meaning yet misguided logic of "let's pretend JavaScript is Java"?
Excellent effort, but complex to set up and also tries to make a regimented system for documenting source code. It is extendable, but again, we have a documentation solution which is trying to force JavaScript into a more limited set of features.
For those who want more insight into how the documentation is created:
for each markdown file in your project,
convert to an HTML file
for each source file,
produce a markdown file from all text between `/**` and `*/` comments
convert the markdown file into an HTML file
for each HTML file,
for each `h1` tag,
add an `id` field based on the contents of the `h1` tag
add contents to a `file.html#id` keyword index
for each HTML file,
for each keyword in our index,
intelligently wrap the keyword with an `a` tag
that points to the `file.html#id` from our keyword index
produce an index:
sort the keyword index
save the keyword index as an HTML file
save the keyword index as a JSON file
produce a table of contents:
build sections based on directory names
retain sorted directory order
save as a JSON file
save as a formatted HTML file
concat all html files into one document:
structure:
header
table of contents
contents from all html files, in order
sorted keyword index
footer
convert all fixed paths to local references:
(e.g. `filename.html#about` becomes simply `#about`)
This produces a bundle of files which can be used a couple of ways:
A loose set of files which is used by the joDoc application (written using the jo library, of course)
An alternative "single page" view of all the documentation (which some people really like)
Your own collection of files with some other organization means (which is trivial to do with pre-rendered HTML and the JSON document structure).
Singleton which the framework uses to store global infomation. It also is responsible for initializing the rest of the framework, detecting your environment, and notifying your application when jo is ready to use.
load()
This method should be called after your DOM is loaded and before your app uses
jo. Typically, you can call this function from your document's onLoad method,
but it is recommended you use more device-specific "ready" notification if
they are available.
getPlatform()
Returns the platform you're running in as a string. Usually this is not needed, but can be useful.
getVersion()
Returns the version of jo you loaded in the form of a string (e.g. 0.1.1).
matchPlatform(string)
Feed in a string list of desired platforms (e.g. "mozilla chrome ipad"),
and returns true if the identified platform is in the test list.
loadEventunloadEvent
These events are fired after jo loads or unloads, and can be used in your application to perform initialization or cleanup tasks.
jo extends the Function object to add a few goodies which augment JavaScript in a farily non-intrusive way.
extend(superclass, prototype)
Gives you an easy way to extend a class using JavaScript's natural prototypal inheritance. See Class Patterns for more information.
bind(context)
Returns a private function wrapper which automagically resolves context
for this when your method is called.
This is a standard DOM element for JavaScript. Most of the jo views, continers and controls deal with these so your application doesn't need to.
Not a complete list by any means, but the useful ones for our purposes are:
appendChild(node)insertChild(before, node)removeChild(node)jo uses these properties quite a bit:
innerHTMLclassNamestyleA singleton which makes it easy to setup deferred object creation and cached results. This is a performance menchanism initially designed for UI views, but could be extended to handle data requests and other object types.
set(key, call, context)
Defines a factory (call) for building an object keyed from the key string.
The context argument is optional, but provides a reference for this.
get(key)
Returns an object based on the key string. If an object has not been created
which corresponds to the key, joCache will call the constructor defined to
create it and store the reference for future calls to get().
Defining a view for on-demand use:
joCache.set("home", function() {
return new joCard([
new joTitle("Home"),
new joMenu([
"Top Stories",
"Latest News",
"Old News",
"No News"
])
]);
});
Displaying a view later:
mystack.push(joCache.get("home"));
// the first call to get() will instantiate
// the view, subsequent calls will return the
// view that was created the first time
Class which strings asyncronous calls together.
In serious need of rework; doesn't meet original goal of sequencing these calls. This class might also become deprecated.
add(Function, context, data)start()stop()next()Singleton which abstracts the system clipboard. Note that this is a platform dependant interface. By default, the class will simply store the contents in a special joPreference named "joClipboardData" to provide clipboard capabilities within your app.
Even if you think you're just going to use the default behavior, it is recommended that you never manipulate the "joClipboardData" preference directly.
get()set(String)
Low level methods which use just strings. At this time, you will need to stringify your own data when setting, and extract your data when getting.
cut(joControl)
copy(joControl)paste(joControl)
High level methods which work with any joControl or subclass. If a control
supports selections, cut() will automatically remove the selection after
copying its contents. Otherwise, cut() will work the same as copy().
Singleton with utility methods for manipulating DOM elements.
get(id)
Returns an HTMLElement which has the given id or if the id is not a string returns the value of id.
create(type, style)
Type is a valid HTML tag type. Style is the same as setStyle()
method. Returns an HTMLElement.
// simple
var x = joDOM.create("div", "mycssclass");
// more interesting
var x = joDOM.create("div", {
id: "name",
className: "selected",
background: "#fff",
color: "#000"
});
setStyle(tag, style)
Style can be an object literal with style information (including "id" or "className") or a string. If it's a string, it will simply use the style string as the className for the new element.
Note that the preferred and most cross-platform method for working
with the DOM is to use className and possibly id and put your
actual style information in your CSS file. That said, sometimes it's
easier to just set the background color in the code. Up to you.
getParentWithin(node, ancestor)
Returns an HTMLElement which is the first child of the ancestor which is a parent of a given node.
addCSSClass(HTMLElement, classname)
Adds a CSS class to an element unless it is already there.
removeCSSClass(HTMLElement, classname)
Removes a CSS class from an element if it exists.
toggleCSSClass(HTMLElement, classname)
Auto add or remove a class from an element.
Singleton with DOM event model utility methods. Ideally, application-level code shouldn't have to use this, but library code does.
on(HTMLElement, event, Function, context, data)
Set a DOM event listener for an HTMLElement which calls a given Function
with an optional context for this and optional static data.
stop(event)
Prevent default and stop event propogation.
getTarget(event)
Returns the HTMLElement which a DOM event relates to.
Wrapper for console.log() (or whatever device-specific logging you have). Also could
be extended to send log information to a RESTful service as well, handy for devices
which don't have decent logging abilities.
It's an all-in-one utility that's smart enough to ferret out whatever you throw at it and display it in the console.
joLog("x=", x, "listdata=", listdata);
Basically, fill it up with strings, variables, objects, arrays and the function will produce a string version of each argument (where appropriate; browser debuggers tend to display objects nicely) in the same console line. Simple, effective, easy to use.
Class for custom events using the Observer Pattern. This is designed to be used inside a subject to create events observers can subscribe to. Unlike the classic observer pattern, a subject can fire more than one event and when called, and each observer gets data from the subject. This is very similar to YUI 2.x event model.
fire(data)
Calls subscriber methods for all observers, and passes in: data from the subject,
a reference to the subject and any static data which was passed in the
subscribe() call.
subscribe(Function, context, data)
unsubscribe(Function, context)
Both context and data are optional. Also, you may use the Function.bind(this)
approach instead of passing in the context as a separate argument.
// inside the Subject, we setup an event observers can subscribe to
this.changeEvent = new joSubject(this);
// to fire the event inside the Subject
this.changeEvent.fire(somedata);
// simple case, using Function.bind()
somesubject.changeEvent.subscribe(this.mymethod.bind());
// explicit context (this)
somesubject.changeEvent.subscribe(this.mymethod, this);
// optional data which gets passed with the event fires
somesubject.changeEvent.subscribe(this.mymethod, this, "hello");
This is a very flexible way to handle messages between objects. Each subject may have multiple events which any number of observer objects can subscribe to.
Utility function which calls a given method within a given context after n
milliseconds with optional static data.
joYield(Function, context, delay, data);
Note that delay defaults to 100ms if not specified, and data is optional.
Button control.
// simple invocation
var x = new joButton("Done");
// optionally pass in a CSS classname to style the button
var y = new joButton("Cancel", "cancelbutton");
// like other controls, you can pass in a joDataSource
// which could be useful, so why not
var z = new joButton(joPreference.bind("processname"));
Basically, a paragraph of text.
Special container for card views, more of an application-level view.
activate()deactivate()
These methods are called automatically by various joView objects, for now joStack is the only one which does. Basically, allows you to add application-level handlers to initialize or cleanup a joCard.
A view which is designed to contain other views and controls. Subclass to provide different layout types. A container can be used to intantiate an entire tree of controls at once, and is a very powerful UI component in jo.
// plain container
var x = new joContainer(data);
// HTML or plain text
var y = new joContainer("Some HTML");
// HTMLElement
var w = new joContainer(joDOM.get("mydiv"));
// nested inline structure with text, HTML, joViews or HTMLElements
var z = new joContainer([
new joTitle("Hello"),
new joList([
"Red",
"Green",
"Blue"
]),
new joFieldset([
"Name", new joInput(joPreference.bind("name")),
"Phone", new joInput(joPreference.bind("phone"))
]),
new joButton("Done")
]);
changeEventsetData(data)
The constructor calls this method if you provide data when you instantiate
(see example above)
push(data)
Same support as setData(), but places the new content at the end of the
existing content.
Interactive, data-driven control class which may be bound to a joDataSource, can receive focus events, and can fire off important events which other objects can listen for and react to.
changeEventselectEventenable()disable()focus()blur()setDataSource(joDataSource)setEvents()div.control
Simple visual divider.
A compound UI element which allows the user to hide/show its contents. The first object passed in becomes the trigger control for the container, and the second becoms the container which expands and contracts. This action is controlled in the CSS by the presence of the "open" class.
var x = new joExpando([
new joSection("Options"),
new joContainer([
new joLabel("Label"),
new joInput("sample field")
]
]);
open()close()toggle()openEventcloseEventSingleton which manages global input and event focus among joControl objects.
set(joControl)
Unsets focus on the last control, and sets focus on the control passed in.
clear()
Unsets focus on the last control.
refresh()
Sets focus back to the last control that was focused.
Attempt to make a filler object which pushed subsequent joView objects further down in the container if possible (to attach its contents to the bottom of a card, for eaxmple).
This behavior requires a working box model to attach properly to the bottom of your container view.
Experimental global gesture handler (keyboard, dpad, back, home, flick?). This needs a lot more fleshing out, so it's not ready for general concumption.
Group of controls, purely visual.
A simple HTML content control. One interesting feature is it intercepts all
<a> tag interactions and fires off a selectEvent with the contents of
the tag's href property.
This is a relatively lightweight approach to displaying arbitrary HTML data inside your app, but it is not recommended you allow external JavaScript inside the HTML chunk in question.
Also keep in mind that your app document already has <html>, <head> and
<body> tags. When you use the setData() method on this view, make sure
you don't use any of these tags to avoid weird issues.
In a future version, it is feasible to load in stylesheets references in the HTML document's
<head>section. For now, that entire can of worms will be avoided, and it's left up to you, the developer, to load in any required CSS files usingjoDOM.loadCSS().
// simple html string
var x = new joHTML("<h1>Hello World!</h1><p>Sup?</p>");
// use a joDataSource like a file loader
var y = new joHTML(new joFileSource("sample.html"));
Single-line text input control. When you instantiate or use setData(), you can
either pass in an initial value or a reference to a joDataSource object which it,
like other joControl instances, will bind to.
// simple value, simple field
var x = new joInput(a);
// attach the value to a preference
var y = new joInput(joPreference.bind("username"));
// attach input control to a custom joDataSource
var username = new joDataSource("bob");
var z = new joInput(username);
focus()blur()
You can manually set focus or call the blur() method (which also
triggers a data save).
setData()
Pass in either some arbitrary value for the control, or a reference to a joDataSource if you want to automatically bind to a storage system (e.g. joPreference).
Label view, purely a visual presentation. Usually placed in front of input fields and other controls.
A widget class which expects an array of any data type and renders the array as a list. The list control handles DOM interactions with only a single touch event to determine which item was selected.
selectEvent
Fired when an item is selected from the list. The data in the call is the index of the item selected.
changeEvent
Fired when the data is changed for the list.
formatItem(data, index)
When subclassing or augmenting, this is the method responsible for rendering a list item's data.
compareItems(a, b)
For sorting purposes, this method is called and should be overriden to support custom data types.
// general logic and approriate return values
if (a > b)
return 1;
else if (a == b)
return 0;
else
return -1
setIndex(index)
getIndex(index)
refresh()
setDefault(message)
Will present this message (HTML string) when the list is empty. Normally the list is empty; this is a convenience for "zero state" UI requirements.
getNodeData(index)
getLength()
next()
prev()
setAutoSort(boolean)
Simple menu class with optional icons.
setData(menudata)
See the example below for the format of the menu data.
// simple inline menu; you can always setup the menu items (or change
// them) but using the `setData()` method, same as any joView
var menu = new joMenu([
{ title: "About" },
{ title: "Frequently Asked Questions", id: "faq" },
{ title: "Visit our website", id: "visit", icon: "images/web" }
]);
// simple inline function event handler
menu.selectEvent.subscribe(function(id) {
switch (id) {
case "0":
// the "About" line; if no id, the index of the menu item is used
stack.push(aboutCard);
break;
case "faq":
stack.push(faqCard);
break;
case "visit":
stack.push(visitCard);
break;
}
});
This could actually be called "more consistent and simple" use. If your menus
are static, you could always setup an id-based dispatch delegate which pushes
the appropriate card based on the menu id selected.
You could use the id in conjunction with view keys you create with joCache.
The handler would then something like:
menu.selectEvent.subscribe(function(id) {
mystack.push(joCache.get(id));
});
Secret data input field (e.g. displays ****** instead of secret).
Note that this requires CSS3 which is known not to be currently supported in Opera or Internet Explorer.
A scroller container.
scrollBy(position)scrollTo(position)scrollToView(joView)
Scrolls to make the top of the specified view visible.
div.joScrollerflick physics defined for flickingflickback snap-back physics after a flickNot ready for use; going through a re-write.
Play preloaded sound effects using the HTML5 Audio object. This module could
be wildly different for various platforms. Be warned.
play()pause()rewind()load()setLoop(n)
Tell the joSound to automatically loop n times. Set to -1 to loop
continuously until pause().
endedEventerrorEventA UI container which keeps an array of views which can be pushed and popped.
The DOM elements for a given view are removed from the DOM tree when popped so we keep the render tree clean.
push(joView | HTMLElement) pop()home()show()hide()forward()back()setLocked(boolean)
The setLocked() method tells the stack to keep the first view pushed onto the
stack set; that is, pop() won't remove it. Most apps will probably use this,
so setting it as a default for now.
showEventhideEventhomeEventpushEventpopEventShould set classNames to new/old views to allow for CSS transitions to be set (swiping in/out, cross fading, etc). Currently, it does none of this.
Also, some weirdness with the new forward() and back() methods in conjuction
with push() -- need to work on that, or just have your app rigged to pop()
on back to keep the nesting simple.
Tab bar widget.
Data is expected to be an array of { data: "", label: ""} objects,
in the display order for the bar.
Title view, purely a visual presentation.
Base class for all other views, containers, controls and other visual doo-dads.
var x = new joView(data);
Where data is either a text or HTML string, an HTMLElement, or any joView object
or subclass.
setData(data)getData()createContainer(type, classname)setContainer(element)getContainer()clear()refresh()Wrapper class for WebKit database.
open(datafile, size)
datafile is a filename, size is an optional parameter for initial
allocation size for the database.
close()
now()
Deprecated convenience method which returns a SQLite-formatted date string for use in queries. Should be replaced with a utility function in joTime.
Wraps data acquisition in an event-driven class. Objects can
subscribe to the changeEvent to update their own data.
This base class can be used as-is as a data dispatcher, but is designed to be extended to handle asyncronous file or SQL queries.
set()get()clear()changeEventerrorEventA singleton used for storing and retrieving preferences. Meant to be
augmented with persistent storage methods for set() and get().
This is a work in progress, and totally subject to change. Binding persistent storage to GUI controls in a way that doesn't require goofy syntax is tricky.
bind(key)
Returns a joDataSource class for a key. Used to automagically bind GUI controls in a two-way link with preference data for a key.
get(key)
Returns the current value for a key or null if there is no value.
set(key, value)
Sets an arbitrary value for a given key.
changeEventThis is getting hairy. Sorting out the data types and adding different data sources to the picture is getting messy.
SQL flavor of joDataSource which uses "HTML5" SQL found in webkit.
setDatabase(joDatabase)setQuery(query)setParameters(arguments)execute(query, arguments)changeEvent
Fired when data is loaded after an execute() or when data is cleared.
errorEvent
Fired when some sort of SQL error happens.