This is a simple OOP framework based on jQuery. Makes JavaScript more Java than Script.
Download latest release.
To create a new namespace foo.bar:
Josie.declare('foo.bar');
to call a namespace:
foo.bar.Test = 'hello';
To create Classes, extend the BaseObject:
com.nysoft.josie.core.BaseObject.extend('foo.bar.Foobar', {});
this will create a new Class named Foobar in namespace foo.bar
to make an instance of this class just call:
new foo.bar.Foobar();
you can implement a constructor by adding a method named init:
com.nysoft.josie.core.BaseObject.extend('foo.bar.Foobar', {
init: function() {
alert(arguments[0]); //arguments are the constructor parameters
}
});
new foo.bar.Foobar('hello');
This will show a messagebox with text hello.
You can call super-class methods by using _super()_:
this._super('init', argument1, argument2, ...);
But this will throw an exception if the method not exists in super-class.
You can use meta-Property to autogenerate getter and setter methods with defaultValue and type-validation:
com.nysoft.josie.core.BaseObject.extend('foo.bar.Foobar', {
meta: {
foo: 'number',
bar: 'string',
foo2: {
type: 'boolean',
defaultValue: true
},
bar2: {
type: 'object',
defaultValue: {
some: 'thing'
}
}
/*
possible types:
number
string
boolean
function
object
null (without ') > no validation
complete classnames like: com.nysoft.josie.core.Control
and collections with []-suffix like: number[] or com.nysoft.josie.core.Control[]
and more. see native javascript types as reference
*/
}
});
var a = new foo.bar.Foobar();
a.setFoo(3); //works
a.setFoo('3'); //throws exception
a.setBar(3); //throws exception
a.setBar('3') //works
If you require a class that is not yet loaded, you can call:
Josie.require('foo.bar.Foobar');
this will load synchronously: /foo/bar/Foobar.js
You also can load external Scripts using Josie.require:
Josie.require('http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js');
A script will only be loaded once! If this is already loaded, Josie.require will skip without an error.
You can create namespace aliases to shorten namespace-names. You can use this aliases also in HTML-Decleration.
Josie.alias('ui', 'com.nysoft.josie.ui');
var text = new ui.Text();
For DOM-Events you should use jQuery-Functions.
But for Object-Events there is an EventStack-Class.
You can set a global eventHandler to a Class. If this event gets executed, each object of this class is affected.
//Create Class
com.nysoft.josie.core.BaseObject.extend('com.nysoft.josie.core.Control', {
init: function() {
alert('world');
}
});
//Bind global Class-event
com.nysoft.josie.core.EventStack.bind('com.nysoft.josie.core.Control', 'onAfterInit', function(e, data) {
alert('hello');
});
var oControl = new com.nysoft.josie.core.Control();
This will alert "hello" after init-Method of each Control-Object is called.
You can also set an object eventHandler. If this event gets executed only this one object is affected.
com.nysoft.josie.core.BaseObject.extend('com.nysoft.josie.core.Control', {
init: function() {
alert('world');
},
foo: function() {
this.trigger('onFoo');
}
});
var oControl = new com.nysoft.josie.core.Control();
oControl.bindEvent('onFoo', function() {
alert('bar');
});
oControl.foo();
This will alert "foo" while calling method foo().
To unbind event just use:
this.unbind('onFoo');
// or
com.nysoft.josie.core.EventStack.unbind('com.nysoft.josie.core.Control', 'onAfterInit');
You can bind 0 ... n eventHanlder to an event. But what you can do to avoid executing next eventHandler in stack?
Easy! Just return false;.
oControl.bindEvent('onFoo', function() {
alert('bar');
return false;
});
oControl.bindEvent('onFoo', function() {
alert('foo');
});
This will alert "bar" but NOT "foo".
You can create a Datamodel with:
var oModel = new com.nysoft.josie.core.Model.JSONModel({
src: '/url/to/json',
key: 'modelKey' // optional. useful if you have more than one datamodel.
});
or with:
<div data-class="com.nysoft.josie.core.Model.JSONModel" data-src="/admin/cache/listCaches"></div>
You can bind data to many objects and to all managed objects.
just pass the data-selector as property-content like this:
/*
Your json-data is something like this:
{
data: [
{
text: 'Submit'
},
{
text: 'foobar'
}
]
}
*/
new com.nysoft.josie.ui.Button({
text: '{".data .text:first-child"}'
});
The binding gets automatically loaded and the control gets automatically updated if the data inside the model changes. You can use normal CSS3 Selectors to select data from your datamodel. For more information see: http://jsonselect.org/
You can create an Object-Tree in Html. Just create objects with a normal div-Tag and add data-Attributes as Object-Properties.
<div data-class="foo.bar.Foobar" data-foo="bar"></div>
You can also use databinding (see section above)
You can aggregate child objects to specific properties or to the default property content
<div data-class="foo.bar.Foobar" data-foo="bar">
<!-- This objects gets aggregated into the parent object's property: content -->
<div data-class="foo.bar.SubFooBar" data-foo="I am content"></div>
<div data-class="foo.bar.SubFooBar" data-foo="I am content 2"></div>
<div data-property="subs">
<!-- This objects gets aggregated into the parent object's property: subs -->
<div data-class="foo.bar.SubFooBar" data-foo="I am sub"></div>
<div data-class="foo.bar.SubFooBar" data-foo="I am sub 2"></div>
</div>
</div>
It is recommended to use the built-in logging mechanism instead of console.log to prevent errors in some browsers.
Josie.log.trace('trace foobar');
Josie.log.debug('debug foobar');
Josie.log.info('info foobar');
Josie.log.warning('warning foobar');
Josie.log.error('ERROR foobar');
The default LogLevel is None. To set the LogLevel use:
Josie.log.setLevel( Josie.log.level.All );
Josie.log.setLevel( Josie.log.level.Info );
/* None, Error, Warning, Info, Debug, Trace, All */
There are coming some little methods with the core.js. Have a look at Josie.utils.
You can split Javascript and HTML by using Class Pattern.
<div data-class="com.nysoft.josie.ui.Button" data-text="FooBar"></div>
This will generate a Button onto this DOM-Element.
The Class-Pattern gets executed on jQuery(document).ready() You can execute the Class-Pattern manually by using jQuery().generateObject()
var aGeneratedObjects = jQuery('div.foo > [data-class]').generateObject();
It will generate the Objects and return this as a list.
This Framework depends on jQuery This should work with all jQuery-Versions from 1.4 up to 2.x. If there is any error/bug with some jQuery version, please tell me or feel free to push a fix.
To get this framework into your project you can download the latest release and add it to your project.
To init the library, you only have to add this to your HTML-Head:
//Before this line you need to load jQuery-Library!
<script type="text/javascript" src="/js/core.js"></script>
Distributed under the MIT license