JSORM Utility

From Jsorm

Jump to: navigation, search

Contents

Overview

In order to ease using JavaScript, especially as related to the jsorm projects, several utility extensions have been implemented.

Array Extensions

All of the array extensions are added to the Array.prototype, allowing them to be inherited by any array.

  • isArray: Property, boolean, returns true if the object is an array. This is the easiest way to determine if something is an array.
[1,2,3].isArray; // true
"word".isArray; // undefined
{a:1, b:2}.isArray; // undefined
  • pushAll: Method to add multiple items to an array at once. JavaScript's array supports push, which allows one to add a single item to an array. If an array is given as an argument to push, that array is added as a single element. Array also has concat, but that returns a new array, rather than modifying the existing array. pushAll allows one to add as many objects as desired to a single array.
a = [1,2,3];
a.pushAll([4,5,6]);
a.length; // 6
a; // [1,2,3,4,5,6]
  • insert: Method to add one or more elements at a single locations in an array. Array supports splice of a single element, but not multiple. Expects arguments:
    • i: position before which to insert. If greater than or equal to array.length, just appends at the end.
    • elm: single element or array of elements
a = [1,2,3];
a.insert(1,6); // a is now [1,6,2,3]
b = [1,2,3];
a.insert(1,[9,8,7]); // a is now [1,9,8,7,2,3]
  • clear: Method to remove all of the elements of an array. This is necessary when you need to keep a reference to the same array object but remove its elements.
a = [1,2,3];
a.clear(); // a is now []
  • replace: Method to replace all of the elements of an array. Equivalent to clear and then pushAll(), while keeping a single array object reference.
a = [1,2,3];
a.replace([9,8,7]); // a is now [9,8,7]
  • hasher: Method to return an object wherein all of the keys are elements of the array, and all of the values are the position in the array. Useful if you want to check if multiple elements exist in an array. With the array, you need to scan it linearly every single time. Once hashed, you can do O(1) lookup.
a = ["a","b","c"];
b = a.hasher(); // {a: 0, b: 1, c: 2}
  • indexOf: Method to return the index of an element within the array.
a = [1,2,3];
a.indexOf(2); // 1
  • remove: Method to remove an element from the array.
a = [1,2,3];
a.remove(2); // a is now [1,3]

Object Extensions

All of the object extensions are added to the Object.prototype, allowing them to be inherited by any object.

  • clear: Method to remove all properties that belong to this object and are not functions. Will not affect the prototype of the object.
a = {a:1, b:2};
a.clear(); // a is now {}

Object Conveniences

All of the object conveniences are added to JSORM.

  • apply: Function to apply all of the properties of one object to another. Takes three arguments: target source fields. Target is the object to which the fields should be applied. Source is the source for values. Fields is an object that determines which fields are to be copied. Any field that exists in fields and in source will be copied; otherwise the fields will not. If fields is null or undefined, all fields in source will be copied to target. Returns target.
a = {a:1,b:2,c:3};
b = {a:10,b:20};
JSORM.apply(a,b); // a is now {a:10, b:20, c:3};
 
a = {a:1, b:2, c:3};
JSORM.apply(null,a); // returns {a:1, b:2, c:3}
 
a = {a:1, b:2, c:3};
b = {a: 10, b: 20, c: 30};
f = {a: true};
JSORM.apply(a,b,f); // a is now {a: 10, b:2, c:3}
  • common: Function to compare two objects and return only those fields that are identical in both. Takes three arguments: a b keys. a and b are the two objects to compare. keys is a boolean: if false or undefined, will match only if the keys and values are the same on a and b; if true, will match as long as the keys exist on both, and the value on the return object will be the value on a.
a = {a:1, b:2, c:3};
b = {a:1, b:20};
JSORM.common(a,b); // returns {a:1};
JSORM.common(a,b,true); // returns {a:1,b:2};
  • first: Function to look at a list of variables and return the first one that is defined, even if it is null. Takes as many arguments as desired. If none is found, return null.
c = 1, d = 2; // note that a and b have not been defined
JSORM.first(a,b,c,d); // returns 1, the value of c
  • clone: Function to clone an object recursively. Takes two arguments: obj deep. obj is the object to clone. deep is boolean: if true, will clone the object and all its children, so that the copy is guaranteed to have no shared elements with the original. If false, properties are copied directly.
a = {deep: true};
b = {a:1, b:a}; // b points to the object a
c = JSORM.clone(b); // returns {a:1, b:a}, not deep
// now change the value of c.a.deep
c.a.deep = false;
// notice that b is changed as well
b.a.deep; // false
 
// now do it with deep
a = {deep: true};
b = {a:1, b:a};
c = JSORM.clone(b,true); // returns {a:1, b:{deep:true}}, deep copy
// now change the value of c.a.deep
c.a.deep = false;
// notice that b is not changed
b.a.deep; // true
  • iclone: Function to clone an object iteratively. Takes two arguments: obj deep. obj is the object to clone. deep is boolean: if true, will clone the object and all its children, so that the copy is guaranteed to have no shared elements with the original. If false, properties are copied directly.
  • compare: Deep compare two objects to see if they have exactly the same properties and values. Takes two arguments: a b. These are the two to compare. Returns true if they are identical, false if otherwise.
// objects
a = {a:1,b:2,c:{f:true}};
b = {a:1,b:2,c:{f:true}};
c = {a:1,b:2,c:{f:false}};
JSORM.compare(a,b); // true
JSORM.compare(a,c); // false
 
// arrays
a = [1,2,3];
b = [1,2,3];
c = [1,2,3,4];
d = [1,2,4];
JSORM.compare(a,b); // true
JSORM.compare(a,c); // false
JSORM.compare(a,d); // false
 
// strings
a = "word";
b = "word";
c = "test";
JSORM.compare(a,b); // true
JSORM.compare(a,c); // false

String Conveniences

All of the string conveniences are added to JSORM.

  • zeropad: Function to convert a number into a string and pad it with zeros, for example turn 10 into "00010". Takes two arguments: n l. n is the number to zeropad, e.g. 10. l is the length to which to pad it with zeros, e.g. 6. If l is less than the number of digits in n, nothing is changed.
JSORM.zeropad(10,6); // returns "000010"
JSORM.zeropad(10,1); // returns "10"

Processing and Network Conveniences

All of the processing and network conveniences are added to JSORM.

  • fork: Function to fork a separate thread and perform a function. Works under a browser window or under a Java implementation of JavaScript, e.g. Rhino. Expects a single argument: config. config is an object. The properties of the object are: fn scope arg. fn is the function to execute after forking. scope is the scope to give the function. arg is a single argument or array of arguments to pass to the function.
var fn = function(arg){alert("I was passed " + arg.n);};
var scope = this;
var arg = {n: 2};
JSORM.form({fn: fn, scope: scope, arg: arg}); // will launch an alert with "I was passed 2"
  • ajax: Function to send an Ajax request and process the response. Single argument as an object. Members are:
    • url: URL to send to. If begins with /, then absolute, else relative to current page.
    • callback: function to call when the Ajax call has completed or failed. Callback will have the following arguments:
      • filename: The original URL sent.
      • xmlHttpRequest: the xmlHttpRequest object
      • success: boolean for success
      • options: original options passed to the JSORM.ajax call
      • message: error message, if any
    • scope: scope to use when launching the callback.
    • options: object with options to pass to the callback.
    • params: parameters to pass to the call, i.e. parameters to the server. This is expected to be a JavaScript object. Each element of the params object will be passed as the name of a parameter to the call. The value of each element is expected to be a string that can be directly passed. Thus {a: "abc", b: "def"} will be converted into "a=abc&b=def".
    • method: method to use, normally one of "POST","GET","PUT","DELETE".
// retrieve input from our server at /foo/get.xml
var fn = function(url, xhr, success, options, message) {
    if (success) {
       // process results
    } else {
       // warn about the message
    }
};
var scope = this;
JSORM.ajax({url: "/foo/get.xml", callback: fn, scope: scope, method: "POST"});

Event Management

Event management is handled by a single function, JSORM.eventualize(). eventualize expects a single argument, the object to which to add event-handling. The eventualized object will be provided with several new methods:

  • fire: Method to fire an event. Expects arguments:
    • event: String name of the event
    • params: Parameters to pass
  • on: Method to register an event-handler. Expects arguments:
    • event: String name of the event to watch for
    • method: Method to call when the event occurs. The method should receive a single parameter, an object, with the following properties:
      • launcher: The object that fired the event
      • other: Parameters that were passed when the event-handler was registered plus the parameters that were passed when the event was fired. Parameters when the event was fired override the parameters passed on event registration.
    • parameters: Object with parameters to pass to the event handler when an event is fired
    • scope: Scope with which to call the method
  • off: Deregister a previously registered event handler. The event, method and parameters must match to deregister. Expects parameters:
    • event: The event for which to register an event handler
    • method: The method which is no longer to be called
    • parameters: The parameters originally registered for the event handler
  • events: Register events to be handled. This must be called prior to on() or off(). Expects string arguments listing events.
  • nonevents: Deregister events to be handled. All event handlers for removed events will be automatically deregistered. Expects string arguments listing events.
// create a new object - could be from a function or new or anything
var a = {};
// register events
a.events("special");
// create a handler
var fn = function(launcher, args) {
   // do something
};
var scope = this;
// register a handler
a.on("special",fn,{},scope);
// a fires an event
a.fire("special",{param: "secret"});
// fn will now be called with scope "this" and param "secret"
// deregister the handler
a.off("special",fn,{});

Object Inheritance

JSORM provides an object inheritance framework. The object inheritance framework provides several key features.

  • Inheritance: Any object can be made the parent (prototype) of any other, without the messy direct work of prototypes.
  • Prototypal: Following the power of JavaScript and Douglas Crockford's recommendations, the inheritance introduced here is neither classical nor pseudoclassical. Rather, it is directly prototypal. Created objects are assumed to be the actual constructor function, called directly, rather than an argument to the "new" keyword.
  • Static: The creation structure provides for adding methods to the constructor function itself. Thus, if your constructor will be foo, created with foo(), you can add elements like foo.method and foo.property.

An object is extended by using JSORM.extend(). The arguments to extend are:

  • parent: Parent object to extend. If an object, use as the parent, else take the prototype of the argument as the parent. If null or undefined, will use a new object {}.
  • constr: A function that will be used as the constructor for the new object. If you wish to add any methods or properties to the newly constructed object, this is the place to do it. The constructor will be called at construction time, and will be provided with appropriate scope.
  • stat: static properties to add to the new class.

The new object will have the following properties given to it by the extend constructor:

  • superclass: The parent of the object, i.e. the parent provided to JSORM.extend().
  • myclass: A reference to the static class of the object, useful for referencing static items.

JSORM.extend returns the constructor function, appropriately wrapped and managed. It should be instantiated by simply invoking it. Do 'not' use the keyword "new".

The following example describes creation of a circle object, with static Pi.

var circle = JSORM.extend({},function(r) {
    var radius = r;
    this.diameter = function() { return(radius*2); };
    this.circumference = function() { return(radius*2*this.myclass.pi);};
    this.area = function() { return(radius*radius*this.myclass.pi);};
},{
   pi: 3.1417
});
 
var c = circle(10);
c.diameter(); // 20
c.circumference(); // 62.834
c.area(); // 314.17