Skip to content

Instantly share code, notes, and snippets.

@miketaylr
Created January 26, 2010 03:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miketaylr/286515 to your computer and use it in GitHub Desktop.
Save miketaylr/286515 to your computer and use it in GitHub Desktop.
/*
* Titan - Javascript Web Framework
* Version 1.1
* Copyright 2009 Valio, Inc.
*
* Visit the Titan website for more information and documentation:
* http://www.titanproject.org
*
* ---------------------------------------------------------------------------
*
* CREDITS:
*
* Mike Osuna, Will Wilson, Drew Wilson
*
* ---------------------------------------------------------------------------
*
* LICENCE:
*
* Released under a MIT Licence: http://www.opensource.org/licenses/mit-license.php
*
*/
(function ($) {
var willChangeStack = [];
var didChangeStack = [];
function makeChain(target, keys, fn, origTarget, origPath) {
var key = keys.shift();
if (keys.length > 0) {
var nextTarget = $(target).attr(key);
var reobserveOriginal = function () {
$(origTarget).unobserve(origPath, fn);
$(origTarget).observe(origPath, fn);
fn();
};
var undoChainLink = function () {
$(target).unbind(key + "-changed", reobserveOriginal);
};
if (nextTarget) {
$(target).bind(key + "-changed", reobserveOriginal);
return [undoChainLink].concat(makeChain(nextTarget, keys, fn, origTarget, origPath));
}
} else {
$(target).bind(key + "-changed", fn);
}
return [];
}
$.extend({
willChangeValueForKey: function (obj, key) {
willChangeStack.push({
obj: obj,
key: key,
val: $(obj).valueForKey(key)
});
},
didChangeValueForKey: function (obj, key) {
var changed = willChangeStack.pop();
if (changed.key != key) {
console.log("Expected didChangeValueForKey: " + changed.key + " but got " + key);
}
didChangeStack.push(changed);
if (willChangeStack.length == 0) {
var changes = didChangeStack;
didChangeStack = [];
$(changes).each(function () {
if ($(this.obj).valueForKey(this.key) !== this.val) {
$(this.obj).trigger(this.key + "-changed", {
oldValue: this.val,
newValue: $(this.obj).valueForKey(this.key)
});
}
});
}
},
valueForKey: function (obj, key, value) {
if ((value != undefined) && (obj.automaticallyNotifiesObserversForKey === undefined || obj.automaticallyNotifiesObserversForKey(key))) {
$.willChangeValueForKey(obj, key);
}
var val;
if ($.isFunction(obj[key])) {
val = obj[key].call(obj, key, value);
} else {
if (value != undefined) {
obj[key] = value;
}
val = obj[key];
}
if ((value != undefined) && (obj.automaticallyNotifiesObserversForKey === undefined || obj.automaticallyNotifiesObserversForKey(key))) {
$.didChangeValueForKey(obj, key);
}
return val;
},
valueForKeyPath: function (obj, path, value) {
var keys = path.split(".");
var key;
while (keys.length > 1) {
key = keys.shift();
obj = $(obj).valueForKey(key);
if (obj == undefined) {
return undefined;
}
}
key = keys.shift();
return $(obj).valueForKey(key, value);
},
observe: function (obj, path, fn) {
var keys = path.split(".");
var chainKey = path.replace(/\./g, "_");
chain = $(obj).data(chainKey, {});
if (keys.length > 1) {
var chain = $(obj).data(chainKey);
var tmp = makeChain(obj, keys.slice(), fn, obj, path);
chain[$.data(fn)] = tmp;
} else {
$(obj).bind(path + "-changed", fn);
}
return fn;
},
unobserve: function (obj, path, fn) {
var keys = path.split(".");
if (keys.length > 1) {
var chainKey = path.replace(/\./g, "_");
var chain = $(obj).data(chainKey);
$(chain[$.data(fn)]).each(function () {
this();
});
} else {
$(obj).unbind(path + "-changed", fn);
}
return fn;
},
connect: function (from, fromAttr, to, toAttr) {
var binding = {
from: from,
to: to,
fromAttr: fromAttr,
toAttr: toAttr,
updateTo: true,
updateFrom: true
};
$(from).data(fromAttr + $.data(to) + toAttr, binding);
binding.fromFn = $(from).observe(fromAttr, function () {
if (binding.updateTo == false) {
binding.updateTo = true;
binding.updateFrom = true;
return;
}
binding.updateFrom = false;
$(to).valueForKeyPath(toAttr, $(from).valueForKeyPath(fromAttr));
});
binding.toFn = $(to).observe(toAttr, function () {
if (binding.updateFrom == false) {
binding.updateTo = true;
binding.updateFrom = true;
return;
}
binding.updateTo = false;
$(from).valueForKeyPath(fromAttr, $(to).valueForKeyPath(toAttr));
});
binding.updateTo = false;
$(from).valueForKeyPath(fromAttr, $(to).valueForKeyPath(toAttr));
},
disconnect: function (obj, fromAttr, to, toAttr) {
var binding = $(obj).data(fromAttr + $.data(to) + toAttr);
binding.to.unobserve(toAttr, binding.toFn);
binding.from.unobserve(fromAttr, binding.fromFn);
}
});
$.fn.extend({
valueForKey: function (key, value) {
if (value === undefined) {
return $.valueForKey(this[0], key);
}
return this.each(function () {
$.valueForKey(this, key, value);
});
},
valueForKeyPath: function (path, value) {
if (value === undefined) {
return $.valueForKeyPath(this[0], path);
}
return this.each(function () {
$.valueForKeyPath(this, path, value);
});
},
observe: function (path, fn) {
return this.each(function () {
$.observe(this, path, fn);
});
},
unobserve: function (path, fn) {
return this.each(function () {
$.unobserve(this, path, fn);
});
},
connect: function (attr, to, toAttr) {
return this.each(function () {
$.connect(this, attr, to, toAttr);
});
},
disconnect: function (attr, to, toAttr) {
return this.each(function () {
$.disconnect(this, attr, to, toAttr);
});
}
});
})(jQuery);
(function ($) {
$.serialize = function (object) {
var values = [];
var prefix = '';
values = $.serialize.recursive_serialize(object, values, prefix);
param_string = values.join('&');
return param_string;
};
$.serialize.recursive_serialize = function (object, values, prefix) {
var key;
for (key in object) {
if (typeof object[key] == 'object') {
if (prefix.length > 0) {
prefix += '[' + key + ']';
} else {
prefix += key;
}
values = $.serialize.recursive_serialize(object[key], values, prefix);
prefixes = prefix.split('[');
if (prefixes.length > 1) {
prefix = prefixes.slice(0, prefixes.length - 1).join('[');
} else {
prefix = prefixes[0];
}
} else {
value = encodeURIComponent(object[key]);
if (prefix.length > 0) {
prefixed_key = prefix + '[' + key + ']';
} else {
prefixed_key = key;
}
prefixed_key = encodeURIComponent(prefixed_key);
if (value) values.push(prefixed_key + '=' + value);
}
}
return values;
};
})(jQuery);
(function ($) {
$.controller = {
defaults: {},
array: function (model, conditions, options) {
if (this.constructor == $.controller.array) {
var that = this;
this.model = model;
if (conditions) {
this.conditions = conditions;
if (conditions.noRetrieve) {
var noRetrieve = conditions.noRetrieve;
delete conditions.noRetrieve;
}
if (conditions.master) {
this.master = conditions.master[0];
this.attr = conditions.master[1];
if (this.master) {
delete this.conditions.master;
$(this.master).observe("selection", function () {
if (!conditions.noRetrieve) {
if (options && options.success) {
that.retrieve({},
{
success: options.success
});
} else {
that.retrieve();
}
}
});
}
}
if (conditions.paginate) {
var defaults = {
perPage: 10,
numberLimit: 10,
overlap: false,
startPage: 1
}
var opts = $.extend(defaults, conditions.paginate);
this.paginating = true;
this.paginate = conditions.paginate;
this.perPage = opts.perPage;
this.numberLimit = opts.numberLimit;
this._page = opts.startPage;
(opts.overlap !== false) ? this.overlap = opts.overlap : this.overlap = 0;
delete this.conditions.paginate;
}
}
if (!noRetrieve) {
if (options && options.success) {
this.retrieve({},
{
success: options.success
});
} else {
this.retrieve();
}
}
} else {
return new $.controller.array(model, conditions, options);
}
},
object: function () {
if (this.constructor == $.controller.object) {} else {
return new $.controller.object();
}
},
create: function (model, obj, options) {
var that = this;
var data = {};
if (model) {
data = obj;
data = $.serialize(data);
} else {
data = obj;
}
$.ajaxq("titan", $.extend({
url: $.controller.defaults.url + "/" + model,
data: data,
type: "POST"
},
options));
},
destroy: function (model, id, options) {
var data = {};
data = {
id: id
};
$.ajaxq("titan", $.extend({
url: $.controller.defaults.url + "/" + model + "?" + $.serialize(data),
type: "DELETE"
},
options));
},
update: function (model, obj, options) {
var data = {};
data = obj;
$.ajaxq("titan", $.extend({
url: $.controller.defaults.url + "/" + model,
data: $.serialize(data),
contentType: "application/json",
type: "PUT"
},
options));
},
retrieve: function (model, conditions, options) {
var that = this;
var data = {};
if (conditions && conditions != {}) {
data = $.serialize(conditions);
}
$.ajaxq("titan", $.extend({
url: $.controller.defaults.url + "/" + model,
contentType: "application/json",
dataType: "json",
type: "GET",
data: data
},
options));
},
count: 0
};
$.extend($.controller.array.prototype, {
root: "",
page: function (value) {
if (value !== undefined) {
this._page = value;
this.retrieve();
}
return this._page;
},
create: function (obj) {
var that = this;
var defaults = {
autoRetrieve: true,
complete: function () {},
retrieveComplete: function () {},
templateComplete: function () {}
};
options = $.extend(defaults, options);
$.controller.create(that.model, obj, {
success: function (data) {
var tpl_complete = function () {
options.templateComplete.call(this, data);
};
that.templateComplete = tpl_complete;
if (options.autoRetrieve) {
that.retrieve({},
{
success: options.retrieveComplete
});
}
options.complete.call(this, data);
}
});
},
destroy: function (id, options) {
var that = this;
var defaults = {
autoRetrieve: true,
complete: function () {},
retrieveComplete: function () {},
templateComplete: function () {}
};
options = $.extend(defaults, options);
$.controller.destroy(that.model, id, {
success: function (data) {
var tpl_complete = function () {
options.templateComplete.call(this, data);
};
that.templateComplete = tpl_complete;
if (options.autoRetrieve) {
that.retrieve({},
{
success: options.retrieveComplete
});
}
options.complete.call(this, data);
}
});
},
update: function (obj, options) {
var that = this;
var defaults = {
autoRetrieve: true,
complete: function () {},
retrieveComplete: function () {},
templateComplete: function () {}
};
options = $.extend(defaults, options);
$.controller.update(that.model, obj, {
success: function (data) {
var tpl_complete = function () {
options.templateComplete.call(this, data);
};
that.templateComplete = tpl_complete;
if (options.autoRetrieve) {
that.retrieve({},
{
success: options.retrieveComplete
});
}
options.complete.call(this, data);
}
});
},
retrieve: function (conditions, opts) {
var that = this;
if (!conditions) {
conditions = {};
}
if (!opts) {
opts = {};
}
function onSuccess(data) {
if (opts.success) {
opts.success.call(this, data);
}
that.count = parseInt(data.count);
data = data.items;
that._last_id = undefined;
var found = false;
if (that._last_id) {
$(data).each(function () {
if (that._last_id == this.id) {
found = true;
$(that).valueForKey("selection", this);
return false;
}
});
if (!found && data.length > 0) {
$(that).valueForKey("selection", data[0]);
}
} else {
$.willChangeValueForKey(that, "selection");
that.selection = undefined;
$.didChangeValueForKey(that, "selection");
}
if (that.paginating) {
var extra = that.overlap * (that.count / that.perPage);
var total = that.count + extra;
that.pages = Math.round((total / that.perPage) + 0.5);
if (((that.pages - 1) * that.perPage) - (that.overlap * (that.pages - 2)) == that.count && that.pages > 1) {
that.pages = that.pages - 1;
}
that.offset = (that._page - 1) * (that.perPage - that.overlap);
$.fn.rearrange.offset = that.offset;
$(that.paginate.selector).pager(that);
}
$(that).valueForKey("contents", data);
}
if (that.master) {
var selection = $(that.master).valueForKey("selection");
if (selection) {
if (that.master_last_id != $(selection).valueForKey("id")) {
that._page = 1;
}
conditions[that.attr] = $(selection).valueForKey("id");
that.master_last_id = $(selection).valueForKey("id");
} else {
$(that).valueForKey("contents", []);
return;
}
}
if ($(that).valueForKey("selection") !== undefined) {
that._last_id = $(that).valueForKeyPath("selection.id");
}
conditions = $.extend(this.conditions, conditions);
if (this.paginating) {
that.offset = (that._page - 1) * (that.perPage - that.overlap);
conditions['limit'] = that.perPage;
conditions['offset'] = that.offset;
$.controller.retrieve(that.model, conditions, {
success: onSuccess
});
} else {
$.controller.retrieve(that.model, conditions, {
success: onSuccess
});
}
}
});
})(jQuery);
(function ($) {
$.template = function (root, controller, options) {
var tpl = this;
var defaults = {};
tpl.root = root;
tpl.pristine = $(root).cloneTemplate(true)[0];
tpl.contents = [];
tpl.controller = controller;
this.options = $.extend(defaults, options);
$(tpl).observe("contents", function () {
tpl.render();
});
$(this).connect("contents", controller, "contents");
}
$.template.prefix = "ti_";
$.template.defaultRender = function (elem, data) {
$(elem).data("data", data);
if ($(elem).data("format") && !$(elem).data("formatExtend")) {
return $(elem).data("format").call(this, elem, data);
} else {
if ($(elem).data("formatExtend")) {
$(elem).data("formatExtend").call(this, elem, data);
}
var classes = elem.className.split(/\s+/);
var prefix = new RegExp("^" + $.template.prefix);
for (var i = 0; i < classes.length; i++) {
if (prefix.test(classes[i])) {
var curData = data[classes[i].replace(prefix, "")];
if (curData != undefined) {
if (curData.constructor == Array) {
var tmp = $("<div></div>");
$(curData).each(function () {
$(tmp).append($.visit($(elem).cloneTemplate(true)[0], this, $.template.defaultRender));
});
$(elem).empty();
$(elem).append($(tmp).contents());
return false;
} else {
var content = curData;
if (/opt_truncate_/.test(classes)) {
var flat = classes.toString();
var truncLimit = flat.match(/opt_truncate_\d+/i);
truncLimit = truncLimit[0].replace(/opt_truncate_/i, "");
content = content.trunc(truncLimit);
}
if (/opt_text/.test(classes)) {
$(elem).text(content);
} else if (/opt_append/.test(classes)) {
$(elem).append(content);
} else if (/opt_prepend/.test(classes)) {
$(elem).prepend(content);
} else if (!/opt_no_html/.test(classes)) {
$(elem).html(content);
}
return true;
}
}
}
}
return true;
}
},
$.template.prototype = {
deactivate: function (root) {
if (this.children) {
$(this.children).each(function () {
this.deactivate(false);
});
}
if (!root) {
$(this).disconnect("contents", this.controller, "contents");
delete this.controller;
}
},
render: function () {
var tpl = this;
var contents = $(tpl).valueForKey("contents");
if (contents) {
$(tpl.root).empty();
$(contents).each(function (i) {
$(tpl.root).append($.visit($(tpl.pristine).cloneTemplate(true)[0], this, $.template.defaultRender));
});
}
if (this.options.success) {
this.options.success();
}
if (tpl.controller.templateComplete) {
tpl.controller.templateComplete.call(this);
}
}
}
$.visit = function (root, data, fn) {
var func, start, current, next = null;
current = start = root;
do {
if (current.nodeType == 1) {
if (fn.call(this, current, data)) {
next = current.firstChild || current.nextSibling;
} else {
next = current.nextSibling;
}
} else {
next = current.firstChild || current.nextSibling;
}
var tmp = current;
if (!next) {
var tmp = current;
do {
next = tmp.parentNode || start;
if (next == start) break;
tmp = next;
next = next.nextSibling;
} while (!next);
}
current = next;
} while (current != start);
return $(start).contents();
}
$.fn.cloneTemplate = function (events) {
var ret = $(this).clone(events);
var clone = ret.find("*").andSelf();
$(this).find("*").andSelf().each(function (i) {
if (this.nodeType == 3) return;
var format = $.data(this, "format");
if (format) {
$.data(clone[i], "format", format);
}
var formatExtend = $.data(this, "formatExtend");
if (formatExtend) {
$.data(clone[i], "formatExtend", formatExtend);
}
});
return ret;
}
$.fn.format = function (fn) {
return $(this).data("format", fn);
}
$.fn.formatExtend = function (fn) {
return $(this).data("formatExtend", fn);
}
$.fn.template = function (controller, options) {
return this.each(function () {
$(this).data("template", new $.template(this, controller, options))
});
}
})(jQuery);
(function ($) {
$.fillIn = function (obj, data) {
obj = $.extend({},
obj);
for (attr in obj) {
if (obj[attr].constructor == Array) {
$(obj[attr]).each(function () {
obj[attr] = $.fillIn(obj[attr], data);
});
} else if (typeof obj[attr] == "object") {
obj[attr] = $.fillIn(obj[attr], data);
} else if (typeof obj[attr] == "string") {
obj[attr] = obj[attr].replace(/{([^{}]*)}/g, function (tag, name) {
var value = data[name];
return typeof value === 'string' || typeof value === 'number' ? value : tag;
});
}
}
return obj;
}
})(jQuery);
(function ($) {
$.fn.hasData = function (key, value) {
var returnVal = false;
var curData = $(this).data("data");
if (curData) {
$.each(curData, function (objKey, objVal) {
if (value) {
if (key == objKey && value == objVal) {
returnVal = true;
}
} else {
if (key == objKey && objVal != "") {
returnVal = true;
}
}
});
}
return returnVal;
}
})(jQuery);
function date(format, timestamp) {
var a, jsdate = ((typeof(timestamp) == 'undefined') ? new Date() : (typeof(timestamp) == 'number') ? new Date(timestamp * 1000) : new Date(timestamp));
var pad = function (n, c) {
if ((n = n + "").length < c) {
return new Array(++c - n.length).join("0") + n;
} else {
return n;
}
};
var txt_weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var txt_ordin = {
1: "st",
2: "nd",
3: "rd",
21: "st",
22: "nd",
23: "rd",
31: "st"
};
var txt_months = ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var f = {
d: function () {
return pad(f.j(), 2);
},
D: function () {
var t = f.l();
return t.substr(0, 3);
},
j: function () {
return jsdate.getDate();
},
l: function () {
return txt_weekdays[f.w()];
},
N: function () {
return f.w() + 1;
},
S: function () {
return txt_ordin[f.j()] ? txt_ordin[f.j()] : 'th';
},
w: function () {
return jsdate.getDay();
},
z: function () {
return (jsdate - new Date(jsdate.getFullYear() + "/1/1")) / 864e5 >> 0;
},
W: function () {
var a = f.z(),
b = 364 + f.L() - a;
var nd2, nd = (new Date(jsdate.getFullYear() + "/1/1").getDay() || 7) - 1;
if (b <= 2 && ((jsdate.getDay() || 7) - 1) <= 2 - b) {
return 1;
} else {
if (a <= 2 && nd >= 4 && a >= (6 - nd)) {
nd2 = new Date(jsdate.getFullYear() - 1 + "/12/31");
return date("W", Math.round(nd2.getTime() / 1000));
} else {
return (1 + (nd <= 3 ? ((a + nd) / 7) : (a - (7 - nd)) / 7) >> 0);
}
}
},
F: function () {
return txt_months[f.n()];
},
m: function () {
return pad(f.n(), 2);
},
M: function () {
t = f.F();
return t.substr(0, 3);
},
n: function () {
return jsdate.getMonth() + 1;
},
t: function () {
var n;
if ((n = jsdate.getMonth() + 1) == 2) {
return 28 + f.L();
} else {
if (n & 1 && n < 8 || !(n & 1) && n > 7) {
return 31;
} else {
return 30;
}
}
},
L: function () {
var y = f.Y();
return (! (y & 3) && (y % 1e2 || !(y % 4e2))) ? 1 : 0;
},
o: function () {
if (f.n() === 12 && f.W() === 1) {
return jsdate.getFullYear() + 1;
}
if (f.n() === 1 && f.W() >= 52) {
return jsdate.getFullYear() - 1;
}
return jsdate.getFullYear();
},
Y: function () {
return jsdate.getFullYear();
},
y: function () {
return (jsdate.getFullYear() + "").slice(2);
},
a: function () {
return jsdate.getHours() > 11 ? "pm" : "am";
},
A: function () {
return f.a().toUpperCase();
},
B: function () {
var off = (jsdate.getTimezoneOffset() + 60) * 60;
var theSeconds = (jsdate.getHours() * 3600) + (jsdate.getMinutes() * 60) + jsdate.getSeconds() + off;
var beat = Math.floor(theSeconds / 86.4);
if (beat > 1000) beat -= 1000;
if (beat < 0) beat += 1000;
if ((String(beat)).length == 1) beat = "00" + beat;
if ((String(beat)).length == 2) beat = "0" + beat;
return beat;
},
g: function () {
return jsdate.getHours() % 12 || 12;
},
G: function () {
return jsdate.getHours();
},
h: function () {
return pad(f.g(), 2);
},
H: function () {
return pad(jsdate.getHours(), 2);
},
i: function () {
return pad(jsdate.getMinutes(), 2);
},
s: function () {
return pad(jsdate.getSeconds(), 2);
},
u: function () {
return pad(jsdate.getMilliseconds() * 1000, 6);
},
I: function () {
var DST = (new Date(jsdate.getFullYear(), 6, 1, 0, 0, 0));
DST = DST.getHours() - DST.getUTCHours();
var ref = jsdate.getHours() - jsdate.getUTCHours();
return ref != DST ? 1 : 0;
},
O: function () {
var t = pad(Math.abs(jsdate.getTimezoneOffset() / 60 * 100), 4);
if (jsdate.getTimezoneOffset() > 0) t = "-" + t;
else t = "+" + t;
return t;
},
P: function () {
var O = f.O();
return (O.substr(0, 3) + ":" + O.substr(3, 2));
},
Z: function () {
var t = -jsdate.getTimezoneOffset() * 60;
return t;
},
c: function () {
return f.Y() + "-" + f.m() + "-" + f.d() + "T" + f.h() + ":" + f.i() + ":" + f.s() + f.P();
},
r: function () {
return f.D() + ', ' + f.d() + ' ' + f.M() + ' ' + f.Y() + ' ' + f.H() + ':' + f.i() + ':' + f.s() + ' ' + f.O();
},
U: function () {
return Math.round(jsdate.getTime() / 1000);
}
};
return format.replace(/[\\]?([a-zA-Z])/g, function (t, s) {
if (t != s) {
ret = s;
} else if (f[s]) {
ret = f[s]();
} else {
ret = s;
}
return ret;
});
}
function relative_time(time_value) {
time_value = new Date(time_value * 1000);
var parsed_date = Date.parse(time_value);
var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
if (delta < 60) {
return 'less than a minute ago';
} else if (delta < 120) {
return 'about a minute ago';
} else if (delta < (45 * 60)) {
return (parseInt(delta / 60)).toString() + ' minutes ago';
} else if (delta < (90 * 60)) {
return 'about an hour ago';
} else if (delta < (24 * 60 * 60)) {
return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
} else if (delta < (48 * 60 * 60)) {
return '1 day ago';
} else {
return (parseInt(delta / 86400)).toString() + ' days ago';
}
}(function ($) {
$.formatDate = function (format, prop, tzoffset) {
return function (elem, data) {
var ca = $(data).valueForKey(prop);
if (ca == undefined || ca == "") {
$(elem).html("");
} else {
var m = ca.match(/(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)/);
var t = new Date(m[1], m[2] - 1, m[3], m[4], m[5], m[6]);
var tz = 0;
if (tzoffset) {
tz = t.getTimezoneOffset() * 60;
}
t = (t.getTime() * 0.001) - tz;
if (format == "relative") {
$(elem).html(relative_time(t));
} else {
$(elem).html(date(format, t));
}
}
}
}
$.fn.formatDate = function (format, prop, tzoffset) {
return $(this).format($.formatDate(format, prop, tzoffset));
}
function number_format(number, decimals, dec_point, thousands_sep) {
var n = number,
prec = decimals,
dec = dec_point,
sep = thousands_sep;
n = !isFinite(+n) ? 0 : +n;
prec = !isFinite(+prec) ? 0 : Math.abs(prec);
sep = sep == undefined ? ',' : sep;
var s = n.toFixed(prec),
abs = Math.abs(n).toFixed(prec),
_, i;
if (abs > 1000) {
_ = abs.split(/\D/);
i = _[0].length % 3 || 3;
_[0] = s.slice(0, i + (n < 0)) + _[0].slice(i).replace(/(\d{3})/g, sep + '$1');
s = _.join(dec || '.');
} else {
s = abs.replace('.', dec_point);
}
return s;
}
$.fn.formatNumber = function (number, options) {
var defaults = {
decimals: 0,
decPoint: ".",
thousandsSep: ""
};
var opts = $.extend(defaults, options);
return $(this).format(function (elem, data) {
var val = $(data).valueForKey(number);
decimals = opts.decimals;
decPoint = opts.decPoint;
thousandsSep = opts.thousandsSep;
if (val == undefined || val == "") {
$(elem).html("");
} else {
$(elem).html(number_format(val, decimals, decPoint, thousandsSep));
}
});
}
$.fn.formatLink = function (text, href, options) {
var defaults = {
title: "",
className: "",
target: ""
};
return $(this).format(function (elem, data) {
var opts = $.extend(defaults, {
text: text,
href: href
},
options);
opts = $.fillIn(opts, data);
$(elem).text(opts.text);
$(elem).attr("href", opts.href);
if (opts.title != "") {
$(elem).attr("title", opts.title);
}
if (opts.className != "") {
$(elem).addClass(opts.className);
}
if (opts.target != "") {
$(elem).attr("target", opts.target);
}
});
}
$.fn.formatForm = function (controller, options) {
return $(this).format(function (elem, data) {
$(elem).submit(function (event) {
event.preventDefault();
var data = $(elem).serialize();
if (options) {
data = data + "&" + $.serialize(options);
}
$.controller.create(false, data, {
success: function () {
controller.retrieve();
}
});
});
});
}
$.objCount = function (obj) {
var count = 0;
for (k in obj) if (obj.hasOwnProperty(k)) count++;
return count;
}
$.fn.objCount = function (obj) {
return $.objCount($(this));
}
$.ajaxq = function (queue, options) {
if (typeof document.ajaxq == "undefined") document.ajaxq = {
q: {},
r: null
};
if (typeof document.ajaxq.q[queue] == "undefined") document.ajaxq.q[queue] = [];
if (typeof options != "undefined") {
var optionsCopy = {};
for (var o in options) optionsCopy[o] = options[o];
options = optionsCopy;
var originalCompleteCallback = options.complete;
options.complete = function (request, status) {
document.ajaxq.q[queue].shift();
document.ajaxq.r = null;
if (originalCompleteCallback) originalCompleteCallback(request, status);
if (document.ajaxq.q[queue].length > 0) document.ajaxq.r = jQuery.ajax(document.ajaxq.q[queue][0]);
};
document.ajaxq.q[queue].push(options);
if (document.ajaxq.q[queue].length == 1) document.ajaxq.r = jQuery.ajax(options);
} else {
if (document.ajaxq.r) {
document.ajaxq.r.abort();
document.ajaxq.r = null;
}
document.ajaxq.q[queue] = [];
}
}
})(jQuery);
function truncate(limit, post) {
if (!limit) {
post = 10;
}
if (!post) {
post = "...";
}
var s = this.toString();
if (s.length > limit) {
var newS = s.slice(0, limit);
var newLimit = newS.lastIndexOf(" ");
if (newLimit == -1) {
newLimit = limit;
}
s = s.slice(0, newLimit) + post;
}
return s;
}
String.prototype.trunc = truncate;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment