oxjs/build/js/ox.ui.js

8632 lines
303 KiB
JavaScript
Raw Normal View History

2010-01-07 20:21:07 +00:00
/*
################################################################################
ox.ui.js
requires
2010-01-25 11:42:28 +00:00
jquery-1.4.js
2010-01-07 20:21:07 +00:00
ox.js
################################################################################
*/
// also see test.js, in demos ...
(function() {
var oxui = {
2010-09-03 20:54:40 +00:00
defaultTheme: 'classic',
2010-01-07 20:21:07 +00:00
elements: {},
getDimensions: function(orientation) {
2010-09-03 20:54:40 +00:00
return orientation == 'horizontal' ?
['width', 'height'] : ['height', 'width'];
2010-01-07 20:21:07 +00:00
},
getEdges: function(orientation) {
2010-09-03 20:54:40 +00:00
return orientation == 'horizontal' ?
['left', 'right', 'top', 'bottom'] :
['top', 'bottom', 'left', 'right'];
2010-01-07 20:21:07 +00:00
},
getBarSize: function(size) {
var sizes = {
2010-02-20 03:58:46 +00:00
small: 20,
medium: 24,
large: 28,
2010-01-07 20:21:07 +00:00
};
return sizes[size];
},
2010-01-25 11:42:28 +00:00
jQueryFunctions: function() {
2010-01-07 20:21:07 +00:00
var functions = [],
2010-09-03 20:54:40 +00:00
$element = $('<div>');
2010-01-25 11:42:28 +00:00
//delete $element.length;
Ox.each($element, function(k, v) {
2010-09-03 20:54:40 +00:00
if (typeof v == 'function') {
2010-01-07 20:21:07 +00:00
functions.push(k);
}
});
return functions.sort();
}(),
2010-09-03 20:54:40 +00:00
path: $('script[src*=ox.ui.js]').attr('src')
.replace('js/ox.ui.js', ''),
2010-06-30 18:47:10 +00:00
scrollbarSize: $.browser.mozilla ? 16 : 12,
2010-06-30 09:27:02 +00:00
symbols: {
2010-09-03 20:54:40 +00:00
alt: '\u2325',
apple: '\uF8FF',
arrow_down: '\u2193',
arrow_left: '\u2190',
arrow_right: '\u2192',
arrow_up: '\u2191',
backspace: '\u232B',
backup: '\u2707',
ballot: '\u2717',
black_star: '\u2605',
burn: '\u2622',
caps_lock: '\u21EA',
check: '\u2713',
//clear: '\u2327',
clear: '\u00D7',
click: '\uF803',
close: '\u2715',
command: '\u2318',
control: '\u2303',
cut: '\u2702',
'delete': '\u2326',
diamond: '\u25C6',
edit: '\uF802',
eject: '\u23CF',
escape: '\u238B',
end: '\u2198',
enter: '\u2324',
fly: '\u2708',
gear: '\u2699',
home: '\u2196',
info: '\u24D8',
navigate: '\u2388',
option: '\u2387',
page_up: '\u21DE',
page_down: '\u21DF',
redo: '\u21BA',
'return': '\u21A9',
//select: '\u21D5',
select: '\u25BE',
shift: '\u21E7',
sound: '\u266B',
space: '\u2423',
tab: '\u21E5',
trash: '\u267A',
triangle_down: '\u25BC',
triangle_left: '\u25C0',
triangle_right: '\u25BA',
triangle_up: '\u25B2',
undo: '\u21BB',
voltage: '\u26A1',
warning: '\u26A0',
white_star: '\u2606'
2010-02-03 12:12:21 +00:00
}
2010-01-07 20:21:07 +00:00
},
$window, $document, $body;
$(function() {
$window = $(window),
$document = $(document),
2010-09-03 20:54:40 +00:00
$body = $('body'),
2010-06-30 09:27:02 +00:00
$elements = {};
2010-01-07 20:21:07 +00:00
Ox.theme(oxui.defaultTheme);
2010-02-04 09:50:45 +00:00
});
2010-01-07 20:21:07 +00:00
/*
============================================================================
Application
============================================================================
*/
/*
----------------------------------------------------------------------------
Ox.App
----------------------------------------------------------------------------
*/
2010-01-27 12:30:00 +00:00
Ox.App = function() {
/*
options:
requestTimeout
requestType
requestURL
*/
return function(options) {
options = options || {};
var self = {},
that = this;
self.options = $.extend({
2010-09-05 00:31:58 +00:00
id: '',
init: '',
name: '',
requestTimeout: 15000,
requestType: 'POST',
requestURL: '',
2010-01-27 12:30:00 +00:00
}, options);
2010-09-05 00:31:58 +00:00
function getUserData() {
//return {};
return {
navigator: {
cookieEnabled: navigator.cookieEnabled,
plugins: $.map(navigator.plugins, function(plugin, i) {
return plugin.name;
}),
userAgent: navigator.userAgent
},
screen: screen,
window: {
innerHeight: window.innerHeight,
innerWidth: window.innerWidth,
outerHeight: window.outerHeight,
outerWidth: window.outerWidth,
screenLeft: window.screenLeft,
screenTop: window.screenTop
}
};
}
function loadImages(callback) {
$.getJSON(oxui.path + 'json/ox.ui.images.json', function(data) {
var counter = 0,
length = data.length;
data.forEach(function(src, i) {
image = new Image()
image.src = oxui.path + src;
image.onload = function() {
(++counter == length) && callback();
}
});
});
}
2010-07-07 12:36:12 +00:00
self.change = function(key, value) {
2010-01-27 12:30:00 +00:00
};
2010-09-05 00:31:58 +00:00
that.launch = function(callback) {
var time = +new Date();
document.title = self.options.name;
2010-01-27 12:30:00 +00:00
$.ajaxSetup({
timeout: self.options.requestTimeout,
type: self.options.requestType,
url: self.options.requestURL
});
2010-09-05 00:31:58 +00:00
loadImages(function() {
window.google = function() {};
$.getScript('http://maps.google.com/maps/api/js?callback=google&sensor=false', function() {
$.getJSON(self.options.config, function(data) {
var config = data;
that.request(self.options.init, $.extend(getUserData(), {
time: (+new Date() - time) / 1000
}), function(data) {
Ox.print('!!!', data)
var user = data.data.user
$body.empty();
callback({
config: config,
user: user
});
});
});
});
});
return that;
2010-01-27 12:30:00 +00:00
};
that.options = function() {
2010-09-05 00:31:58 +00:00
return Ox.getset(self.options, Array.prototype.slice.call(arguments), self.change, that);
2010-01-27 12:30:00 +00:00
};
2010-01-31 08:03:22 +00:00
that.request = function(action, data, callback) {
if (arguments.length == 2) {
2010-01-27 13:25:37 +00:00
callback = data;
data = {};
}
return Ox.Request.send({
url: self.options.requestURL,
data: {
2010-01-31 08:03:22 +00:00
action: action,
2010-01-27 13:25:37 +00:00
data: JSON.stringify(data)
},
callback: callback
});
};
2010-01-27 12:30:00 +00:00
return that;
};
}();
2010-01-07 20:21:07 +00:00
/*
----------------------------------------------------------------------------
Ox.Event
----------------------------------------------------------------------------
*/
Ox.Event = function() {
2010-09-03 20:54:40 +00:00
var $eventHandler = $('<div>'),
2010-09-03 08:47:40 +00:00
events = {};
function addEvent(id, type, event, callback) {
events[id] = events[id] || {};
events[id][type] = events[id][type] || {};
events[id][type][event] = events[id][type][event] || [];
events[id][type][event].push(callback);
2010-09-03 20:54:40 +00:00
if (type == 'normal' || Ox.Focus.focused() == id) {
Ox.print('bind', id, event);
$eventHandler.bind(event + (id ? '_' + id : ''), callback); // requestStart/requestStop currently have '' as id
2010-09-03 08:47:40 +00:00
}
2010-02-05 09:13:03 +00:00
}
2010-09-03 08:47:40 +00:00
function removeEvent(id, type, event, callback) {
2010-09-03 20:54:40 +00:00
var focused = type == 'normal' || Ox.Focus.focused() == id,
toString = (callback || '').toString();
Ox.print('removeEvent', id, type, event, callback);
2010-09-03 08:47:40 +00:00
if (events[id] && events[id][type] && (!event || events[id][type][event])) {
$.each(events[id][type], function(e, fns) {
if (!event || event == e) {
events[id][type][e] = $.map(events[id][type][e], function(fn, i) {
if (!callback || toString == fn.toString()) {
2010-09-03 20:54:40 +00:00
focused && $eventHandler.unbind(e + '_' + id, fn);
2010-09-03 08:47:40 +00:00
return null;
} else {
return fn;
}
});
}
});
Ox.print(id, type, events)
if (!callback || (event && events[id][type][event].length == 0)) {
delete events[id][type][event];
2010-07-05 16:52:12 +00:00
}
2010-09-03 08:47:40 +00:00
if (!event || Ox.length(events[id].normal) == 0) {
delete events[id][type];
2010-02-05 09:13:03 +00:00
}
2010-09-03 08:47:40 +00:00
if (Ox.length(events[id]) == 0) {
delete events[id];
2010-02-05 09:13:03 +00:00
}
2010-09-03 08:47:40 +00:00
}
}
function isKeyboardEvent(event) { // fixme: currently unused
2010-09-03 20:54:40 +00:00
return event.substr(0, 4) == 'key_';
2010-09-03 08:47:40 +00:00
}
return {
_print: function() {
Ox.print(events);
},
add: function(id, event, callback) {
// add keyboard event
2010-09-03 20:54:40 +00:00
addEvent(id, 'keyboard', event, callback);
2010-09-03 08:47:40 +00:00
},
bind: function(id, event, callback) {
// bind event
2010-09-03 20:54:40 +00:00
addEvent(id, 'normal', event, callback);
2010-02-04 08:02:23 +00:00
},
2010-02-05 09:13:03 +00:00
bindKeyboard: function(id) {
2010-09-03 08:47:40 +00:00
// bind all keyboard events
2010-09-03 20:54:40 +00:00
//Ox.print('binding', 'id', id, 'events', events[id], Ox.length(events[id]), 'keyboardevents', events[id]['keyboard'])
2010-09-03 08:47:40 +00:00
$.each(events[id], function(k, v) {
2010-09-03 20:54:40 +00:00
Ox.print('|' + k + '|');
2010-09-03 08:47:40 +00:00
})
events[id] && events[id].keyboard && $.each(events[id].keyboard, function(event, callbacks) {
$.each(callbacks, function(i, callback) {
2010-09-03 20:54:40 +00:00
Ox.print('bind', id, event);
2010-09-03 08:47:40 +00:00
$eventHandler.bind(event, callback);
});
2010-02-05 09:13:03 +00:00
});
2010-02-04 09:50:45 +00:00
},
2010-09-03 08:47:40 +00:00
changeId: function(oldId, newId) {
// fixme: would it be better to pass that.id instead of self.options.id?
// then this renaming wouldn't be necessary
2010-09-03 20:54:40 +00:00
Ox.print('changeId', oldId, newId, events[oldId]);
2010-09-03 08:47:40 +00:00
$.each($.extend({}, events[oldId] || {}), function(type, events_) {
2010-09-03 20:54:40 +00:00
var bind = type == 'normal' ? 'bind' : 'add',
unbind = type == 'normal' ? 'unbind' : 'remove';
2010-09-03 08:47:40 +00:00
$.each(events_, function(event, callbacks) {
$.each(callbacks, function(i, callback) {
Ox.Event[unbind](oldId, event, callback);
Ox.Event[bind](newId, event, callback);
});
});
});
},
remove: function(id, event, callback) {
// remove keyboard event
// event and callback are optional
2010-09-03 20:54:40 +00:00
removeEvent(id, 'keyboard', event, callback);
2010-02-04 08:02:23 +00:00
},
2010-02-05 09:13:03 +00:00
unbind: function(id, event, callback) {
2010-09-03 08:47:40 +00:00
// unbind event
// event and callback are optional
2010-09-03 20:54:40 +00:00
removeEvent(id, 'normal', event, callback);
2010-09-03 08:47:40 +00:00
},
trigger: function(id, event, data) {
// trigger event
// data is optional
2010-09-03 20:54:40 +00:00
// keyboard handler will call this with '' as id
Ox.print('trigger', id, event, data || {});
$eventHandler.trigger(event + (id ? '_' + id : ''), data || {});
2010-02-05 09:13:03 +00:00
},
unbindKeyboard: function(id) {
2010-09-03 08:47:40 +00:00
// unbind all keyboard events
2010-09-03 20:54:40 +00:00
Ox.print('unbinding', id /*events[id].keyboard*/)
2010-09-03 08:47:40 +00:00
events[id] && events[id].keyboard && $.each(events[id].keyboard, function(event, callbacks) {
$.each(callbacks, function(i, callback) {
2010-09-03 20:54:40 +00:00
Ox.print('unbind', event)
2010-09-03 08:47:40 +00:00
$eventHandler.unbind(event, callback);
2010-01-07 20:21:07 +00:00
});
});
}
2010-09-03 08:47:40 +00:00
}
2010-01-07 20:21:07 +00:00
}();
/*
----------------------------------------------------------------------------
Ox.Focus
----------------------------------------------------------------------------
*/
Ox.Focus = function() {
var stack = [];
return {
2010-06-30 09:27:02 +00:00
blur: function(id) {
2010-09-03 08:47:40 +00:00
var index = stack.indexOf(id);
if (index == stack.length - 1) {
stack.length == 1 ? stack.pop() :
stack.splice(stack.length - 2, 0, stack.pop());
2010-09-03 20:54:40 +00:00
Ox.Event.unbindKeyboard($elements[id].options('id'));
stack.length && Ox.Event.bindKeyboard($elements[stack[stack.length - 1]].options('id'));
2010-09-04 14:28:40 +00:00
//$elements[id].removeClass('OxFocus');
$('.OxFocus').removeClass('OxFocus'); // fixme: the above is better, and should work
stack.length && $elements[stack[stack.length - 1]].addClass('OxFocus');
2010-09-03 20:54:40 +00:00
Ox.print('blur', id, stack);
2010-06-30 09:27:02 +00:00
}
},
2010-01-07 20:21:07 +00:00
focus: function(id) {
2010-02-07 15:01:22 +00:00
var index = stack.indexOf(id);
2010-09-03 08:47:40 +00:00
if (index == -1 || index < stack.length - 1) {
2010-09-03 20:54:40 +00:00
stack.length && Ox.Event.unbindKeyboard($elements[stack[stack.length - 1]].options('id'));
2010-09-03 08:47:40 +00:00
index > -1 && stack.splice(index, 1);
stack.push(id);
2010-09-03 20:54:40 +00:00
Ox.Event.bindKeyboard($elements[id].options('id'));
2010-09-04 14:28:40 +00:00
$('.OxFocus').removeClass('OxFocus'); // fixme: see above
$elements[id].addClass('OxFocus');
2010-09-03 20:54:40 +00:00
Ox.print('focus', id, stack);
2010-01-07 20:21:07 +00:00
}
2010-02-05 09:13:03 +00:00
},
focused: function() {
return stack[stack.length - 1];
2010-01-07 20:21:07 +00:00
}
};
}();
/*
----------------------------------------------------------------------------
Ox.History
----------------------------------------------------------------------------
*/
/*
----------------------------------------------------------------------------
Ox.Keyboard
----------------------------------------------------------------------------
*/
(function() {
2010-01-25 11:42:28 +00:00
2010-09-03 20:54:40 +00:00
var buffer = '',
2010-01-07 20:21:07 +00:00
bufferTime = 0,
bufferTimeout = 1000,
keyNames = function() {
return {
2010-09-03 20:54:40 +00:00
0: 'section',
8: 'backspace',
9: 'tab',
12: 'clear',
13: 'enter',
16: 'shift',
17: 'control',
18: 'alt',
20: 'capslock',
27: 'escape',
32: 'space',
33: 'pageup',
34: 'pagedown',
35: 'end',
36: 'home',
37: 'left',
38: 'up',
39: 'right',
40: 'down',
45: 'insert',
46: 'delete',
47: 'help',
48: '0',
49: '1',
50: '2',
51: '3',
52: '4',
53: '5',
54: '6',
55: '7',
56: '8',
57: '9',
65: 'a',
66: 'b',
67: 'c',
68: 'd',
69: 'e',
70: 'f',
71: 'g',
72: 'h',
73: 'i',
74: 'j',
75: 'k',
76: 'l',
77: 'm',
78: 'n',
79: 'o',
80: 'p',
81: 'q',
82: 'r',
83: 's',
84: 't',
85: 'u',
86: 'v',
87: 'w',
88: 'x',
89: 'y',
90: 'z',
91: 'meta.left',
92: 'meta.right',
93: 'select',
96: '0.numpad',
97: '1.numpad',
98: '2.numpad',
99: '3.numpad',
100: '4.numpad',
101: '5.numpad',
102: '6.numpad',
103: '7.numpad',
104: '8.numpad',
105: '9.numpad',
106: 'asterisk.numpad',
107: 'plus.numpad',
109: 'minus.numpad',
108: 'enter.numpad',
110: 'dot.numpad',
111: 'slash.numpad',
112: 'f1',
113: 'f2',
114: 'f3',
115: 'f4',
116: 'f5',
117: 'f6',
118: 'f7',
119: 'f8',
120: 'f9',
121: 'f10',
122: 'f11',
123: 'f12',
124: 'f13',
125: 'f14',
126: 'f15',
127: 'f16',
144: 'numlock',
145: 'scrolllock',
186: 'semicolon',
187: 'equal',
188: 'comma',
189: 'minus',
190: 'dot',
191: 'slash',
192: 'backtick',
219: 'openbracket',
220: 'backslash',
221: 'closebracket',
222: 'quote'
2010-01-07 20:21:07 +00:00
// see dojo, for ex.
};
}(),
modifierNames = {
2010-09-03 20:54:40 +00:00
altKey: 'alt', // mac: option
ctrlKey: 'control',
// metaKey: 'meta', // mac: command
shiftKey: 'shift'
2010-01-07 20:21:07 +00:00
};
2010-02-05 15:42:52 +00:00
2010-02-04 09:50:45 +00:00
$(function() {
2010-02-05 15:42:52 +00:00
// fixme: how to do this better?
2010-02-19 14:19:48 +00:00
// in firefox on mac, keypress doesn't fire for up/down
2010-02-19 11:47:13 +00:00
// if the cursor is at the start/end of an input element
2010-02-19 14:19:48 +00:00
// on linux, it doesn't seem to fire if the input element has focus
2010-02-19 11:47:13 +00:00
if ($.browser.mozilla) {
2010-02-18 07:27:32 +00:00
$document.keypress(keypress);
2010-02-19 11:47:13 +00:00
$document.keydown(function(event) {
2010-09-03 20:54:40 +00:00
var $element = $('input:focus');
2010-02-19 11:47:13 +00:00
if ($element.length) {
if (
(
2010-09-03 20:54:40 +00:00
keyNames[event.keyCode] == 'up' &&
2010-02-19 11:47:13 +00:00
$element[0].selectionStart + $element[0].selectionEnd == 0
) || (
2010-09-03 20:54:40 +00:00
keyNames[event.keyCode] == 'down' &&
2010-02-19 11:47:13 +00:00
$element[0].selectionStart == $element.val().length &&
$element[0].selectionEnd == $element.val().length
)
) {
keypress(event);
}
}
});
} else {
$document.keydown(keypress);
2010-02-05 15:31:19 +00:00
}
2010-02-04 09:50:45 +00:00
});
2010-02-18 07:27:32 +00:00
function keypress(event) {
2010-02-04 09:50:45 +00:00
var key,
keys = [],
2010-02-20 03:58:46 +00:00
//ret = true,
2010-02-04 09:50:45 +00:00
time;
$.each(modifierNames, function(k, v) {
if (event[k]) {
keys.push(v);
2010-01-07 20:21:07 +00:00
}
2010-02-04 09:50:45 +00:00
});
// avoid pushing modifier twice
2010-09-03 20:54:40 +00:00
Ox.print('keys', keys)
2010-02-04 09:50:45 +00:00
if (keyNames[event.keyCode] && keys.indexOf(keyNames[event.keyCode]) == -1) {
keys.push(keyNames[event.keyCode]);
}
2010-09-03 20:54:40 +00:00
key = keys.join('_');
2010-02-04 09:50:45 +00:00
if (key.match(/^[\w\d-]$|SPACE/)) {
time = Ox.getTime();
if (time - bufferTime > bufferTimeout) {
2010-09-03 20:54:40 +00:00
buffer = '';
2010-01-07 20:21:07 +00:00
}
2010-09-03 20:54:40 +00:00
buffer += key == 'SPACE' ? ' ' : key;
2010-02-04 09:50:45 +00:00
bufferTime = time;
2010-01-07 20:21:07 +00:00
}
2010-09-03 20:54:40 +00:00
Ox.Event.trigger('', 'key_' + key);
2010-02-18 14:24:17 +00:00
//return false;
2010-02-04 09:50:45 +00:00
/*
$.each(stack, function(i, v) {
// fixme: we dont get the return value!
2010-09-03 20:54:40 +00:00
ret = Ox.event.trigger(keyboard + Ox.toCamelCase(key) + '.' + v);
2010-02-04 09:50:45 +00:00
return ret;
});
*/
}
2010-01-07 20:21:07 +00:00
})();
/*
----------------------------------------------------------------------------
Ox.Mouse (??)
----------------------------------------------------------------------------
*/
2010-01-27 12:30:00 +00:00
/*
----------------------------------------------------------------------------
Ox.Request
----------------------------------------------------------------------------
*/
Ox.Request = function() {
var cache = {},
pending = {},
requests = {},
self = {
options: {
timeout: 15000,
2010-09-03 20:54:40 +00:00
type: 'POST',
url: 'api'
2010-01-27 12:30:00 +00:00
}
};
return {
cancel: function() {
var index;
if (arguments.length == 0) {
requests = {};
} else if (Ox.isFunction(arguments[0])) {
// cancel with function
$.each(requests, function(id, req) {
if (arguments[0](req)) {
delete requests[id];
}
})
} else {
// cancel by id
delete requests[arguments[0]]
}
},
2010-01-27 12:34:27 +00:00
emptyCache: function() {
cache = {};
2010-01-27 12:35:37 +00:00
},
2010-01-27 12:34:27 +00:00
2010-01-27 12:30:00 +00:00
options: function(options) {
2010-01-27 12:34:27 +00:00
return Ox.getset(self.options, options, $.noop(), this);
2010-01-27 12:30:00 +00:00
},
send: function(options) {
2010-07-01 23:51:08 +00:00
var options = $.extend({
age: -1,
callback: function() {},
id: Ox.uid(),
timeout: self.options.timeout,
type: self.options.type,
url: self.options.url
}, options),
req = JSON.stringify({
2010-01-27 12:30:00 +00:00
url: options.url,
data: options.data
});
2010-01-31 10:06:52 +00:00
function callback(data) {
2010-01-27 12:30:00 +00:00
delete requests[options.id];
2010-09-03 20:54:40 +00:00
Ox.length(requests) == 0 && Ox.Event.trigger('', 'requestStop');
2010-01-31 10:06:52 +00:00
options.callback(data);
2010-01-27 12:30:00 +00:00
}
2010-01-31 09:32:41 +00:00
function debug(request) {
2010-09-03 20:54:40 +00:00
var $iframe = $('<iframe>')
2010-01-31 09:32:41 +00:00
.css({ // fixme: should go into a class
width: 768,
height: 384
}),
$dialog = new Ox.Dialog({
2010-09-03 20:54:40 +00:00
title: 'Application Error',
2010-01-31 09:32:41 +00:00
buttons: [
{
2010-09-03 20:54:40 +00:00
title: 'Close',
2010-01-31 09:32:41 +00:00
click: function() {
$dialog.close();
}
}
],
width: 800,
height: 400
})
.append($iframe)
.open(),
iframe = $iframe[0].contentDocument || $iframe[0].contentWindow.document;
iframe.open();
iframe.write(request.responseText);
iframe.close();
}
2010-01-27 12:30:00 +00:00
function error(request, status, error) {
2010-01-31 10:06:52 +00:00
var data;
2010-02-01 06:11:35 +00:00
if (arguments.length == 1) {
data = arguments[0]
} else {
try {
data = JSON.parse(request.responseText);
} catch (err) {
data = {
status: {
code: request.status,
text: request.statusText
}
};
}
2010-01-27 13:25:37 +00:00
}
2010-01-31 10:06:52 +00:00
if (data.status.code < 500) {
callback(data);
} else {
2010-01-27 13:25:37 +00:00
var $dialog = new Ox.Dialog({
2010-09-03 20:54:40 +00:00
title: 'Application Error',
2010-01-31 09:32:41 +00:00
buttons: [
{
2010-09-03 20:54:40 +00:00
title: 'Details',
2010-01-31 09:32:41 +00:00
click: function() {
$dialog.close(function() {
debug(request);
});
}
},
{
2010-09-03 20:54:40 +00:00
title: 'Close',
2010-01-31 09:32:41 +00:00
click: function() {
2010-01-31 10:06:52 +00:00
$dialog.close(function() {
callback(data);
});
2010-01-31 09:32:41 +00:00
}
}
],
width: 400,
2010-06-30 18:47:10 +00:00
height: 200
2010-01-31 09:32:41 +00:00
})
2010-09-03 20:54:40 +00:00
.append('Sorry, we have encountered an application error while handling your request. To help us find out what went wrong, you may want to report this error to an administrator. Otherwise, please try again later.')
2010-01-31 09:32:41 +00:00
.open();
2010-02-01 06:11:35 +00:00
// fixme: change this to Send / Don't Send
2010-01-27 13:25:37 +00:00
Ox.print({
request: request,
status: status,
error: error
});
}
2010-01-27 12:30:00 +00:00
pending[options.id] = false;
}
function success(data) {
pending[options.id] = false;
cache[req] = {
data: data,
time: Ox.getTime()
};
2010-01-31 10:06:52 +00:00
callback(data);
2010-01-27 12:30:00 +00:00
}
if (pending[options.id]) {
setTimeout(function() {
Ox.Request.send(options);
}, 0);
} else {
requests[options.id] = {
url: options.url,
data: options.data
};
if (cache[req] && (options.age == -1 || options.age > Ox.getTime() - cache[req].time)) {
setTimeout(function() {
2010-01-31 10:06:52 +00:00
callback(cache[req].data);
2010-01-27 12:30:00 +00:00
}, 0);
} else {
pending[options.id] = true;
$.ajax({
data: options.data,
2010-09-03 20:54:40 +00:00
dataType: 'json',
2010-01-27 12:30:00 +00:00
error: error,
success: success,
timeout: options.timeout,
type: options.type,
url: options.url
});
2010-09-03 20:54:40 +00:00
Ox.print('request', options.data, Ox.length(requests));
Ox.length(requests) == 1 && Ox.Event.trigger('', 'requestStart');
2010-01-27 12:30:00 +00:00
}
}
2010-07-01 23:51:08 +00:00
2010-01-27 12:30:00 +00:00
return options.id;
2010-07-01 23:51:08 +00:00
},
requests: function() {
return Ox.length(requests);
2010-01-27 12:30:00 +00:00
}
};
}();
2010-01-07 20:21:07 +00:00
/*
----------------------------------------------------------------------------
Ox.URL
----------------------------------------------------------------------------
*/
/*
============================================================================
Core
============================================================================
*/
/*
----------------------------------------------------------------------------
Ox.Container
----------------------------------------------------------------------------
*/
// fixme: wouldn't it be better to let the elements be,
// rather then $element, $content, and potentially others,
// 0, 1, 2, etc, so that append would append 0, and appendTo
// would append (length - 1)?
2010-06-28 11:19:04 +00:00
Ox.Container = function(options, self) {
2010-09-03 20:54:40 +00:00
var that = new Ox.Element('div', self)
2010-09-03 08:47:40 +00:00
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxContainer');
that.$content = new Ox.Element('div', self)
2010-09-03 08:47:40 +00:00
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxContent')
2010-01-07 20:21:07 +00:00
.appendTo(that);
return that;
2010-02-07 15:01:22 +00:00
};
2010-01-07 20:21:07 +00:00
/*
----------------------------------------------------------------------------
Ox.Element
----------------------------------------------------------------------------
*/
// check out http://ejohn.org/apps/learn/#36 (-#38, making fns work w/o new)
Ox.Element = function() {
return function(options, self) {
// construct
options = options || {};
self = self || {};
var that = this;
// init
(function() {
2010-09-03 20:54:40 +00:00
// allow for Ox.Widget('tagname', self)
if (typeof options == 'string') {
2010-01-07 20:21:07 +00:00
options = {
element: options
};
}
that.ox = Ox.version;
that.id = Ox.uid();
2010-09-03 20:54:40 +00:00
that.$element = $('<' + (options.element || 'div') + '/>', {
2010-01-25 11:42:28 +00:00
data: {
ox: that.id
}
});
2010-06-30 09:27:02 +00:00
$elements[that.id] = that;
2010-01-07 20:21:07 +00:00
wrapjQuery();
})();
// private
function wrapjQuery() {
2010-02-10 18:42:59 +00:00
$.each(oxui.jQueryFunctions, function(i, fn) {
2010-02-10 18:52:46 +00:00
that[fn] = function() {
2010-01-07 20:21:07 +00:00
var args = arguments,
length = args.length,
2010-02-10 19:50:10 +00:00
id, ret;
2010-02-10 18:42:59 +00:00
$.each(args, function(i, arg) {
2010-07-20 20:04:13 +00:00
if (Ox.isUndefined(arg)) {
2010-09-03 20:54:40 +00:00
Ox.print('fn', fn, 'undefined argument')
2010-07-20 20:04:13 +00:00
}
2010-01-07 20:21:07 +00:00
// if an ox object was passed
// then pass its $element instead
// so we can do oxObj.jqFn(oxObj)
2010-02-10 19:59:10 +00:00
if (arg.ox) {
args[i] = arg.$element;
}
2010-02-10 19:41:25 +00:00
/*
2010-02-10 18:52:46 +00:00
if (arg.ox) { // fixme: or is this too much magic?
2010-09-03 20:54:40 +00:00
if (fn == 'appendTo' && arg.$content) {
2010-02-10 18:52:46 +00:00
args[i] = arg.$content
2010-02-10 18:42:59 +00:00
} else {
2010-02-10 18:52:46 +00:00
args[i] = arg.$element;
2010-02-10 18:42:59 +00:00
}
2010-01-07 20:21:07 +00:00
}
2010-02-10 19:41:25 +00:00
*/
2010-01-07 20:21:07 +00:00
});
2010-02-10 19:41:25 +00:00
/*
2010-09-03 20:54:40 +00:00
if (fn == 'html' && that.$content) { // fixme: or is this too much magic?
2010-02-10 18:42:59 +00:00
$element = that.$content;
} else {
$element = that.$element;
}
2010-02-10 19:41:25 +00:00
*/
2010-07-17 08:46:27 +00:00
// why does this not work? (that?)
// ret = that.$element[fn].apply(this, arguments);
2010-01-07 20:21:07 +00:00
if (length == 0) {
2010-02-10 19:50:10 +00:00
ret = that.$element[fn]();
2010-01-07 20:21:07 +00:00
} else if (length == 1) {
2010-02-10 19:50:10 +00:00
ret = that.$element[fn](args[0]);
2010-01-07 20:21:07 +00:00
} else if (length == 2) {
2010-02-10 19:50:10 +00:00
ret = that.$element[fn](args[0], args[1]);
2010-01-07 20:21:07 +00:00
} else if (length == 3) {
2010-02-10 19:50:10 +00:00
ret = that.$element[fn](args[0], args[1], args[2]);
2010-01-07 20:21:07 +00:00
} else if (length == 4) {
2010-02-10 19:50:10 +00:00
ret = that.$element[fn](args[0], args[1], args[2], args[3]);
2010-01-07 20:21:07 +00:00
}
2010-09-03 20:54:40 +00:00
if (fn == 'data') {
// Ox.print('data ret', ret, $(ret))
2010-02-07 15:01:22 +00:00
}
2010-01-07 20:21:07 +00:00
// if the $element of an ox object was returned
// then return the ox object instead
// so we can do oxObj.jqFn().oxFn()
2010-09-03 20:54:40 +00:00
return ret.jquery && $elements[id = ret.data('ox')] ?
2010-06-30 09:27:02 +00:00
$elements[id] : ret;
2010-01-07 20:21:07 +00:00
}
});
}
// shared
self.onChange = function() {
2010-02-07 15:01:22 +00:00
// self.onChange(key, value)
2010-01-07 20:21:07 +00:00
// is called when an option changes
// (to be implemented by widget)
};
// public
2010-09-03 08:47:40 +00:00
that.addEvent = function() {
/*
adds a keyboard event, to be bound when focused
addEvent(event, fn) or addEvent({event0: fn0, event1: fn1, ...})
*/
if (arguments.length == 1) {
$.each(arguments[0], function(event, fn) {
Ox.Event.add(self.options.id, event, fn);
});
} else {
Ox.Event.add(self.options.id, arguments[0], arguments[1]);
}
return that;
};
2010-02-05 09:13:03 +00:00
that.bindEvent = function() {
/*
2010-09-03 08:47:40 +00:00
binds a function to an event triggered by this object
2010-02-05 09:13:03 +00:00
bindEvent(event, fn) or bindEvent({event0: fn0, event1: fn1, ...})
*/
if (arguments.length == 1) {
$.each(arguments[0], function(event, fn) {
2010-09-03 08:47:40 +00:00
Ox.Event.bind(self.options.id, event, fn);
2010-02-10 16:37:26 +00:00
});
2010-02-05 09:13:03 +00:00
} else {
2010-09-03 08:47:40 +00:00
Ox.Event.bind(self.options.id, arguments[0], arguments[1]);
2010-02-05 09:13:03 +00:00
}
return that;
2010-09-03 08:47:40 +00:00
}
2010-01-07 20:21:07 +00:00
that.defaults = function(defaults) {
/*
that.defaults({foo: x}) sets self.defaults
*/
self.defaults = defaults;
delete self.options; // fixme: hackish fix for that = Ox.Foo({...}, self).defaults({...}).options({...})
2010-01-07 20:21:07 +00:00
return that;
2010-02-05 09:13:03 +00:00
};
2010-09-03 08:47:40 +00:00
2010-02-05 09:13:03 +00:00
that.gainFocus = function() {
Ox.Focus.focus(that.id);
2010-02-09 05:43:36 +00:00
return that;
2010-02-05 09:13:03 +00:00
};
2010-09-03 08:47:40 +00:00
2010-02-05 09:13:03 +00:00
that.hasFocus = function() {
return Ox.Focus.focused() == that.id;
};
2010-09-03 08:47:40 +00:00
2010-02-05 09:13:03 +00:00
that.loseFocus = function() {
Ox.Focus.blur(that.id);
2010-02-09 05:43:36 +00:00
return that;
2010-02-05 09:13:03 +00:00
};
2010-09-03 08:47:40 +00:00
2010-02-05 09:13:03 +00:00
that.options = function() { // fixme: use Ox.getset
2010-01-07 20:21:07 +00:00
/*
that.options() returns self.options
2010-09-03 20:54:40 +00:00
that.options('foo') returns self.options.foo
that.options('foo', x) sets self.options.foo,
2010-01-07 20:21:07 +00:00
returns that
that.options({foo: x, bar: y}) sets self.options.foo
and self.options.bar,
returns that
*/
var length = arguments.length,
2010-09-03 08:47:40 +00:00
id = self.options && self.options.id,
2010-01-07 20:21:07 +00:00
args, ret;
if (length == 0) {
// options()
2010-07-06 18:28:58 +00:00
ret = self.options || options; // this is silly. make sure self.options get populated with options
2010-09-03 20:54:40 +00:00
} else if (length == 1 && typeof arguments[0] == 'string') {
2010-01-07 20:21:07 +00:00
// options(str)
2010-07-06 18:28:58 +00:00
ret = self.options ? self.options[arguments[0]] : options[arguments[0]];
2010-01-07 20:21:07 +00:00
} else {
// options (str, val) or options({str: val, ...})
// translate (str, val) to ({str: val})
args = Ox.makeObject.apply(that, arguments);
2010-02-06 08:23:42 +00:00
/*
options = self.options;
*/
// if options have not been set, extend defaults,
// otherwise, extend options
2010-02-06 08:23:42 +00:00
self.options = $.extend(self.options || self.defaults, args);
$.each(args, function(key, value) {
2010-09-03 20:54:40 +00:00
key == 'id' && id && Ox.Event.changeId(id, value);
self.onChange(key, value);
2010-02-06 08:23:42 +00:00
/*
fixme: why does this not work?
2010-09-03 20:54:40 +00:00
Ox.print('options', options, key, value)
2010-02-06 08:23:42 +00:00
//Ox.print(!options, !options || !options[key], !options || !options[key] || options[key] !== value)
if (!options || !options[key] || options[key] !== value) {
2010-09-03 20:54:40 +00:00
Ox.print('onChange...')
2010-02-06 08:23:42 +00:00
self.onChange(key, value);
} else {
2010-09-03 20:54:40 +00:00
Ox.print('NO CHANGE');
2010-02-06 08:23:42 +00:00
}
*/
2010-01-07 20:21:07 +00:00
});
ret = that;
}
return ret;
2010-02-10 16:37:26 +00:00
};
2010-09-03 08:47:40 +00:00
2010-01-07 20:21:07 +00:00
that.remove = function() {
that.$element.remove();
2010-06-30 09:27:02 +00:00
delete $elements[that.ox];
return that;
2010-02-10 16:37:26 +00:00
};
2010-09-03 08:47:40 +00:00
that.removeEvent = function() {
/*
removes a keyboard event
removeEvent(event, fn) or removeEvent({event0: fn0, event1: fn1, ...})
*/
if (arguments.length == 1) {
$.each(arguments[0], function(event, fn) {
Ox.Event.remove(self.options.id, event, fn);
});
} else {
Ox.Event.remove(self.options.id, arguments[0], arguments[1]);
}
return that;
};
2010-02-06 08:23:42 +00:00
that.triggerEvent = function() {
/*
2010-09-03 08:47:40 +00:00
triggers an event
triggerEvent(event) or triggerEvent(event, data) or triggerEvent({event0: data, event1: data, ...})
2010-02-06 08:23:42 +00:00
*/
2010-02-08 09:35:24 +00:00
if (Ox.isObject(arguments[0])) {
2010-09-03 08:47:40 +00:00
$.each(arguments[0], function(event, data) {
Ox.Event.trigger(self.options.id, event, data);
2010-02-06 08:23:42 +00:00
});
} else {
2010-09-03 08:47:40 +00:00
Ox.Event.trigger(self.options.id, arguments[0], arguments[1] || {});
2010-02-06 08:23:42 +00:00
}
return that;
2010-02-10 16:37:26 +00:00
};
2010-09-03 08:47:40 +00:00
2010-02-05 09:13:03 +00:00
that.unbindEvent = function() {
/*
2010-09-03 08:47:40 +00:00
unbinds an event
2010-02-05 09:13:03 +00:00
unbindEvent(event, fn) or unbindEvent({event0: fn0, event1: fn1, ...})
*/
if (arguments.length == 1) {
$.each(arguments[0], function(event, fn) {
2010-09-03 08:47:40 +00:00
Ox.Event.unbind(self.options.id, event, fn);
});
2010-02-05 09:13:03 +00:00
} else {
2010-09-03 08:47:40 +00:00
Ox.Event.unbind(self.options.id, arguments[0], arguments[1]);
2010-02-05 09:13:03 +00:00
}
return that;
2010-02-10 16:37:26 +00:00
};
2010-01-07 20:21:07 +00:00
// return
return that;
}
}();
Ox._Element = function(element) {
var that = this;
that.def = {};
that.opt = {};
that.ox = Ox.version;
that.id = Ox.uid();
2010-09-03 20:54:40 +00:00
//Ox.print('that.id', that.id)
that.$element = $('<' + (element || 'div') + '/>')
//.addClass('OxElement')
.data('ox', that.id);
2010-01-07 20:21:07 +00:00
oxui.elements[that.id] = that;
2010-09-03 20:54:40 +00:00
// Ox.print('oxui.elements', oxui.elements)
2010-01-07 20:21:07 +00:00
//function setOption() {};
that.setOption = function() {};
/*
*/
that.destroy = function() {
that.$element.remove();
delete oxui.elements[that.ox];
}
/*
*/
that.disable = function() {
}
/*
*/
that.enable = function() {
}
/*
*/
///*
that.defaults = function() {
var length = arguments.length,
ret;
if (length == 0) {
ret = that.def
2010-09-03 20:54:40 +00:00
} else if (length == 1 && typeof arguments[0] == 'string') {
2010-01-07 20:21:07 +00:00
ret = that.def[arguments[0]];
} else {
2010-09-03 20:54:40 +00:00
// translate ('key', 'value') to {'key': 'value'}
2010-01-07 20:21:07 +00:00
that.def = $.extend(
that.def, Ox.makeObject.apply(that, arguments)
);
ret = that;
}
return ret;
}
//*/
/*
Ox.Element.options()
get options
2010-09-03 20:54:40 +00:00
Ox.Element.options('foo')
2010-01-07 20:21:07 +00:00
get options.foo
2010-09-03 20:54:40 +00:00
Ox.Element.options('foo', 0)
2010-01-07 20:21:07 +00:00
set options.foo
Ox.Element.options({foo: 0, bar: 1})
set options.foo and options.bar
*/
///*
that.options = function() {
var length = arguments.length,
args, ret;
if (length == 0) {
2010-09-03 20:54:40 +00:00
//Ox.print('getting all options', options);
2010-01-07 20:21:07 +00:00
ret = that.opt;
2010-09-03 20:54:40 +00:00
} else if (length == 1 && typeof arguments[0] == 'string') {
//Ox.print('getting one option', options, arguments[0], options[arguments[0]]);
2010-01-07 20:21:07 +00:00
ret = that.opt[arguments[0]];
} else {
2010-09-03 20:54:40 +00:00
// translate ('key', 'value') to {'key': 'value'}
2010-01-07 20:21:07 +00:00
args = Ox.makeObject.apply(that, arguments);
// if options have been set then extend options,
// otherwise extend defaults
that.opt = $.extend(Ox.length(that.opt) ?
that.opt : that.def, args);
2010-09-03 20:54:40 +00:00
// that.trigger('OxElement' + that.id + 'SetOptions', args);
2010-01-07 20:21:07 +00:00
$.each(args, function(k, v) {
that.setOption(k, v);
2010-09-03 20:54:40 +00:00
//Ox.print('triggering', 'OxElement' + that.id + 'SetOption', {k: v})
//that.trigger('OxElement' + that.id + 'SetOption', {k: v});
2010-01-07 20:21:07 +00:00
})
ret = that;
}
return ret;
}
// should become self.publish
that.publish = function(event, data) {
Ox.Event.publish(event + that.id, data);
return that;
}
that.subscribe = function(event, callback) {
Ox.Event.subscribe(event, callback);
return that;
}
//that.setOptions = function() {};
//*/
// wrap jquery functions
// so we can do oxObj.jqFn()
$.each(oxui.jqueryFunctions, function(i, v) {
that[v] = function() {
var args = arguments,
length = args.length,
$element, id, ret;
$.each(args, function(i, v) {
// if an oxui object was passed
// then pass its $element instead
// so we can do jqObj.append(oxObj)
if (v.ox) {
args[i] = v.$element;
}
});
2010-09-03 20:54:40 +00:00
if (v == 'html' && that.$content) {
2010-01-07 20:21:07 +00:00
$element = that.$content;
} else {
$element = that.$element;
}
// why does this not work?
// ret = that.$element[v].apply(this, arguments);
// maybe because we pass this, and not that.$element[v] ... ?
// ret = that.$element[v].apply(that.$element[v], arguments);
// doesn't work either ...
if (length == 0) {
ret = $element[v]();
} else if (length == 1) {
ret = $element[v](args[0]);
} else if (length == 2) {
ret = $element[v](args[0], args[1]);
} else if (length == 3) {
ret = $element[v](args[0], args[1], args[2]);
} else if (length == 4) {
ret = $element[v](args[0], args[1], args[2], args[3]);
}
// if the $element of an oxui object was returned
// then return the oxui object instead
// so we can do oxObj.jqFn().oxFn()
2010-09-03 20:54:40 +00:00
//Ox.print('v', v, 'arguments', arguments)
2010-01-07 20:21:07 +00:00
if (ret.jquery) {
2010-09-03 20:54:40 +00:00
//Ox.print('ret', ret, 'ret.data('id')', ret.data('ox'))
2010-01-07 20:21:07 +00:00
}
2010-09-03 20:54:40 +00:00
return ret.jquery && oxui.elements[id = ret.data('ox')] ?
2010-01-07 20:21:07 +00:00
oxui.elements[id] : ret;
}
});
return that;
};
2010-07-24 01:32:08 +00:00
/*
----------------------------------------------------------------------------
Ox.Window
----------------------------------------------------------------------------
*/
Ox.Window = function(options, self) {
self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-07-24 01:32:08 +00:00
.defaults({
draggable: true,
fullscreenable: true, // fixme: silly name
height: 225,
resizeable: true,
scaleable: true,
width: 400
})
.options(options || {})
self.center = function() {
};
self.drag = function() {
};
self.fullscreen = function() {
};
self.onChange = function() {
};
self.reset = function() {
};
self.resize = function() {
};
self.scale = function() {
};
that.close = function() {
};
that.open = function() {
};
return that;
};
2010-01-07 20:21:07 +00:00
/*
----------------------------------------------------------------------------
Ox.theme()
get theme
2010-09-03 20:54:40 +00:00
Ox.theme('foo')
set theme to 'foo'
2010-01-07 20:21:07 +00:00
----------------------------------------------------------------------------
*/
2010-09-03 22:12:25 +00:00
// fixme: this should be Ox.Theme, and provide Ox.Theme.set(), Ox.Theme.load, etc.
2010-01-07 20:21:07 +00:00
Ox.theme = function() {
var length = arguments.length,
2010-09-03 20:54:40 +00:00
classes = $body.attr('class').split(' '),
2010-01-07 20:21:07 +00:00
arg, theme;
$.each(classes, function(i, v) {
2010-09-03 20:54:40 +00:00
if (Ox.startsWith(v, 'OxTheme')) {
theme = v.replace('OxTheme', '').toLowerCase();
2010-01-07 20:21:07 +00:00
if (length == 1) {
$body.removeClass(v);
}
return false;
}
});
if (length == 1) {
arg = arguments[0]
2010-09-03 20:54:40 +00:00
$body.addClass('OxTheme' + Ox.toTitleCase(arg));
2010-01-07 20:21:07 +00:00
if (theme) {
2010-09-03 20:54:40 +00:00
$('input[type=image]').each(function() {
2010-01-07 20:21:07 +00:00
var $this = $(this);
$this.attr({
2010-09-03 20:54:40 +00:00
src: $this.attr('src').replace(
'/ox.ui.' + theme + '/', '/ox.ui.' + arg + '/'
2010-01-07 20:21:07 +00:00
)
});
});
2010-09-03 20:54:40 +00:00
$('.OxLoadingIcon').each(function() {
2010-02-20 10:34:50 +00:00
var $this = $(this);
$this.attr({
2010-09-03 20:54:40 +00:00
src: $this.attr('src').replace(
'/ox.ui.' + theme + '/', '/ox.ui.' + arg + '/'
2010-02-20 10:34:50 +00:00
)
});
})
2010-01-07 20:21:07 +00:00
}
}
return theme;
};
/*
============================================================================
Bars
============================================================================
*/
Ox.Bar = function(options, self) {
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
2010-09-03 20:54:40 +00:00
orientation: 'horizontal',
size: 'medium' // can be int
2010-01-07 20:21:07 +00:00
})
2010-02-18 07:27:32 +00:00
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxBar Ox' + Ox.toTitleCase(self.options.orientation)),
2010-01-07 20:21:07 +00:00
dimensions = oxui.getDimensions(self.options.orientation);
2010-02-20 03:58:46 +00:00
self.options.size = Ox.isString(self.options.size) ?
oxui.getBarSize(self.options.size) : self.options.size;
2010-09-03 20:54:40 +00:00
that.css(dimensions[0], '100%')
.css(dimensions[1], self.options.size + 'px');
2010-01-07 20:21:07 +00:00
return that;
};
2010-07-06 18:28:58 +00:00
/*
----------------------------------------------------------------------------
Ox.Resizebar
----------------------------------------------------------------------------
*/
Ox.Resizebar = function(options, self) {
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
2010-07-07 07:18:38 +00:00
collapsed: false,
2010-07-06 18:28:58 +00:00
collapsible: true,
2010-09-03 20:54:40 +00:00
edge: 'left',
2010-07-06 18:28:58 +00:00
elements: [],
2010-09-03 20:54:40 +00:00
orientation: 'horizontal',
2010-07-06 18:28:58 +00:00
parent: null,
resizable: true,
resize: [],
size: 0
})
.options(options || {}) // fixme: options function should be able to handle undefined, no need for || {}
2010-09-03 20:54:40 +00:00
.addClass('OxResizebar Ox' + Ox.toTitleCase(self.options.orientation))
2010-07-06 18:28:58 +00:00
/*
.attr({
2010-09-03 20:54:40 +00:00
draggable: 'true'
2010-07-06 18:28:58 +00:00
})
2010-09-03 20:54:40 +00:00
.bind('dragstart', function(e) {
// e.originalEvent.dataTransfer.setDragImage($('<div>')[0], 0, 0);
2010-07-06 18:28:58 +00:00
})
2010-09-03 20:54:40 +00:00
.bind('drag', function(e) {
Ox.print('dragging', e)
2010-07-06 18:28:58 +00:00
})
*/
.mousedown(dragStart)
.dblclick(toggle)
2010-09-03 20:54:40 +00:00
.append($('<div>').addClass('OxSpace'))
.append($('<div>').addClass('OxLine'))
.append($('<div>').addClass('OxSpace'));
2010-07-06 18:28:58 +00:00
$.extend(self, {
2010-09-03 20:54:40 +00:00
clientXY: self.options.orientation == 'horizontal' ? 'clientY' : 'clientX',
2010-07-15 19:04:47 +00:00
dimensions: oxui.getDimensions(self.options.orientation), // fixme: should orientation be the opposite orientation here?
edges: oxui.getEdges(self.options.orientation),
2010-07-06 18:28:58 +00:00
ids: $.map(self.options.elements, function(v, i) {
2010-09-03 20:54:40 +00:00
return v.options('id');
2010-07-06 18:28:58 +00:00
}),
length: self.options.resize.length,
startPos: 0,
startSize: 0
});
function drag(e) {
var d = e[self.clientXY] - self.startPos, i;
self.options.size = Ox.limit(self.startSize + d, self.options.resize[0], self.options.resize[self.length - 1]);
2010-09-03 20:54:40 +00:00
Ox.print('sS', self.startSize, 'd', d, 's.o.s', self.options.size)
2010-07-06 18:28:58 +00:00
$.each(self.options.resize, function(i, v) {
if (self.options.size > v - 8 && self.options.size < v + 8) {
self.options.size = v;
return false;
}
});
2010-09-03 20:54:40 +00:00
that.css(self.edges[2], self.options.size + 'px');
self.options.elements[0].css(self.dimensions[1], self.options.size + 'px');
self.options.elements[1].css(self.edges[2], (self.options.size + 1) + 'px');
Ox.Event.trigger(self.ids[0], 'resize', self.options.size);
Ox.Event.trigger(self.ids[1], 'resize', self.options.elements[1][self.dimensions[1]]());
2010-07-06 18:28:58 +00:00
}
function dragStart(e) {
self.startPos = e[self.clientXY];
self.startSize = self.options.size;
2010-09-03 20:54:40 +00:00
Ox.print('startSize', self.startSize)
2010-07-06 18:28:58 +00:00
$window.mousemove(drag);
2010-09-03 20:54:40 +00:00
$window.one('mouseup', dragStop);
2010-07-06 18:28:58 +00:00
}
function dragStop() {
2010-09-03 20:54:40 +00:00
$window.unbind('mousemove');
2010-07-06 18:28:58 +00:00
}
function toggle() {
2010-09-03 20:54:40 +00:00
Ox.print('toggle');
if (Ox.isUndefined(self.options.position)) {
self.options.position = parseInt(self.options.parent.css(self.options.edge)) +
(self.options.collapsed ? self.options.size : 0);
}
var size = self.options.position -
(self.options.collapsed ? 0 : self.options.size),
2010-07-07 07:18:38 +00:00
animate = {};
2010-09-03 20:54:40 +00:00
Ox.print('s.o.e', self.options.edge);
2010-07-07 07:18:38 +00:00
animate[self.options.edge] = size;
self.options.parent.animate(animate, 200, function() {
2010-09-03 20:54:40 +00:00
var i = (self.options.edge == 'left' || self.options.edge == 'top') ? 1 : 0;
Ox.Event.trigger(self.ids[i], 'resize', self.options.elements[i][self.dimensions[1]]());
2010-07-07 07:18:38 +00:00
self.options.collapsed = !self.options.collapsed;
});
2010-07-06 18:28:58 +00:00
}
return that;
};
2010-01-07 20:21:07 +00:00
/*
----------------------------------------------------------------------------
Ox.Tabbar
----------------------------------------------------------------------------
*/
Ox.Tabbar = function(options, self) {
var self = self || {},
that = new Ox.Bar({
size: 20
}, self)
.defaults({
selected: 0,
2010-02-10 09:59:59 +00:00
tabs: []
2010-01-07 20:21:07 +00:00
})
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxTabbar');
2010-01-07 20:21:07 +00:00
2010-02-08 09:35:24 +00:00
Ox.ButtonGroup({
2010-02-10 09:59:59 +00:00
buttons: self.options.tabs,
2010-02-08 09:35:24 +00:00
group: true,
selectable: true,
selected: self.options.selected,
2010-09-03 20:54:40 +00:00
size: 'medium',
style: 'tab',
2010-02-08 09:35:24 +00:00
}).appendTo(that);
2010-01-07 20:21:07 +00:00
return that;
};
2010-02-20 03:58:46 +00:00
// fixme: no need for this
2010-01-07 20:21:07 +00:00
Ox.Toolbar = function(options, self) {
var self = self || {},
that = new Ox.Bar({
2010-02-07 15:01:22 +00:00
size: oxui.getBarSize(options.size)
}, self);
2010-01-07 20:21:07 +00:00
return that;
};
2010-01-27 12:30:00 +00:00
/*
============================================================================
2010-01-31 08:03:22 +00:00
Ox.Dialog
2010-01-27 12:30:00 +00:00
============================================================================
*/
Ox.Dialog = function(options, self) {
2010-02-20 07:46:31 +00:00
2010-02-18 07:27:32 +00:00
// fixme: dialog should be derived from a generic draggable
2010-07-24 01:32:08 +00:00
// fixme: pass button elements directly
2010-09-04 14:28:40 +00:00
// fixme: buttons should have a close attribute, or the dialog a close id
2010-01-27 12:30:00 +00:00
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-02-20 03:42:03 +00:00
.defaults({
2010-09-03 20:54:40 +00:00
title: '',
2010-02-20 03:42:03 +00:00
buttons: [],
2010-02-21 06:47:18 +00:00
height: 216,
minHeight: 144,
2010-02-21 05:40:11 +00:00
minWidth: 256,
2010-07-24 01:32:08 +00:00
padding: 16,
2010-02-21 05:20:39 +00:00
width: 384
2010-02-20 03:42:03 +00:00
})
.options(options || {})
2010-09-04 14:28:40 +00:00
.addClass('OxDialog')
.addEvent({
key_escape: function() {
that.close();
}
});
2010-02-20 07:46:31 +00:00
2010-02-21 05:20:39 +00:00
if (!Ox.isArray(self.options.buttons[0])) {
self.options.buttons = [[], self.options.buttons];
}
2010-01-31 08:03:22 +00:00
that.$titlebar = new Ox.Bar({
2010-09-03 20:54:40 +00:00
size: 'medium'
2010-01-31 08:03:22 +00:00
})
2010-09-03 20:54:40 +00:00
.addClass('OxTitleBar')
2010-02-21 05:20:39 +00:00
.mousedown(drag)
.dblclick(center)
2010-01-27 12:30:00 +00:00
.appendTo(that);
2010-09-04 14:28:40 +00:00
2010-02-09 05:43:36 +00:00
that.$title = new Ox.Element()
2010-09-03 20:54:40 +00:00
.addClass('OxTitle')
2010-02-20 03:42:03 +00:00
.html(self.options.title)
2010-02-09 05:43:36 +00:00
.appendTo(that.$titlebar);
2010-09-04 14:28:40 +00:00
2010-07-24 01:32:08 +00:00
// fixme: should the following be a container?
that.$content = new Ox.Element()
2010-09-03 20:54:40 +00:00
.addClass('OxContent')
2010-07-24 01:32:08 +00:00
.css({
2010-09-03 20:54:40 +00:00
padding: self.options.padding + 'px',
overflow: 'auto'
2010-07-24 01:32:08 +00:00
})
2010-01-27 12:30:00 +00:00
.appendTo(that);
2010-09-04 14:28:40 +00:00
2010-02-20 04:26:53 +00:00
that.$buttonsbar = new Ox.Bar({})
2010-09-03 20:54:40 +00:00
.addClass('OxButtonsBar')
2010-01-27 12:30:00 +00:00
.appendTo(that);
2010-09-04 14:28:40 +00:00
2010-01-31 09:32:41 +00:00
that.$buttons = [];
2010-02-21 05:20:39 +00:00
$.each(self.options.buttons[0], function(i, button) {
2010-01-31 09:32:41 +00:00
that.$buttons[i] = new Ox.Button({
2010-07-20 20:04:13 +00:00
disabled: button.disabled || false,
2010-09-03 20:54:40 +00:00
size: 'medium',
2010-09-03 08:47:40 +00:00
title: button.title
2010-02-21 05:20:39 +00:00
})
2010-09-03 20:54:40 +00:00
.addClass('OxLeft')
2010-02-21 05:20:39 +00:00
.click(button.click) // fixme: rather use event?
.appendTo(that.$buttonsbar);
});
2010-09-04 14:28:40 +00:00
2010-02-21 05:20:39 +00:00
that.$resize = new Ox.Element()
2010-09-03 20:54:40 +00:00
.addClass('OxResize')
2010-02-21 05:20:39 +00:00
.mousedown(resize)
2010-02-21 06:47:18 +00:00
.dblclick(reset)
2010-02-21 05:20:39 +00:00
.appendTo(that.$buttonsbar);
2010-09-04 14:28:40 +00:00
2010-02-21 05:20:39 +00:00
$.each(self.options.buttons[1].reverse(), function(i, button) {
that.$buttons[that.$buttons.length] = new Ox.Button({
2010-07-20 20:04:13 +00:00
disabled: button.disabled || false,
2010-07-24 01:32:08 +00:00
id: button.id,
2010-09-03 20:54:40 +00:00
size: 'medium',
2010-09-03 08:47:40 +00:00
title: button.title
2010-02-21 05:20:39 +00:00
})
2010-09-03 20:54:40 +00:00
.addClass('OxRight')
2010-02-21 05:20:39 +00:00
.click(button.click) // fixme: rather use event?
.appendTo(that.$buttonsbar);
2010-01-27 12:30:00 +00:00
});
2010-09-04 14:28:40 +00:00
2010-01-31 09:32:41 +00:00
that.$buttons[0].focus();
2010-09-04 14:28:40 +00:00
that.$layer = new Ox.Element() // fixme: Layer widget that would handle click?
2010-09-03 20:54:40 +00:00
.addClass('OxLayer')
2010-02-21 07:09:32 +00:00
.mousedown(mousedownLayer)
.mouseup(mouseupLayer);
2010-02-20 07:46:31 +00:00
function center() {
2010-07-20 20:04:13 +00:00
var documentHeight = $document.height();
that.css({
left: 0,
2010-09-03 20:54:40 +00:00
top: Math.max(parseInt(-documentHeight / 10), self.options.height - documentHeight + 40) + 'px',
right: 0,
bottom: 0,
2010-09-03 20:54:40 +00:00
margin: 'auto'
});
}
2010-02-21 05:20:39 +00:00
function drag(event) {
var bodyWidth = $body.width(),
bodyHeight = $document.height(),
2010-02-21 06:47:18 +00:00
elementWidth = that.width(),
2010-02-21 05:20:39 +00:00
offset = that.offset(),
x = event.clientX,
y = event.clientY;
$window.mousemove(function(event) {
that.css({
margin: 0
});
2010-02-21 05:20:39 +00:00
var left = Ox.limit(
offset.left - x + event.clientX,
24 - elementWidth, bodyWidth - 24
//0, documentWidth - elementWidth
2010-02-21 05:20:39 +00:00
),
top = Ox.limit(
offset.top - y + event.clientY,
24, bodyHeight - 24
//24, documentHeight - elementHeight
2010-02-21 05:20:39 +00:00
);
that.css({
2010-09-03 20:54:40 +00:00
left: left + 'px',
top: top + 'px'
2010-02-21 05:20:39 +00:00
});
});
2010-09-03 20:54:40 +00:00
$window.one('mouseup', function() {
$window.unbind('mousemove');
});
2010-02-21 05:20:39 +00:00
}
2010-07-24 01:32:08 +00:00
function getButtonById(id) {
var ret = null
$.each(that.$buttons, function(i, button) {
2010-09-03 20:54:40 +00:00
if (button.options('id') == id) {
2010-07-24 01:32:08 +00:00
ret = button;
return false;
}
});
return ret;
}
2010-02-21 07:09:32 +00:00
function mousedownLayer() {
that.$layer.stop().animate({
opacity: 0.5
}, 0);
2010-02-21 07:09:32 +00:00
}
function mouseupLayer() {
that.$layer.stop().animate({
opacity: 0
}, 0);
2010-02-21 07:09:32 +00:00
}
2010-02-21 06:47:18 +00:00
function reset() {
2010-09-04 14:28:40 +00:00
that/*.css({
2010-07-24 01:32:08 +00:00
left: Math.max(that.offset().left, 24 - that.width())
2010-09-04 14:28:40 +00:00
})*/
.width(self.options.width)
.height(self.options.height);
2010-07-24 01:32:08 +00:00
that.$content.height(self.options.height - 48 - 2 * self.options.padding); // fixme: this should happen automatically
2010-02-21 06:47:18 +00:00
}
2010-02-21 05:20:39 +00:00
function resize(event) {
2010-07-24 01:32:08 +00:00
var documentWidth = $document.width(),
2010-02-21 05:20:39 +00:00
documentHeight = $document.height(),
elementWidth = that.width(),
elementHeight = that.height(),
2010-02-21 05:40:11 +00:00
offset = that.offset(),
2010-02-21 05:20:39 +00:00
x = event.clientX,
y = event.clientY;
$window.mousemove(function(event) {
2010-02-21 05:34:17 +00:00
that.css({
2010-02-21 05:40:11 +00:00
left: offset.left,
top: offset.top,
2010-02-21 05:34:17 +00:00
margin: 0
});
2010-02-21 05:20:39 +00:00
var width = Ox.limit(
elementWidth - x + event.clientX,
2010-02-21 06:47:18 +00:00
self.options.minWidth, Math.min(documentWidth, documentWidth - offset.left)
2010-02-21 05:20:39 +00:00
),
height = Ox.limit(
elementHeight - y + event.clientY,
self.options.minHeight, documentHeight - offset.top
2010-02-21 05:20:39 +00:00
);
that.width(width);
that.height(height);
2010-07-24 01:32:08 +00:00
that.$content.height(height - 48 - 2 * self.options.padding); // fixme: this should happen automatically
2010-02-21 05:20:39 +00:00
});
2010-09-03 20:54:40 +00:00
$window.one('mouseup', function() {
$window.unbind('mousemove');
2010-02-21 05:20:39 +00:00
});
}
2010-01-31 08:03:22 +00:00
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'height' || key == 'width') {
2010-07-24 01:32:08 +00:00
that.animate({
2010-09-03 20:54:40 +00:00
height: self.options.height + 'px',
width: self.options.width + 'px'
2010-07-24 01:32:08 +00:00
}, 250);
that.$content.height(self.options.height - 48 - 2 * self.options.padding); // fixme: this should happen automatically
2010-09-03 20:54:40 +00:00
} else if (key == 'title') {
2010-07-20 20:04:13 +00:00
that.$title.animate({
opacity: 0
}, 250, function() {
that.$title.html(value).animate({
opacity: 1
}, 250);
});
2010-01-31 08:03:22 +00:00
}
}
2010-02-20 07:46:31 +00:00
2010-01-27 12:30:00 +00:00
that.append = function($element) {
that.$content.append($element);
return that;
}
2010-02-20 07:46:31 +00:00
2010-01-31 09:32:41 +00:00
that.close = function(callback) {
callback = callback || function() {};
2010-01-27 12:30:00 +00:00
that.animate({
opacity: 0
}, 200, function() {
that.remove();
that.$layer.remove();
2010-01-31 09:32:41 +00:00
callback();
});
2010-09-03 20:54:40 +00:00
$window.unbind('mouseup', mouseupLayer)
return that;
2010-01-27 12:30:00 +00:00
}
2010-02-20 07:46:31 +00:00
that.disable = function() {
2010-02-10 16:37:26 +00:00
// to be used on submit of form, like login
2010-09-03 20:54:40 +00:00
that.$layer.addClass('OxFront');
2010-07-20 20:04:13 +00:00
return that;
2010-02-10 16:37:26 +00:00
};
2010-02-20 07:46:31 +00:00
2010-07-24 01:32:08 +00:00
that.disableButton = function(id) {
getButtonById(id).options({
disabled: true
});
2010-09-04 14:28:40 +00:00
return that;
2010-07-24 01:32:08 +00:00
};
2010-02-20 07:46:31 +00:00
that.enable = function() {
2010-09-03 20:54:40 +00:00
that.$layer.removeClass('OxFront');
2010-07-20 20:04:13 +00:00
return that;
2010-07-24 01:32:08 +00:00
};
that.enableButton = function(id) {
getButtonById(id).options({
disabled: false
});
2010-09-04 14:28:40 +00:00
return that;
2010-07-24 01:32:08 +00:00
};
2010-02-20 07:46:31 +00:00
2010-01-27 12:30:00 +00:00
that.open = function() {
2010-02-20 07:46:31 +00:00
that.$layer.appendTo($body);
2010-01-27 12:30:00 +00:00
that.css({
opacity: 0
2010-05-05 18:27:09 +00:00
}).appendTo($body).animate({
2010-01-27 12:30:00 +00:00
opacity: 1
}, 200);
2010-09-04 14:28:40 +00:00
center();
reset();
2010-09-05 00:31:58 +00:00
// fixme: reenable, but implement preview-style dialog
//that.gainFocus();
2010-09-03 20:54:40 +00:00
$window.bind('mouseup', mouseupLayer)
2010-01-27 12:30:00 +00:00
return that;
2010-07-24 01:32:08 +00:00
};
2010-02-20 07:46:31 +00:00
2010-01-27 12:30:00 +00:00
return that;
2010-02-20 07:46:31 +00:00
2010-01-27 12:30:00 +00:00
}
2010-01-07 20:21:07 +00:00
/*
============================================================================
Forms
============================================================================
*/
2010-07-24 01:32:08 +00:00
/*
----------------------------------------------------------------------------
Ox.Filter
----------------------------------------------------------------------------
*/
Ox.Filter = function(options, self) {
var self = self || {}
that = new Ox.Element()
.defaults({
})
.options(options || {});
return that;
};
/*
----------------------------------------------------------------------------
Ox.Form
----------------------------------------------------------------------------
*/
2010-02-10 16:37:26 +00:00
Ox.Form = function(options, self) {
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
.defaults({
2010-09-03 20:54:40 +00:00
error: '',
id: '',
2010-07-24 01:32:08 +00:00
items: [],
submit: null
})
.options(options || {}); // fixme: the || {} can be done once, in the options function
2010-07-20 20:04:13 +00:00
$.extend(self, {
2010-07-24 01:32:08 +00:00
$items: [],
$messages: [],
2010-07-20 20:04:13 +00:00
formIsValid: false,
2010-07-24 01:32:08 +00:00
itemIds: [],
itemIsValid: []
});
// fixme: form isn't necessarily empty/invalid
$.map(self.options.items, function(item, i) {
2010-09-03 20:54:40 +00:00
self.itemIds[i] = item.id || item.element.options('id');
2010-07-24 01:32:08 +00:00
self.itemIsValid[i] = false;
2010-07-20 20:04:13 +00:00
});
$.each(self.options.items, function(i, item) {
2010-09-03 20:54:40 +00:00
var id = item.element.options('id');
2010-07-24 01:32:08 +00:00
that.append(self.$items[i] = new Ox.FormItem(item))
2010-09-03 20:54:40 +00:00
.append(self.$messages[i] = new Ox.Element().addClass('OxFormMessage'));
2010-09-03 08:47:40 +00:00
// fixme: use widget.bindEvent()
2010-09-03 20:54:40 +00:00
Ox.Event.bind(id, 'validate', function(event, data) {
2010-07-24 01:32:08 +00:00
validate(i, data.valid);
});
2010-09-03 20:54:40 +00:00
Ox.Event.bind(id, 'blur', function(event, data) {
2010-07-24 01:32:08 +00:00
validate(i, data.valid);
if (data.valid) {
2010-09-03 20:54:40 +00:00
self.$messages[i].html('').hide();
2010-07-24 01:32:08 +00:00
} else {
self.$messages[i].html(data.message).show();
}
});
2010-09-03 20:54:40 +00:00
Ox.Event.bind(id, 'submit', function(event, data) {
2010-07-24 01:32:08 +00:00
self.formIsValid && that.submit();
});
});
2010-07-24 01:32:08 +00:00
function getItemPositionById(id) {
return self.itemIds.indexOf(id);
}
function setMessage(id, message) {
2010-09-03 20:54:40 +00:00
self.$messages[getItemPositionById(id)].html(message)[message !== '' ? 'show' : 'hide']();
2010-07-24 01:32:08 +00:00
}
function submitCallback(data) {
$.each(data, function(i, v) {
setMessage(v.id, v.message);
});
}
function validate(pos, valid) {
2010-09-03 20:54:40 +00:00
Ox.print('validate', pos, valid)
2010-07-24 01:32:08 +00:00
self.itemIsValid[pos] = valid;
2010-07-20 20:04:13 +00:00
if (Ox.every(self.itemIsValid) != self.formIsValid) {
self.formIsValid = !self.formIsValid;
2010-09-03 20:54:40 +00:00
that.triggerEvent('validate', {
2010-07-24 01:32:08 +00:00
valid: self.formIsValid
2010-07-20 20:04:13 +00:00
});
}
}
2010-07-24 01:32:08 +00:00
that.submit = function() {
self.options.submit(that.values(), submitCallback);
};
that.values = function() { // fixme: can this be private?
var values = {};
if (arguments.length == 0) {
2010-07-24 01:32:08 +00:00
$.each(self.$items, function(i, $item) {
values[self.itemIds[i]] = self.$items[i].value();
});
return values;
} else {
$.each(arguments[0], function(key, value) {
});
return that;
}
};
return that;
2010-02-10 16:37:26 +00:00
};
Ox.FormItem = function(options, self) {
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
.defaults({
2010-07-20 20:04:13 +00:00
element: null,
2010-09-03 20:54:40 +00:00
error: '',
})
2010-07-20 20:04:13 +00:00
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxFormItem')
2010-07-20 20:04:13 +00:00
.append(self.options.element);
2010-07-24 01:32:08 +00:00
that.value = function() {
return self.options.element.$input.val();
};
return that;
}
2010-01-07 20:21:07 +00:00
/*
----------------------------------------------------------------------------
2010-09-03 08:47:40 +00:00
Form Elements
2010-01-07 20:21:07 +00:00
----------------------------------------------------------------------------
*/
Ox.Button = function(options, self) {
2010-02-10 09:59:59 +00:00
/*
events:
2010-09-03 08:47:40 +00:00
click non-selectable button was clicked
deselect selectable button was deselected
select selectable button was selected
2010-02-10 09:59:59 +00:00
*/
2010-01-07 20:21:07 +00:00
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('input', self)
2010-01-07 20:21:07 +00:00
.defaults({
disabled: false,
2010-09-03 08:47:40 +00:00
group: false,
2010-09-03 20:54:40 +00:00
id: '',
overlap: 'none',
2010-01-07 20:21:07 +00:00
selectable: false,
selected: false,
2010-09-03 20:54:40 +00:00
size: 'medium',
// fixme: 'default' or ''?
style: 'default', // can be default, checkbox, symbol, or tab
title: '',
tooltip: '',
type: 'text',
width: 'auto'
2010-01-07 20:21:07 +00:00
})
2010-09-03 08:47:40 +00:00
.options(options || {})
2010-02-06 08:23:42 +00:00
.attr({
2010-09-03 20:54:40 +00:00
disabled: self.options.disabled ? 'disabled' : '',
type: self.options.type == 'text' ? 'button' : 'image'
})
2010-09-03 20:54:40 +00:00
.addClass('OxButton Ox' + Ox.toTitleCase(self.options.size) +
(self.options.disabled ? ' OxDisabled': '') +
(self.options.selected ? ' OxSelected': '') +
(self.options.style != 'default' ? ' Ox' + Ox.toTitleCase(self.options.style) : '') +
(self.options.overlap != 'none' ? ' OxOverlap' + Ox.toTitleCase(self.options.overlap) : ''))
.css(self.options.width == 'auto' ? {} : {
width: (self.options.width - 14) + 'px'
2010-09-03 08:47:40 +00:00
})
.mousedown(mousedown)
.click(click);
2010-09-03 08:47:40 +00:00
$.extend(self, Ox.isArray(self.options.title) ? {
2010-09-03 20:54:40 +00:00
selectedTitle: Ox.setPropertyOnce(self.options.title, 'selected'),
2010-09-03 08:47:40 +00:00
titles: self.options.title
} : {
selectedTitle: 0,
titles: [{
2010-09-03 20:54:40 +00:00
id: '',
2010-09-03 08:47:40 +00:00
title: self.options.title
}]
});
setTitle(self.titles[self.selectedTitle].title);
if (self.options.tooltip) {
self.tooltips = Ox.isArray(self.options.tooltip) ? self.options.tooltip : [self.options.tooltip];
self.$tooltip = new Ox.Tooltip({
title: self.tooltips[self.selectedTitle]
});
that.mouseenter(mouseenter)
.mouseleave(mouseleave);
2010-01-07 20:21:07 +00:00
}
2010-09-03 08:47:40 +00:00
2010-01-07 20:21:07 +00:00
function click() {
2010-09-03 08:47:40 +00:00
var data = self.titles[self.selectedTitle];
2010-02-10 09:59:59 +00:00
if (!self.options.selectable) {
2010-09-03 20:54:40 +00:00
that.triggerEvent('click', data);
2010-09-03 08:47:40 +00:00
} else {
2010-02-10 09:59:59 +00:00
if (self.options.group) {
2010-09-03 20:54:40 +00:00
that.triggerEvent('select', data);
2010-02-10 09:59:59 +00:00
} else {
that.toggleSelected();
}
2010-01-07 20:21:07 +00:00
}
2010-09-03 08:47:40 +00:00
if (self.titles.length == 2) {
that.toggleTitle();
}
}
function mousedown(event) {
2010-09-03 20:54:40 +00:00
if (self.options.type == 'image' && $.browser.safari) {
2010-09-03 08:47:40 +00:00
// keep image from being draggable
event.preventDefault();
}
}
function mouseenter(event) {
self.$tooltip.show(event.clientX, event.clientY);
}
function mouseleave(event) {
self.$tooltip.hide();
}
function setTitle(title) {
self.title = title;
2010-09-03 20:54:40 +00:00
if (self.options.type == 'image') {
2010-09-03 08:47:40 +00:00
that.attr({
2010-09-03 20:54:40 +00:00
src: oxui.path + 'png/ox.ui.' + Ox.theme() +
'/symbol' + Ox.toTitleCase(title) + '.png'
2010-09-03 08:47:40 +00:00
});
} else {
that.val(title);
2010-01-07 20:21:07 +00:00
}
}
2010-09-03 08:47:40 +00:00
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'disabled') {
2010-07-24 01:32:08 +00:00
that.attr({
2010-09-03 20:54:40 +00:00
disabled: value ? 'disabled' : ''
2010-07-24 01:32:08 +00:00
})
2010-09-03 20:54:40 +00:00
.toggleClass('OxDisabled');
} else if (key == 'selected') {
if (value != that.hasClass('OxSelected')) { // fixme: neccessary?
that.toggleClass('OxSelected');
2010-01-07 20:21:07 +00:00
}
2010-09-03 20:54:40 +00:00
that.triggerEvent('change');
} else if (key == 'title') {
2010-09-03 08:47:40 +00:00
setTitle(value);
2010-09-03 20:54:40 +00:00
} else if (key == 'width') {
2010-09-03 08:47:40 +00:00
that.$element.css({
2010-09-03 20:54:40 +00:00
width: (value - 14) + 'px'
2010-09-03 08:47:40 +00:00
});
2010-01-07 20:21:07 +00:00
}
}
2010-09-03 08:47:40 +00:00
2010-01-31 08:03:22 +00:00
that.toggleDisabled = function() {
that.options({
enabled: !self.options.disabled
});
}
2010-09-03 08:47:40 +00:00
2010-01-07 20:21:07 +00:00
that.toggleSelected = function() {
that.options({
selected: !self.options.selected
});
}
2010-09-03 08:47:40 +00:00
that.toggleTitle = function() {
self.selectedTitle = 1 - self.selectedTitle;
setTitle(self.titles[self.selectedTitle].title);
2010-09-03 20:54:40 +00:00
self.$tooltip && self.$tooltip.options({
2010-09-03 08:47:40 +00:00
title: self.tooltips[self.selectedTitle]
});
}
2010-01-07 20:21:07 +00:00
return that;
2010-09-03 08:47:40 +00:00
};
2010-01-07 20:21:07 +00:00
Ox.ButtonGroup = function(options, self) {
2010-02-08 09:35:24 +00:00
2010-02-10 09:59:59 +00:00
/*
2010-09-03 08:47:40 +00:00
Ox.ButtonGroup
options:
buttons array of buttons
max integer, maximum number of selected buttons, 0 for all
min integer, minimum number of selected buttons, 0 for none
selectable if true, buttons are selectable
2010-09-03 20:54:40 +00:00
type string, 'image' or 'text'
2010-02-10 09:59:59 +00:00
events:
2010-09-03 08:47:40 +00:00
change {id, value} selection within a group changed
2010-02-10 09:59:59 +00:00
*/
2010-01-07 20:21:07 +00:00
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
2010-02-10 09:59:59 +00:00
buttons: [],
2010-09-03 08:47:40 +00:00
max: 1,
min: 1,
2010-01-07 20:21:07 +00:00
selectable: false,
2010-09-03 20:54:40 +00:00
size: 'medium',
style: '',
type: 'text',
2010-01-07 20:21:07 +00:00
})
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxButtonGroup');
2010-02-08 09:35:24 +00:00
2010-09-03 08:47:40 +00:00
if (self.options.selectable) {
self.optionGroup = new Ox.OptionGroup(
self.options.buttons,
self.options.min,
self.options.max,
2010-09-03 20:54:40 +00:00
'selected'
2010-09-03 08:47:40 +00:00
);
self.options.buttons = self.optionGroup.init();
}
self.$buttons = [];
2010-02-10 09:59:59 +00:00
$.each(self.options.buttons, function(position, button) {
2010-09-03 08:47:40 +00:00
var id = self.options.id + Ox.toTitleCase(button.id)
self.$buttons[position] = Ox.Button({
disabled: button.disabled,
group: true,
id: id,
selectable: self.options.selectable,
selected: button.selected,
size: self.options.size,
style: self.options.style,
title: button.title,
type: self.options.type
})
2010-09-03 20:54:40 +00:00
.bindEvent('select', function() {
2010-09-03 08:47:40 +00:00
selectButton(position);
})
.appendTo(that);
2010-02-08 09:35:24 +00:00
});
2010-09-03 08:47:40 +00:00
function selectButton(pos) {
var toggled = self.optionGroup.toggle(pos);
if (toggled.length) {
$.each(toggled, function(i, pos) {
self.$buttons[pos].toggleSelected();
});
2010-09-03 20:54:40 +00:00
that.triggerEvent('change', {
2010-09-03 08:47:40 +00:00
selected: $.map(self.optionGroup.selected(), function(v, i) {
return self.options.buttons[v].id;
})
});
2010-02-08 09:35:24 +00:00
}
}
2010-02-10 09:59:59 +00:00
2010-01-07 20:21:07 +00:00
return that;
};
2010-09-03 08:47:40 +00:00
Ox.Checkbox = function(options, self) {
/***
Ox.Checkbox
Checkbox Form Element
Options:
disabled boolean, if true, checkbox is disabled
id element id
group boolean, if true, checkbox is part of a group
checked boolean, if true, checkbox is checked
title string, text on label
width integer, width in px
Methods:
toggleChecked function()
toggles checked property
returns that
Events:
change triggered when checked property changes
passes {checked, id, title}
***/
2010-02-19 10:24:02 +00:00
2010-01-07 20:21:07 +00:00
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-01-07 20:21:07 +00:00
.defaults({
2010-09-03 08:47:40 +00:00
disabled: false,
2010-09-03 20:54:40 +00:00
id: '',
2010-09-03 08:47:40 +00:00
group: false,
checked: false,
2010-09-03 20:54:40 +00:00
title: '',
width: 'auto'
2010-01-07 20:21:07 +00:00
})
2010-02-18 07:27:32 +00:00
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxCheckbox')
2010-09-03 08:47:40 +00:00
.attr(self.options.disabled ? {
2010-09-03 20:54:40 +00:00
disabled: 'disabled'
2010-09-03 08:47:40 +00:00
} : {});
2010-02-19 10:24:02 +00:00
2010-09-03 08:47:40 +00:00
if (self.options.title) {
2010-09-03 20:54:40 +00:00
self.options.width != 'auto' && that.css({
width: self.options.width + 'px'
2010-09-03 08:47:40 +00:00
});
self.$title = new Ox.Label({
disabled: self.options.disabled,
2010-09-03 20:54:40 +00:00
id: self.options.id + 'Label',
overlap: 'left',
2010-09-03 08:47:40 +00:00
title: self.options.title,
width: self.options.width - 16
})
.css({
2010-09-03 20:54:40 +00:00
float: 'right'
2010-02-19 10:24:02 +00:00
})
2010-09-03 08:47:40 +00:00
.click(clickTitle)
2010-02-19 10:24:02 +00:00
.appendTo(that);
}
2010-09-03 08:47:40 +00:00
self.$button = new Ox.Button({
disabled: self.options.disabled,
2010-09-03 20:54:40 +00:00
id: self.options.id + 'Button',
2010-09-03 08:47:40 +00:00
title: [
2010-09-03 20:54:40 +00:00
{id: 'none', title: 'none', selected: !self.options.checked},
{id: 'check', title: 'check', selected: self.options.checked}
2010-09-03 08:47:40 +00:00
],
2010-09-03 20:54:40 +00:00
type: 'image'
2010-02-19 10:24:02 +00:00
})
2010-09-03 20:54:40 +00:00
.addClass('OxCheckbox')
2010-09-03 08:47:40 +00:00
.click(clickButton)
2010-02-19 10:24:02 +00:00
.appendTo(that);
2010-09-03 08:47:40 +00:00
function clickButton() {
self.options.checked = !self.options.checked;
// click will have toggled the button,
// if it is part of a group, we have to revert that
self.options.group && that.toggleChecked();
2010-09-03 20:54:40 +00:00
that.triggerEvent('change', {
2010-09-03 08:47:40 +00:00
checked: self.options.checked,
id: self.options.id,
title: self.options.title
2010-02-18 07:27:32 +00:00
});
}
2010-02-19 10:24:02 +00:00
2010-09-03 08:47:40 +00:00
function clickTitle() {
2010-09-03 20:54:40 +00:00
!self.options.disabled && self.$button.trigger('click');
2010-02-26 13:46:14 +00:00
}
2010-07-24 01:32:08 +00:00
2010-09-03 08:47:40 +00:00
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'checked') {
2010-09-03 08:47:40 +00:00
that.toggleChecked();
}
};
that.toggleChecked = function() {
self.$button.toggleTitle();
return that;
2010-07-24 01:32:08 +00:00
}
2010-09-03 08:47:40 +00:00
return that;
2010-02-19 10:24:02 +00:00
2010-09-03 08:47:40 +00:00
};
Ox.CheckboxGroup = function(options, self) {
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-09-03 08:47:40 +00:00
.defaults({
checkboxes: [],
max: 1,
min: 1,
width: 256
})
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxCheckboxGroup');
2010-09-03 08:47:40 +00:00
self.optionGroup = new Ox.OptionGroup(
self.options.checkboxes,
self.options.min,
self.options.max);
self.options.checkboxes = self.optionGroup.init();
$.extend(self, {
$checkboxes: [],
checkboxWidth: $.map(Ox.divideInt(
self.options.width + (self.options.checkboxes.length - 1) * 6,
self.options.checkboxes.length
), function(v, i) {
return v + (i < self.options.checkboxes.length - 1 ? 10 : 0);
})
2010-09-05 00:31:58 +00:00
});
2010-09-03 08:47:40 +00:00
$.each(self.options.checkboxes, function(position, checkbox) {
var id = self.options.id + Ox.toTitleCase(checkbox.id)
self.$checkboxes[position] = new Ox.Checkbox($.extend(checkbox, {
group: true,
id: id,
width: self.checkboxWidth[position]
}))
2010-09-03 20:54:40 +00:00
.bindEvent('change', function() {
2010-09-03 08:47:40 +00:00
change(position);
})
.appendTo(that);
});
function change(pos) {
var toggled = self.optionGroup.toggle(pos);
2010-09-03 20:54:40 +00:00
//Ox.print('change', pos, 'toggled', toggled)
2010-09-03 08:47:40 +00:00
if (toggled.length) {
$.each(toggled, function(i, pos) {
self.$checkboxes[pos].toggleChecked();
});
2010-09-03 20:54:40 +00:00
that.triggerEvent('change', {
2010-09-03 08:47:40 +00:00
checked: $.map(self.optionGroup.checked(), function(v, i) {
return self.options.checkboxes[v].id;
})
});
}
}
return that;
};
Ox.Input = function(options, self) {
/*
options:
2010-09-03 20:54:40 +00:00
arrows boolearn, if true, and type is 'float' or 'integer', display arrows
2010-09-03 08:47:40 +00:00
arrowStep number, step when clicking arrows
autocomplete array of possible values, or
function(key, value, callback), returns one or more values
autocompleteReplace boolean, if true, value is replaced
autocompleteReplaceCorrect boolean, if true, only valid values can be entered
autocompleteSelect boolean, if true, menu is displayed
autocompleteSelectHighlight boolean, if true, value in menu is highlighted
autocompleteSelectSubmit boolean, if true, submit input on menu selection
2010-09-04 14:28:40 +00:00
autocorrect string ('email', 'float', 'integer', 'phone', 'url'), or
2010-09-03 08:47:40 +00:00
regexp(value), or
function(key, value, blur, callback), returns value
2010-09-04 14:28:40 +00:00
auto validate --remote validation--
2010-09-03 08:47:40 +00:00
clear boolean, if true, has clear button
disabled boolean, if true, is disabled
2010-09-03 20:54:40 +00:00
height integer, px (for type='textarea' and type='range' with orientation='horizontal')
2010-09-03 08:47:40 +00:00
id string, element id
key string, to be passed to autocomplete and autovalidate functions
2010-09-03 20:54:40 +00:00
max number, max value if type is 'integer' or 'float'
min number, min value if type is 'integer' or 'float'
name string, will be displayed by autovalidate function ('invalid ' + name)
overlap string, '', 'left' or 'right', will cause padding and negative margin
2010-09-03 08:47:40 +00:00
picker
//rangeOptions
arrows boolean, if true, display arrows
//arrowStep number, step when clicking arrows
//arrowSymbols array of two strings
max number, maximum value
min number, minimum value
2010-09-03 20:54:40 +00:00
orientation 'horizontal' or 'vertical'
2010-09-03 08:47:40 +00:00
step number, step
thumbValue boolean, if true, value is displayed on thumb, or
array of strings per value, or
function(value), returns string
thumbSize integer, px
trackGradient string, css gradient for track
trackImage string, image url, or
array of image urls
2010-09-03 20:54:40 +00:00
//trackStep number, 0 for 'scroll here', positive for step
2010-09-03 08:47:40 +00:00
trackValues boolean
serialize
2010-09-03 20:54:40 +00:00
textAlign 'left', 'center' or 'right'
type 'float', 'integer', 'password', 'text'
2010-09-03 08:47:40 +00:00
value string
width integer, px
methods:
events:
change
submit
*/
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-09-03 08:47:40 +00:00
.defaults({
arrows: false,
arrowStep: 1,
autocomplete: null,
autocompleteReplace: false,
autocompleteReplaceCorrect: false,
autocompleteSelect: false,
autocompleteSelectHighlight: false,
autocompleteSelectSubmit: false,
autovalidate: null,
clear: false,
2010-09-03 20:54:40 +00:00
key: '',
2010-09-03 08:47:40 +00:00
min: 0,
max: 100,
2010-09-03 20:54:40 +00:00
label: '',
2010-09-03 08:47:40 +00:00
labelWidth: 64,
2010-09-03 20:54:40 +00:00
overlap: 'none',
placeholder: '',
2010-09-03 08:47:40 +00:00
serialize: null,
2010-09-03 20:54:40 +00:00
textAlign: 'left',
type: 'text',
value: '',
2010-09-03 08:47:40 +00:00
width: 128
})
.options(options)
2010-09-03 20:54:40 +00:00
.addClass('OxInput OxMedium')
.addEvent($.extend(self.options.type == 'textarea' ? {} : {
2010-09-03 08:47:40 +00:00
key_enter: submit
}, {
key_escape: cancel
}));
if (
Ox.isArray(self.options.autocomplete) &&
self.options.autocompleteReplace &&
self.options.autocompleteReplaceCorrect &&
2010-09-03 20:54:40 +00:00
self.options.value === ''
2010-09-03 08:47:40 +00:00
) {
self.options.value = self.options.autocomplete[0]
}
// fixme: set to min, not 0
2010-09-03 20:54:40 +00:00
if (self.options.type == 'float') {
2010-09-03 08:47:40 +00:00
$.extend(self.options, {
2010-09-03 20:54:40 +00:00
autovalidate: 'float',
textAlign: 'right',
value: self.options.value || '0.0'
2010-09-03 08:47:40 +00:00
});
2010-09-03 20:54:40 +00:00
} else if (self.options.type == 'integer') {
2010-09-03 08:47:40 +00:00
$.extend(self.options, {
2010-09-03 20:54:40 +00:00
autovalidate: 'integer',
textAlign: 'right',
value: self.options.value || '0'
2010-09-03 08:47:40 +00:00
});
}
if (self.options.label) {
self.$label = new Ox.Label({
2010-09-03 20:54:40 +00:00
overlap: 'right',
textAlign: 'right',
2010-09-03 08:47:40 +00:00
title: self.options.label,
width: self.options.labelWidth
})
.css({
2010-09-03 20:54:40 +00:00
float: 'left', // fixme: use css rule
2010-09-03 08:47:40 +00:00
})
.click(function() {
that.focus();
})
.appendTo(that);
}
if (self.options.arrows) {
self.arrows = [];
self.arrows[0] = [
new Ox.Button({
2010-09-03 20:54:40 +00:00
overlap: 'right',
title: 'previous',
type: 'image'
2010-09-03 08:47:40 +00:00
})
.css({
2010-09-03 20:54:40 +00:00
float: 'left'
2010-09-03 08:47:40 +00:00
})
.click(function() {
clickArrow(0);
})
.appendTo(that),
new Ox.Button({
2010-09-03 20:54:40 +00:00
overlap: 'left',
title: 'next',
type: 'image'
2010-09-03 08:47:40 +00:00
})
.css({
2010-09-03 20:54:40 +00:00
float: 'right'
2010-09-03 08:47:40 +00:00
})
.click(function() {
clickArrow(1);
})
.appendTo(that)
]
}
$.extend(self, {
bindKeyboard: self.options.autocomplete || self.options.autovalidate,
2010-09-03 20:54:40 +00:00
hasPasswordPlaceholder: self.options.type == 'password' && self.options.placeholder,
2010-09-03 08:47:40 +00:00
inputWidth: getInputWidth()
});
if (self.options.clear) {
self.$button = new Ox.Button({
2010-09-03 20:54:40 +00:00
overlap: 'left',
title: 'clear',
type: 'image'
2010-09-03 08:47:40 +00:00
})
.css({
2010-09-03 20:54:40 +00:00
float: 'right' // fixme: use css rule
2010-09-03 08:47:40 +00:00
})
.click(clear)
.appendTo(that);
}
2010-09-03 20:54:40 +00:00
self.$input = $('<input>')
.addClass('OxInput OxMedium')
2010-09-03 08:47:40 +00:00
.attr({
2010-09-03 20:54:40 +00:00
disabled: self.options.disabled ? 'disabled' : '',
type: self.options.type == 'password' ? 'password' : 'text'
2010-09-03 08:47:40 +00:00
})
.css({
2010-09-03 20:54:40 +00:00
width: self.inputWidth + 'px',
2010-09-03 08:47:40 +00:00
textAlign: self.options.textAlign
})
.val(self.options.value)
.blur(blur)
.change(change)
.focus(focus)
.appendTo(that.$element);
if (self.hasPasswordPlaceholder) {
self.$input.hide();
2010-09-03 20:54:40 +00:00
self.$placeholder = $('<input>')
.addClass('OxInput OxMedium OxPlaceholder')
2010-09-03 08:47:40 +00:00
.attr({
2010-09-03 20:54:40 +00:00
type: 'text'
2010-09-03 08:47:40 +00:00
})
.css({
2010-09-03 20:54:40 +00:00
//float: 'left',
width: self.inputWidth + 'px'
2010-09-03 08:47:40 +00:00
})
.val(self.options.placeholder)
.focus(focus)
.appendTo(that.$element);
}
if (self.options.autocomplete && self.options.autocompleteSelect) {
self.$autocompleteMenu = new Ox.Menu({
element: self.$input,
2010-09-03 20:54:40 +00:00
id: self.options.id + 'Menu', // fixme: we do this in other places ... are we doing it the same way? var name?,
2010-09-03 08:47:40 +00:00
offset: {
left: 4,
top: 0
},
size: self.options.size
})
2010-09-03 20:54:40 +00:00
.bindEvent('click', clickMenu);
2010-09-03 08:47:40 +00:00
if (self.options.autocompleteReplace) {
self.$autocompleteMenu.bindEvent({
deselect: deselectMenu,
select: selectMenu,
});
}
}
self.options.placeholder && setPlaceholder();
function autocomplete(oldValue, oldCursor) {
if (self.options.value || self.options.autocompleteReplaceCorrect) {
Ox.isFunction(self.options.autocomplete) ?
(self.options.key ? self.options.autocomplete(
self.options.key,
self.options.value,
autocompleteCallback
) : self.options.autocomplete(
self.options.value,
autocompleteCallback
)) : autocompleteCallback(autocompleteFunction(self.options.value));
}
if (!self.options.value) {
self.options.autocompleteSelect && self.$autocompleteMenu.hideMenu();
}
function autocompleteFunction() {
var values = Ox.find(self.options.autocomplete, self.options.value);
return self.options.autocompleteReplace ? values[0] :
$.merge(values[0], values[1]);
}
function autocompleteCallback(values) {
2010-09-03 20:54:40 +00:00
Ox.print('autocompleteCallback', values[0], self.options.value, self.options.value.length, oldValue, oldCursor)
2010-09-03 08:47:40 +00:00
var length = self.options.value.length,
deleted = length <= oldValue.length - (oldCursor[1] - oldCursor[0]),
newValue = values[0] ?
((self.options.autocompleteReplaceCorrect || !deleted) ?
values[0] : self.options.value) :
(self.options.autocompleteReplaceCorrect ? oldValue : self.options.value),
newLength = newValue.length,
pos = cursor(),
selected = -1,
selectEnd = length == 0 || (values[0] && values[0].length),
value;
2010-09-03 20:54:40 +00:00
Ox.print('selectEnd', selectEnd)
2010-09-03 08:47:40 +00:00
if (self.options.autocompleteReplace) {
self.options.value = newValue;
self.$input.val(self.options.value);
if (selectEnd) {
cursor(length, newLength);
} else if (self.options.autocompleteReplaceCorrect) {
cursor(oldCursor);
} else {
cursor(pos);
}
selected = 0;
}
if (self.options.autocompleteSelect) {
value = self.options.value.toLowerCase();
if (values.length) {
self.oldCursor = cursor();
self.oldValue = self.options.value;
self.$autocompleteMenu.options({
items: $.map(values, function(v, i) {
if (value == v.toLowerCase()) {
selected = i;
}
return {
2010-09-03 20:54:40 +00:00
id: v.toLowerCase().replace(/ /g, '_'), // fixme: need function to do lowercase, underscores etc?
2010-09-03 08:47:40 +00:00
title: self.options.autocompleteSelectHighlight ? v.replace(
2010-09-03 20:54:40 +00:00
new RegExp('(' + value + ')', 'ig'),
'<span class="OxHighlight">$1</span>'
2010-09-03 08:47:40 +00:00
) : v
};
}),
selected: selected
}).showMenu();
} else {
self.$autocompleteMenu.hideMenu();
}
}
2010-09-03 20:54:40 +00:00
that.triggerEvent('autocomplete', {
2010-09-03 08:47:40 +00:00
value: newValue
});
}
}
function autovalidate() {
var blur, oldCursor, oldValue;
if (arguments.length == 1) {
blur = arguments[0];
} else {
blur = false;
oldValue = arguments[0];
oldCursor = arguments[1];
}
Ox.isFunction(self.options.autovalidate) ?
(self.options.key ? self.options.autovalidate(
self.options.key,
self.options.value,
blur,
autovalidateCallback
) : self.options.autovalidate(
self.options.value,
blur,
autovalidateCallback
)) : Ox.isRegExp(self.options.autovalidate) ?
autovalidateCallback(autovalidateFunction(self.options.value)) :
autovalidateTypeFunction(self.options.type, self.options.value);
function autovalidateFunction(value) {
var regexp = new RegExp(self.options.autovalidate);
2010-09-03 20:54:40 +00:00
return $.map(value.toLowerCase().split(''), function(v, i) {
2010-09-03 08:47:40 +00:00
if (regexp(v)) {
return v;
} else {
return null;
}
2010-09-03 20:54:40 +00:00
}).join('');
2010-09-03 08:47:40 +00:00
}
function autovalidateTypeFunction(type, value) {
var cursor,
2010-09-03 20:54:40 +00:00
regexp = type == 'float' ? /[\d\.]/ : /\d/;
if (type == 'float') {
if (value.indexOf('.') != value.lastIndexOf('.')) {
2010-09-03 08:47:40 +00:00
value = oldValue;
} else {
if (self.autovalidateFloatFlag) {
2010-09-03 20:54:40 +00:00
if (Ox.endsWith(value, '.')) {
2010-09-03 08:47:40 +00:00
value = value.substr(0, value.length - 1);
}
self.autovalidateFloatFlag = false;
}
2010-09-03 20:54:40 +00:00
while (Ox.startsWith(value, '.')) {
if (Ox.startsWith(value, '..')) {
2010-09-03 08:47:40 +00:00
value = value.substr(1);
} else {
2010-09-03 20:54:40 +00:00
value = '0' + value;
2010-09-03 08:47:40 +00:00
}
}
2010-09-03 20:54:40 +00:00
if (Ox.endsWith(value, '.')) {
value += '0';
2010-09-03 08:47:40 +00:00
cursor = [value.length - 1, value.length];
self.autovalidateFloatFlag = true;
}
}
}
2010-09-03 20:54:40 +00:00
value = $.map(value.split(''), function(v, i) {
2010-09-03 08:47:40 +00:00
if (regexp(v)) {
return v;
} else {
return null;
}
2010-09-03 20:54:40 +00:00
}).join('');
if (type == 'integer') {
while (value.length > 1 && Ox.startsWith(value, '0')) {
2010-09-03 08:47:40 +00:00
value = value.substr(1);
}
}
2010-09-03 20:54:40 +00:00
if (value === '') {
value = type == 'float' ? '0.0' : '0';
2010-09-03 08:47:40 +00:00
cursor = [0, value.length];
} else if (value > self.options.max) {
value = oldValue;
}
autovalidateCallback(value, cursor);
}
function autovalidateCallback(newValue, newCursor) {
2010-09-03 20:54:40 +00:00
Ox.print('autovalidateCallback', newValue, oldCursor)
2010-09-03 08:47:40 +00:00
self.options.value = newValue;
self.$input.val(self.options.value);
!blur && cursor(
newCursor || (oldCursor[1] + newValue.length - oldValue.length)
);
2010-09-03 20:54:40 +00:00
that.triggerEvent('autovalidate', {
2010-09-03 08:47:40 +00:00
value: self.options.value
});
}
}
/*
function autovalidate(blur) {
2010-09-03 20:54:40 +00:00
Ox.print('autovalidate', self.options.value, blur || false)
2010-09-03 08:47:40 +00:00
self.autocorrectBlur = blur || false;
self.autocorrectCursor = cursor();
Ox.isFunction(self.options.autocorrect) ?
(self.options.key ? self.options.autocorrect(
self.options.key,
self.options.value,
self.autocorrectBlur,
autocorrectCallback
) : self.options.autocorrect(
self.options.value,
self.autocorrectBlur,
autocorrectCallback
)) : autocorrectCallback(autocorrect(self.options.value));
}
function autovalidateFunction(value) {
var length = value.length;
2010-09-03 20:54:40 +00:00
return $.map(value.toLowerCase().split(''), function(v, i) {
2010-09-03 08:47:40 +00:00
if (new RegExp(self.options.autocorrect)(v)) {
return v;
} else {
return null;
}
2010-09-03 20:54:40 +00:00
}).join('');
2010-09-03 08:47:40 +00:00
}
*/
function blur() {
2010-09-03 20:54:40 +00:00
Ox.print('blur')
2010-09-03 08:47:40 +00:00
that.loseFocus();
2010-09-03 20:54:40 +00:00
//that.removeClass('OxFocus');
2010-09-03 08:47:40 +00:00
self.options.value = self.$input.val();
self.options.autovalidate && autovalidate(true);
self.options.placeholder && setPlaceholder();
if (self.bindKeyboard) {
2010-09-03 20:54:40 +00:00
$document.unbind('keydown', keypress);
$document.unbind('keypress', keypress);
2010-09-03 08:47:40 +00:00
}
}
function cancel() {
self.$input.blur();
}
function change() {
self.options.value = self.$input.val();
2010-09-03 20:54:40 +00:00
that.triggerEvent('change', {
2010-09-03 08:47:40 +00:00
value: self.options.value
});
}
function clear() {
// fixme: set to min, not zero
// fixme: make this work for password
2010-09-03 20:54:40 +00:00
var value = '';
if (self.options.type == 'float') {
value = '0.0';
} else if (self.options.type == 'integer') {
value = '0'
2010-09-03 08:47:40 +00:00
}
self.$input.val(value);
cursor(0, value.length);
}
function clickArrow(i) {
self.options.value = Ox.limit(
parseFloat(self.options.value) + (i == 0 ? -1 : 1) * self.options.arrowStep,
self.options.min,
self.options.max
);
self.$input.val(self.options.value);//.focus();
}
function clickMenu(event, data) {
2010-09-03 20:54:40 +00:00
Ox.print('clickMenu', data);
2010-09-03 08:47:40 +00:00
self.options.value = data.title;
self.$input.val(self.options.value).focus();
that.gainFocus();
self.options.autocompleteSelectSubmit && submit();
}
function cursor(start, end) {
/*
cursor() returns [start, end]
cursor(start) sets start
cursor([start, end]) sets start and end
cursor(start, end) sets start and end
*/
var isArray = Ox.isArray(start);
if (arguments.length == 0) {
return [self.$input[0].selectionStart, self.$input[0].selectionEnd];
} else {
end = isArray ? start[1] : (end ? end : start);
start = isArray ? start[0] : start;
self.$input[0].setSelectionRange(start, end);
}
}
function deselectMenu() {
self.options.value = self.oldValue;
self.$input.val(self.options.value);
cursor(self.oldCursor);
}
function focus() {
2010-09-03 20:54:40 +00:00
Ox.print('focus()')
2010-09-03 08:47:40 +00:00
if (
2010-09-03 20:54:40 +00:00
that.hasClass('OxFocus') || // fixme: this is just a workaround, since for some reason, focus() gets called twice on focus
(self.$autocompleteMenu && self.$autocompleteMenu.is(':visible')) ||
(self.hasPasswordPlaceholder && self.$input.is(':visible'))
2010-09-03 08:47:40 +00:00
) {
return;
}
that.gainFocus();
self.options.placeholder && setPlaceholder();
if (self.bindKeyboard) {
2010-09-03 20:54:40 +00:00
Ox.print('binding...')
2010-09-03 08:47:40 +00:00
// fixme: different in webkit and firefox (?), see keyboard handler, need generic function
$document.keydown(keypress);
$document.keypress(keypress);
self.options.autocompleteSelect && setTimeout(autocomplete, 0); // fixme: why is the timeout needed?
}
}
function getInputWidth() {
return self.options.width - 14 -
(self.options.arrows ? 32 : 0) -
(self.options.clear ? 16 : 0) -
(self.options.label ? self.options.labelWidth : 0);
}
function keypress(event) {
var oldCursor = cursor(),
oldValue = self.options.value,
newValue = oldValue.substr(0, oldCursor[0] - 1),
hasDeletedSelectedEnd = (event.keyCode == 8 || event.keyCode == 46) &&
oldCursor[0] < oldCursor[1] && oldCursor[1] == oldValue.length;
2010-09-03 20:54:40 +00:00
Ox.print('keypress', event.keyCode)
2010-09-03 08:47:40 +00:00
if (event.keyCode != 9 && event.keyCode != 13 && event.keyCode != 27) { // fixme: can't 13 and 27 return false?
setTimeout(function() { // wait for val to be set
var value = self.$input.val();
if (self.options.autocompleteReplaceCorrect && hasDeletedSelectedEnd) {
2010-09-03 20:54:40 +00:00
Ox.print(value, '->', newValue);
2010-09-03 08:47:40 +00:00
value = newValue; // value.substr(0, value.length - 1);
self.$input.val(value);
}
if (value != self.options.value) {
self.options.value = value;
self.options.autocomplete && autocomplete(oldValue, oldCursor);
self.options.autovalidate && autovalidate(oldValue, oldCursor);
}
}, 0);
}
2010-09-03 20:54:40 +00:00
if ((event.keyCode == 38 || event.keyCode == 40) && self.options.autocompleteSelect && self.$autocompleteMenu.is(':visible')) {
2010-09-03 08:47:40 +00:00
return false;
}
}
function selectMenu(event, data) {
var pos = cursor();
2010-09-03 20:54:40 +00:00
Ox.print('selectMenu', pos)
2010-09-03 08:47:40 +00:00
self.options.value = data.title
self.$input.val(self.options.value);
cursor(pos[0], self.options.value.length)
}
function setPlaceholder() {
if (self.options.placeholder) {
2010-09-03 20:54:40 +00:00
if (that.hasClass('OxFocus')) {
if (self.options.value === '') {
if (self.options.type == 'password') {
2010-09-03 08:47:40 +00:00
self.$placeholder.hide();
self.$input.show().focus();
} else {
self.$input
2010-09-03 20:54:40 +00:00
.removeClass('OxPlaceholder')
.val('');
2010-09-03 08:47:40 +00:00
}
}
} else {
2010-09-03 20:54:40 +00:00
if (self.options.value === '') {
if (self.options.type == 'password') {
2010-09-03 08:47:40 +00:00
self.$input.hide();
self.$placeholder.show();
} else {
self.$input
2010-09-03 20:54:40 +00:00
.addClass('OxPlaceholder')
2010-09-03 08:47:40 +00:00
.val(self.options.placeholder)
}
} else {
self.$input
2010-09-03 20:54:40 +00:00
.removeClass('OxPlaceholder')
2010-09-03 08:47:40 +00:00
.val(self.options.value)
}
}
}
}
function setWidth() {
}
function submit() {
self.$input.blur();
2010-09-03 20:54:40 +00:00
that.triggerEvent('submit', {
2010-09-03 08:47:40 +00:00
value: self.options.value
});
}
self.onChange = function(key, value) {
var inputWidth, val;
2010-09-04 14:28:40 +00:00
if (key == 'placeholder') {
setPlaceholder();
} else if (key == 'value') {
2010-09-03 08:47:40 +00:00
val = self.$input.val();
self.$input.val(value);
setPlaceholder();
2010-09-03 20:54:40 +00:00
} else if (key == 'width') {
2010-09-03 08:47:40 +00:00
inputWidth = getInputWidth();
self.$input.css({
2010-09-03 20:54:40 +00:00
width: inputWidth + 'px'
2010-09-03 08:47:40 +00:00
});
self.hasPasswordPlaceholder && self.$placeholder.css({
2010-09-03 20:54:40 +00:00
width: inputWidth + 'px'
2010-09-03 08:47:40 +00:00
});
}
};
that.focus = function() {
self.$input.focus();
cursor(0, self.$input.val().length);
};
return that;
};
Ox.AutocorrectIntFunction = function(min, max, pad, year) {
var pad = pad || false,
year = year || false,
maxLength = max.toString().length,
ret = null,
values = [];
$.each(Ox.range(min, max + 1), function(i, v) {
2010-09-03 20:54:40 +00:00
values.push(v + '');
2010-09-03 08:47:40 +00:00
pad && v.toString().length < maxLength && values.push(Ox.pad(v, maxLength));
});
return function(value, blur, callback) {
var results;
2010-09-03 20:54:40 +00:00
if (year && value == '1') {
value = '1900';
2010-09-03 08:47:40 +00:00
} else {
results = Ox.find(values, value);
value = results[0].length == 1 && results[0][0].length < maxLength ?
(pad ? Ox.pad(results[0][0], maxLength) : results[0][0]) :
(results[0].length ? results[0][0] : null);
}
callback(value);
};
};
Ox.InputGroup = function(options, self) {
/***
Ox.InputGroup
Options:
Methods:
Events:
***/
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-09-03 08:47:40 +00:00
.defaults({
2010-09-03 20:54:40 +00:00
id: '',
2010-09-03 08:47:40 +00:00
inputs: [],
separators: [],
width: 0
})
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxInputGroup')
2010-09-03 08:47:40 +00:00
.click(click);
if (self.options.width) {
setWidths();
} else {
self.options.width = getWidth();
}
that.css({
2010-09-03 20:54:40 +00:00
width: self.options.width + 'px'
2010-09-03 08:47:40 +00:00
});
$.extend(self, {
//$input: [],
$separator: []
});
$.each(self.options.separators, function(i, v) {
self.$separator[i] = new Ox.Label({
2010-09-03 20:54:40 +00:00
textAlign: 'center',
2010-09-03 08:47:40 +00:00
title: v.title,
width: v.width + 32
})
2010-09-03 20:54:40 +00:00
.addClass('OxSeparator')
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
marginLeft: (self.options.inputs[i].options('width') - (i == 0 ? 16 : 32)) + 'px'
2010-09-03 08:47:40 +00:00
})
.appendTo(that);
});
$.each(self.options.inputs, function(i, $input) {
$input.options({
2010-09-03 20:54:40 +00:00
id: self.options.id + Ox.toTitleCase($input.options('id')),
2010-09-03 08:47:40 +00:00
parent: that
})
.css({
marginLeft: -Ox.sum($.map(self.options.inputs, function(v_, i_) {
2010-09-03 20:54:40 +00:00
return i_ > i ? self.options.inputs[i_ - 1].options('width') +
2010-09-03 08:47:40 +00:00
self.options.separators[i_ - 1].width : (i_ == i ? 16 : 0);
2010-09-03 20:54:40 +00:00
})) + 'px'
2010-09-03 08:47:40 +00:00
})
.bindEvent({
change: change,
submit: change
})
.appendTo(that);
});
function change(event, data) {
2010-09-03 20:54:40 +00:00
Ox.print('InputGroup change')
2010-09-03 08:47:40 +00:00
// fixme: would be good to pass a value here
2010-09-03 20:54:40 +00:00
that.triggerEvent('change');
2010-09-03 08:47:40 +00:00
}
function click(event) {
2010-09-03 20:54:40 +00:00
if ($(event.target).hasClass('OxSeparator')) {
2010-09-03 08:47:40 +00:00
self.options.inputs[0].focus();
}
}
function getWidth() {
return Ox.sum($.map(self.options.inputs, function(v, i) {
2010-09-03 20:54:40 +00:00
return v.options('width');
2010-09-03 08:47:40 +00:00
})) + Ox.sum($.map(self.options.separators, function(v, i) {
return v.width;
}));
}
function setWidths() {
var length = self.options.inputs.length,
inputWidths = Ox.divideInt(
self.options.width - Ox.sum($.map(self.options.separators, function(v, i) {
return v.width;
})), length
);
$.each(self.options.inputs, function(i, v) {
v.options({
width: inputWidths[1]
});
});
}
// fixme: is this used?
that.getInputById = function(id) {
var input = null;
$.each(self.options.inputs, function(i, v) {
2010-09-03 20:54:40 +00:00
Ox.print(v, v.options('id'), id)
if (v.options('id') == self.options.id + Ox.toTitleCase(id)) {
2010-09-03 08:47:40 +00:00
input = v;
return false;
}
});
return input;
};
return that;
};
Ox.ColorInput = function(options, self) {
var self = $.extend(self || {}, {
options: $.extend({
2010-09-03 20:54:40 +00:00
id: '',
value: '0, 0, 0'
2010-09-03 08:47:40 +00:00
}, options)
}),
that;
2010-09-03 20:54:40 +00:00
self.values = self.options.value.split(', ');
2010-09-03 08:47:40 +00:00
self.$inputs = [];
2010-09-03 20:54:40 +00:00
$.each(['red', 'green', 'blue'], function(i, v) {
2010-09-03 08:47:40 +00:00
self.$inputs[i] = new Ox.Input({
id: v,
max: 255,
2010-09-03 20:54:40 +00:00
type: 'integer',
2010-09-03 08:47:40 +00:00
value: self.values[i],
width: 36
})
2010-09-03 20:54:40 +00:00
.bindEvent('autovalidate', change);
2010-09-03 08:47:40 +00:00
});
self.$inputs[3] = new Ox.Label({
2010-09-03 20:54:40 +00:00
id: 'color',
2010-09-03 08:47:40 +00:00
width: 36
})
.css({
2010-09-03 20:54:40 +00:00
background: 'rgb(' + self.options.value + ')'
2010-09-03 08:47:40 +00:00
});
self.$inputs[4] = new Ox.ColorPicker({
2010-09-03 20:54:40 +00:00
id: 'picker'
2010-09-03 08:47:40 +00:00
})
2010-09-03 20:54:40 +00:00
.bindEvent('change', function(event, data) {
Ox.print('change function called');
2010-09-03 08:47:40 +00:00
self.options.value = data.value;
2010-09-03 20:54:40 +00:00
self.values = data.value.split(', ');
2010-09-03 08:47:40 +00:00
$.each(Ox.range(3), function(i) {
self.$inputs[i].options({
value: self.values[i]
});
});
})
.options({
width: 16 // this is just a hack to make the InputGroup layout work
});
that = new Ox.InputGroup({
id: self.options.id,
inputs: self.$inputs,
separators: [
2010-09-03 20:54:40 +00:00
{title: ',', width: 8},
{title: ',', width: 8},
{title: '', width: 8},
{title: '', width: 8}
2010-09-03 08:47:40 +00:00
],
value: self.options.value // fixme: it'd be nicer if this would be taken care of by passing self
}, self)
2010-09-03 20:54:40 +00:00
.bindEvent('change', change);
2010-09-03 08:47:40 +00:00
function change() {
self.options.value = $.map(self.$inputs, function(v, i) {
2010-09-03 20:54:40 +00:00
return v.options('value');
}).join(', ');
2010-09-03 08:47:40 +00:00
self.$inputs[3].css({
2010-09-03 20:54:40 +00:00
background: 'rgb(' + self.options.value + ')'
2010-09-03 08:47:40 +00:00
});
}
return that;
};
Ox.DateInput = function(options, self) {
var self = $.extend(self || {}, {
options: $.extend({
2010-09-03 20:54:40 +00:00
format: 'short',
value: Ox.formatDate(new Date(), '%F'),
2010-09-03 08:47:40 +00:00
weekday: false,
width: {
day: 32,
2010-09-03 20:54:40 +00:00
month: options.format == 'long' ? 80 : (options.format == 'medium' ? 40 : 32),
weekday: options.format == 'long' ? 80 : 40,
2010-09-03 08:47:40 +00:00
year: 48
}
}, options)
}),
that;
$.extend(self, {
2010-09-03 20:54:40 +00:00
date: new Date(self.options.value.replace(/-/g, '/')),
2010-09-03 08:47:40 +00:00
formats: {
2010-09-03 20:54:40 +00:00
day: '%d',
month: self.options.format == 'short' ? '%m' :
(self.options.format == 'medium' ? '%b' : '%B'),
weekday: self.options.format == 'long' ? '%A' : '%a',
year: '%Y'
2010-09-03 08:47:40 +00:00
},
2010-09-03 20:54:40 +00:00
months: self.options.format == 'long' ? Ox.MONTHS : $.map(Ox.MONTHS, function(v, i) {
2010-09-03 08:47:40 +00:00
return v.substr(0, 3);
}),
2010-09-03 20:54:40 +00:00
weekdays: self.options.format == 'long' ? Ox.WEEKDAYS : $.map(Ox.WEEKDAYS, function(v, i) {
2010-09-03 08:47:40 +00:00
return v.substr(0, 3);
})
});
self.$input = $.extend(self.options.weekday ? {
weekday: new Ox.Input({
autocomplete: self.weekdays,
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
2010-09-03 20:54:40 +00:00
id: 'weekday',
2010-09-03 08:47:40 +00:00
value: Ox.formatDate(self.date, self.formats.weekday),
width: self.options.width.weekday
})
2010-09-03 20:54:40 +00:00
.bindEvent('autocomplete', changeWeekday),
2010-09-03 08:47:40 +00:00
} : {}, {
day: new Ox.Input({
autocomplete: $.map(Ox.range(1, Ox.getDaysInMonth(
2010-09-03 20:54:40 +00:00
parseInt(Ox.formatDate(self.date, '%Y'), 10),
parseInt(Ox.formatDate(self.date, '%m'), 10)
2010-09-03 08:47:40 +00:00
) + 1), function(v, i) {
2010-09-03 20:54:40 +00:00
return self.options.format == 'short' ? Ox.pad(v, 2) : v.toString();
2010-09-03 08:47:40 +00:00
}),
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
2010-09-03 20:54:40 +00:00
id: 'day',
2010-09-03 08:47:40 +00:00
value: Ox.formatDate(self.date, self.formats.day),
2010-09-03 20:54:40 +00:00
textAlign: 'right',
2010-09-03 08:47:40 +00:00
width: self.options.width.day
})
2010-09-03 20:54:40 +00:00
.bindEvent('autocomplete', changeDay),
2010-09-03 08:47:40 +00:00
month: new Ox.Input({
2010-09-03 20:54:40 +00:00
autocomplete: self.options.format == 'short' ? $.map(Ox.range(1, 13), function(v, i) {
2010-09-03 08:47:40 +00:00
return Ox.pad(v, 2);
}) : self.months,
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
2010-09-03 20:54:40 +00:00
id: 'month',
2010-09-03 08:47:40 +00:00
value: Ox.formatDate(self.date, self.formats.month),
2010-09-03 20:54:40 +00:00
textAlign: self.options.format == 'short' ? 'right' : 'left',
2010-09-03 08:47:40 +00:00
width: self.options.width.month
})
2010-09-03 20:54:40 +00:00
.bindEvent('autocomplete', changeMonthOrYear),
2010-09-03 08:47:40 +00:00
year: new Ox.Input({
autocomplete: $.map($.merge(Ox.range(1900, 3000), Ox.range(1000, 1900)), function(v, i) {
return v.toString();
}),
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
2010-09-03 20:54:40 +00:00
id: 'year',
2010-09-03 08:47:40 +00:00
value: Ox.formatDate(self.date, self.formats.year),
2010-09-03 20:54:40 +00:00
textAlign: 'right',
2010-09-03 08:47:40 +00:00
width: self.options.width.year
})
2010-09-03 20:54:40 +00:00
.bindEvent('autocomplete', changeMonthOrYear)
2010-09-03 08:47:40 +00:00
});
that = new Ox.InputGroup($.extend(self.options, {
id: self.options.id,
inputs: $.merge(self.options.weekday ? [
self.$input.weekday
2010-09-03 20:54:40 +00:00
] : [], self.options.format == 'short' ? [
2010-09-03 08:47:40 +00:00
self.$input.year, self.$input.month, self.$input.day
] : [
self.$input.month, self.$input.day, self.$input.year
]),
separators: $.merge(self.options.weekday ? [
2010-09-03 20:54:40 +00:00
{title: self.options.format == 'short' ? '' : ',', width: 8},
] : [], self.options.format == 'short' ? [
{title: '-', width: 8}, {title: '-', width: 8}
2010-09-03 08:47:40 +00:00
] : [
2010-09-03 20:54:40 +00:00
{title: '', width: 8}, {title: ',', width: 8}
2010-09-03 08:47:40 +00:00
]),
width: 0
}), self);
2010-09-03 20:54:40 +00:00
Ox.print('SELF', self)
2010-09-03 08:47:40 +00:00
function changeDay() {
self.options.weekday && self.$input.weekday.options({
value: Ox.formatDate(new Date([
2010-09-03 20:54:40 +00:00
self.$input.month.options('value'),
self.$input.day.options('value'),
self.$input.year.options('value')
].join(' ')), self.formats.weekday)
2010-09-03 08:47:40 +00:00
});
setValue();
}
function changeMonthOrYear() {
2010-09-03 20:54:40 +00:00
var day = self.$input.day.options('value'),
month = self.$input.month.options('value'),
year = self.$input.year.options('value'),
days = Ox.getDaysInMonth(year, self.options.format == 'short' ? parseInt(month, 10) : month);
2010-09-03 08:47:40 +00:00
day = day <= days ? day : days;
2010-09-03 20:54:40 +00:00
Ox.print(year, month, 'day days', day, days)
2010-09-03 08:47:40 +00:00
self.options.weekday && self.$input.weekday.options({
2010-09-03 20:54:40 +00:00
value: Ox.formatDate(new Date([month, day, year].join(' ')), self.formats.weekday)
2010-09-03 08:47:40 +00:00
});
self.$input.day.options({
autocomplete: $.map(Ox.range(1, days + 1), function(v, i) {
2010-09-03 20:54:40 +00:00
return self.options.format == 'short' ? Ox.pad(v, 2) : v.toString();
2010-09-03 08:47:40 +00:00
}),
2010-09-03 20:54:40 +00:00
value: self.options.format == 'short' ? Ox.pad(day, 2) : day.toString()
2010-09-03 08:47:40 +00:00
});
setValue();
}
function changeWeekday() {
var date = getDateInWeek(
2010-09-03 20:54:40 +00:00
self.$input.weekday.options('value'),
self.$input.month.options('value'),
self.$input.day.options('value'),
self.$input.year.options('value')
2010-09-03 08:47:40 +00:00
);
self.$input.month.options({value: date.month});
self.$input.day.options({
autocomplete: $.map(Ox.range(1, Ox.getDaysInMonth(date.year, date.month) + 1), function(v, i) {
2010-09-03 20:54:40 +00:00
return self.options.format == 'short' ? Ox.pad(v, 2) : v.toString();
2010-09-03 08:47:40 +00:00
}),
value: date.day
});
self.$input.year.options({value: date.year});
setValue();
}
function getDateInWeek(weekday, month, day, year) {
2010-09-03 20:54:40 +00:00
Ox.print([month, day, year].join(' '))
var date = new Date([month, day, year].join(' '));
2010-09-03 08:47:40 +00:00
date = Ox.getDateInWeek(date, weekday);
return {
day: Ox.formatDate(date, self.formats.day),
month: Ox.formatDate(date, self.formats.month),
year: Ox.formatDate(date, self.formats.year)
};
}
function setValue() {
2010-09-03 20:54:40 +00:00
self.options.value = Ox.formatDate(new Date(self.options.format == 'short' ? [
self.$input.year.options('value'),
self.$input.month.options('value'),
self.$input.day.options('value')
].join('/') : [
self.$input.month.options('value'),
self.$input.day.options('value'),
self.$input.year.options('value')
].join(' ')), '%F');
2010-09-03 08:47:40 +00:00
}
/*
function normalize() {
2010-09-03 20:54:40 +00:00
var year = that.getInputById('year').options('value'),
month = that.getInputById('month').options('value'),
day = that.getInputById('day').options('value')
2010-09-03 08:47:40 +00:00
return {
year: year,
2010-09-03 20:54:40 +00:00
month: self.options.format == 'short' ? month :
Ox.pad((format == 'medium' ? Ox.WEEKDAYS.map(function(v, i) {
2010-09-03 08:47:40 +00:00
return v.substr(0, 3);
}) : Ox.WEEKDAYS).indexOf(month), 2),
day: Ox.pad(day, 2)
}
}
*/
/*
that.serialize = function() {
var normal = normalize();
2010-09-03 20:54:40 +00:00
return [normal.year, normal.month, normal.day].join('-');
2010-09-03 08:47:40 +00:00
}
*/
return that;
};
Ox.DateTimeInput = function(options, self) {
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
ampm: false,
2010-09-03 20:54:40 +00:00
format: 'short',
2010-09-03 08:47:40 +00:00
seconds: false,
2010-09-03 20:54:40 +00:00
value: Ox.formatDate(new Date(), '%F %T'),
2010-09-03 08:47:40 +00:00
weekday: false
})
.options(options || {});
2010-09-03 20:54:40 +00:00
self.values = self.options.value.split(' ');
2010-09-03 08:47:40 +00:00
Ox.print(self.values)
that = new Ox.InputGroup({
inputs: [
new Ox.DateInput({
format: self.options.format,
2010-09-03 20:54:40 +00:00
id: 'date',
2010-09-03 08:47:40 +00:00
value: self.values[0],
weekday: self.options.weekday
}),
new Ox.TimeInput({
ampm: self.options.ampm,
2010-09-03 20:54:40 +00:00
id: 'time',
2010-09-03 08:47:40 +00:00
value: self.values[1],
seconds: self.options.seconds
})
],
separators: [
2010-09-03 20:54:40 +00:00
{title: '', width: 8}
2010-09-03 08:47:40 +00:00
],
value: self.options.value
})
2010-09-03 20:54:40 +00:00
.bindEvent('change', setValue);
2010-09-03 08:47:40 +00:00
function setValue() {
self.options.value = [
2010-09-03 20:54:40 +00:00
self.options('inputs')[0].options('value'),
self.options('inputs')[1].options('value')
].join(' ');
2010-09-03 08:47:40 +00:00
}
return that;
};
Ox.PlaceInput = function(options, self) {
var self = $.extend(self || {}, {
options: $.extend({
2010-09-03 20:54:40 +00:00
id: '',
value: 'United States'
2010-09-03 08:47:40 +00:00
}, options)
}),
that;
that = new Ox.FormElementGroup({
id: self.options.id,
elements: [
new Ox.Input({
2010-09-03 20:54:40 +00:00
id: 'input',
2010-09-03 08:47:40 +00:00
value: self.options.value
}),
new Ox.PlacePicker({
2010-09-03 20:54:40 +00:00
id: 'picker',
overlap: 'left',
2010-09-03 08:47:40 +00:00
value: self.options.value
})
],
2010-09-03 20:54:40 +00:00
float: 'right'
2010-09-03 08:47:40 +00:00
}, self)
2010-09-03 20:54:40 +00:00
.bindEvent('change', change);
2010-09-03 08:47:40 +00:00
function change() {
}
return that;
};
Ox.TimeInput = function(options, self) {
// fixme: seconds get set even if options.seconds is false
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
ampm: false,
seconds: false,
milliseconds: false,
2010-09-03 20:54:40 +00:00
value: Ox.formatDate(new Date(), '%T'),
2010-09-03 08:47:40 +00:00
})
.options(options || {});
if (self.options.milliseconds) {
self.options.seconds = true;
2010-09-03 20:54:40 +00:00
if (self.options.value.indexOf('.') == -1) {
self.options.value += '.000';
2010-09-03 08:47:40 +00:00
}
}
self.date = getDate();
self.values = getValues();
self.$input = {
hours: Ox.Input({
autocomplete: $.map(self.options.ampm ? Ox.range(1, 13) : Ox.range(0, 24), function(v) {
return Ox.pad(v, 2);
}),
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
2010-09-03 20:54:40 +00:00
id: 'hours',
textAlign: 'right',
2010-09-03 08:47:40 +00:00
value: self.values.hours,
width: 32
}),
minutes: Ox.Input({
autocomplete: $.map(Ox.range(0, 60), function(v) {
return Ox.pad(v, 2);
}),
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
2010-09-03 20:54:40 +00:00
id: 'minutes',
textAlign: 'right',
2010-09-03 08:47:40 +00:00
value: self.values.minutes,
width: 32
}),
seconds: Ox.Input({
autocomplete: $.map(Ox.range(0, 60), function(v) {
return Ox.pad(v, 2);
}),
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
2010-09-03 20:54:40 +00:00
id: 'seconds',
textAlign: 'right',
2010-09-03 08:47:40 +00:00
value: self.values.seconds,
width: 32
}),
milliseconds: Ox.Input({
autocomplete: $.map(Ox.range(0, 1000), function(v) {
return Ox.pad(v, 3);
}),
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
2010-09-03 20:54:40 +00:00
id: 'milliseconds',
textAlign: 'right',
2010-09-03 08:47:40 +00:00
value: self.values.milliseconds,
width: 40
}),
ampm: Ox.Input({
2010-09-03 20:54:40 +00:00
autocomplete: ['AM', 'PM'],
2010-09-03 08:47:40 +00:00
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
2010-09-03 20:54:40 +00:00
id: 'ampm',
2010-09-03 08:47:40 +00:00
value: self.values.ampm,
width: 32
})
};
that = new Ox.InputGroup($.extend(self.options, {
inputs: $.merge($.merge($.merge([
self.$input.hours,
self.$input.minutes,
], self.options.seconds ? [
self.$input.seconds
] : []), self.options.milliseconds ? [
self.$input.milliseconds
] : []), self.options.ampm ? [
self.$input.ampm
] : []),
separators: $.merge($.merge($.merge([
2010-09-03 20:54:40 +00:00
{title: ':', width: 8},
2010-09-03 08:47:40 +00:00
], self.options.seconds ? [
2010-09-03 20:54:40 +00:00
{title: ':', width: 8}
2010-09-03 08:47:40 +00:00
] : []), self.options.milliseconds ? [
2010-09-03 20:54:40 +00:00
{title: '.', width: 8}
2010-09-03 08:47:40 +00:00
] : []), self.options.ampm ? [
2010-09-03 20:54:40 +00:00
{title: '', width: 8}
2010-09-03 08:47:40 +00:00
] : []),
//width: self.options.width || 128
}), self)
2010-09-03 20:54:40 +00:00
.bindEvent('change', setValue);
2010-09-03 08:47:40 +00:00
setValue();
function getDate() {
2010-09-03 20:54:40 +00:00
return new Date('1970/01/01 ' + (
2010-09-03 08:47:40 +00:00
self.options.milliseconds ?
self.options.value.substr(0, self.options.value.length - 4) :
self.options.value
));
}
function getValues() {
self.date = getDate();
return {
2010-09-03 20:54:40 +00:00
ampm: Ox.formatDate(self.date, '%p'),
hours: Ox.formatDate(self.date, self.options.ampm ? '%I' : '%H'),
milliseconds: self.options.milliseconds ? self.options.value.substr(-3) : '000',
minutes: Ox.formatDate(self.date, '%M'),
seconds: Ox.formatDate(self.date, '%S')
2010-09-03 08:47:40 +00:00
};
}
function setValue() {
2010-09-03 20:54:40 +00:00
self.options.value = Ox.formatDate(new Date('1970/01/01 ' + [
self.$input.hours.options('value'),
self.$input.minutes.options('value'),
self.options.seconds ? self.$input.seconds.options('value') : '00'
].join(':') + (self.options.ampm ? ' ' + self.$input.ampm.options('value') : '')),
(self.options.seconds? '%T' : '%H:%M')) +
(self.options.milliseconds ? '.' + self.$input.milliseconds.options('value') : '');
Ox.print('SETVALUE', self.options.value);
2010-09-03 08:47:40 +00:00
}
function setValues() {
self.values = getValues();
$.each(self.$input, function(k, v) {
self.$input[k].options({
value: self.values[k]
});
});
}
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'value') {
2010-09-03 08:47:40 +00:00
setValues();
}
}
return that;
};
Ox.Label = function(options, self) {
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-09-03 08:47:40 +00:00
.defaults({
disabled: false,
2010-09-03 20:54:40 +00:00
id: '',
overlap: 'none',
textAlign: 'left',
title: '',
width: 'auto'
2010-09-03 08:47:40 +00:00
})
.options(options)
.addClass(
2010-09-03 20:54:40 +00:00
'OxLabel' + (self.options.disabled ? ' OxDisabled' : '') +
(self.options.overlap != 'none' ?
' OxOverlap' + Ox.toTitleCase(self.options.overlap) : '')
2010-09-03 08:47:40 +00:00
)
2010-09-03 20:54:40 +00:00
.css($.extend(self.options.width == 'auto' ? {} : {
width: (self.options.width - 14) + 'px'
2010-09-03 08:47:40 +00:00
}, {
textAlign: self.options.textAlign
}))
.html(self.options.title);
return that;
};
Ox.OptionGroup = function(items, min, max, property) {
/*
to be used by ButtonGroup, CheckboxGroup, Select and Menu
*/
2010-09-03 20:54:40 +00:00
var property = property || 'checked'
2010-09-03 08:47:40 +00:00
length = items.length,
max = max == -1 ? length : max;
function getLastBefore(pos) {
// returns the position of the last checked item before position pos
var last = -1;
Ox.print(items, items.length, length, $.merge(
pos > 0 ? Ox.range(pos - 1, -1, -1) : [],
2010-09-03 20:54:40 +00:00
pos < items.length - 1 ? Ox.range(items.length - 1, pos, -1) : []
2010-09-03 08:47:40 +00:00
))
2010-09-03 20:54:40 +00:00
// fixme: why is length not == items.length here?
2010-09-03 08:47:40 +00:00
$.each($.merge(
pos > 0 ? Ox.range(pos - 1, -1, -1) : [],
2010-09-03 20:54:40 +00:00
pos < items.length - 1 ? Ox.range(items.length - 1, pos, -1) : []
2010-09-03 08:47:40 +00:00
), function(i, v) {
Ox.print(pos, v)
if (items[v][property]) {
last = v;
return false;
}
});
return last;
}
function getNumber() {
// returns the number of checked items
var num = 0;
$.each(items, function(i, item) {
if (item[property]) {
num++;
}
})
return num;
}
this[property] = function() {
// returns an array with the positions of all checked item
var checked = [];
$.each(items, function(i, item) {
if (item[property]) {
checked.push(i);
}
})
return checked;
};
this.init = function() {
var num = getNumber(),
count = 0;
//if (num < min || num > max) {
$.each(items, function(i, item) {
if (Ox.isUndefined(item[property])) {
item[property] = false;
}
if (item[property]) {
count++;
if (count > max) {
item[property] = false;
}
} else {
if (num < min) {
item[property] = true;
num++;
}
}
});
//}
return items;
};
this.toggle = function(pos) {
var last,
num = getNumber(),
toggled = [];
if (!items[pos][property]) { // check
if (num >= max) {
last = getLastBefore(pos);
items[last][property] = false;
toggled.push(last);
}
if (!items[pos][property]) {
items[pos][property] = true;
toggled.push(pos);
}
} else { // uncheck
if (num > min) {
items[pos][property] = false;
toggled.push(pos);
}
}
return toggled;
}
return this;
}
Ox.Range = function(options, self) {
/***
Ox.Range
Options:
arrows boolean if true, show arrows
arrowStep number step when clicking arrows
2010-09-03 20:54:40 +00:00
arrowSymbols array arrow symbols, like ['minus', 'plus']
2010-09-03 08:47:40 +00:00
max number maximum value
min number minimum value
2010-09-03 20:54:40 +00:00
orientation string 'horizontal' or 'vertical'
2010-09-03 08:47:40 +00:00
step number step between values
size number width or height, in px
thumbSize number minimum width or height of thumb, in px
thumbValue boolean if true, display value on thumb
trackGradient array colors
trackImages string or array one or multiple track background image URLs
trackStep number 0 (scroll here) or step when clicking track
value number initial value
valueNames array value names to display on thumb
***/
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
arrows: false,
arrowStep: 1,
2010-09-03 20:54:40 +00:00
arrowSymbols: ['previous', 'next'],
2010-09-03 08:47:40 +00:00
max: 100,
min: 0,
2010-09-03 20:54:40 +00:00
orientation: 'horizontal',
2010-09-03 08:47:40 +00:00
step: 1,
size: 128,
thumbSize: 16,
thumbValue: false,
trackColors: [],
trackImages: [],
trackStep: 0,
value: 0,
valueNames: null,
})
.options($.extend(options, {
arrowStep: options.arrowStep ?
options.arrowStep : options.step,
trackImages: $.makeArray(options.trackImages || [])
}))
2010-09-03 20:54:40 +00:00
.addClass('OxRange')
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
width: self.options.size + 'px'
2010-09-03 08:47:40 +00:00
});
$.extend(self, {
trackColors: self.options.trackColors.length,
trackImages: self.options.trackImages.length,
trackSize: self.options.size - self.options.arrows * 32,
values: (self.options.max - self.options.min + self.options.step) /
self.options.step
});
$.extend(self, {
thumbSize: Math.max(self.trackSize / self.values, self.options.thumbSize),
trackImageWidths: self.trackImages == 1 ? [self.trackSize - 16] :
Ox.divideInt(self.trackSize - 2, self.trackImages)
});
$.extend(self, {
trackColorsStart: self.thumbSize / 2 / self.options.size,
trackColorsStep: (self.options.size - self.thumbSize) / (self.trackColors - 1) / self.options.size
});
if (self.options.arrows) {
self.$arrows = [];
$.each(Ox.range(0, 2), function(i) {
self.$arrows[i] = Ox.Button({
2010-09-03 20:54:40 +00:00
overlap: i == 0 ? 'right' : 'left',
2010-09-03 08:47:40 +00:00
title: self.options.arrowSymbols[i],
2010-09-03 20:54:40 +00:00
type: 'image'
2010-09-03 08:47:40 +00:00
})
2010-09-03 20:54:40 +00:00
.addClass('OxArrow')
2010-09-03 08:47:40 +00:00
.mousedown(function(e) {
clickArrow(e, i);
})
.appendTo(that.$element);
});
}
2010-09-03 20:54:40 +00:00
self.$track = $('<div>')
.addClass('OxTrack')
2010-09-03 08:47:40 +00:00
.css($.extend({
2010-09-03 20:54:40 +00:00
width: (self.trackSize - 2) + 'px'
2010-09-03 08:47:40 +00:00
}, self.trackImages == 1 ? {
2010-09-03 20:54:40 +00:00
background: 'rgb(0, 0, 0)'
2010-09-03 08:47:40 +00:00
} : {}))
.mousedown(clickTrack)
.appendTo(that.$element);
self.trackColors && setTrackColors();
if (self.trackImages) {
2010-09-03 20:54:40 +00:00
self.$trackImages = $('<div>')
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
width: self.trackSize + 'px',
marginRight: (-self.trackSize - 1) + 'px'
2010-09-03 08:47:40 +00:00
})
.appendTo(self.$track);
$.each(self.options.trackImages, function(i, v) {
Ox.print(self.trackImageWidths[i])
2010-09-03 20:54:40 +00:00
$('<img>')
2010-09-03 08:47:40 +00:00
.attr({
src: v
})
2010-09-03 20:54:40 +00:00
.addClass(i == 0 ? 'OxFirstChild' : '')
.addClass(i == self.trackImages - 1 ? 'OxLastChild' : '')
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
width: self.trackImageWidths[i] + 'px'
2010-09-03 08:47:40 +00:00
})
.mousedown(function(e) {
e.preventDefault(); // prevent drag
})
.appendTo(self.$trackImages);
//left += self.trackImageWidths[i];
});
}
self.$thumb = Ox.Button({
2010-09-03 20:54:40 +00:00
id: self.options.id + 'Thumb',
2010-09-03 08:47:40 +00:00
title: self.options.thumbValue ? (self.options.valueNames ?
self.options.valueNames[self.options.value] :
2010-09-03 20:54:40 +00:00
self.options.value) : '',
2010-09-03 08:47:40 +00:00
width: self.thumbSize
})
2010-09-03 20:54:40 +00:00
.addClass('OxThumb')
2010-09-03 08:47:40 +00:00
/*
.css({
2010-09-03 20:54:40 +00:00
border: '1px solid rgb(255, 255, 255)',
background: 'rgba(0, 0, 0, 0)'
2010-09-03 08:47:40 +00:00
})
*/
.appendTo(self.$track);
setThumb();
function clickArrow(e, i) {
// fixme: shift doesn't work, see menu scrolling
var interval,
timeout = setTimeout(function() {
interval = setInterval(function() {
setValue(self.options.value + self.options.arrowStep * (i == 0 ? -1 : 1));
}, 50);
}, 500);
setValue(self.options.value + self.options.arrowStep * (i == 0 ? -1 : 1) * (e.shiftKey ? 2 : 1), true);
2010-09-03 20:54:40 +00:00
$window.one('mouseup', function() {
2010-09-03 08:47:40 +00:00
clearInterval(interval);
clearTimeout(timeout);
});
}
function clickTrack(e) {
//Ox.Focus.focus();
2010-09-03 20:54:40 +00:00
var isThumb = $(e.target).hasClass('OxThumb'),
2010-09-03 08:47:40 +00:00
left = self.$track.offset().left,
offset = isThumb ? e.clientX - self.$thumb.offset().left - 8 /*self.thumbSize / 2*/ : 0;
setValue(val(e), !isThumb);
$window.mousemove(function(e) {
setValue(val(e));
});
2010-09-03 20:54:40 +00:00
$window.one('mouseup', function() {
$window.unbind('mousemove');
2010-09-03 08:47:40 +00:00
});
function val(e) {
return getVal(e.clientX - left - offset);
}
}
function getPx(val) {
var pxPerVal = (self.trackSize - self.thumbSize) /
(self.options.max - self.options.min);
return Math.ceil((val - self.options.min) * pxPerVal);
}
/*
function getTime(oldValue, newValue) {
return self.animationTime * Math.abs(oldValue - newValue) / (self.options.max - self.options.min);
}
*/
function getVal(px) {
var px = self.trackSize / self.values >= 16 ? px : px - 8,
valPerPx = (self.options.max - self.options.min) /
(self.trackSize - self.thumbSize);
return Ox.limit(self.options.min +
Math.floor(px * valPerPx / self.options.step) * self.options.step,
self.options.min, self.options.max);
}
function setThumb(animate) {
self.$thumb.stop().animate({
2010-09-03 20:54:40 +00:00
marginLeft: (getPx(self.options.value) - 1) + 'px',
//width: self.thumbSize + 'px'
2010-09-03 08:47:40 +00:00
}, animate ? 200 : 0, function() {
if (self.options.thumbValue) {
self.$thumb.options({
title: self.options.valueNames ?
self.options.valueNames[self.options.value] :
self.options.value
});
}
});
}
function setTrackColors() {
self.$track.css({
backgroundImage: $.browser.mozilla ?
2010-09-03 20:54:40 +00:00
('-moz-linear-gradient(left, ' +
self.options.trackColors[0] + ' 0%, ' + $.map(self.options.trackColors, function(v, i) {
return v + ' ' + ((self.trackColorsStart + self.trackColorsStep * i) * 100) + '%';
}).join(', ') + ', ' + self.options.trackColors[self.trackColors - 1] + ' 100%)') :
('-webkit-gradient(linear, left top, right top, color-stop(0, ' +
self.options.trackColors[0] + '), ' + $.map(self.options.trackColors, function(v, i) {
return 'color-stop(' + (self.trackColorsStart + self.trackColorsStep * i) + ', ' + v + ')';
}).join(', ') + ', color-stop(1, ' + self.options.trackColors[self.trackColors - 1] + '))')
2010-09-03 08:47:40 +00:00
});
}
function setValue(value, animate) {
var value = Ox.limit(value, self.options.min, self.options.max);
if (value != self.options.value) {
//time = getTime(self.options.value, value);
self.options.value = value;
setThumb(animate);
2010-09-03 20:54:40 +00:00
that.triggerEvent('change', {
2010-09-03 08:47:40 +00:00
value: value
});
}
}
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'trackColors') {
2010-09-03 08:47:40 +00:00
setTrackColors();
2010-09-03 20:54:40 +00:00
} else if (key == 'value') {
2010-09-03 08:47:40 +00:00
setThumb();
}
}
return that;
};
Ox.Select = function(options, self) {
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self) // fixme: do we use 'div', or {}, or '', by default?
2010-09-03 08:47:40 +00:00
.defaults({
2010-09-03 20:54:40 +00:00
id: '',
2010-09-03 08:47:40 +00:00
items: [],
max: 1,
min: 1,
2010-09-03 20:54:40 +00:00
overlap: 'none', // can be none, left or right
2010-09-03 08:47:40 +00:00
selectable: true,
2010-09-03 20:54:40 +00:00
size: 'medium',
title: '',
type: 'text', // can be 'text' or 'image'
width: 'auto'
2010-09-03 08:47:40 +00:00
})
.options(options)
.addClass(
2010-09-03 20:54:40 +00:00
'OxSelect Ox' + Ox.toTitleCase(self.options.size) +
(self.options.overlap == 'none' ? '' : ' OxOverlap' +
2010-09-03 08:47:40 +00:00
Ox.toTitleCase(self.options.overlap))
)
2010-09-03 20:54:40 +00:00
.css(self.options.width == 'auto' ? {} : {
width: self.options.width + 'px'
2010-09-04 14:28:40 +00:00
})
.addEvent({
key_escape: loseFocus,
key_down: showMenu
2010-09-03 08:47:40 +00:00
});
$.extend(self, {
2010-09-03 20:54:40 +00:00
buttonId: self.options.id + 'Button',
groupId: self.options.id + 'Group',
menuId: self.options.id + 'Menu'
2010-09-03 08:47:40 +00:00
});
if (self.options.selectable) {
self.optionGroup = new Ox.OptionGroup(
self.options.items,
self.options.min,
self.options.max
);
self.options.items = self.optionGroup.init();
self.checked = self.optionGroup.checked();
}
2010-09-03 20:54:40 +00:00
if (self.options.type == 'text') {
self.$title = $('<div>')
.addClass('OxTitle')
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
width: (self.options.width - 22) + 'px'
2010-09-03 08:47:40 +00:00
})
.html(
self.options.title ? self.options.title :
self.options.items[self.checked[0]].title
)
2010-09-04 14:28:40 +00:00
.click(showMenu)
2010-09-03 08:47:40 +00:00
.appendTo(that.$element);
}
self.$button = new Ox.Button({
id: self.buttonId,
2010-09-03 20:54:40 +00:00
style: 'symbol',
title: 'select',
type: 'image'
2010-09-03 08:47:40 +00:00
})
2010-09-04 14:28:40 +00:00
.bindEvent('click', showMenu)
2010-09-03 08:47:40 +00:00
.appendTo(that);
self.$menu = new Ox.Menu({
element: self.$title || self.$button,
id: self.menuId,
items: [self.options.selectable ? {
group: self.groupId,
items: self.options.items,
max: self.options.max,
min: self.options.min
} : self.options.items],
2010-09-03 20:54:40 +00:00
side: 'bottom',
2010-09-03 08:47:40 +00:00
size: self.options.size
})
2010-09-03 20:54:40 +00:00
.bindEvent({
change: changeMenu,
click: clickMenu,
hide: hideMenu
});
2010-09-03 08:47:40 +00:00
function clickMenu(event, data) {
2010-09-03 20:54:40 +00:00
}
function changeMenu(event, data) {
Ox.print('clickMenu: ', self.options.id, data)
self.checked = self.optionGroup.checked();
2010-09-03 08:47:40 +00:00
self.$title && self.$title.html(
self.options.title ? self.options.title :
2010-09-03 20:54:40 +00:00
data.checked[0].title
2010-09-03 08:47:40 +00:00
);
2010-09-04 14:28:40 +00:00
that.triggerEvent('change', {
selected: data.checked
});
2010-09-03 08:47:40 +00:00
}
function hideMenu() {
2010-09-03 20:54:40 +00:00
that.removeClass('OxSelected');
self.$button.removeClass('OxSelected');
2010-09-03 08:47:40 +00:00
}
2010-09-04 14:28:40 +00:00
function loseFocus() {
that.loseFocus();
}
function showMenu() {
that.gainFocus();
that.addClass('OxSelected');
self.$menu.showMenu();
}
2010-09-03 08:47:40 +00:00
self.onChange = function(key, value) {
};
2010-09-03 20:54:40 +00:00
that.selected = function() {
return $.map(/*self.checked*/self.optionGroup.checked(), function(v, i) {
return {
id: self.options.items[i].id,
title: self.options.items[i].title
};
});
};
2010-09-03 08:47:40 +00:00
that.selectItem = function(id) {
2010-09-03 20:54:40 +00:00
Ox.print('selectItem', id, Ox.getObjectById(self.options.items, id).title)
self.options.type == 'text' && self.$title.html(
Ox.getObjectById(self.options.items, id).title[0] // fixme: title should not have become an array
2010-09-03 08:47:40 +00:00
);
self.$menu.checkItem(id);
2010-09-03 20:54:40 +00:00
self.checked = self.optionGroup.checked();
2010-09-03 08:47:40 +00:00
};
/*
that.width = function(val) {
// fixme: silly hack, and won't work for css() ... remove!
that.$element.width(val + 16);
that.$button.width(val);
//that.$symbol.width(val);
return that;
};
*/
return that;
}
Ox.FormElementGroup = function(options, self) {
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-09-03 08:47:40 +00:00
.defaults({
2010-09-03 20:54:40 +00:00
id: '',
2010-09-03 08:47:40 +00:00
elements: [],
2010-09-03 20:54:40 +00:00
float: 'left',
2010-09-03 08:47:40 +00:00
separators: [],
width: 0
})
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxInputGroup');
2010-09-03 08:47:40 +00:00
2010-09-03 20:54:40 +00:00
$.each(self.options.float == 'left' ? self.options.elements : self.options.elements.reverse(), function(i, $element) {
2010-09-03 08:47:40 +00:00
$element.options({
2010-09-03 20:54:40 +00:00
id: self.options.id + Ox.toTitleCase($element.options('id')),
2010-09-03 08:47:40 +00:00
parent: that
})
.css({
float: self.options.float // fixme: make this a class
})
.appendTo(that);
});
/*
if (self.options.width) {
setWidths();
} else {
self.options.width = getWidth();
}
that.css({
2010-09-03 20:54:40 +00:00
width: self.options.width + 'px'
2010-09-03 08:47:40 +00:00
});
*/
function getWidth() {
}
function setWidth() {
}
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'trackColors') {
2010-09-03 08:47:40 +00:00
}
}
return that;
}
Ox.Picker = function(options, self) {
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-09-03 08:47:40 +00:00
.defaults({
element: null,
elementHeight: 128,
elementWidth: 256,
2010-09-03 20:54:40 +00:00
id: '',
overlap: 'none'
2010-09-03 08:47:40 +00:00
})
.options(options || {});
self.$selectButton = new Ox.Button({
overlap: self.options.overlap,
2010-09-03 20:54:40 +00:00
title: 'select',
type: 'image'
2010-09-03 08:47:40 +00:00
})
.click(showMenu)
.appendTo(that);
2010-09-03 20:54:40 +00:00
self.$menu = new Ox.Element('div')
.addClass('OxPicker')
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
width: self.options.elementWidth + 'px',
height: (self.options.elementHeight + 24) + 'px'
2010-09-03 08:47:40 +00:00
});
self.options.element
.css({
2010-09-03 20:54:40 +00:00
width: self.options.elementWidth + 'px',
height: self.options.elementHeight + 'px'
2010-09-03 08:47:40 +00:00
})
.appendTo(self.$menu);
self.$bar = new Ox.Bar({
2010-09-03 20:54:40 +00:00
orientation: 'horizontal',
2010-09-03 08:47:40 +00:00
size: 24
})
.appendTo(self.$menu);
that.$label = new Ox.Label({
width: self.options.elementWidth - 60
})
.appendTo(self.$bar);
self.$doneButton = new Ox.Button({
2010-09-03 20:54:40 +00:00
title: 'Done',
2010-09-03 08:47:40 +00:00
width: 48
})
.click(hideMenu)
.appendTo(self.$bar);
2010-09-03 20:54:40 +00:00
self.$layer = $('<div>')
.addClass('OxLayer')
2010-09-03 08:47:40 +00:00
.click(hideMenu);
function hideMenu() {
self.$menu.detach();
self.$layer.detach();
self.$selectButton
2010-09-03 20:54:40 +00:00
.removeClass('OxSelected')
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
MozBorderRadius: '8px',
WebkitBorderRadius: '8px'
2010-09-03 08:47:40 +00:00
});
2010-09-03 20:54:40 +00:00
that.triggerEvent('hide');
2010-09-03 08:47:40 +00:00
};
function showMenu() {
var offset = that.offset(),
left = offset.left,
top = offset.top + 15;
self.$selectButton
2010-09-03 20:54:40 +00:00
.addClass('OxSelected')
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
MozBorderRadius: '8px 8px 0 0',
WebkitBorderRadius: '8px 8px 0 0'
2010-09-03 08:47:40 +00:00
});
self.$layer.appendTo($body);
self.$menu
.css({
2010-09-03 20:54:40 +00:00
left: left + 'px',
top: top + 'px'
2010-09-03 08:47:40 +00:00
})
.appendTo($body);
2010-09-03 20:54:40 +00:00
that.triggerEvent('show');
2010-09-03 08:47:40 +00:00
};
return that;
};
Ox.ColorPicker = function(options, self) {
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-09-03 08:47:40 +00:00
.defaults({
2010-09-03 20:54:40 +00:00
id: '',
value: '0, 0, 0'
2010-09-03 08:47:40 +00:00
})
.options(options || {});
Ox.print(self)
self.$ranges = [];
2010-09-03 20:54:40 +00:00
self.rgb = ['red', 'green', 'blue'];
self.values = self.options.value.split(', ');
2010-09-03 08:47:40 +00:00
$.each(Ox.range(3), function(i) {
self.$ranges[i] = new Ox.Range({
arrows: true,
id: self.options.id + Ox.toTitleCase(self.rgb[i]),
max: 255,
size: 328, // 256 + 16 + 40 + 16
thumbSize: 40,
thumbValue: true,
trackColors: getColors(i),
value: self.values[i]
})
.css({
2010-09-03 20:54:40 +00:00
position: 'absolute',
top: (i * 15) + 'px'
2010-09-03 08:47:40 +00:00
})
2010-09-03 20:54:40 +00:00
.bindEvent('change', function(event, data) {
2010-09-03 08:47:40 +00:00
change(i, data.value);
})
.appendTo(that);
// fixme: make self.$ranges[i].children() work
if (i == 0) {
2010-09-03 20:54:40 +00:00
self.$ranges[i].$element.children('input.OxOverlapRight').css({
2010-09-03 08:47:40 +00:00
MozBorderRadius: 0,
WebkitBorderRadius: 0
});
2010-09-03 20:54:40 +00:00
self.$ranges[i].$element.children('input.OxOverlapLeft').css({
MozBorderRadius: '0 8px 0 0',
WebkitBorderRadius: '0 8px 0 0'
2010-09-03 08:47:40 +00:00
});
} else {
2010-09-03 20:54:40 +00:00
self.$ranges[i].$element.children('input').css({
2010-09-03 08:47:40 +00:00
MozBorderRadius: 0,
WebkitBorderRadius: 0
});
}
});
that = new Ox.Picker({
element: that,
elementHeight: 46,
elementWidth: 328,
id: self.options.id
});
function change(index, value) {
self.values[index] = value;
2010-09-03 20:54:40 +00:00
self.options.value = self.values.join(', ');
2010-09-03 08:47:40 +00:00
that.$label.css({
2010-09-03 20:54:40 +00:00
background: 'rgb(' + self.options.value + ')'
2010-09-03 08:47:40 +00:00
});
$.each(Ox.range(3), function(i) {
if (i != index) {
self.$ranges[i].options({
trackColors: getColors(i)
});
}
});
2010-09-03 20:54:40 +00:00
that.triggerEvent('change', {
2010-09-03 08:47:40 +00:00
value: self.options.value
});
}
function getColors(index) {
return [
2010-09-03 20:54:40 +00:00
'rgb(' + $.map(Ox.range(3), function(v) {
2010-09-03 08:47:40 +00:00
return v == index ? 0 : self.values[v];
2010-09-03 20:54:40 +00:00
}).join(', ') + ')',
'rgb(' + $.map(Ox.range(3), function(v) {
2010-09-03 08:47:40 +00:00
return v == index ? 255 : self.values[v];
2010-09-03 20:54:40 +00:00
}).join(', ') + ')'
2010-09-03 08:47:40 +00:00
]
}
return that;
};
Ox.PlacePicker = function(options, self) {
var self = $.extend(self || {}, {
options: $.extend({
2010-09-03 20:54:40 +00:00
id: '',
value: 'United States'
2010-09-03 08:47:40 +00:00
}, options)
}),
that;
2010-09-03 20:54:40 +00:00
self.$element = new Ox.Element('div')
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
width: '256px',
height: '192px'
2010-09-03 08:47:40 +00:00
})
.append(
self.$topBar = new Ox.Bar({
size: 16
})
.css({
2010-09-03 20:54:40 +00:00
MozBorderRadius: '0 8px 0 0',
WebkitBorderRadius: '0 8px 0 0'
2010-09-03 08:47:40 +00:00
})
.append(
self.$input = new Ox.Input({
clear: true,
2010-09-03 20:54:40 +00:00
id: self.options.id + 'Input',
placeholder: 'Find',
2010-09-03 08:47:40 +00:00
width: 256
})
2010-09-03 20:54:40 +00:00
.bindEvent('submit', findPlace)
2010-09-03 08:47:40 +00:00
)
)
.append(
2010-09-03 20:54:40 +00:00
self.$container = new Ox.Element('div')
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
width: '256px',
height: '160px'
2010-09-03 08:47:40 +00:00
})
)
.append(
self.$bottomBar = new Ox.Bar({
size: 16
})
.append(
self.$range = new Ox.Range({
arrows: true,
2010-09-03 20:54:40 +00:00
id: self.options.id + 'Range',
2010-09-03 08:47:40 +00:00
max: 22,
size: 256,
thumbSize: 32,
thumbValue: true
})
2010-09-03 20:54:40 +00:00
.bindEvent('change', changeZoom)
2010-09-03 08:47:40 +00:00
)
);
2010-09-03 20:54:40 +00:00
self.$input.$element.children('input[type=text]').css({
width: '230px',
paddingLeft: '2px',
MozBorderRadius: '0 8px 8px 0',
WebkitBorderRadius: '0 8px 8px 0'
2010-09-03 08:47:40 +00:00
});
2010-09-03 20:54:40 +00:00
self.$input.$element.children('input[type=image]').css({
MozBorderRadius: '0 8px 0 0',
WebkitBorderRadius: '0 8px 0 0'
2010-09-03 08:47:40 +00:00
});
2010-09-03 20:54:40 +00:00
self.$range.$element.children('input').css({
2010-09-03 08:47:40 +00:00
MozBorderRadius: 0,
WebkitBorderRadius: 0
});
that = new Ox.Picker({
element: self.$element,
elementHeight: 192,
elementWidth: 256,
id: self.options.id,
overlap: self.options.overlap,
value: self.options.value
}, self)
2010-09-03 20:54:40 +00:00
.bindEvent('show', showPicker);
2010-09-03 08:47:40 +00:00
2010-09-03 20:54:40 +00:00
that.$label.bind('click', clickLabel)
2010-09-03 08:47:40 +00:00
self.map = false;
function changeZoom(event, data) {
2010-09-03 20:54:40 +00:00
Ox.print('changeZoom')
2010-09-03 08:47:40 +00:00
self.$map.zoom(data.value);
}
function clickLabel() {
var name = that.$label.html();
if (name) {
self.$input.options({
value: name
})
2010-09-03 20:54:40 +00:00
.triggerEvent('submit', {
2010-09-03 08:47:40 +00:00
value: name
});
}
}
function findPlace(event, data) {
2010-09-03 20:54:40 +00:00
Ox.print('findPlace', data);
2010-09-03 08:47:40 +00:00
self.$map.find(data.value, function(location) {
if (location) {
that.$label.html(location.name.formatted);
}
})
}
function onSelect(event, data) {
that.$label.html(data.name.formatted);
}
function onZoom(event, data) {
self.$range.options({
value: data.value
});
}
function showPicker() {
if (!self.map) {
self.$map = new Ox.Map({
2010-09-03 20:54:40 +00:00
id: self.options.id + 'Map',
2010-09-03 08:47:40 +00:00
places: [self.options.value]
})
.css({
2010-09-03 20:54:40 +00:00
width: '256px',
height: '160px'
2010-09-03 08:47:40 +00:00
})
.bindEvent({
select: onSelect,
zoom: onZoom
})
.appendTo(self.$container);
self.map = true;
}
}
return that;
};
/*
----------------------------------------------------------------------------
delete below
----------------------------------------------------------------------------
*/
Ox.Input_ = function(options, self) {
/*
options:
clear boolean, clear button, or not
disabled boolean, disabled, or not
2010-09-03 20:54:40 +00:00
height height (px), if type is 'textarea'
2010-09-03 08:47:40 +00:00
id
label string, or
array [{ id, title, checked }] (selectable label) or
array [{ id, label: [{ id, title, checked }], width }] (multiple selectable labels)
label and placeholder are mutually exclusive
labelWidth integer (px)
placeholder string, or
array [{ id, title, checked }] (selectable placeholder)
label and placeholder are mutually exclusive
separator string, or
array of strings
to separate multiple values
separatorWidth integer (px), or
array of integers
serialize function
2010-09-03 20:54:40 +00:00
size 'large', 'medium' or 'small'
type 'password', 'select' or 'text'
2010-09-03 08:47:40 +00:00
unit string, or
array [{ id, title, checked }] (selectable unit)
unitWidth integer (px)
value string, or
array [{ id, value, width }] (multiple values)
width integer (px)
methods:
events:
*/
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-09-03 08:47:40 +00:00
.defaults({
autocomplete: null,
autocorrect: null,
autosuggest: null,
autosuggestHighlight: false,
autosuggestSubmit: false,
autovalidate: null,
2010-09-03 20:54:40 +00:00
autovalidateName: 'Value',
2010-09-03 08:47:40 +00:00
clear: false,
disabled: false,
height: 128,
2010-09-03 20:54:40 +00:00
id: '',
key: '',
label: '',
2010-09-03 08:47:40 +00:00
labelWidth: 64,
2010-09-03 20:54:40 +00:00
placeholder: '',
separator: '',
2010-09-03 08:47:40 +00:00
separatorWidth: 16,
serialize: null,
2010-09-03 20:54:40 +00:00
size: 'medium',
type: 'text',
unit: '',
2010-09-03 08:47:40 +00:00
unitWidth: 64,
2010-09-03 20:54:40 +00:00
value: '',
2010-09-03 08:47:40 +00:00
width: 128
})
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxInput Ox' + Ox.toTitleCase(self.options.size))
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
width: self.options.width + 'px'
2010-09-03 08:47:40 +00:00
});
$.extend(self, {
clearWidth: 16,
2010-09-03 20:54:40 +00:00
hasMultipleKeys: Ox.isArray(self.options.label) && 'label' in self.options.label[0],
2010-09-03 08:47:40 +00:00
hasMultipleValues: Ox.isArray(self.options.value) &&
2010-09-03 20:54:40 +00:00
(self.options.type != 'select' || 'items' in self.options.value[0]),
2010-09-03 08:47:40 +00:00
hasSelectableKeys: Ox.isArray(self.options.label) || Ox.isArray(self.options.placeholder),
hasSelectableUnits: Ox.isArray(self.options.unit),
2010-09-03 20:54:40 +00:00
keyName: self.options.label ? 'label' : (self.options.placeholder ? 'placeholder' : ''),
2010-09-03 08:47:40 +00:00
placeholderWidth: 16,
selectedKey: [0], // fixme: only set on demand?
selectedValue: 0,
selectedUnit: 0,
/* valid: autovalidateCall(true) */
});
2010-09-03 20:54:40 +00:00
$.each(['autocomplete', 'autocorrect', 'autosuggest', 'autovalidate'], function(i, v) {
2010-09-03 08:47:40 +00:00
//if (!Ox.isFunction(self.options[v])) {
self.options[v] = {
2010-09-03 20:54:40 +00:00
'': self.options[v]
2010-09-03 08:47:40 +00:00
};
//}
});
if (self.keyName && !self.hasMultipleKeys) {
self.options[self.keyName] = [$.extend({
2010-09-03 20:54:40 +00:00
id: '',
2010-09-03 08:47:40 +00:00
label: self.options[self.keyName],
2010-09-03 20:54:40 +00:00
}, self.keyName == 'label' ? {
id: '',
2010-09-03 08:47:40 +00:00
width: self.options.labelWidth
} : {})];
if (!self.hasSelectableKeys) {
self.options[self.keyName][0].label = [{
2010-09-03 20:54:40 +00:00
id: '',
2010-09-03 08:47:40 +00:00
title: self.options[self.keyName][0].label
}];
}
}
if (self.hasSelectableKeys) {
$.each(self.options[self.keyName], function(keyPos, key) {
if (key.width) {
self.options.labelWidth = (keyPos == 0 ? 0 : self.options.labelWidth) + key.width;
}
self.selectedKey[keyPos] = 0;
$.each(key, function(valuePos, value) {
if (value.checked) {
self.selectedKey[keyPos] = valuePos;
return false;
}
});
});
}
self.valueWidth = self.options.width -
(self.options.label ? self.options.labelWidth : 0) -
((self.options.placeholder && self.options.placeholder[0].label.length > 1) ? self.placeholderWidth : 0) -
(self.options.unit ? self.options.unitWidth : 0) -
(self.options.clear ? self.clearWidth : 0);
/*
if (self.hasMultipleValues) {
self.valueWidth -= Ox.isArray(self.options.separatorWidth) ?
Ox.sum(self.options.separatorWidth) :
(self.options.value.length - 1) * self.options.separatorWidth;
}
*/
2010-09-03 20:54:40 +00:00
Ox.print('self.hasMulVal', self.hasMultipleValues);
Ox.print('self.options.value', self.options.value)
2010-09-03 08:47:40 +00:00
if (!self.hasMultipleValues) {
2010-09-03 20:54:40 +00:00
if (self.options.type == 'select') {
2010-09-03 08:47:40 +00:00
self.options.value = [{
2010-09-03 20:54:40 +00:00
id: '',
2010-09-03 08:47:40 +00:00
items: self.options.value,
width: self.valueWidth
}];
2010-09-03 20:54:40 +00:00
} else if (self.options.type == 'range') {
2010-09-03 08:47:40 +00:00
self.options.value = [$.extend({
2010-09-03 20:54:40 +00:00
id: '',
2010-09-03 08:47:40 +00:00
size: self.valueWidth
}, self.options.value)];
2010-02-19 10:24:02 +00:00
} else {
2010-09-03 08:47:40 +00:00
self.options.value = [{
2010-09-03 20:54:40 +00:00
id: '',
2010-09-03 08:47:40 +00:00
value: self.options.value,
width: self.valueWidth
}]
}
}
2010-09-03 20:54:40 +00:00
Ox.print('self.options.value', self.options.value)
2010-09-03 08:47:40 +00:00
self.values = self.options.value.length;
2010-09-03 20:54:40 +00:00
Ox.print(self.options.id, 'self.values', self.values)
2010-09-03 08:47:40 +00:00
if (Ox.isString(self.options.separator)) {
self.options.separator = $.map(new Array(self.values - 1), function(v, i) {
return self.options.separator;
});
}
if (Ox.isNumber(self.options.separatorWidth)) {
self.options.separatorWidth = $.map(new Array(self.values - 1), function(v, i) {
return self.options.separatorWidth;
});
}
if (self.options.unit) {
if (self.hasSelectableUnits) {
$.each(self.options.unit, function(pos, unit) {
if (unit.checked) {
self.selectedUnit = pos;
return false;
2010-02-19 10:24:02 +00:00
}
});
2010-09-03 08:47:40 +00:00
} else {
self.options.unit = [{
2010-09-03 20:54:40 +00:00
id: '',
2010-09-03 08:47:40 +00:00
title: self.options.unit
}];
2010-02-19 10:24:02 +00:00
}
2010-02-20 11:05:58 +00:00
}
2010-09-03 20:54:40 +00:00
Ox.print('self', self);
2010-09-03 08:47:40 +00:00
if (self.keyName) {
that.$key = [];
$.each(self.options[self.keyName], function(keyPos, key) {
2010-09-03 20:54:40 +00:00
Ox.print('keyPos key', keyPos, key)
if (self.keyName == 'label' && key.label.length == 1) {
2010-09-03 08:47:40 +00:00
that.$key[keyPos] = new Ox.Label({
2010-09-03 20:54:40 +00:00
overlap: 'right',
2010-09-03 08:47:40 +00:00
title: key.label[0].title,
width: self.options.labelWidth
})
.css({
2010-09-03 20:54:40 +00:00
float: 'left'
2010-09-03 08:47:40 +00:00
})
.click(function() {
that.$input[0].focus();
})
.appendTo(that);
} else if (key.label.length > 1) {
2010-09-03 20:54:40 +00:00
Ox.print('key.length > 1')
2010-09-03 08:47:40 +00:00
self.selectKeyId = self.options.id + Ox.toTitleCase(self.keyName) +
2010-09-03 20:54:40 +00:00
(self.options[self.keyName].length == 1 ? '' : keyPos);
Ox.print('three', self.selectedKey, keyPos, self.selectedKey[keyPos]);
2010-09-03 08:47:40 +00:00
that.$key[keyPos] = new Ox.Select({
id: self.selectKeyId,
items: $.map(key.label, function(value, valuePos) {
return {
checked: valuePos == self.selectedKey[keyPos],
id: value.id,
group: self.selectKeyId, // fixme: same id, works here, but should be different
title: value.title
};
}),
2010-09-03 20:54:40 +00:00
overlap: 'right',
type: self.options.label ? 'text' : 'image',
2010-09-03 08:47:40 +00:00
width: self.options.label ? (self.options.label.length == 1 ? self.options.labelWidth : key.width) : self.placeholderWidth
})
.css({
2010-09-03 20:54:40 +00:00
float: 'left'
2010-09-03 08:47:40 +00:00
})
.appendTo(that);
2010-09-03 20:54:40 +00:00
that.bindEvent('change_' + self.selectKeyId, changeKey);
2010-09-03 08:47:40 +00:00
}
});
}
if (self.options.clear) {
that.$clear = new Ox.Button({
2010-09-03 20:54:40 +00:00
overlap: 'left',
type: 'image',
value: 'clear'
2010-09-03 08:47:40 +00:00
})
.css({
2010-09-03 20:54:40 +00:00
float: 'right'
2010-09-03 08:47:40 +00:00
})
.click(clear)
.appendTo(that);
}
if (self.options.unit.length == 1) {
that.$unit = new Ox.Label({
2010-09-03 20:54:40 +00:00
overlap: 'left',
2010-09-03 08:47:40 +00:00
title: self.options.unit[0].title,
width: self.options.unitWidth
})
.css({
2010-09-03 20:54:40 +00:00
float: 'right'
2010-09-03 08:47:40 +00:00
})
.click(function() {
that.$input[0].focus();
})
.appendTo(that);
} else if (self.options.unit.length > 1) {
2010-09-03 20:54:40 +00:00
self.selectUnitId = self.options.id + 'Unit';
2010-09-03 08:47:40 +00:00
that.$unit = new Ox.Select({
id: self.selectUnitId,
items: $.map(self.options.unit, function(unit, i) {
2010-09-03 20:54:40 +00:00
Ox.print('unit', unit)
2010-09-03 08:47:40 +00:00
return {
checked: i == 0,
id: unit.id,
group: self.selectUnitId, // fixme: same id, works here, but should be different
title: unit.title
};
}),
2010-09-03 20:54:40 +00:00
overlap: 'left',
2010-09-03 08:47:40 +00:00
size: self.options.size,
width: self.options.unitWidth
})
.css({
2010-09-03 20:54:40 +00:00
float: 'right'
2010-09-03 08:47:40 +00:00
})
.appendTo(that);
}
if (self.values) {
that.$separator = [];
$.each(self.options.value, function(i, v) {
if (i < self.values - 1) {
that.$separator[i] = new Ox.Label({
2010-09-03 20:54:40 +00:00
textAlign: 'center',
2010-09-03 08:47:40 +00:00
title: self.options.separator[i],
width: self.options.separatorWidth[i] + 32
})
.css({
2010-09-03 20:54:40 +00:00
float: 'left',
marginLeft: (v.width - (i == 0 ? 16 : 32)) + 'px'
2010-09-03 08:47:40 +00:00
})
.click(function() {
that.$input[0].focus();
})
.appendTo(that);
}
});
}
that.$input = [];
//self.margin = 0;
$.each(self.options.value, function(i, v) {
2010-09-03 20:54:40 +00:00
Ox.print('o k i', self.options, self.keyName, i);
2010-09-03 08:47:40 +00:00
var id = self.keyName ? $.map(self.selectedKey, function(v, i) {
return self.options[self.keyName][i].id;
2010-09-03 20:54:40 +00:00
}).join('.') : '';
2010-09-03 08:47:40 +00:00
//self.margin -= (i == 0 ? 16 : self.options.value[i - 1].width)
2010-09-03 20:54:40 +00:00
Ox.print('v:', v, 'id:', id)
if (self.options.type == 'select') {
2010-09-03 08:47:40 +00:00
that.$input[i] = new Ox.Select({
id: v.id,
items: v.items,
width: v.width
}).
css({
2010-09-03 20:54:40 +00:00
float: 'left'
2010-09-03 08:47:40 +00:00
});
2010-09-03 20:54:40 +00:00
} else if (self.options.type == 'range') {
2010-09-03 08:47:40 +00:00
that.$input[i] = new Ox.Range(v)
.css({
2010-09-03 20:54:40 +00:00
float: 'left'
2010-09-03 08:47:40 +00:00
});
} else {
that.$input[i] = new Ox.InputElement({
autocomplete: self.options.autocomplete[id],
autocorrect: self.options.autocorrect[id],
autosuggest: self.options.autosuggest[id],
autosuggestHighlight: self.options.autosuggestHighlight,
autosuggestSubmit: self.options.autosuggestSubmit,
autovalidate: self.options.autovalidate[id],
autovalidateName: self.options.autovalidateName,
disabled: self.options.disabled,
height: self.options.height,
2010-09-03 20:54:40 +00:00
id: self.options.id + 'Input' + Ox.toTitleCase(v.id),
key: self.hasSelectableKeys ? self.options[self.keyName][0].label[self.selectedKey[0]].id : '',
2010-09-03 08:47:40 +00:00
parent: that,
2010-09-03 20:54:40 +00:00
placeholder: self.options.placeholder ? self.options.placeholder[0].label[0].title : '',
2010-09-03 08:47:40 +00:00
size: self.options.size,
type: self.options.type,
value: v.value,
width: v.width
});
}
that.$input[i]
.css($.extend({}, self.options.value.length > 1 ? {
2010-09-03 20:54:40 +00:00
float: 'left',
2010-09-03 08:47:40 +00:00
marginLeft: -Ox.sum($.map(self.options.value, function(v_, i_) {
return i_ > i ? self.options.value[i_ - 1].width + self.options.separatorWidth[i_ - 1] : (i_ == i ? 16 : 0);
}))
} : {}))
.appendTo(that);
});
//width(self.options.width);
function changeKey(event, data) {
2010-09-03 20:54:40 +00:00
Ox.print('changeKey', data);
2010-09-03 08:47:40 +00:00
if (data) { // fixme: necessary?
self.key = {
id: data.id,
title: data.value // fixme: should be data.title
};
that.$input[0].options({
key: data.id
});
}
if (self.options.label) {
//that.$label.html(self.option.title);
that.$input[0].focus();
//autocompleteCall();
} else {
that.$input[0].options({
placeholder: data.value // fixme: should be data.title
});
/*
2010-09-03 20:54:40 +00:00
if (that.$input.hasClass('OxPlaceholder')) {
2010-09-03 08:47:40 +00:00
that.$input.val(self.key.title);
//that.$input.focus();
2010-07-02 12:33:45 +00:00
} else {
2010-09-03 08:47:40 +00:00
that.$input.focus();
self.options.autosuggest && autosuggestCall();
2010-07-02 12:33:45 +00:00
}
2010-09-03 08:47:40 +00:00
*/
}
}
function changeUnit() {
that.$input[0].focus();
}
function clear() {
$.each(that.$input, function(i, v) {
2010-09-03 20:54:40 +00:00
v.val('');
2010-09-03 08:47:40 +00:00
});
that.$input[0].focus();
}
function height(value) {
var stop = 8 / value;
2010-09-03 20:54:40 +00:00
if (self.options.type == 'textarea') {
2010-09-03 08:47:40 +00:00
that.$element
.height(value)
.css({
2010-09-03 20:54:40 +00:00
background: '-moz-linear-gradient(top, rgb(224, 224, 224), rgb(208, 208, 208) ' + (stop * 100) + '%, rgb(208, 208, 208) ' + (100 - stop * 100) + '%, rgb(192, 192, 192))'
2010-09-03 08:47:40 +00:00
})
.css({
2010-09-03 20:54:40 +00:00
background: '-webkit-gradient(linear, left top, left bottom, from(rgb(224, 224, 224)), color-stop(' + stop + ', rgb(208, 208, 208)), color-stop(' + (1 - stop) + ', rgb(208, 208, 208)), to(rgb(192, 192, 192)))'
2010-09-03 08:47:40 +00:00
});
that.$input
.height(value)
.css({
2010-09-03 20:54:40 +00:00
background: '-moz-linear-gradient(top, rgb(224, 224, 224), rgb(240, 240, 240) ' + (stop * 100) + '%, rgb(240, 240, 240) ' + (100 - stop * 100) + '%, rgb(255, 255, 255))'
2010-09-03 08:47:40 +00:00
})
.css({
2010-09-03 20:54:40 +00:00
background: '-webkit-gradient(linear, left top, left bottom, from(rgb(224, 224, 224)), color-stop(' + stop + ', rgb(240, 240, 240)), color-stop(' + (1 - stop) + ', rgb(240, 240, 240)), to(rgb(255, 255, 255)))'
2010-09-03 08:47:40 +00:00
});
}
}
function selectUnit() {
self.$selectUnitMenu.show();
}
function submit() {
2010-09-03 20:54:40 +00:00
Ox.print('submit')
2010-09-03 08:47:40 +00:00
var value = that.$input.val();
that.$input.blur();
2010-09-03 20:54:40 +00:00
that.triggerEvent('submit', self.options.key ? {
2010-09-03 08:47:40 +00:00
key: self.options.key,
value: value
} : value);
}
function width(value) {
that.$element.width(value);
that.$input.width(
2010-09-03 20:54:40 +00:00
value - (self.options.type == 'textarea' ? 0 : 12) -
2010-09-03 08:47:40 +00:00
(self.options.label ? self.options.labelWidth : 0) -
(self.options.placeholder.length > 1 ? 16 : 0) -
(self.options.unit ? self.options.unitWidth : 0) -
(self.options.clear ? 16 : 0)
);
}
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'height') {
2010-09-03 08:47:40 +00:00
height(value);
2010-09-03 20:54:40 +00:00
} else if (key == 'width') {
2010-09-03 08:47:40 +00:00
width(value);
}
};
that.changeLabel = function(id) {
that.$key.html(Ox.getObjectById(self.options.label, id).title);
self.selectMenu.checkItem(id);
};
return that;
}
Ox.InputElement_ = function(options, self) {
var self = self || {},
that = new Ox.Element(
2010-09-03 20:54:40 +00:00
options.type == 'textarea' ? 'textarea' : 'input', self
2010-09-03 08:47:40 +00:00
)
.defaults({
autocomplete: null,
autocorrect: null,
autosuggest: null,
autosuggestHighlight: false,
autosuggestSubmit: false,
autovalidate: null,
disabled: false,
height: 128,
2010-09-03 20:54:40 +00:00
id: '',
key: '',
2010-09-03 08:47:40 +00:00
parent: null,
2010-09-03 20:54:40 +00:00
placeholder: '',
size: 'medium',
type: 'text',
value: '',
2010-09-03 08:47:40 +00:00
width: 128
})
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxInput Ox' + Ox.toTitleCase(self.options.size) + (
(self.options.placeholder && self.options.value === '') ?
' OxPlaceholder' : ''
2010-09-03 08:47:40 +00:00
))
2010-09-03 20:54:40 +00:00
.attr(self.options.type == 'textarea' ? {} : {
2010-09-03 08:47:40 +00:00
type: self.options.type
})
.css({
2010-09-03 20:54:40 +00:00
float: 'left',
width: (self.options.width - 14) + 'px'
2010-09-03 08:47:40 +00:00
})
.val(
2010-09-03 20:54:40 +00:00
(self.options.placeholder && self.options.value === '') ?
2010-09-03 08:47:40 +00:00
self.options.placeholder : self.options.value
)
.blur(blur)
.change(change)
.focus(focus);
2010-09-03 20:54:40 +00:00
Ox.print('InputElement self.options', self.options)
2010-09-03 08:47:40 +00:00
self.bindKeyboard = self.options.autocomplete || self.options.autocorrect ||
self.options.autosuggest || self.options.autovalidate;
if (self.options.autosuggest) {
2010-09-03 20:54:40 +00:00
self.autosuggestId = self.options.id + 'Menu'; // fixme: we do this in other places ... are we doing it the same way? var name?
2010-09-03 08:47:40 +00:00
self.$autosuggestMenu = new Ox.Menu({
element: that.$element,
id: self.autosuggestId,
offset: {
left: 4,
top: 0
},
size: self.options.size
});
2010-09-03 20:54:40 +00:00
that.bindEvent('click_' + self.autosuggestId, clickMenu);
2010-09-03 08:47:40 +00:00
}
2010-09-03 20:54:40 +00:00
that.bindEvent($.extend(self.options.type == 'textarea' ? {} : {
2010-09-03 08:47:40 +00:00
key_enter: submit
}, {
key_escape: cancel
}));
function autocomplete(value) {
var value = value.toLowerCase(),
2010-09-03 20:54:40 +00:00
ret = '';
if (value !== '') {
2010-09-03 08:47:40 +00:00
$.each(self.options.autocomplete, function(i, v) {
if (v.toLowerCase().indexOf(value) == 0) {
ret = v;
return false;
}
});
}
return ret;
}
function autocompleteCall() {
var value = that.$element.val();
Ox.isFunction(self.options.autocomplete) ?
self.options.autocomplete(self.options.key ? {
key: self.options.key,
value: value
} : value, autocompleteCallback) :
autocompleteCallback(autocomplete(value));
}
function autocompleteCallback(value) {
var pos = cursor()[0];
if (value) {
that.$element.val(value);
cursor(pos, value.length);
2010-02-19 10:24:02 +00:00
}
2010-02-18 07:27:32 +00:00
}
2010-02-19 10:24:02 +00:00
2010-09-03 08:47:40 +00:00
function autocorrect(value) {
var length = value.length;
2010-09-03 20:54:40 +00:00
return $.map(value.toLowerCase().split(''), function(v, i) {
2010-09-03 08:47:40 +00:00
if (new RegExp(self.options.autocorrect)(v)) {
return v
} else {
return null;
}
2010-09-03 20:54:40 +00:00
}).join('');
2010-09-03 08:47:40 +00:00
}
function autocorrectCall(blur) {
var blur = blur || false,
value = that.$element.val(),
pos = cursor()[0];
Ox.isFunction(self.options.autocorrect) ?
self.options.autocorrect(value, blur, autocorrectCallback) :
autocorrectCallback(autocorrect(value), blue);
}
function autocorrectCallback(value, blur) {
var length = that.$element.val().length;
that.$element.val(self.options.value);
!blur && cursor(pos + value.length - length);
}
function autosuggest(value) {
var value = value.toLowerCase(),
values = [[], []];
2010-09-03 20:54:40 +00:00
if (value !== '') {
2010-09-03 08:47:40 +00:00
$.each(self.options.key ? self.options.autosuggest[self.options.key] : self.options.autosuggest, function(i, v) {
2010-09-03 20:54:40 +00:00
//Ox.print('v...', v)
2010-09-03 08:47:40 +00:00
var index = v.toLowerCase().indexOf(value);
index > -1 && values[index == 0 ? 0 : 1].push(v);
});
}
return $.merge(values[0], values[1]);
}
function autosuggestCall() {
var value = that.$element.val();
Ox.isFunction(self.options.autosuggest) ?
self.options.autosuggest(self.options.key ? {
key: self.options.key,
value: value
} : value, autosuggestCallback) :
autosuggestCallback(autosuggest(value));
}
function autosuggestCallback(values) {
var values = values || [],
selected = values.length == 1 ? 0 : -1,
value = that.$element.val().toLowerCase();
2010-09-03 20:54:40 +00:00
//Ox.print('values', values);
2010-09-03 08:47:40 +00:00
if (values.length) {
values = $.map(values, function(v, i) {
if (value == v.toLowerCase()) {
selected = i;
2010-02-18 15:11:14 +00:00
}
2010-02-18 07:56:37 +00:00
return {
2010-09-03 20:54:40 +00:00
id: v.toLowerCase().replace(/ /g, '_'), // fixme: need function to do lowercase, underscores etc?
2010-09-03 08:47:40 +00:00
title: self.options.autosuggestHighlight ? v.replace(
2010-09-03 20:54:40 +00:00
new RegExp('(' + value + ')', 'ig'),
'<span class="OxHighlight">$1</span>'
2010-09-03 08:47:40 +00:00
) : v
2010-02-18 09:11:47 +00:00
};
2010-02-18 07:56:37 +00:00
});
2010-09-03 08:47:40 +00:00
// self.selectMenu && self.selectMenu.hideMenu(); // fixme: need event
self.$autosuggestMenu.options({
items: values,
2010-02-18 15:11:14 +00:00
selected: selected
2010-02-18 07:56:37 +00:00
}).showMenu();
} else {
2010-09-03 08:47:40 +00:00
self.$autosuggestMenu.hideMenu();
2010-02-18 07:56:37 +00:00
}
2010-02-10 15:49:33 +00:00
}
2010-02-19 10:24:02 +00:00
2010-09-03 08:47:40 +00:00
function autovalidate(value) {
return {
valid: self.options.autovalidate(value) != null,
2010-09-03 20:54:40 +00:00
message: 'Invalid ' + self.options.name
2010-09-03 08:47:40 +00:00
};
}
function autovalidateCall(blur) {
2010-07-24 01:32:08 +00:00
var blur = blur || false,
2010-09-03 08:47:40 +00:00
value = that.$element.val();
2010-09-03 20:54:40 +00:00
if (value !== '') {
2010-09-03 08:47:40 +00:00
Ox.isFunction(self.options.autovalidate) ?
self.options.autovalidate(value, autovalidateCallback) :
autovalidateCallback(autovalidate(value), blur);
} else {
autovalidateCallback({
blur: blur,
valid: false,
2010-09-03 20:54:40 +00:00
message: 'Empty ' + self.options.name
2010-09-03 08:47:40 +00:00
});
}
}
function autovalidateCallback(data, blur) {
if (data.valid != self.valid) {
self.valid = data.valid;
2010-09-03 20:54:40 +00:00
that.triggerEvent('validate', $.extend(data, {
2010-09-03 08:47:40 +00:00
blur: blur
}));
2010-07-24 01:32:08 +00:00
}
}
function blur() {
2010-09-03 20:54:40 +00:00
if (!self.options.autosuggest || self.$autosuggestMenu.is(':hidden')) {
Ox.print('losing focus...')
2010-09-03 08:47:40 +00:00
that.loseFocus();
2010-09-03 20:54:40 +00:00
self.options.parent.removeClass('OxFocus');
2010-09-03 08:47:40 +00:00
self.options.autocorrect && autocorrectCall(true);
// self.options.autosuggest && self.$autosuggestMenu.hideMenu();
self.options.autovalidate && autovalidateCall(true);
2010-09-03 20:54:40 +00:00
if (self.options.placeholder && that.$element.val() === '') {
that.$element.addClass('OxPlaceholder').val(self.options.placeholder);
2010-09-03 08:47:40 +00:00
}
2010-07-24 01:32:08 +00:00
}
2010-09-03 08:47:40 +00:00
if (self.bindKeyboard) {
2010-09-03 20:54:40 +00:00
$document.unbind('keydown', keypress);
$document.unbind('keypress', keypress);
2010-07-24 01:32:08 +00:00
}
}
2010-02-19 10:24:02 +00:00
function cancel() {
2010-09-03 08:47:40 +00:00
that.$element.blur();
2010-02-19 10:24:02 +00:00
}
2010-09-03 08:47:40 +00:00
function change() {
2010-02-19 10:24:02 +00:00
}
2010-02-20 11:05:58 +00:00
function clear() {
2010-09-03 20:54:40 +00:00
that.$element.val('').focus();
2010-07-24 01:32:08 +00:00
}
2010-09-03 08:47:40 +00:00
function clickMenu(event, data) {
2010-09-03 20:54:40 +00:00
Ox.print('clickMenu', data);
2010-09-03 08:47:40 +00:00
that.$element.val(data.title);
//self.$autosuggestMenu.hideMenu();
self.options.autosuggestSubmit && submit();
}
function cursor(start, end) {
/*
cursor() returns [start, end]
cursor(start) sets start
cursor([start, end]) sets start and end
cursor(start, end) sets start and end
*/
var isArray = Ox.isArray(start);
2010-07-24 01:32:08 +00:00
if (arguments.length == 0) {
2010-09-03 08:47:40 +00:00
return [that.$element[0].selectionStart, that.$element[0].selectionEnd];
2010-07-24 01:32:08 +00:00
} else {
2010-09-03 08:47:40 +00:00
start = isArray ? start[0] : start;
end = isArray ? start[1] : (end ? end : start);
that.$element[0].setSelectionRange(start, end);
2010-07-24 01:32:08 +00:00
}
2010-01-07 20:21:07 +00:00
}
2010-02-19 10:24:02 +00:00
2010-01-07 20:21:07 +00:00
function focus() {
2010-09-03 08:47:40 +00:00
var val = that.$element.val();
2010-02-19 10:24:02 +00:00
that.gainFocus();
2010-09-03 20:54:40 +00:00
self.options.parent.addClass('OxFocus');
if (that.$element.hasClass('OxPlaceholder')) {
that.$element.val('').removeClass('OxPlaceholder');
2010-01-07 20:21:07 +00:00
}
2010-09-03 08:47:40 +00:00
if (self.bindKeyboard) {
2010-02-18 07:27:32 +00:00
// fixme: different in webkit and firefox (?), see keyboard handler, need generic function
2010-09-03 08:47:40 +00:00
$document.keydown(keypress);
$document.keypress(keypress);
2010-09-03 20:54:40 +00:00
Ox.print('calling autosuggest...')
2010-09-03 08:47:40 +00:00
self.options.autosuggest && setTimeout(autosuggestCall, 0); // fixme: why is the timeout needed?
2010-02-18 07:27:32 +00:00
}
2010-01-07 20:21:07 +00:00
}
2010-02-19 10:24:02 +00:00
2010-02-18 14:24:17 +00:00
function keypress(event) {
2010-09-03 20:54:40 +00:00
Ox.print('keyCode', event.keyCode)
2010-09-03 08:47:40 +00:00
if (event.keyCode != 9 && event.keyCode != 13 && event.keyCode != 27) { // fixme: can't 13 and 27 return false?
setTimeout(function() { // fixme: document what this timeout is for
var value = that.$element.val();
if (value != self.options.value) {
self.options.value = value;
2010-07-24 01:32:08 +00:00
self.options.autocomplete && autocompleteCall();
2010-09-03 08:47:40 +00:00
self.options.autocorrect && autocorrectCall();
self.options.autosuggest && autosuggestCall();
self.options.autovalidate && autovalidateCall();
2010-02-18 15:15:23 +00:00
}
2010-02-18 15:19:36 +00:00
}, 25);
2010-02-18 15:15:23 +00:00
}
2010-02-18 07:56:37 +00:00
}
2010-02-19 10:24:02 +00:00
function submit() {
2010-09-03 08:47:40 +00:00
2010-07-24 01:32:08 +00:00
}
2010-09-03 08:47:40 +00:00
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'placeholder') {
that.$element.hasClass('OxPlaceholder') && that.$element.val(value);
} else if (key == 'value') {
2010-09-03 08:47:40 +00:00
if (self.options.placeholder) {
2010-09-03 20:54:40 +00:00
if (value === '') {
that.$element.addClass('OxPlaceholder').val(self.options.placeholder);
2010-09-03 08:47:40 +00:00
} else {
2010-09-03 20:54:40 +00:00
that.$element.removeClass('OxPlaceholder');
2010-09-03 08:47:40 +00:00
}
2010-07-24 01:32:08 +00:00
}
2010-09-03 08:47:40 +00:00
change(); // fixme: keypress too
2010-07-24 01:32:08 +00:00
}
}
2010-02-27 08:46:49 +00:00
return that;
2010-09-03 08:47:40 +00:00
}
2010-01-07 20:21:07 +00:00
2010-09-03 08:47:40 +00:00
Ox.Range_ = function(options, self) {
2010-01-07 20:21:07 +00:00
/*
init
*/
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
animate: false,
arrows: false,
arrowStep: 1,
2010-09-03 20:54:40 +00:00
arrowSymbols: ['previous', 'next'],
2010-01-07 20:21:07 +00:00
max: 100,
min: 0,
2010-09-03 20:54:40 +00:00
orientation: 'horizontal',
2010-01-07 20:21:07 +00:00
step: 1,
size: 128,
thumbSize: 16,
thumbValue: false,
trackImages: [],
trackStep: 0,
2010-09-03 08:47:40 +00:00
value: 0,
valueNames: null
2010-01-07 20:21:07 +00:00
})
.options($.extend(options, {
arrowStep: options.arrowStep ?
options.arrowStep : options.step,
trackImages: $.makeArray(options.trackImages || [])
}))
2010-09-03 20:54:40 +00:00
.addClass('OxRange')
2010-09-03 08:47:40 +00:00
.css({
2010-09-03 20:54:40 +00:00
width: self.options.size + 'px'
2010-09-03 08:47:40 +00:00
});
2010-01-07 20:21:07 +00:00
// fixme: self. ... ?
var trackImages = self.options.trackImages.length,
values = (self.options.max - self.options.min + self.options.step) /
self.options.step;
/*
construct
*/
that.$element
.css({
2010-09-03 20:54:40 +00:00
width: self.options.size + 'px'
2010-01-07 20:21:07 +00:00
});
if (self.options.arrows) {
var $arrowDec = Ox.Button({
2010-09-03 20:54:40 +00:00
style: 'symbol',
type: 'image',
2010-03-06 09:54:30 +00:00
value: self.options.arrowSymbols[0]
2010-01-07 20:21:07 +00:00
})
2010-09-03 20:54:40 +00:00
.addClass('OxArrow')
2010-01-07 20:21:07 +00:00
.mousedown(mousedownArrow)
.click(clickArrowDec)
.appendTo(that.$element);
}
var $track = new Ox.Element()
2010-09-03 20:54:40 +00:00
.addClass('OxTrack')
2010-01-07 20:21:07 +00:00
.mousedown(clickTrack)
2010-09-03 08:47:40 +00:00
.appendTo(that.$element);
2010-01-07 20:21:07 +00:00
if (trackImages) {
var width = parseFloat(screen.width / trackImages),
2010-09-03 20:54:40 +00:00
$image = $('<canvas>')
2010-01-07 20:21:07 +00:00
.attr({
width: width * trackImages,
height: 14
})
2010-09-03 20:54:40 +00:00
.addClass('OxImage')
2010-09-03 08:47:40 +00:00
.appendTo($track.$element),
2010-01-07 20:21:07 +00:00
c = $image[0].getContext('2d');
2010-01-25 15:10:44 +00:00
c.mozImageSmoothingEnabled = false; // we may want to remove this later
2010-01-07 20:21:07 +00:00
$.each(self.options.trackImages, function(i, v) {
2010-09-03 08:47:40 +00:00
var left = 0;
2010-09-03 20:54:40 +00:00
$('<img/>')
2010-01-07 20:21:07 +00:00
.attr({
src: v
})
.load(function() {
2010-09-03 08:47:40 +00:00
c.drawImage(this, left, 0, self.trackImageWidth[i], 14);
2010-01-07 20:21:07 +00:00
});
2010-09-03 08:47:40 +00:00
left += self.trackImageWidth[i];
2010-01-07 20:21:07 +00:00
});
}
var $thumb = Ox.Button({})
2010-09-03 20:54:40 +00:00
.addClass('OxThumb')
2010-01-07 20:21:07 +00:00
.appendTo($track);
2010-09-03 20:54:40 +00:00
Ox.print('----')
2010-01-07 20:21:07 +00:00
if (self.options.arrows) {
var $arrowInc = Ox.Button({
2010-09-03 20:54:40 +00:00
style: 'symbol',
type: 'image',
2010-03-06 09:54:30 +00:00
value: self.options.arrowSymbols[1]
2010-01-07 20:21:07 +00:00
})
2010-09-03 20:54:40 +00:00
.addClass('OxArrow')
2010-01-07 20:21:07 +00:00
.mousedown(mousedownArrow)
.click(clickArrowInc)
.appendTo(that.$element);
}
var rangeWidth, trackWidth, imageWidth, thumbWidth;
setWidth(self.options.size);
/*
private functions
*/
function clickArrowDec() {
2010-09-03 20:54:40 +00:00
that.removeClass('OxActive');
2010-01-07 20:21:07 +00:00
setValue(self.options.value - self.options.arrowStep, 200)
}
function clickArrowInc() {
2010-09-03 20:54:40 +00:00
that.removeClass('OxActive');
2010-01-07 20:21:07 +00:00
setValue(self.options.value + self.options.arrowStep, 200);
}
function clickTrack(e) {
2010-09-03 08:47:40 +00:00
//Ox.Focus.focus();
2010-01-07 20:21:07 +00:00
var left = $track.offset().left,
2010-09-03 20:54:40 +00:00
offset = $(e.target).hasClass('OxThumb') ?
2010-01-07 20:21:07 +00:00
e.clientX - $thumb.offset().left - thumbWidth / 2 - 2 : 0;
function val(e) {
return getVal(e.clientX - left - offset);
}
setValue(val(e), 200);
$window.mousemove(function(e) {
setValue(val(e));
});
2010-09-03 20:54:40 +00:00
$window.one('mouseup', function() {
$window.unbind('mousemove');
2010-01-07 20:21:07 +00:00
});
}
function getPx(val) {
var pxPerVal = (trackWidth - thumbWidth - 2) /
2010-09-03 08:47:40 +00:00
(self.options.max - self.options.min);
2010-01-07 20:21:07 +00:00
return Math.ceil((val - self.options.min) * pxPerVal + 1);
}
function getVal(px) {
var px = trackWidth / values >= 16 ? px : px - 8,
valPerPx = (self.options.max - self.options.min) /
(trackWidth - thumbWidth);
return Ox.limit(self.options.min +
2010-09-03 08:47:40 +00:00
Math.floor(px * valPerPx / self.options.step) * self.options.step,
self.options.min, self.options.max);
2010-01-07 20:21:07 +00:00
}
function mousedownArrow() {
2010-09-03 20:54:40 +00:00
that.addClass('OxActive');
2010-01-07 20:21:07 +00:00
}
function setThumb(animate) {
2010-09-03 20:54:40 +00:00
var animate = typeof animate != 'undefined' ? animate : 0;
2010-01-07 20:21:07 +00:00
$thumb.animate({
2010-09-03 20:54:40 +00:00
marginLeft: (getPx(self.options.value) - 2) + 'px',
width: thumbWidth + 'px'
2010-01-07 20:21:07 +00:00
}, self.options.animate ? animate : 0, function() {
if (self.options.thumbValue) {
$thumb.options({
2010-09-03 08:47:40 +00:00
value: self.options.valueNames ?
self.options.valueNames[self.options.value] :
self.options.value
2010-01-07 20:21:07 +00:00
});
}
});
}
function setValue(val, animate) {
val = Ox.limit(val, self.options.min, self.options.max);
if (val != self.options.value) {
that.options({
value: val
});
setThumb(animate);
2010-09-03 20:54:40 +00:00
that.triggerEvent('change', { value: val });
2010-01-07 20:21:07 +00:00
}
}
function setWidth(width) {
trackWidth = width - self.options.arrows * 32;
thumbWidth = Math.max(trackWidth / values - 2, self.options.thumbSize - 2);
that.$element.css({
2010-09-03 20:54:40 +00:00
width: (width - 2) + 'px'
2010-01-07 20:21:07 +00:00
});
$track.css({
2010-09-03 20:54:40 +00:00
width: (trackWidth - 2) + 'px'
2010-01-07 20:21:07 +00:00
});
if (trackImages) {
$image.css({
2010-09-03 20:54:40 +00:00
width: (trackWidth - 2) + 'px'
2010-01-07 20:21:07 +00:00
});
}
$thumb.css({
2010-09-03 20:54:40 +00:00
width: (thumbWidth - 2) + 'px',
2010-01-07 20:21:07 +00:00
padding: 0
});
setThumb();
}
/*
shared functions
*/
2010-09-03 08:47:40 +00:00
self.onChange = function(key, value) {
2010-01-07 20:21:07 +00:00
}
return that;
};
2010-02-10 09:59:59 +00:00
/*
============================================================================
Lists
============================================================================
*/
2010-07-05 07:09:34 +00:00
Ox.IconList = function(options, self) {
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
2010-09-03 20:54:40 +00:00
id: '',
2010-07-05 07:09:34 +00:00
item: function() {},
keys: [],
2010-09-03 20:54:40 +00:00
orientation: 'both',
2010-07-05 07:09:34 +00:00
request: function() {},
size: 128,
sort: [],
})
.options(options || {});
$.extend(self, {
itemHeight: self.options.size * 1.5,
itemWidth: self.options.size
});
that.$element = new Ox.List({
construct: constructItem,
itemHeight: self.itemHeight,
itemWidth: self.itemWidth,
2010-09-03 20:54:40 +00:00
keys: 'foo',
orientation: 'both',
2010-07-05 07:09:34 +00:00
request: function() {},
rowLength: 1,
size: 128,
2010-09-03 20:54:40 +00:00
type: 'icon',
2010-07-05 07:09:34 +00:00
}, self)
.click(click)
.dblclick(dblclick)
.scroll(scroll);
function click() {
}
function constructItem(data) {
var data = self.options.item(data, self.options.sort);
return new Ox.IconItem($.extend(data, {
size: self.options.size
}));
}
function dblclick() {
}
function scroll() {
}
2010-09-03 20:54:40 +00:00
Ox.print('IconList', that.options('id'))
2010-07-05 07:09:34 +00:00
return that;
};
Ox.IconItem = function(options, self) {
var self = self || {}
that = new Ox.Element({}, self)
.defaults({
height: 0,
2010-09-03 20:54:40 +00:00
id: '',
info: '',
2010-07-05 07:09:34 +00:00
size: 128,
2010-09-03 20:54:40 +00:00
title: '',
2010-07-05 07:09:34 +00:00
width: 0,
2010-09-03 20:54:40 +00:00
url: ''
2010-07-05 07:09:34 +00:00
})
.options(options || {});
$.extend(self, {
height: self.options.size * 1.5,
2010-09-03 20:54:40 +00:00
url: oxui.path + '/png/ox.ui.' + Ox.theme() + '/icon.png',
2010-07-05 07:09:34 +00:00
width: self.options.size + 4
});
that.css({
2010-09-03 20:54:40 +00:00
width: self.width + 'px',
height: self.height + 'px'
2010-07-05 07:09:34 +00:00
});
2010-09-03 20:54:40 +00:00
that.$icon = $('<div>')
.addClass('OxIcon')
2010-07-05 07:09:34 +00:00
.css({
top: self.options.size == 64 ? -70 : -128,
2010-09-03 20:54:40 +00:00
width: self.options.size + 'px',
height: self.options.size + 'px'
2010-07-05 07:09:34 +00:00
});
2010-09-03 20:54:40 +00:00
that.$iconImage = $('<img>')
2010-07-05 07:09:34 +00:00
.attr({
src: self.url
})
.css({
2010-09-03 20:54:40 +00:00
width: iconWidth + 'px',
height: iconHeight + 'px'
2010-07-05 07:09:34 +00:00
})
.mouseenter(mouseenter)
.mouseleave(mouseleave)
2010-09-03 20:54:40 +00:00
.one('load', function() {
2010-07-05 07:09:34 +00:00
that.$iconImage.attr({
src: self.options.url
});
});
2010-09-03 20:54:40 +00:00
that.$textBox = $('<div>')
.addClass('OxText')
2010-07-05 07:09:34 +00:00
.css({
2010-09-03 20:54:40 +00:00
top: (self.options.size / 2 + 2) + 'px',
width: self.width + 'px',
height: (self.options.size == 64 ? 38 : 58) + 'px'
2010-07-05 07:09:34 +00:00
})
2010-09-03 20:54:40 +00:00
that.$text = $('<div>')
.html(self.options.title + '<br/><span class="OxInfo">' + self.options.info + '</span>')
2010-07-05 07:09:34 +00:00
.mouseenter(mouseenter)
.mouseleave(mouseleave)
2010-09-03 20:54:40 +00:00
that.$reflection = $('<div>')
.addClass('OxReflection')
2010-07-05 07:09:34 +00:00
.css({
2010-09-03 20:54:40 +00:00
top: (self.options.size + 2) + 'px',
width: self.options.size + 'px',
height: (self.options.size / 2) + 'px'
2010-07-05 07:09:34 +00:00
});
2010-09-03 20:54:40 +00:00
that.$reflectionImage = $('<img>')
.addClass('OxReflection')
2010-07-05 07:09:34 +00:00
.attr({
src: self.url
})
.css({
2010-09-03 20:54:40 +00:00
width: self.options.width + 'px',
height: self.options.height + 'px'
2010-07-05 07:09:34 +00:00
})
2010-09-03 20:54:40 +00:00
.one('load', function() {
2010-07-05 07:09:34 +00:00
that.$reflectionImage.attr({
src: self.options.url
});
});
2010-09-03 20:54:40 +00:00
that.$gradient = $('<div>')
.addClass('OxGradient')
2010-07-05 07:09:34 +00:00
.css({
2010-09-03 20:54:40 +00:00
top: (-self.options.size - 2) + 'px'
2010-07-05 07:09:34 +00:00
});
that.append(
that.$reflection.append(
that.$reflectionImage
).append(
that.$gradientImage
)
).append(
that.$textBox.append(
that.$text
)
).append(
that.$icon.append(
that.$iconImage
)
);
function mouseenter() {
2010-09-03 20:54:40 +00:00
that.addClass('OxHover');
2010-07-05 07:09:34 +00:00
}
function mouseleave() {
2010-09-03 20:54:40 +00:00
that.removeClass('OxHover');
2010-07-05 07:09:34 +00:00
}
return that;
};
2010-02-10 09:59:59 +00:00
Ox.List = function(options, self) {
var self = self || {},
2010-06-25 15:55:25 +00:00
that = new Ox.Container({}, self)
.defaults({
2010-06-28 11:19:04 +00:00
construct: function() {},
2010-06-25 15:55:25 +00:00
itemHeight: 16,
itemWidth: 16,
2010-06-28 09:16:36 +00:00
keys: [],
2010-09-03 20:54:40 +00:00
orientation: 'vertical',
2010-06-25 15:55:25 +00:00
request: function() {}, // {sort:, range:, callback:}, without parameter returns {items, size etc.}
rowLength: 1,
sort: [],
2010-09-03 20:54:40 +00:00
type: 'text',
unique: ''
2010-06-25 15:55:25 +00:00
})
2010-06-28 09:16:36 +00:00
.options(options || {})
2010-06-29 22:19:41 +00:00
.click(click)
2010-06-28 09:16:36 +00:00
.scroll(scroll);
2010-06-25 15:55:25 +00:00
$.extend(self, {
$items: [],
$pages: [],
ids: {},
2010-06-30 14:21:06 +00:00
keyboardEvents: {
key_alt_control_a: invertSelection,
key_control_a: selectAll,
key_control_shift_a: selectNone,
key_end: scrollToFirst,
2010-07-20 20:04:13 +00:00
key_enter: open,
2010-06-30 14:21:06 +00:00
key_home: scrollToLast,
key_pagedown: scrollPageDown,
2010-07-20 20:04:13 +00:00
key_pageup: scrollPageUp,
key_space: preview
2010-06-30 14:21:06 +00:00
},
2010-06-25 15:55:25 +00:00
page: 0,
pageLength: 100,
2010-07-20 20:04:13 +00:00
preview: false,
2010-06-28 09:16:36 +00:00
requests: [],
2010-06-25 15:55:25 +00:00
selected: []
});
2010-09-03 20:54:40 +00:00
self.keyboardEvents['key_' + (self.options.orientation == 'horizontal' ? 'left' : 'up')] = selectPrevious;
self.keyboardEvents['key_' + (self.options.orientation == 'horizontal' ? 'right' : 'down')] = selectNext;
self.keyboardEvents['key_' + (self.options.orientation == 'horizontal' ? 'shift_left' : 'shift_up')] = addPreviousToSelection;
self.keyboardEvents['key_' + (self.options.orientation == 'horizontal' ? 'shift_right' : 'shift_down')] = addNextToSelection;
2010-06-28 09:16:36 +00:00
2010-06-30 18:47:10 +00:00
updateQuery();
2010-09-03 20:54:40 +00:00
Ox.print('s.o', self.options)
2010-09-03 08:47:40 +00:00
that.addEvent(self.keyboardEvents);
2010-06-25 15:55:25 +00:00
function addAllToSelection(pos) {
var arr,
len = self.$items.length;
if (!isSelected(pos)) {
2010-06-30 09:02:13 +00:00
if (self.selected.length == 0) {
2010-06-25 15:55:25 +00:00
addToSelection(pos);
} else {
2010-06-30 09:02:13 +00:00
if (Ox.min(self.selected) < pos) {
2010-06-25 15:55:25 +00:00
var arr = [pos];
for (var i = pos - 1; i >= 0; i--) {
if (isSelected(i)) {
$.each(arr, function(i, v) {
addToSelection(v);
});
break;
}
arr.push(i);
}
}
2010-06-30 09:02:13 +00:00
if (Ox.max(self.selected) > pos) {
2010-06-25 15:55:25 +00:00
var arr = [pos];
for (var i = pos + 1; i < len; i++) {
if (isSelected(i)) {
$.each(arr, function(i, v) {
addToSelection(v);
});
break;
}
arr.push(i);
}
}
}
}
}
2010-06-30 14:21:06 +00:00
function addNextToSelection() {
var pos = getNext();
if (pos > -1) {
addToSelection(pos);
scrollTo(pos);
}
}
function addPreviousToSelection() {
var pos = getPrevious();
if (pos > -1) {
addToSelection(pos);
scrollTo(pos);
}
}
2010-06-25 15:55:25 +00:00
function addToSelection(pos) {
if (!isSelected(pos)) {
2010-06-30 09:02:13 +00:00
self.selected.push(pos);
2010-06-25 15:55:25 +00:00
if (!Ox.isUndefined(self.$items[pos])) {
2010-09-03 20:54:40 +00:00
self.$items[pos].addClass('OxSelected');
2010-06-25 15:55:25 +00:00
}
2010-09-03 20:54:40 +00:00
Ox.print('addToSelection')
2010-07-17 08:46:27 +00:00
triggerSelectEvent();
2010-06-25 15:55:25 +00:00
}
}
2010-06-30 18:47:10 +00:00
function clear() {
$.each(self.requests, function(i, v) {
2010-09-03 20:54:40 +00:00
Ox.print('Ox.Request.cancel', v);
2010-06-30 18:47:10 +00:00
Ox.Request.cancel(v);
});
$.extend(self, {
$items: [],
$pages: [],
page: 0,
requests: []
});
}
2010-06-29 22:19:41 +00:00
function click(e) {
2010-06-30 09:02:13 +00:00
var $element = $(e.target), pos;
2010-06-30 09:27:02 +00:00
that.gainFocus();
2010-09-03 20:54:40 +00:00
while (!$element.hasClass('OxItem') && !$element.hasClass('OxPage')) {
2010-06-30 09:02:13 +00:00
$element = $element.parent();
}
2010-09-03 20:54:40 +00:00
if ($element.hasClass('OxItem')) {
Ox.print($element.attr('id'), $element.data('position'));
pos = $element.data('position');
2010-06-30 09:02:13 +00:00
if (e.shiftKey) {
addAllToSelection(pos);
} else if (e.metaKey) {
toggleSelection(pos);
} else {
select(pos);
}
} else {
selectNone();
}
2010-06-29 22:19:41 +00:00
}
2010-06-25 15:55:25 +00:00
function deselect(pos) {
if (isSelected(pos)) {
2010-06-30 09:02:13 +00:00
self.selected.splice(self.selected.indexOf(pos), 1);
2010-06-25 15:55:25 +00:00
if (!Ox.isUndefined(self.$items[pos])) {
2010-09-03 20:54:40 +00:00
self.$items[pos].removeClass('OxSelected');
2010-06-25 15:55:25 +00:00
}
2010-07-17 08:46:27 +00:00
triggerSelectEvent();
2010-06-25 15:55:25 +00:00
}
}
2010-06-30 14:21:06 +00:00
function getHeight() {
2010-06-30 18:47:10 +00:00
return that.height() - (that.$content.width() > that.width() ? oxui.scrollbarSize : 0);
2010-06-30 14:21:06 +00:00
}
2010-06-25 15:55:25 +00:00
function getNext() {
var pos = -1;
2010-06-30 09:02:13 +00:00
if (self.selected.length) {
pos = Ox.max(self.selected) + 1;
2010-06-25 15:55:25 +00:00
if (pos == self.$items.length) {
pos = -1;
}
}
return pos;
}
function getPage() {
2010-09-03 20:54:40 +00:00
return self.options.orientation == 'horizontal'
2010-06-30 21:41:27 +00:00
? Math.floor(that.scrollLeft() / self.pageWidth)
: Math.floor(that.scrollTop() / self.pageHeight);
2010-06-25 15:55:25 +00:00
}
2010-06-30 18:47:10 +00:00
function getPositions() {
2010-09-03 20:54:40 +00:00
Ox.print('getPositions', $.map(self.selected, function(v, i) {
2010-06-30 18:47:10 +00:00
return self.ids[v];
}));
// fixme: optimize: send non-selected ids if more than half of the items are selected
if (self.selected.length /*&& self.selected.length < self.listLength*/) {
self.requests.push(self.options.request({
callback: getPositionsCallback,
ids: $.map(self.selected, function(v, i) {
return self.ids[v];
}),
sort: self.options.sort
}));
} else {
getPositionsCallback();
}
}
function getPositionsCallback(result) {
2010-09-03 20:54:40 +00:00
Ox.print('getPositionsCallback', result)
2010-06-30 18:47:10 +00:00
if (result) {
$.extend(self, {
ids: {},
selected: []
});
$.each(result.data.positions, function(id, pos) {
2010-09-03 20:54:40 +00:00
Ox.print('id', id, 'pos', pos)
2010-06-30 18:47:10 +00:00
self.selected.push(pos);
});
}
load();
}
2010-06-25 15:55:25 +00:00
function getPrevious() {
var pos = -1;
2010-06-30 09:02:13 +00:00
if (self.selected.length) {
pos = Ox.min(self.selected) - 1;
2010-06-25 15:55:25 +00:00
}
return pos;
}
2010-07-20 20:04:13 +00:00
function getSelectedIds() {
// fixme: is carring self.ids around the best way?
return $.map(self.selected, function(v, i) {
return self.ids[v];
});
}
2010-06-30 14:21:06 +00:00
function getWidth() {
2010-06-30 18:47:10 +00:00
return that.width() - (that.$content.height() > that.height() ? oxui.scrollbarSize : 0);
2010-06-30 14:21:06 +00:00
}
2010-06-25 15:55:25 +00:00
function invertSelection() {
2010-06-30 14:21:06 +00:00
$.each(Ox.range(self.listLength), function(i, v) {
toggleSelection(v);
2010-06-25 15:55:25 +00:00
});
}
function isSelected(pos) {
2010-06-28 09:16:36 +00:00
return self.selected.indexOf(pos) > -1;
2010-06-25 15:55:25 +00:00
}
2010-06-30 18:47:10 +00:00
function load() {
that.scrollTop(0);
that.$content.empty();
loadPages(self.page);
}
2010-06-25 15:55:25 +00:00
function loadPage(page, callback) {
2010-09-03 20:54:40 +00:00
Ox.print('loadPage', page)
2010-06-30 18:47:10 +00:00
if (page < 0 || page >= self.pages) {
!Ox.isUndefined(callback) && callback();
2010-06-25 15:55:25 +00:00
return;
}
2010-09-03 20:54:40 +00:00
var keys = $.inArray('id', self.options.keys) > -1 ? self.options.keys :
$.merge(self.options.keys, ['id']),
2010-06-30 09:02:13 +00:00
offset = page * self.pageLength,
2010-06-25 15:55:25 +00:00
range = [offset, offset + (page < self.pages - 1 ?
self.pageLength : self.listLength % self.pageLength)];
if (Ox.isUndefined(self.$pages[page])) {
2010-06-28 09:16:36 +00:00
self.requests.push(self.options.request({
2010-06-28 11:19:04 +00:00
callback: function(result) {
2010-06-25 15:55:25 +00:00
self.$pages[page] = new Ox.ListPage();
2010-09-03 20:54:40 +00:00
if (self.options.type == 'text') {
2010-06-25 15:55:25 +00:00
self.$pages[page].css({
2010-09-03 20:54:40 +00:00
top: (page * self.pageHeight) + 'px'
2010-06-25 15:55:25 +00:00
});
} else {
self.$pages[page].css({
});
}
2010-06-28 11:19:04 +00:00
$.each(result.data.items, function(i, v) {
2010-06-25 15:55:25 +00:00
var pos = offset + i;
2010-06-28 11:19:04 +00:00
self.$items[pos] = new Ox.ListItem({
construct: self.options.construct,
data: v,
2010-06-30 18:47:10 +00:00
id: v[self.options.unique],
2010-06-30 09:02:13 +00:00
position: pos
2010-06-28 11:19:04 +00:00
});
2010-06-30 18:47:10 +00:00
self.ids[pos] = v[self.options.unique];
2010-06-25 15:55:25 +00:00
if (isSelected(pos)) {
2010-09-03 20:54:40 +00:00
self.$items[pos].addClass('OxSelected');
2010-06-25 15:55:25 +00:00
}
self.$items[pos].appendTo(self.$pages[page]);
2010-06-25 15:55:25 +00:00
});
2010-09-03 20:54:40 +00:00
if (self.options.type == 'text' && page == 0) {
2010-07-05 16:52:12 +00:00
var height = that.height() - (that.width() < that.$content.width() ? oxui.scrollbarSize : 0),
visibleItems = Math.ceil(height / self.options.itemHeight);
if (result.data.items.length < visibleItems) {
self.$pages[page].height(height).css({
2010-09-03 20:54:40 +00:00
overflow: 'hidden'
});
$.each(Ox.range(result.data.items.length, visibleItems), function(i, v) {
new Ox.ListItem({
construct: self.options.construct,
data: {},
2010-09-03 20:54:40 +00:00
id: '',
position: v
}).appendTo(self.$pages[page]);
});
}
}
2010-06-28 09:16:36 +00:00
self.$pages[page].appendTo(that.$content);
2010-06-30 18:47:10 +00:00
!Ox.isUndefined(callback) && callback();
2010-06-25 15:55:25 +00:00
},
2010-06-30 09:02:13 +00:00
keys: keys,
2010-06-25 15:55:25 +00:00
range: range,
sort: self.options.sort
2010-06-28 09:16:36 +00:00
}));
} else {
self.$pages[page].appendTo(that.$content);
2010-06-25 15:55:25 +00:00
}
}
function loadPages(page, callback) {
var counter = 0,
fn = function() {
counter++;
counter == 2 && !Ox.isUndefined(callback) && callback();
};
loadPage(page, function() {
loadPage(page - 1, fn);
loadPage(page + 1, fn);
});
}
2010-07-20 20:04:13 +00:00
function open() {
2010-09-03 20:54:40 +00:00
that.triggerEvent('open', {
2010-07-20 20:04:13 +00:00
ids: getSelectedIds()
});
}
function preview() {
self.preview = !self.preview;
if (self.preview) {
2010-09-03 20:54:40 +00:00
that.triggerEvent('openpreview', {
2010-07-20 20:04:13 +00:00
ids: getSelectedIds()
});
} else {
2010-09-03 20:54:40 +00:00
that.triggerEvent('closepreview');
2010-07-20 20:04:13 +00:00
}
}
2010-06-28 09:16:36 +00:00
function scroll() {
var page = self.page;
self.page = getPage();
setTimeout(function() {
if (self.page == getPage()) {
if (self.page == page - 1) {
unloadPage(self.page + 2);
loadPage(self.page - 1);
} else if (self.page == page + 1) {
unloadPage(self.page - 2);
loadPage(self.page + 1);
} else if (self.page == page - 2) {
unloadPage(self.page + 3);
unloadPage(self.page + 2);
loadPage(self.page);
loadPage(self.page - 1);
} else if (self.page == page + 2) {
unloadPage(self.page - 3);
unloadPage(self.page - 2);
loadPage(self.page);
loadPage(self.page + 1);
} else if (self.page != page) {
unloadPages(page);
loadPages(self.page);
}
}
}, 100);
2010-06-28 09:16:36 +00:00
}
2010-06-30 14:21:06 +00:00
function scrollPageDown() {
that.scrollBy(getHeight());
}
function scrollPageUp() {
that.scrollBy(-getHeight());
}
function scrollTo(pos) {
var positions = [], scroll, size;
2010-09-03 20:54:40 +00:00
if (self.options.orientation == 'horizontal') {
2010-06-30 14:21:06 +00:00
2010-09-03 20:54:40 +00:00
} else if (self.options.orientation == 'vertical') {
2010-06-30 14:21:06 +00:00
positions[0] = self.options.itemHeight * pos;
positions[1] = positions[0] + self.options.itemHeight;
scroll = that.scrollTop();
size = getHeight();
if (positions[0] < scroll) {
that.animate({
2010-09-03 20:54:40 +00:00
scrollTop: positions[0] + 'px'
2010-06-30 14:21:06 +00:00
}, 0);
} else if (positions[1] > scroll + size) {
that.animate({
2010-09-03 20:54:40 +00:00
scrollTop: (positions[1] - size) + 'px'
2010-06-30 14:21:06 +00:00
}, 0);
}
} else {
}
}
function scrollToFirst() {
that.scrollTop(0);
}
function scrollToLast() {
2010-06-30 18:47:10 +00:00
that.scrollTop(self.listHeight);
2010-06-30 14:21:06 +00:00
}
2010-06-25 15:55:25 +00:00
function select(pos) {
2010-06-30 09:02:13 +00:00
if (!isSelected(pos) || self.selected.length > 1) {
2010-06-25 15:55:25 +00:00
selectNone();
addToSelection(pos);
}
}
function selectAll() {
2010-06-30 14:21:06 +00:00
$.each(Ox.range(self.listLength), function(i, v) {
2010-09-03 20:54:40 +00:00
Ox.print('adding', v);
2010-06-30 14:21:06 +00:00
addToSelection(v);
2010-06-25 15:55:25 +00:00
});
}
function selectNext() {
var pos = getNext();
if (pos > -1) {
select(pos);
scrollTo(pos);
}
}
function selectNone() {
$.each(self.$items, function(i, v) {
deselect(i);
});
}
function selectPrevious() {
var pos = getPrevious();
if (pos > -1) {
select(pos);
scrollTo(pos);
}
}
function selectQuery(str) {
$.each(self.$items, function(i, v) {
if (Ox.toLatin(v.title).toUpperCase().indexOf(str) == 0) {
select(i);
scrollTo(i);
return false;
}
});
}
function toggleSelection(pos) {
if (!isSelected(pos)) {
addToSelection(pos);
} else {
deselect(pos);
}
}
2010-07-17 08:46:27 +00:00
function triggerSelectEvent() {
2010-07-20 20:04:13 +00:00
var ids = getSelectedIds();
2010-07-17 08:46:27 +00:00
setTimeout(function() {
2010-07-20 20:04:13 +00:00
var ids_ = getSelectedIds();
2010-07-17 08:46:27 +00:00
if (ids.length == ids_.length && (ids.length == 0 || ids[0] == ids_[0])) {
2010-09-03 20:54:40 +00:00
that.triggerEvent('select', {
2010-07-17 08:46:27 +00:00
ids: ids
});
2010-09-03 20:54:40 +00:00
self.preview && that.triggerEvent('openpreview', {
2010-07-20 20:04:13 +00:00
ids: ids
});
2010-07-17 08:46:27 +00:00
} else {
2010-09-03 20:54:40 +00:00
Ox.print('select event not triggered after timeout');
2010-07-17 08:46:27 +00:00
}
}, 100);
}
2010-06-25 15:55:25 +00:00
function unloadPage(page) {
2010-06-29 22:19:41 +00:00
if (page < 0 || page >= self.pages) {
return;
}
2010-09-03 20:54:40 +00:00
Ox.print('unloadPage', page)
Ox.print('self.$pages', self.$pages)
2010-06-29 22:19:41 +00:00
Ox.print(!Ox.isUndefined(self.$pages[page]))
2010-06-25 15:55:25 +00:00
!Ox.isUndefined(self.$pages[page]) && self.$pages[page].remove();
}
function unloadPages(page) {
unloadPage(page);
unloadPage(page - 1);
unloadPage(page + 1)
}
2010-02-10 09:59:59 +00:00
2010-06-30 18:47:10 +00:00
function updateQuery() {
clear();
self.requests.push(self.options.request({
callback: function(result) {
var keys = {};
2010-09-03 20:54:40 +00:00
that.triggerEvent('load', result.data);
$.extend(self, {
2010-06-30 18:47:10 +00:00
listHeight: result.data.items * self.options.itemHeight, // fixme: should be listSize
listLength: result.data.items,
pages: Math.ceil(result.data.items / self.pageLength),
2010-09-03 20:54:40 +00:00
pageWidth: self.options.orientation == 'horizontal' ?
2010-06-30 18:47:10 +00:00
self.pageLength * self.options.itemWidth : 0,
2010-09-03 20:54:40 +00:00
pageHeight: self.options.orientation == 'horizontal' ? 0 :
2010-06-30 18:47:10 +00:00
self.pageLength * self.options.itemHeight / self.options.rowLength
});
2010-06-30 18:47:10 +00:00
that.$content.css({
2010-09-03 20:54:40 +00:00
height: self.listHeight + 'px'
});
2010-06-30 18:47:10 +00:00
getPositions();
}
2010-06-30 18:47:10 +00:00
}));
}
2010-06-30 18:47:10 +00:00
function updateSort() {
2010-07-03 08:35:28 +00:00
if (self.listLength > 1) {
clear();
getPositions();
}
2010-06-28 09:16:36 +00:00
}
2010-06-30 18:47:10 +00:00
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
Ox.print('list onChange', key, value);
if (key == 'request') {
2010-06-30 18:47:10 +00:00
updateQuery();
}
};
2010-09-04 14:28:40 +00:00
that.clearCache = function() { // used by TextList resizeColumn
2010-06-30 18:47:10 +00:00
self.$pages = [];
2010-09-04 14:28:40 +00:00
return that;
};
that.reload = function() {
clear();
that.clearCache();
that.$content.empty();
loadPages(self.page);
return that;
2010-06-30 18:47:10 +00:00
};
2010-06-28 09:16:36 +00:00
that.sort = function(key, operator) {
if (key != self.options.sort[0].key || operator != self.options.sort[0].operator) {
self.options.sort[0] = {
key: key,
operator: operator
}
2010-09-03 20:54:40 +00:00
that.triggerEvent('sort', self.options.sort[0]);
2010-06-30 18:47:10 +00:00
updateSort();
2010-06-28 09:16:36 +00:00
}
2010-09-04 14:28:40 +00:00
return that;
2010-06-28 09:16:36 +00:00
}
2010-02-10 09:59:59 +00:00
return that;
};
Ox.ListItem = function(options, self) {
2010-06-28 11:19:04 +00:00
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
construct: function() {},
data: {},
2010-09-03 20:54:40 +00:00
id: '',
2010-06-30 09:02:13 +00:00
position: 0
2010-06-28 11:19:04 +00:00
})
.options(options || {});
2010-06-28 11:19:04 +00:00
$.each(self.options.data, function(k, v) {
2010-09-03 20:54:40 +00:00
self.options.data[k] = $.isArray(v) ? v.join(', ') : v;
2010-06-28 11:19:04 +00:00
});
2010-06-30 09:02:13 +00:00
that.$element = self.options.construct(self.options.data)
2010-09-03 20:54:40 +00:00
.addClass('OxItem')
2010-06-30 09:02:13 +00:00
.attr({
2010-06-30 18:47:10 +00:00
id: self.options.id
2010-06-30 09:02:13 +00:00
})
2010-09-03 20:54:40 +00:00
.data('position', self.options.position);
2010-06-28 11:19:04 +00:00
return that;
2010-02-10 09:59:59 +00:00
};
2010-06-25 15:55:25 +00:00
Ox.ListPage = function(options, self) {
var self = self || {},
that = new Ox.Element({}, self)
2010-09-03 20:54:40 +00:00
.addClass('OxPage');
2010-06-25 15:55:25 +00:00
return that;
};
Ox.TextList = function(options, self) {
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
columns: [],
2010-09-04 14:28:40 +00:00
columnsMovable: false,
columnsRemovable: false,
//columnWidth: [40, 800],
2010-09-03 20:54:40 +00:00
id: '',
2010-06-25 15:55:25 +00:00
request: function() {}, // {sort, range, keys, callback}
2010-06-28 09:16:36 +00:00
sort: []
2010-06-25 15:55:25 +00:00
})
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxTextList');
2010-06-25 15:55:25 +00:00
2010-06-30 18:47:10 +00:00
$.each(self.options.columns, function(i, v) { // fixme: can this go into a generic ox.js function?
if (Ox.isUndefined(v.unique)) {
v.unique = false;
}
if (Ox.isUndefined(v.visible)) {
v.visible = false;
}
if (v.unique) {
self.unique = v.id;
}
});
2010-06-25 15:55:25 +00:00
$.extend(self, {
2010-07-03 11:31:25 +00:00
columnPositions: [],
2010-06-25 15:55:25 +00:00
columnWidths: [],
itemHeight: 16,
page: 0,
pageLength: 100,
scrollLeft: 0,
2010-06-29 21:24:07 +00:00
selectedColumn: getColumnIndexById(self.options.sort[0].key),
2010-06-28 09:16:36 +00:00
visibleColumns: $.map(self.options.columns, function(v, i) {
return v.visible ? v : null;
})
2010-06-25 15:55:25 +00:00
});
$.extend(self, {
pageHeight: self.pageLength * self.itemHeight
});
// Head
that.$bar = new Ox.Bar({
2010-09-03 20:54:40 +00:00
orientation: 'horizontal',
2010-06-25 15:55:25 +00:00
size: 16
}).appendTo(that);
that.$head = new Ox.Container()
2010-09-03 20:54:40 +00:00
.addClass('OxHead')
2010-06-25 15:55:25 +00:00
.appendTo(that.$bar);
2010-09-03 20:54:40 +00:00
that.$head.$content.addClass('OxTitles');
2010-09-04 14:28:40 +00:00
constructHead();
if (self.options.columnsRemovable) {
that.$select = new Ox.Select({
id: self.options.id + 'SelectColumns',
items: $.map(self.options.columns, function(v, i) {
return {
checked: v.visible,
disabled: v.removable === false,
id: v.id,
title: v.title
}
}),
max: -1,
min: 1,
type: 'image'
2010-06-25 15:55:25 +00:00
})
2010-09-04 14:28:40 +00:00
.bindEvent('change', changeColumns)
.appendTo(that.$bar.$element);
2010-07-24 01:32:08 +00:00
}
2010-06-25 15:55:25 +00:00
// Body
2010-06-28 09:16:36 +00:00
that.$body = new Ox.List({
2010-06-28 11:19:04 +00:00
construct: constructItem,
2010-06-30 09:27:02 +00:00
id: self.options.id,
2010-06-28 09:16:36 +00:00
itemHeight: 16,
2010-06-30 09:02:13 +00:00
itemWidth: getItemWidth(),
2010-06-28 11:19:04 +00:00
keys: $.map(self.visibleColumns, function(v, i) {
return v.id;
}),
2010-09-03 20:54:40 +00:00
orientation: 'vertical',
2010-06-28 09:16:36 +00:00
request: self.options.request,
sort: self.options.sort,
2010-09-03 20:54:40 +00:00
type: 'text',
2010-06-30 18:47:10 +00:00
unique: self.unique
2010-06-28 11:19:04 +00:00
})
2010-09-03 20:54:40 +00:00
.addClass('OxBody')
2010-06-28 09:16:36 +00:00
.scroll(function() {
var scrollLeft = $(this).scrollLeft();
if (scrollLeft != self.scrollLeft) {
self.scrollLeft = scrollLeft;
that.$head.scrollLeft(scrollLeft);
}
})
.appendTo(that);
that.$body.$content.css({
2010-09-03 20:54:40 +00:00
width: getItemWidth() + 'px'
2010-06-25 15:55:25 +00:00
});
2010-09-03 20:54:40 +00:00
Ox.print('s.vC', self.visibleColumns)
2010-07-06 04:39:11 +00:00
2010-06-28 09:16:36 +00:00
function addColumn(id) {
2010-09-04 14:28:40 +00:00
Ox.print('addColumn', id);
var column,
index = 0;
$.each(self.options.columns, function(i, v) {
if (v.visible) {
index++;
} else if (v.id == id) {
column = v;
return false;
}
});
column.visible = true;
self.visibleColumns.splice(index, 0, column);
that.$head.$content.empty();
constructHead();
that.$body.options({
keys: $.map(self.visibleColumns, function(v, i) {
return v.id;
})
});
that.$body.reload();
}
function changeColumns(event, data) {
var add,
ids = [];
$.each(data.selected, function(i, column) {
var index = getColumnIndexById(column.id);
if (!self.options.columns[index].visible) {
addColumn(column.id);
add = true;
return false;
}
ids.push(column.id);
});
if (!add) {
$.each(self.visibleColumns, function(i, column) {
if (ids.indexOf(column.id) == -1) {
removeColumn(column.id);
return false
}
});
}
2010-06-28 09:16:36 +00:00
}
2010-06-29 21:24:07 +00:00
function clickColumn(id) {
2010-09-03 20:54:40 +00:00
Ox.print('clickColumn', id);
2010-06-29 21:24:07 +00:00
var i = getColumnIndexById(id),
isSelected = self.options.sort[0].key == self.options.columns[i].id;
2010-06-29 16:28:22 +00:00
that.sort(
2010-06-29 21:24:07 +00:00
self.options.columns[i].id, isSelected ?
2010-09-03 20:54:40 +00:00
(self.options.sort[0].operator === '' ? '-' : '') :
2010-06-29 21:24:07 +00:00
self.options.columns[i].operator
2010-06-29 16:28:22 +00:00
);
}
2010-09-04 14:28:40 +00:00
function constructHead() {
that.$titles = [];
self.columnPositions = [];
self.columnWidths = [];
$.each(self.visibleColumns, function(i, v) {
var $order, $resize, $left, $center, $right, timeout = 0;
self.columnWidths[i] = v.width;
that.$titles[i] = $('<div>')
.addClass('OxTitle OxColumn' + Ox.toTitleCase(v.id))
.css({
width: (v.width - 9) + 'px',
textAlign: v.align
})
.html(v.title)
.mousedown(function(e) {
timeout = setTimeout(function() {
dragColumn(v.id, e);
timeout = 0;
}, 250);
})
.mouseup(function() {
if (timeout) {
clearTimeout(timeout);
timeout = 0;
clickColumn(v.id);
}
})
.appendTo(that.$head.$content.$element);
self.columnPositions[i] = Ox.sum(self.columnWidths) - self.columnWidths[i] / 2;
$order = $('<div>')
.addClass('OxOrder')
.html(oxui.symbols['triangle_' + (
v.operator === '' ? 'up' : 'down'
)])
.click(function() {
$(this).prev().trigger('click')
})
.appendTo(that.$head.$content.$element);
$resize = $('<div>')
.addClass('OxResize')
.mousedown(function(e) {
var startWidth = self.columnWidths[i],
startX = e.clientX;
$window.mousemove(function(e) {
var x = e.clientX,
width = Ox.limit(
startWidth - startX + x,
self.options.columnWidth[0],
self.options.columnWidth[1]
);
resizeColumn(v.id, width);
});
$window.one('mouseup', function() {
$window.unbind('mousemove');
});
})
.dblclick(function() {
resizeColumn(v.id, v.width);
})
.appendTo(that.$head.$content.$element);
$left = $('<div>').addClass('OxLeft').appendTo($resize);
$center = $('<div>').addClass('OxCenter').appendTo($resize);
$right = $('<div>').addClass('OxRight').appendTo($resize);
});
that.$head.$content.css({
width: (Ox.sum(self.columnWidths) + 2) + 'px'
});
Ox.print('s.sC', self.selectedColumn)
if (getColumnPositionById(self.options.columns[self.selectedColumn].id) > -1) { // fixme: save in var
toggleSelected(self.options.columns[self.selectedColumn].id);
that.$titles[getColumnPositionById(self.options.columns[self.selectedColumn].id)].css({
width: (self.options.columns[self.selectedColumn].width - 25) + 'px'
});
}
}
2010-06-30 09:02:13 +00:00
function constructItem(data) {
2010-09-03 20:54:40 +00:00
var $item = $('<div>')
2010-06-25 15:55:25 +00:00
.css({
2010-09-04 14:28:40 +00:00
width: getItemWidth() + 'px'
2010-06-30 09:02:13 +00:00
});
2010-06-28 11:19:04 +00:00
$.each(self.visibleColumns, function(i, v) {
2010-09-03 20:54:40 +00:00
var $cell = $('<div>')
.addClass('OxCell OxColumn' + Ox.toTitleCase(v.id))
2010-06-25 15:55:25 +00:00
.css({
2010-09-03 20:54:40 +00:00
width: (self.columnWidths[i] - 9) + 'px',
2010-06-25 15:55:25 +00:00
textAlign: v.align
})
2010-09-03 20:54:40 +00:00
.html(!$.isEmptyObject(data) ? data[v.id] : '')
.appendTo($item);
2010-06-25 15:55:25 +00:00
});
return $item;
}
2010-07-03 11:31:25 +00:00
function dragColumn(id, e) {
var startX = e.clientX,
startPos = getColumnPositionById(id),
pos = startPos,
stopPos = startPos,
positions = $.map(self.visibleColumns, function(v, i) {
return self.columnPositions[i] - self.columnPositions[startPos]
});
2010-09-03 20:54:40 +00:00
$('.OxColumn' + Ox.toTitleCase(id)).css({
2010-07-05 07:09:34 +00:00
opacity: 0.1
});
2010-09-03 20:54:40 +00:00
that.$titles[startPos].addClass('OxDrag').css({ // fixme: why does the class not work?
cursor: 'move'
2010-07-03 11:31:25 +00:00
});
2010-09-03 20:54:40 +00:00
Ox.print('positions', positions)
2010-07-03 11:31:25 +00:00
$window.mousemove(function(e) {
var d = e.clientX - startX;
$.each(positions, function(i, v) {
if (d < 0 && d < v) {
stopPos = i;
return false;
} else if (d > 0 && d > v) {
stopPos = i;
}
});
if (stopPos != pos) {
pos = stopPos;
moveColumn(id, pos);
}
});
2010-09-03 20:54:40 +00:00
$window.one('mouseup', function() {
2010-07-03 11:31:25 +00:00
dropColumn(id, pos);
2010-09-03 20:54:40 +00:00
$window.unbind('mousemove');
2010-07-03 11:31:25 +00:00
});
}
function dropColumn(id, pos) {
2010-09-03 20:54:40 +00:00
Ox.print('dropColumn', id, pos)
2010-07-03 11:31:25 +00:00
var startPos = getColumnPositionById(id),
stopPos = pos,
$title = that.$titles.splice(startPos, 1)[0],
column = self.visibleColumns.splice(startPos, 1)[0],
width = self.columnWidths.splice(startPos, 1)[0];
that.$titles.splice(stopPos, 0, $title);
self.visibleColumns.splice(stopPos, 0, column);
self.columnWidths.splice(stopPos, 0, width);
2010-09-03 20:54:40 +00:00
Ox.print('s.vC', self.visibleColumns)
$('.OxColumn' + Ox.toTitleCase(id)).css({
2010-07-05 07:09:34 +00:00
opacity: 1
});
2010-09-03 20:54:40 +00:00
that.$titles[stopPos].removeClass('OxDrag').css({
cursor: 'pointer'
2010-07-03 11:31:25 +00:00
});
}
2010-06-29 21:24:07 +00:00
function getColumnIndexById(id) {
2010-06-25 15:55:25 +00:00
var pos = -1;
$.each(self.options.columns, function(i, v) {
if (v.id == id) {
pos = i;
return false;
}
});
return pos;
}
2010-06-29 21:24:07 +00:00
function getColumnPositionById(id) {
var pos = -1;
$.each(self.visibleColumns, function(i, v) {
if (v.id == id) {
pos = i;
return false;
}
});
return pos;
}
2010-06-30 09:02:13 +00:00
function getItemWidth() {
2010-06-30 18:47:10 +00:00
return Math.max(Ox.sum(self.columnWidths), that.$element.width() - oxui.scrollbarSize);
2010-09-04 14:28:40 +00:00
//return Ox.sum(self.columnWidths)
2010-06-30 09:02:13 +00:00
}
2010-07-03 11:31:25 +00:00
function moveColumn(id, pos) {
2010-09-03 20:54:40 +00:00
Ox.print('moveColumn', id, pos)
2010-07-03 11:31:25 +00:00
var startPos = getColumnPositionById(id),
stopPos = pos,
2010-09-03 20:54:40 +00:00
startClassName = '.OxColumn' + Ox.toTitleCase(id),
stopClassName = '.OxColumn' + Ox.toTitleCase(self.visibleColumns[stopPos].id),
$column = $('.OxTitle' + startClassName),
2010-07-03 11:31:25 +00:00
$order = $column.next(),
$resize = $order.next();
2010-09-03 20:54:40 +00:00
$column.detach().insertBefore($('.OxTitle' + stopClassName));
2010-07-03 11:31:25 +00:00
$order.detach().insertAfter($column);
$resize.detach().insertAfter($order);
2010-09-03 20:54:40 +00:00
$.each(that.$body.find('.OxItem'), function(i, v) {
2010-07-03 11:31:25 +00:00
var $v = $(v);
$v.children(startClassName).detach().insertBefore($v.children(stopClassName));
});
2010-06-28 09:16:36 +00:00
}
function removeColumn(id) {
2010-09-04 14:28:40 +00:00
Ox.print('removeColumn', id);
var className = '.OxColumn' + Ox.toTitleCase(id),
index = getColumnIndexById(id),
position = getColumnPositionById(id),
$column = $('.OxTitle' + className),
$order = $column.next(),
$resize = $order.next();
self.options.columns[index].visible = false;
self.visibleColumns.splice(position, 1);
self.columnWidths.splice(position, 1);
itemWidth = getItemWidth();
$column.remove();
$order.remove();
$resize.remove();
$.each(that.$body.find('.OxItem'), function(i, v) {
var $v = $(v);
$v.children(className).remove();
$v.css({
width: itemWidth + 'px'
});
});
that.$body.$content.css({
width: itemWidth + 'px'
});
that.$body.options({
keys: $.map(self.visibleColumns, function(v, i) {
return v.id;
})
});
2010-06-28 09:16:36 +00:00
}
2010-06-29 22:19:41 +00:00
function resize() {
}
2010-06-29 21:24:07 +00:00
function resizeColumn(id, width) {
var i = getColumnIndexById(id),
pos = getColumnPositionById(id);
2010-06-25 15:55:25 +00:00
self.columnWidths[pos] = width;
that.$head.$content.css({
2010-09-03 20:54:40 +00:00
width: (Ox.sum(self.columnWidths) + 2) + 'px'
2010-06-25 15:55:25 +00:00
});
that.$titles[pos].css({
2010-09-03 20:54:40 +00:00
width: (width - 9 - (i == self.selectedColumn ? 16 : 0)) + 'px'
2010-06-25 15:55:25 +00:00
});
2010-09-03 20:54:40 +00:00
that.$body.$content.find('.OxItem').css({ // fixme: can we avoid this lookup?
width: getItemWidth() + 'px'
2010-06-25 15:55:25 +00:00
});
that.$body.$content.css({
2010-09-03 20:54:40 +00:00
width: getItemWidth() + 'px' // fixme: check if scrollbar visible, and listen to resize/toggle event
2010-06-25 15:55:25 +00:00
});
2010-09-03 20:54:40 +00:00
$('.OxCell.OxColumn' + Ox.toTitleCase(self.options.columns[i].id)).css({
width: (width - 9) + 'px'
2010-06-25 15:55:25 +00:00
});
that.$body.clearCache();
}
2010-06-29 21:24:07 +00:00
function toggleSelected(id) {
var pos = getColumnPositionById(id);
2010-07-07 12:36:12 +00:00
if (pos > -1) {
updateOrder(id);
2010-09-03 20:54:40 +00:00
pos > 0 && that.$titles[pos].prev().children().eq(2).toggleClass('OxSelected');
that.$titles[pos].toggleClass('OxSelected');
that.$titles[pos].next().toggleClass('OxSelected');
that.$titles[pos].next().next().children().eq(0).toggleClass('OxSelected');
2010-07-07 12:36:12 +00:00
that.$titles[pos].css({
width: (
2010-09-03 20:54:40 +00:00
that.$titles[pos].width() + (that.$titles[pos].hasClass('OxSelected') ? -16 : 16)
) + 'px'
2010-07-07 12:36:12 +00:00
});
}
2010-06-25 15:55:25 +00:00
}
2010-06-29 21:24:07 +00:00
function updateOrder(id) {
var pos = getColumnPositionById(id);
Ox.print(id, pos)
2010-06-29 17:39:21 +00:00
that.$titles[pos].next().html(oxui.symbols[
2010-09-03 20:54:40 +00:00
'triangle_' + (self.options.sort[0].operator === '' ? 'up' : 'down')
2010-06-29 17:39:21 +00:00
]);
}
2010-06-30 18:47:10 +00:00
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'request') {
2010-06-30 18:47:10 +00:00
that.$body.options(key, value);
}
};
2010-07-20 20:04:13 +00:00
that.closePreview = function() {
self.preview = false;
};
that.resizeColumn = function(id, width) {
resizeColumn(id, width);
return that;
}
2010-06-25 15:55:25 +00:00
that.sort = function(key, operator) {
2010-06-29 16:28:22 +00:00
var isSelected = key == self.options.sort[0].key;
self.options.sort = [
{
key: key,
operator: operator
}
];
if (isSelected) {
2010-06-29 21:24:07 +00:00
updateOrder(self.options.columns[self.selectedColumn].id);
2010-06-29 16:28:22 +00:00
} else {
2010-06-29 21:24:07 +00:00
toggleSelected(self.options.columns[self.selectedColumn].id);
self.selectedColumn = getColumnIndexById(key);
toggleSelected(self.options.columns[self.selectedColumn].id);
2010-06-25 15:55:25 +00:00
}
2010-06-29 16:28:22 +00:00
that.$body.sort(self.options.sort[0].key, self.options.sort[0].operator);
return that;
2010-06-25 15:55:25 +00:00
};
return that;
};
2010-07-24 01:32:08 +00:00
/*
============================================================================
Maps
============================================================================
*/
Ox.Map = function(options, self) {
var self = self || {}
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-07-24 01:32:08 +00:00
.defaults({
places: [],
2010-09-03 20:54:40 +00:00
type: 'satellite'
2010-07-24 01:32:08 +00:00
})
.options(options || {});
init();
2010-07-24 19:27:39 +00:00
function canContain(outerBounds, innerBounds) {
var outerSpan = outerBounds.toSpan(),
innerSpan = innerBounds.toSpan();
return outerSpan.lat() > innerSpan.lat() &&
outerSpan.lng() > innerSpan.lng();
}
function click(event) {
2010-09-03 20:54:40 +00:00
Ox.print('event', event);
2010-07-24 19:27:39 +00:00
getLocationByLatLng(event.latLng, self.map.getBounds(), function(location) {
self.marker && self.marker.remove();
self.polygon && self.polygon.remove();
if (location) {
self.marker = location.marker.add();
self.polygon = location.polygon.add();
2010-09-03 20:54:40 +00:00
that.triggerEvent('select', location)
2010-07-24 19:27:39 +00:00
}
})
}
function getLocationByLatLng(latlng, bounds, callback) {
2010-09-03 20:54:40 +00:00
Ox.print('ll b', latlng, bounds)
2010-07-24 19:27:39 +00:00
var callback = arguments.length == 3 ? callback : bounds,
bounds = arguments.length == 3 ? bounds : null;
2010-07-24 01:32:08 +00:00
self.geocoder.geocode({
2010-07-24 19:27:39 +00:00
latLng: latlng
2010-07-24 01:32:08 +00:00
}, function(results, status) {
2010-09-03 20:54:40 +00:00
Ox.print('results', results)
2010-07-24 19:27:39 +00:00
var length = results.length;
2010-07-24 01:32:08 +00:00
if (status == google.maps.GeocoderStatus.OK) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
2010-07-24 19:27:39 +00:00
if (bounds) {
$.each(results.reverse(), function(i, result) {
if (
i == length - 1 ||
canContain(bounds, result.geometry.bounds || result.geometry.viewport)
) {
callback(new Location(results[i]));
return false;
}
});
} else {
callback(new Location(results[0]));
}
2010-07-24 01:32:08 +00:00
} else {
callback(null);
}
} else {
2010-09-03 20:54:40 +00:00
Ox.print('geocode failed:', status);
2010-07-24 01:32:08 +00:00
callback(null);
}
});
}
2010-07-24 19:27:39 +00:00
function getLocationByName(name, callback) {
self.geocoder.geocode({
address: name
}, function(results, status) {
2010-07-24 01:32:08 +00:00
if (status == google.maps.GeocoderStatus.OK) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
2010-07-24 19:27:39 +00:00
callback(new Location(results[0]))
} else {
callback(null);
2010-07-24 01:32:08 +00:00
}
2010-07-24 19:27:39 +00:00
} else {
2010-09-03 20:54:40 +00:00
Ox.print('geocode failed:', status);
2010-07-24 19:27:39 +00:00
callback(null);
2010-07-24 01:32:08 +00:00
}
});
}
function init() {
var counter = 0,
length = self.options.places.length;
$.extend(self, {
geocoder: new google.maps.Geocoder(),
2010-07-24 19:27:39 +00:00
locations: [],
selectedMarker: null
2010-07-24 01:32:08 +00:00
});
$.each(self.options.places, function(i, place) {
if (Ox.isString(place)) {
self.options.places[i] = {
name: place
};
} else if (Ox.isArray(place)) {
self.options.places[i] = {
2010-09-03 20:54:40 +00:00
name: '',
2010-07-24 01:32:08 +00:00
point: place
};
}
2010-09-03 20:54:40 +00:00
'point' in self.options.places[i] ?
2010-07-24 01:32:08 +00:00
getLocationByPoint(self.options.places[i].point, callback) :
getLocationByName(self.options.places[i].name, callback);
});
function callback(location) {
if (location) {
2010-09-03 20:54:40 +00:00
Ox.print('counter', counter, location)
2010-07-24 01:32:08 +00:00
self.locations.push(location);
self.bounds = counter == 0 ? location.rectangle.bounds :
self.bounds.union(location.rectangle.bounds);
}
if (counter++ == length - 1) {
loadMap();
}
}
}
function loadMap() {
2010-09-03 20:54:40 +00:00
Ox.print('loadMap');
2010-07-24 01:32:08 +00:00
$.extend(self, {
map: new google.maps.Map(that.$element[0], {
center: self.bounds.getCenter(),
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId[self.options.type.toUpperCase()],
zoom: 0
})
});
self.map.fitBounds(self.bounds)
2010-09-03 20:54:40 +00:00
google.maps.event.addListener(self.map, 'click', click);
google.maps.event.addListener(self.map, 'zoom_changed', zoom);
2010-07-24 01:32:08 +00:00
$.each(self.locations, function(i, location) {
location.marker.add();
});
2010-09-03 08:47:40 +00:00
resize();
2010-07-24 01:32:08 +00:00
};
2010-07-24 19:27:39 +00:00
function resize() {
2010-09-03 20:54:40 +00:00
google.maps.event.trigger(self.map, 'resize');
2010-07-24 19:27:39 +00:00
}
2010-07-24 01:32:08 +00:00
function zoom() {
2010-09-03 20:54:40 +00:00
that.triggerEvent('zoom', {
2010-09-03 08:47:40 +00:00
value: self.map.getZoom()
});
2010-07-24 01:32:08 +00:00
}
function Location(geocode) {
2010-09-03 20:54:40 +00:00
Ox.print('geocode', geocode);
2010-07-24 01:32:08 +00:00
var bounds = geocode.geometry.bounds || geocode.geometry.viewport,
area = [
[bounds.getSouthWest().lat(), bounds.getSouthWest().lng()],
[bounds.getNorthEast().lat(), bounds.getNorthEast().lng()]
],
location = {
geocode: geocode,
name: {
formatted: geocode.formatted_address,
long: $.map(geocode.address_components, function(v) {
return v.long_name;
2010-09-03 20:54:40 +00:00
}).join(', ')
2010-07-24 01:32:08 +00:00
},
rectangle: new Rectangle(area),
};
2010-09-03 20:54:40 +00:00
Ox.print('area', area)
2010-07-24 01:32:08 +00:00
return $.extend(location, {
marker: new Marker(location),
polygon: new Polygon(location)
});
}
function Marker(location) {
var listeners = {},
marker = new google.maps.Marker({
2010-09-03 20:54:40 +00:00
icon: icon('red'),
2010-07-24 01:32:08 +00:00
position: location.rectangle.center,
title: location.name.formatted
2010-07-24 19:27:39 +00:00
}),
selected = false;
2010-07-24 01:32:08 +00:00
function click() {
2010-07-24 19:27:39 +00:00
selected = !selected;
2010-07-24 01:32:08 +00:00
marker.setOptions({
2010-09-03 20:54:40 +00:00
icon: icon(selected ? 'blue' : 'red')
2010-07-24 01:32:08 +00:00
});
2010-09-03 20:54:40 +00:00
location.polygon[selected ? 'add' : 'remove']();
2010-07-24 19:27:39 +00:00
}
function dblclick() {
click();
self.map.fitBounds(location.rectangle.bounds);
2010-07-24 01:32:08 +00:00
}
function icon(color) {
2010-09-03 20:54:40 +00:00
return 'http://dev.pan.do:8000' + oxui.path + 'png/ox.ui/marker' + Ox.toTitleCase(color) + '.png'
2010-07-24 01:32:08 +00:00
}
return {
add: function() {
marker.setMap(self.map);
2010-07-24 19:27:39 +00:00
listeners = {
2010-09-03 20:54:40 +00:00
click: google.maps.event.addListener(marker, 'click', click),
dblclick: google.maps.event.addListener(marker, 'dblclick', dblclick),
2010-07-24 19:27:39 +00:00
};
return this;
},
deselect: function() {
2010-07-24 01:32:08 +00:00
},
remove: function() {
marker.setMap(null);
2010-07-24 19:27:39 +00:00
$.each(listeners, function(i, listener) {
google.maps.event.removeListener(listener);
});
return this;
},
select: function() {
2010-07-24 01:32:08 +00:00
}
};
}
function Polygon(location) {
var listeners = {},
points = [
location.rectangle.latlng.sw,
location.rectangle.latlng.nw,
location.rectangle.latlng.ne,
location.rectangle.latlng.se,
location.rectangle.latlng.sw
],
polygon = new google.maps.Polygon({
paths: points
}),
selected = false;
2010-07-24 19:27:39 +00:00
setOptions();
function click() {
selected = !selected;
setOptions();
}
2010-07-24 01:32:08 +00:00
function setOptions() {
2010-09-03 20:54:40 +00:00
var color = selected ? '#8080FF' : '#FFFFFF';
2010-07-24 01:32:08 +00:00
polygon.setOptions({
clickable: true,
fillColor: color,
fillOpacity: selected ? 0.1 : 0,
strokeColor: color,
strokeOpacity: 1,
strokeWeight: 2
});
}
return {
add: function() {
polygon.setMap(self.map);
2010-09-03 20:54:40 +00:00
listeners.click = google.maps.event.addListener(polygon, 'click', click);
2010-07-24 19:27:39 +00:00
return this;
2010-07-24 01:32:08 +00:00
},
deselect: function() {
selected = false;
setOptions();
},
remove: function() {
polygon.setMap(null);
google.maps.event.removeListener(listeners.click);
2010-07-24 19:27:39 +00:00
return this;
2010-07-24 01:32:08 +00:00
},
select: function() {
selected = true;
setOptions();
}
};
}
function Rectangle(area) {
var latlng = {
sw: new google.maps.LatLng(area[0][0], area[0][1]),
ne: new google.maps.LatLng(area[1][0], area[1][1])
},
bounds = new google.maps.LatLngBounds(latlng.sw, latlng.ne),
lat = {},
lng = {};
latlng.mc = bounds.getCenter();
$.each(latlng, function(k, v) {
lat[k] = v.lat();
lng[k] = v.lng();
});
$.extend(latlng, {
sc: new google.maps.LatLng(lat.sw, lng.mc),
2010-07-24 19:27:39 +00:00
se: new google.maps.LatLng(lat.sw, lng.ne),
mw: new google.maps.LatLng(lat.mc, lng.sw),
mw: new google.maps.LatLng(lat.mc, lng.ne),
nw: new google.maps.LatLng(lat.ne, lng.sw),
nc: new google.maps.LatLng(lat.ne, lng.mc),
2010-07-24 01:32:08 +00:00
});
return {
area: area,
bounds: bounds,
canContain: function(rectangle) {
var outerSpan = this.bounds.toSpan(),
innerSpan = rectangle.bounds.toSpan();
return outerSpan.lat() > innerSpan.lat() &&
outerSpan.lng() > innerSpan.lng();
},
center: latlng.mc,
contains: function(rectangle) {
return this.bounds.contains(rectangle.bounds.getSouthWest()) &&
this.bounds.contains(rectangle.bounds.getNorthEast());
},
latlng: latlng
};
}
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'type') {
2010-07-24 01:32:08 +00:00
}
};
2010-09-03 08:47:40 +00:00
that.find = function(name, callback) {
getLocationByName(name, function(location) {
if (location) {
self.polygon && self.polygon.remove();
self.polygon = location.polygon.add();
self.bounds = location.rectangle.bounds;
self.map.fitBounds(self.bounds);
}
callback(location);
});
};
that.zoom = function(value) {
self.map.setZoom(value);
};
2010-07-24 01:32:08 +00:00
return that;
};
Ox.MapImage = function(options, self) {
/*
options:
height image height (px)
2010-09-03 20:54:40 +00:00
places array of either names (''), points ([0, 0]),
2010-07-24 01:32:08 +00:00
or objects ({name, point, highlight})
2010-09-03 20:54:40 +00:00
type map type ('hybrid', 'roadmap', 'satellite', 'terrain')
2010-07-24 01:32:08 +00:00
width image width (px)
*/
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('img', self)
2010-07-24 01:32:08 +00:00
.defaults({
height: 360,
2010-09-03 20:54:40 +00:00
markerColorHighlight: 'yellow',
markerColorNormal: 'blue',
2010-07-24 01:32:08 +00:00
places: [],
2010-09-03 20:54:40 +00:00
type: 'satellite',
2010-07-24 01:32:08 +00:00
width: 640
})
.options(options || {})
$.extend(self, {
markers: {
highlight: [],
normal: []
},
2010-09-03 20:54:40 +00:00
src: 'http://maps.google.com/maps/api/staticmap?sensor=false' +
'&size=' + self.options.width + 'x' + self.options.height +
'&maptype=' + self.options.type
2010-07-24 01:32:08 +00:00
});
if (self.options.places.length) {
$.each(self.options.places, function(i, place) {
if (Ox.isString(place)) {
self.markers.normal.push(place);
} else if (Ox.isArray(place)) {
2010-09-03 20:54:40 +00:00
self.markers.normal.push(place.join(','));
2010-07-24 01:32:08 +00:00
} else {
2010-09-03 20:54:40 +00:00
self.markers[place.highlight ? 'highlight' : 'normal']
.push('point' in place ? place.point.join(',') : place.name)
2010-07-24 01:32:08 +00:00
}
});
$.each(self.markers, function(k, markers) {
if (markers.length) {
2010-09-03 20:54:40 +00:00
self.src += '&markers=icon:' + 'http://dev.pan.do:8000' + oxui.path + 'png/ox.ui/marker' +
Ox.toTitleCase(self.options['markerColor' + Ox.toTitleCase(k)]) + '.png|' +
markers.join('|')
2010-07-24 01:32:08 +00:00
}
});
} else {
2010-09-03 20:54:40 +00:00
self.src += '&center=0,0&zoom=2'
2010-07-24 01:32:08 +00:00
}
that.attr({
src: self.src
});
self.onChange = function(key, value) {
};
return that;
};
2010-01-07 20:21:07 +00:00
/*
============================================================================
2010-02-02 16:03:11 +00:00
Menus
============================================================================
*/
Ox.MainMenu = function(options, self) {
2010-02-07 15:01:22 +00:00
2010-02-19 10:24:02 +00:00
/* options:
* extras
* menus
* size
*/
2010-02-07 15:01:22 +00:00
var self = self || {},
that = new Ox.Bar({}, self)
2010-02-08 09:35:24 +00:00
.defaults({
2010-02-19 10:24:02 +00:00
extras: [],
2010-02-08 09:35:24 +00:00
menus: [],
2010-09-03 20:54:40 +00:00
size: 'medium'
2010-02-08 09:35:24 +00:00
})
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxMainMenu Ox' + Ox.toTitleCase(self.options.size)) // fixme: bar should accept small/medium/large ... like toolbar
2010-02-08 09:35:24 +00:00
.click(click)
.mousemove(mousemove);
2010-02-07 15:01:22 +00:00
2010-02-08 09:35:24 +00:00
self.focused = false;
self.selected = -1;
that.menus = [];
2010-02-09 05:43:36 +00:00
that.titles = [];
2010-09-03 20:54:40 +00:00
that.layer = $('<div>').addClass('OxLayer');
2010-02-08 09:35:24 +00:00
2010-02-19 10:57:19 +00:00
$.each(self.options.menus, function(position, menu) {
2010-09-03 20:54:40 +00:00
that.titles[position] = $('<div>')
.addClass('OxTitle')
2010-02-08 09:35:24 +00:00
.html(menu.title)
2010-09-03 20:54:40 +00:00
.data('position', position)
2010-02-08 09:35:24 +00:00
.appendTo(that.$element);
that.menus[position] = new Ox.Menu($.extend(menu, {
2010-09-03 08:47:40 +00:00
element: that.titles[position],
mainmenu: that,
size: self.options.size
}))
2010-09-03 20:54:40 +00:00
.bindEvent({
hide: onHideMenu
});
2010-02-08 09:35:24 +00:00
});
2010-02-19 10:57:19 +00:00
if (self.options.extras.length) {
2010-09-03 20:54:40 +00:00
that.extras = $('<div>')
.addClass('OxExtras')
2010-02-19 10:57:19 +00:00
.appendTo(that.$element);
$.each(self.options.extras, function(position, extra) {
2010-02-20 08:29:03 +00:00
extra.css({
2010-09-03 20:54:40 +00:00
float: 'left' // fixme: need class!
2010-02-20 08:29:03 +00:00
}).appendTo(that.extras);
2010-02-19 10:57:19 +00:00
});
}
2010-02-08 09:35:24 +00:00
function click(event) {
var $target = $(event.target),
2010-09-03 20:54:40 +00:00
position = typeof $target.data('position') != 'undefined' ?
$target.data('position') : -1;
2010-02-09 05:43:36 +00:00
clickTitle(position);
}
function clickTitle(position) {
var selected = self.selected;
if (self.selected > -1) {
that.menus[self.selected].hideMenu();
}
if (position > -1) {
if (position != selected) {
self.focused = true;
self.selected = position;
2010-09-03 20:54:40 +00:00
that.titles[self.selected].addClass('OxSelected');
2010-02-09 05:43:36 +00:00
that.menus[self.selected].showMenu();
}
2010-02-08 09:35:24 +00:00
}
}
function mousemove(event) {
var $target = $(event.target),
2010-02-09 05:43:36 +00:00
focused,
2010-09-03 20:54:40 +00:00
position = typeof $target.data('position') != 'undefined' ?
$target.data('position') : -1;
2010-02-09 05:43:36 +00:00
if (self.focused && position != self.selected) {
if (position > -1) {
clickTitle(position);
} else {
focused = self.focused;
that.menus[self.selected].hideMenu();
self.focused = focused;
2010-02-08 10:17:00 +00:00
}
2010-02-08 09:35:24 +00:00
}
}
2010-02-09 05:43:36 +00:00
function onHideMenu() {
2010-02-09 12:20:23 +00:00
if (self.selected > -1) {
2010-09-03 20:54:40 +00:00
that.titles[self.selected].removeClass('OxSelected');
2010-02-09 12:20:23 +00:00
self.selected = -1;
}
2010-02-08 09:35:24 +00:00
self.focused = false;
}
self.onChange = function(key, value) {
};
2010-02-19 10:24:02 +00:00
that.addMenuAfter = function(id) {
2010-02-08 10:17:00 +00:00
};
2010-02-19 10:24:02 +00:00
that.addMenuBefore = function(id) {
2010-02-08 10:17:00 +00:00
};
2010-07-07 12:36:12 +00:00
that.checkItem = function(id) {
2010-09-03 20:54:40 +00:00
var ids = id.split('_'),
itemId = ids.pop(),
menuId = ids.join('_');
that.getMenu(menuId).checkItem(itemId);
2010-07-07 12:36:12 +00:00
};
2010-02-10 16:37:26 +00:00
that.disableItem = function(id) {
2010-07-13 22:38:53 +00:00
that.getItem(id).options({
disabled: true
});
2010-02-10 16:37:26 +00:00
};
that.enableItem = function(id) {
2010-07-13 22:38:53 +00:00
that.getItem(id).options({
disabled: false
});
2010-02-10 16:37:26 +00:00
};
2010-02-19 16:13:22 +00:00
that.getItem = function(id) {
2010-09-03 20:54:40 +00:00
var ids = id.split('_'),
2010-07-07 12:36:12 +00:00
item;
if (ids.length == 1) {
$.each(that.menus, function(i, menu) {
item = menu.getItem(id);
return !item;
});
} else {
2010-09-03 20:54:40 +00:00
item = that.getMenu(ids.shift()).getItem(ids.join('_'));
2010-07-07 12:36:12 +00:00
}
2010-09-03 20:54:40 +00:00
Ox.print('getItem', id, item);
2010-02-19 16:13:22 +00:00
return item;
};
2010-09-03 20:54:40 +00:00
that.getMenu = function(id) {
var ids = id.split('_'),
menu;
if (ids.length == 1) {
$.each(that.menus, function(i, v) {
if (v.options('id') == id) {
menu = v;
return false;
}
});
} else {
menu = that.getMenu(ids.shift()).getSubmenu(ids.join('_'));
}
Ox.print('getMenu', id, menu);
return menu;
};
2010-02-08 10:17:00 +00:00
that.removeMenu = function() {
};
2010-02-08 09:35:24 +00:00
that.selectNextMenu = function() {
if (self.selected < self.options.menus.length - 1) {
clickTitle(self.selected + 1);
}
};
that.selectPreviousMenu = function() {
if (self.selected) {
clickTitle(self.selected - 1);
}
};
2010-07-07 12:36:12 +00:00
that.uncheckItem = function(id) {
2010-07-13 22:38:53 +00:00
that.getItem(id).options({
checked: false
});
2010-07-07 12:36:12 +00:00
};
2010-02-08 09:35:24 +00:00
return that;
};
2010-02-02 16:03:11 +00:00
Ox.Menu = function(options, self) {
2010-02-09 12:58:47 +00:00
/*
2010-02-10 15:49:57 +00:00
2010-02-09 12:58:47 +00:00
options:
2010-09-03 08:47:40 +00:00
element the element the menu is attached to
id the menu id
items array of menu items
mainmenu the main menu this menu is part of, if any
offset offset of the menu, in px
parent the supermenu, if any
selected the position of the selected item
2010-09-03 20:54:40 +00:00
side open to 'bottom' or 'right'
size 'large', 'medium' or 'small'
2010-02-10 15:49:57 +00:00
2010-07-07 12:36:12 +00:00
methods:
2010-02-10 15:49:57 +00:00
events:
2010-09-03 08:47:40 +00:00
change_groupId {id, value} checked item of a group has changed
click_itemId item not belonging to a group was clicked
click_menuId {id, value} item not belonging to a group was clicked
deselect_menuId {id, value} item was deselected not needed, not implemented
hide_menuId menu was hidden
select_menuId {id, value} item was selected
2010-02-10 15:49:57 +00:00
2010-02-09 12:58:47 +00:00
*/
2010-02-02 16:03:11 +00:00
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
2010-02-04 08:02:23 +00:00
element: null,
2010-09-03 20:54:40 +00:00
id: '',
2010-02-02 16:03:11 +00:00
items: [],
2010-02-08 09:35:24 +00:00
mainmenu: null,
2010-02-02 16:03:11 +00:00
offset: {
left: 0,
top: 0
},
2010-02-05 09:13:03 +00:00
parent: null,
2010-02-04 09:50:45 +00:00
selected: -1,
2010-09-03 20:54:40 +00:00
side: 'bottom',
size: 'medium',
2010-02-02 16:03:11 +00:00
})
2010-09-03 08:47:40 +00:00
.options(options || {})
2010-02-03 12:12:21 +00:00
.addClass(
2010-09-03 20:54:40 +00:00
'OxMenu Ox' + Ox.toTitleCase(self.options.side) +
' Ox' + Ox.toTitleCase(self.options.size)
2010-02-07 15:01:22 +00:00
)
.click(click)
.mouseenter(mouseenter)
.mouseleave(mouseleave)
2010-09-03 08:47:40 +00:00
.mousemove(mousemove)
.addEvent({
key_up: selectPreviousItem,
key_down: selectNextItem,
key_left: selectSupermenu,
key_right: selectSubmenu,
key_escape: hideMenu,
key_enter: clickSelectedItem
}),
2010-09-03 20:54:40 +00:00
itemHeight = self.options.size == 'small' ? 12 : (self.options.size == 'medium' ? 16 : 20),
2010-02-18 14:24:17 +00:00
// menuHeight,
2010-02-07 15:01:22 +00:00
scrollSpeed = 1,
2010-02-05 14:59:24 +00:00
$item; // fixme: used?
2010-09-03 08:47:40 +00:00
// fixme: attach all private vars to self
2010-02-02 16:03:11 +00:00
// construct
2010-02-04 08:02:23 +00:00
that.items = [];
that.submenus = {};
2010-02-02 16:03:11 +00:00
that.$scrollbars = [];
2010-09-03 20:54:40 +00:00
that.$top = $('<div>')
.addClass('OxTop')
2010-02-02 16:03:11 +00:00
.appendTo(that.$element);
2010-09-03 20:54:40 +00:00
that.$scrollbars.up = constructScrollbar('up')
2010-02-02 16:03:11 +00:00
.appendTo(that.$element);
2010-09-03 20:54:40 +00:00
that.$container = $('<div>')
.addClass('OxContainer')
2010-02-02 16:03:11 +00:00
.appendTo(that.$element);
2010-09-03 20:54:40 +00:00
that.$content = $('<table>')
.addClass('OxContent')
2010-02-02 16:03:11 +00:00
.appendTo(that.$container);
2010-02-18 07:27:32 +00:00
constructItems(self.options.items);
2010-09-03 20:54:40 +00:00
that.$scrollbars.down = constructScrollbar('down')
2010-02-02 16:03:11 +00:00
.appendTo(that.$element);
2010-09-03 20:54:40 +00:00
that.$bottom = $('<div>')
.addClass('OxBottom')
2010-02-02 16:03:11 +00:00
.appendTo(that.$element);
2010-09-03 20:54:40 +00:00
that.$layer = $('<div>')
.addClass(self.options.mainmenu ? 'OxMainMenuLayer' : 'OxLayer')
2010-09-03 08:47:40 +00:00
.click(click);
2010-02-02 16:03:11 +00:00
2010-02-05 09:13:03 +00:00
function click(event) {
2010-02-07 15:01:22 +00:00
var item,
2010-02-07 15:12:14 +00:00
position,
2010-09-03 08:47:40 +00:00
$target = $(event.target),
$parent = $target.parent();
// necessary for highlight
2010-09-03 20:54:40 +00:00
if ($parent.is('.OxCell')) {
2010-09-03 08:47:40 +00:00
$target = $parent;
$parent = $target.parent();
}
2010-09-03 20:54:40 +00:00
if ($target.is('.OxCell')) {
position = $parent.data('position');
2010-02-07 15:12:14 +00:00
item = that.items[position];
2010-09-03 20:54:40 +00:00
if (!item.options('disabled')) {
2010-02-07 15:12:14 +00:00
clickItem(position);
2010-02-09 12:20:23 +00:00
} else {
that.hideMenu();
2010-02-07 15:01:22 +00:00
}
2010-02-09 12:20:23 +00:00
} else {
that.hideMenu();
2010-02-05 09:13:03 +00:00
}
}
2010-02-07 15:12:14 +00:00
function clickItem(position) {
2010-09-03 08:47:40 +00:00
var item = that.items[position],
toggled;
2010-09-04 14:28:40 +00:00
that.hideMenu();
2010-09-03 20:54:40 +00:00
if (!item.options('items').length) {
if (that.options('parent')) {
that.options('parent').hideMenu().triggerEvent('click');
2010-02-08 09:35:24 +00:00
}
2010-09-03 20:54:40 +00:00
if (item.options('checked') !== null) {
if (item.options('group')) {
Ox.print('has group', item.options('group'))
toggled = self.optionGroups[item.options('group')].toggle(position);
Ox.print('toggled', toggled)
2010-09-03 08:47:40 +00:00
if (toggled.length) {
$.each(toggled, function(i, pos) {
that.items[pos].toggleChecked();
});
2010-09-03 20:54:40 +00:00
Ox.print('--triggering change event--');
(self.options.mainmenu || that).triggerEvent('change', {
id: item.options('group'),
checked: $.map(self.optionGroups[item.options('group')].checked(), function(v, i) {
2010-09-03 08:47:40 +00:00
return {
2010-09-03 20:54:40 +00:00
id: that.items[v].options('id'),
title: Ox.stripTags(that.items[v].options('title')[0])
};
2010-09-03 08:47:40 +00:00
})
});
}
} else {
item.toggleChecked();
2010-09-03 20:54:40 +00:00
(self.options.mainmenu || that).triggerEvent('change', {
checked: item.options('checked'),
id: item.options('id'),
title: Ox.stripTags(item.options('title')[0])
2010-09-03 08:47:40 +00:00
});
}
2010-02-09 12:20:23 +00:00
} else {
2010-09-03 20:54:40 +00:00
(self.options.mainmenu || that).triggerEvent('click', {
id: item.options('id'),
title: Ox.stripTags(item.options('title')[0])
2010-02-18 14:24:17 +00:00
});
2010-02-07 15:12:14 +00:00
}
2010-09-03 20:54:40 +00:00
if (item.options('title').length == 2) {
2010-02-07 15:12:14 +00:00
item.toggleTitle();
}
}
}
function clickSelectedItem() {
2010-02-09 05:43:36 +00:00
// called on key.enter
2010-02-04 09:50:45 +00:00
if (self.options.selected > -1) {
2010-02-07 15:12:14 +00:00
clickItem(self.options.selected);
2010-02-05 05:20:13 +00:00
} else {
that.hideMenu();
2010-02-04 09:50:45 +00:00
}
}
2010-02-18 07:27:32 +00:00
function constructItems(items) {
2010-09-03 08:47:40 +00:00
2010-02-18 07:27:32 +00:00
that.$content.empty();
2010-02-18 14:24:17 +00:00
scrollMenuUp();
2010-09-03 08:47:40 +00:00
self.optionGroups = {};
$.each(items, function(i, item) {
if (item.group) {
items[i] = $.map(item.items, function(v, i) {
return $.extend(v, {
group: item.group
});
});
self.optionGroups[item.group] = new Ox.OptionGroup(
items[i],
2010-09-03 20:54:40 +00:00
'min' in item ? item.min : 1,
'max' in item ? item.max : 1
2010-09-03 08:47:40 +00:00
);
}
});
items = Ox.flatten(items);
that.items = [];
2010-02-18 07:27:32 +00:00
$.each(items, function(i, item) {
var position;
if (item.id) {
that.items.push(new Ox.MenuItem($.extend(item, {
menu: that,
position: position = that.items.length
2010-09-03 20:54:40 +00:00
})).data('position', position).appendTo(that.$content)); // fixme: jquery bug when passing {position: position}? does not return the object?;
2010-02-18 07:27:32 +00:00
if (item.items) {
that.submenus[item.id] = new Ox.Menu({
element: that.items[position],
2010-09-03 20:54:40 +00:00
id: Ox.toCamelCase(self.options.id + '/' + item.id),
2010-02-18 07:27:32 +00:00
items: item.items,
mainmenu: self.options.mainmenu,
offset: {
left: 0,
top: -4
},
parent: that,
2010-09-03 20:54:40 +00:00
side: 'right',
2010-02-18 07:27:32 +00:00
size: self.options.size,
});
}
} else {
that.$content.append(constructSpace());
that.$content.append(constructLine());
that.$content.append(constructSpace());
}
});
2010-09-03 08:47:40 +00:00
2010-09-03 20:54:40 +00:00
if (!that.is(':hidden')) {
2010-02-18 14:24:17 +00:00
that.hideMenu();
that.showMenu();
}
2010-09-03 08:47:40 +00:00
2010-02-18 07:27:32 +00:00
}
2010-02-02 16:03:11 +00:00
function constructLine() {
2010-09-03 20:54:40 +00:00
return $('<tr>').append(
$('<td>', {
'class': 'OxLine',
2010-02-04 08:02:23 +00:00
colspan: 5
2010-02-03 12:12:21 +00:00
})
);
2010-02-02 16:03:11 +00:00
}
function constructScrollbar(direction) {
2010-02-05 14:59:24 +00:00
var interval,
2010-09-03 20:54:40 +00:00
speed = direction == 'up' ? -1 : 1;
return $('<div/>', {
'class': 'OxScrollbar Ox' + Ox.toTitleCase(direction),
html: oxui.symbols['triangle_' + direction],
2010-02-03 12:12:21 +00:00
click: function() { // fixme: do we need to listen to click event?
return false;
},
mousedown: function() {
scrollSpeed = 2;
return false;
},
mouseenter: function() {
2010-09-03 20:54:40 +00:00
var $otherScrollbar = that.$scrollbars[direction == 'up' ? 'down' : 'up'];
$(this).addClass('OxSelected');
if ($otherScrollbar.is(':hidden')) {
2010-02-03 12:12:21 +00:00
$otherScrollbar.show();
that.$container.height(that.$container.height() - itemHeight);
2010-09-03 20:54:40 +00:00
if (direction == 'down') {
2010-02-03 12:12:21 +00:00
that.$content.css({
2010-09-03 20:54:40 +00:00
top: -itemHeight + 'px'
2010-02-03 12:12:21 +00:00
});
}
}
2010-02-05 14:59:24 +00:00
scrollMenu(speed);
2010-02-03 12:12:21 +00:00
interval = setInterval(function() {
2010-02-05 14:59:24 +00:00
scrollMenu(speed);
2010-02-03 12:12:21 +00:00
}, 100);
},
mouseleave: function() {
2010-09-03 20:54:40 +00:00
$(this).removeClass('OxSelected');
2010-02-03 12:12:21 +00:00
clearInterval(interval);
},
mouseup: function() {
scrollSpeed = 1;
return false;
}
});
2010-02-02 16:03:11 +00:00
}
function constructSpace() {
2010-09-03 20:54:40 +00:00
return $('<tr>').append(
$('<td>', {
'class': 'OxSpace',
2010-02-04 08:02:23 +00:00
colspan: 5
2010-02-03 12:12:21 +00:00
})
);
2010-02-02 16:03:11 +00:00
}
function getElement(id) {
2010-02-05 09:13:03 +00:00
// fixme: needed?
2010-09-03 20:54:40 +00:00
return $('#' + Ox.toCamelCase(options.id + '/' + id));
}
function getItemPositionById(id) {
var position;
$.each(that.items, function(i, v) {
if (v.options('id') == id) {
position = i;
return false;
}
});
return position;
2010-02-02 16:03:11 +00:00
}
function hideMenu() {
// called on key_escape
that.hideMenu();
}
2010-02-05 05:20:13 +00:00
function isFirstEnabledItem() {
var ret = true;
$.each(that.items, function(i, item) {
2010-09-03 20:54:40 +00:00
if (i < self.options.selected && !item.options('disabled')) {
2010-02-05 05:20:13 +00:00
return ret = false;
}
});
return ret;
}
function isLastEnabledItem() {
var ret = true;
$.each(that.items, function(i, item) {
2010-09-03 20:54:40 +00:00
if (i > self.options.selected && !item.options('disabled')) {
2010-02-05 05:20:13 +00:00
return ret = false;
}
});
return ret;
}
2010-02-07 15:01:22 +00:00
function mouseenter() {
that.gainFocus();
}
function mouseleave() {
2010-09-03 20:54:40 +00:00
if (self.options.selected > -1 && !that.items[self.options.selected].options('items').length) {
2010-02-07 15:01:22 +00:00
selectItem(-1);
}
}
function mousemove(event) {
var item,
position,
$target = $(event.target);
2010-09-03 08:47:40 +00:00
$parent = $target.parent();
2010-09-03 20:54:40 +00:00
if ($parent.is('.OxCell')) {
2010-09-03 08:47:40 +00:00
$target = $parent;
$parent = $target.parent();
}
2010-09-03 20:54:40 +00:00
if ($target.is('.OxCell')) {
position = $parent.data('position');
2010-02-07 15:01:22 +00:00
item = that.items[position];
2010-09-03 20:54:40 +00:00
if (!item.options('disabled') && position != self.options.selected) {
2010-02-07 15:01:22 +00:00
selectItem(position);
}
} else {
mouseleave();
}
}
2010-02-03 12:12:21 +00:00
function scrollMenu(speed) {
var containerHeight = that.$container.height(),
contentHeight = that.$content.height(),
2010-09-03 20:54:40 +00:00
top = parseInt(that.$content.css('top')) || 0,
2010-02-03 12:12:21 +00:00
min = containerHeight - contentHeight + itemHeight,
max = 0;
top += speed * scrollSpeed * -itemHeight;
if (top <= min) {
top = min;
2010-09-03 20:54:40 +00:00
that.$scrollbars.down.hide().trigger('mouseleave');
2010-02-05 14:59:24 +00:00
that.$container.height(containerHeight + itemHeight);
2010-09-03 20:54:40 +00:00
that.items[that.items.length - 1].trigger('mouseover');
2010-02-03 12:12:21 +00:00
} else if (top >= max - itemHeight) {
top = max;
2010-09-03 20:54:40 +00:00
that.$scrollbars.up.hide().trigger('mouseleave');
2010-02-05 14:59:24 +00:00
that.$container.height(containerHeight + itemHeight);
2010-09-03 20:54:40 +00:00
that.items[0].trigger('mouseover');
2010-02-03 12:12:21 +00:00
}
that.$content.css({
2010-09-03 20:54:40 +00:00
top: top + 'px'
2010-02-03 12:12:21 +00:00
});
2010-02-02 16:03:11 +00:00
}
2010-02-05 17:37:15 +00:00
function scrollMenuUp() {
2010-09-03 20:54:40 +00:00
if (that.$scrollbars.up.is(':visible')) {
2010-02-05 17:37:15 +00:00
that.$content.css({
2010-09-03 20:54:40 +00:00
top: '0px'
2010-02-05 17:37:15 +00:00
});
that.$scrollbars.up.hide();
2010-09-03 20:54:40 +00:00
if (that.$scrollbars.down.is(':hidden')) {
2010-02-05 17:37:15 +00:00
that.$scrollbars.down.show();
} else {
that.$container.height(that.$container.height() + itemHeight);
}
}
}
2010-02-07 15:01:22 +00:00
function selectItem(position) {
var item;
if (self.options.selected > -1) {
2010-09-03 20:54:40 +00:00
//Ox.print('s.o.s', self.options.selected, that.items)
2010-02-18 14:24:17 +00:00
item = that.items[self.options.selected]
2010-09-03 20:54:40 +00:00
item.removeClass('OxSelected');
/* disabled
that.triggerEvent('deselect', {
id: item.options('id'),
title: Ox.stripTags(item.options('title')[0])
2010-09-03 08:47:40 +00:00
});
2010-09-03 20:54:40 +00:00
*/
2010-02-07 15:01:22 +00:00
}
if (position > -1) {
item = that.items[position];
$.each(that.submenus, function(id, submenu) {
2010-09-03 20:54:40 +00:00
if (!submenu.is(':hidden')) {
2010-02-07 15:01:22 +00:00
submenu.hideMenu();
return false;
}
});
2010-09-03 20:54:40 +00:00
item.options('items').length && that.submenus[item.options('id')].showMenu(); // fixme: do we want to switch to this style?
item.addClass('OxSelected');
/* disabled
that.triggerEvent('select', {
id: item.options('id'),
title: Ox.stripTags(item.options('title')[0])
2010-09-03 08:47:40 +00:00
});
2010-09-03 20:54:40 +00:00
*/
2010-02-07 15:01:22 +00:00
}
2010-02-18 09:11:47 +00:00
self.options.selected = position;
2010-02-07 15:01:22 +00:00
}
2010-02-02 16:03:11 +00:00
function selectNextItem() {
2010-02-05 15:26:23 +00:00
var offset,
selected = self.options.selected;
2010-09-03 20:54:40 +00:00
Ox.print('sNI', selected)
2010-02-05 05:20:13 +00:00
if (!isLastEnabledItem()) {
2010-02-05 17:37:15 +00:00
if (selected == -1) {
scrollMenuUp();
} else {
2010-09-03 20:54:40 +00:00
that.items[selected].removeClass('OxSelected');
2010-02-04 09:50:45 +00:00
}
2010-02-05 05:20:13 +00:00
do {
selected++;
2010-09-03 20:54:40 +00:00
} while (that.items[selected].options('disabled'))
2010-02-07 15:01:22 +00:00
selectItem(selected);
2010-02-05 15:26:23 +00:00
offset = that.items[selected].offset().top + itemHeight -
that.$container.offset().top - that.$container.height();
if (offset > 0) {
2010-09-03 20:54:40 +00:00
if (that.$scrollbars.up.is(':hidden')) {
2010-02-05 15:26:23 +00:00
that.$scrollbars.up.show();
that.$container.height(that.$container.height() - itemHeight);
offset += itemHeight;
}
if (selected == that.items.length - 1) {
that.$scrollbars.down.hide();
that.$container.height(that.$container.height() + itemHeight);
} else {
that.$content.css({
2010-09-03 20:54:40 +00:00
top: ((parseInt(that.$content.css('top')) || 0) - offset) + 'px'
2010-02-05 15:26:23 +00:00
});
}
}
2010-02-04 09:50:45 +00:00
}
2010-02-02 16:03:11 +00:00
}
function selectPreviousItem() {
2010-02-05 15:26:23 +00:00
var offset,
selected = self.options.selected;
2010-09-03 20:54:40 +00:00
Ox.print('sPI', selected)
2010-02-05 17:37:15 +00:00
if (selected > - 1) {
if (!isFirstEnabledItem()) {
2010-09-03 20:54:40 +00:00
that.items[selected].removeClass('OxSelected');
2010-02-05 17:37:15 +00:00
do {
selected--;
2010-09-03 20:54:40 +00:00
} while (that.items[selected].options('disabled'))
2010-02-07 15:01:22 +00:00
selectItem(selected);
2010-02-05 15:26:23 +00:00
}
2010-02-05 17:37:15 +00:00
offset = that.items[selected].offset().top - that.$container.offset().top;
if (offset < 0) {
2010-09-03 20:54:40 +00:00
if (that.$scrollbars.down.is(':hidden')) {
2010-02-05 17:37:15 +00:00
that.$scrollbars.down.show();
that.$container.height(that.$container.height() - itemHeight);
}
if (selected == 0) {
that.$scrollbars.up.hide();
that.$container.height(that.$container.height() + itemHeight);
}
that.$content.css({
2010-09-03 20:54:40 +00:00
top: ((parseInt(that.$content.css('top')) || 0) - offset) + 'px'
2010-02-05 17:37:15 +00:00
});
2010-02-05 15:26:23 +00:00
}
}
2010-02-02 16:03:11 +00:00
}
2010-02-05 09:13:03 +00:00
function selectSubmenu() {
2010-09-03 20:54:40 +00:00
Ox.print('selectSubmenu', self.options.selected)
2010-02-05 17:37:15 +00:00
if (self.options.selected > -1) {
2010-09-03 20:54:40 +00:00
var submenu = that.submenus[that.items[self.options.selected].options('id')];
Ox.print('submenu', submenu, that.submenus);
2010-02-05 17:37:15 +00:00
if (submenu && submenu.hasEnabledItems()) {
submenu.gainFocus();
submenu.selectFirstItem();
2010-02-08 09:35:24 +00:00
} else if (self.options.mainmenu) {
self.options.mainmenu.selectNextMenu();
}
} else if (self.options.mainmenu) {
self.options.mainmenu.selectNextMenu();
2010-02-05 09:13:03 +00:00
}
}
function selectSupermenu() {
2010-09-03 20:54:40 +00:00
Ox.print('selectSupermenu', self.options.selected)
2010-02-05 09:13:03 +00:00
if (self.options.parent) {
2010-09-03 20:54:40 +00:00
self.options.selected > -1 && that.items[self.options.selected].trigger('mouseleave');
scrollMenuUp();
2010-02-05 09:13:03 +00:00
self.options.parent.gainFocus();
2010-02-08 09:35:24 +00:00
} else if (self.options.mainmenu) {
self.options.mainmenu.selectPreviousMenu();
2010-02-05 09:13:03 +00:00
}
}
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'items') {
2010-02-18 07:27:32 +00:00
constructItems(value);
2010-09-03 20:54:40 +00:00
} else if (key == 'selected') {
that.$content.find('.OxSelected').removeClass('OxSelected');
2010-02-18 09:11:47 +00:00
selectItem(value);
2010-02-18 07:27:32 +00:00
}
2010-02-05 09:13:03 +00:00
}
2010-02-20 03:42:03 +00:00
that.addItem = function(item, position) {
};
2010-02-19 16:13:22 +00:00
that.addItemAfter = function(item, id) {
2010-02-08 10:17:00 +00:00
};
2010-02-19 16:13:22 +00:00
that.addItemBefore = function(item, id) {
2010-02-08 10:17:00 +00:00
};
2010-07-07 12:36:12 +00:00
that.checkItem = function(id) {
2010-09-03 20:54:40 +00:00
var item = that.getItem(id);
if (item.options('group')) {
var position = getItemPositionById(id),
toggled = self.optionGroups[item.options('group')].toggle(position);
if (toggled.length) {
$.each(toggled, function(i, pos) {
that.items[pos].toggleChecked();
});
}
} else {
item.options({
checked: true
});
}
2010-07-07 12:36:12 +00:00
};
2010-02-10 16:37:26 +00:00
that.getItem = function(id) {
2010-09-03 20:54:40 +00:00
Ox.print('id', id)
var ids = id.split('_'),
2010-07-07 12:36:12 +00:00
item;
if (ids.length == 1) {
$.each(that.items, function(i, v) {
2010-09-03 20:54:40 +00:00
if (v.options('id') == id) {
2010-07-07 12:36:12 +00:00
item = v;
return false;
}
});
if (!item) {
$.each(that.submenus, function(k, submenu) {
item = submenu.getItem(id);
return !item;
});
2010-02-10 20:02:58 +00:00
}
2010-07-07 12:36:12 +00:00
} else {
2010-09-03 20:54:40 +00:00
item = that.submenus[ids.shift()].getItem(ids.join('_'));
2010-07-07 12:36:12 +00:00
}
2010-02-19 16:13:22 +00:00
return item;
2010-02-10 16:37:26 +00:00
};
2010-09-03 20:54:40 +00:00
that.getSubmenu = function(id) {
var ids = id.split('_'),
submenu;
if (ids.length == 1) {
submenu = that.submenus[id];
} else {
submenu = that.submenus[ids.shift()].getSubmenu(ids.join('_'));
}
Ox.print('getSubmenu', id, submenu);
return submenu;
}
2010-02-05 09:13:03 +00:00
that.hasEnabledItems = function() {
var ret = false;
$.each(that.items, function(i, item) {
2010-09-03 20:54:40 +00:00
if (!item.options('disabled')) {
2010-02-05 09:13:03 +00:00
return ret = true;
}
});
return ret;
};
2010-02-02 16:03:11 +00:00
that.hideMenu = function() {
2010-09-03 20:54:40 +00:00
if (that.is(':hidden')) {
return;
}
2010-02-04 08:02:23 +00:00
$.each(that.submenus, function(i, submenu) {
2010-09-03 20:54:40 +00:00
if (submenu.is(':visible')) {
2010-02-04 08:02:23 +00:00
submenu.hideMenu();
2010-02-03 12:12:21 +00:00
return false;
}
});
2010-02-08 09:39:15 +00:00
selectItem(-1);
2010-02-05 17:37:15 +00:00
scrollMenuUp();
2010-09-03 20:54:40 +00:00
that.$scrollbars.up.is(':visible') && that.$scrollbars.up.hide();
that.$scrollbars.down.is(':visible') && that.$scrollbars.down.hide();
2010-02-18 14:24:17 +00:00
//that.$scrollbars.down.hide();
2010-02-05 15:42:52 +00:00
if (self.options.parent) {
2010-09-03 20:54:40 +00:00
//self.options.element.removeClass('OxSelected');
self.options.parent.options({
selected: -1
});
2010-02-05 15:42:52 +00:00
}
2010-02-09 05:43:36 +00:00
that.hide()
.loseFocus()
2010-09-03 20:54:40 +00:00
.triggerEvent('hide');
2010-02-09 05:43:36 +00:00
that.$layer.hide();
2010-02-08 09:35:24 +00:00
return that;
2010-02-05 09:13:03 +00:00
};
2010-02-08 10:17:00 +00:00
that.removeItem = function() {
};
2010-02-05 09:13:03 +00:00
that.selectFirstItem = function() {
selectNextItem();
2010-02-02 16:03:11 +00:00
};
that.showMenu = function() {
2010-09-03 20:54:40 +00:00
if (!that.is(':hidden')) {
return;
}
2010-02-09 05:43:36 +00:00
if (!self.options.parent && !that.$layer.parent().length) {
that.$layer.appendTo($body);
}
2010-09-03 08:47:40 +00:00
that.parent().length == 0 && that.appendTo($body);
2010-02-18 14:42:53 +00:00
that.css({
2010-09-03 20:54:40 +00:00
left: '-1000px',
top: '-1000px',
2010-02-18 14:42:53 +00:00
}).show();
2010-02-04 08:02:23 +00:00
var offset = self.options.element.offset(),
width = self.options.element.outerWidth(),
height = self.options.element.outerHeight(),
2010-09-03 20:54:40 +00:00
left = Ox.limit(
offset.left + self.options.offset.left + (self.options.side == 'bottom' ? 0 : width),
0, $window.width() - that.width()
),
top = offset.top + self.options.offset.top + (self.options.side == 'bottom' ? height : 0),
2010-02-18 14:42:53 +00:00
menuHeight = that.$content.outerHeight(); // fixme: why is outerHeight 0 when hidden?
2010-06-29 13:10:13 +00:00
menuMaxHeight = Math.floor($window.height() - top - 16);
2010-02-05 17:37:15 +00:00
if (self.options.parent) {
2010-02-18 14:24:17 +00:00
if (menuHeight > menuMaxHeight) {
2010-09-03 08:47:40 +00:00
top = Ox.limit(top - menuHeight + menuMaxHeight, self.options.parent.offset().top, top);
2010-02-18 14:24:17 +00:00
menuMaxHeight = Math.floor($window.height() - top - 16);
2010-02-05 17:37:15 +00:00
}
}
2010-02-18 14:42:53 +00:00
that.css({
2010-09-03 20:54:40 +00:00
left: left + 'px',
top: top + 'px'
2010-02-18 14:42:53 +00:00
});
2010-02-18 14:24:17 +00:00
if (menuHeight > menuMaxHeight) {
that.$container.height(menuMaxHeight - itemHeight - 8); // margin
2010-02-03 12:12:21 +00:00
that.$scrollbars.down.show();
2010-02-18 14:24:17 +00:00
} else {
that.$container.height(menuHeight);
2010-02-03 12:12:21 +00:00
}
2010-09-03 20:54:40 +00:00
if (!self.options.parent) {
2010-09-03 08:47:40 +00:00
that.gainFocus();
}
that.$layer.show();
2010-02-08 09:35:24 +00:00
return that;
2010-09-03 20:54:40 +00:00
//that.triggerEvent('show');
2010-02-02 16:03:11 +00:00
};
2010-02-03 12:12:21 +00:00
that.toggleMenu = function() {
2010-09-03 20:54:40 +00:00
that.is(':hidden') ? that.showMenu() : that.hideMenu();
2010-02-02 16:03:11 +00:00
};
return that;
2010-02-03 12:12:21 +00:00
};
2010-02-02 16:03:11 +00:00
Ox.MenuItem = function(options, self) {
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('tr', self)
2010-02-02 16:03:11 +00:00
.defaults({
2010-09-03 08:47:40 +00:00
bind: [], // fixme: what's this?
2010-02-04 08:02:23 +00:00
checked: null,
2010-02-02 16:03:11 +00:00
disabled: false,
2010-09-03 20:54:40 +00:00
group: '',
icon: '',
id: '',
2010-02-05 05:20:13 +00:00
items: [],
2010-09-03 20:54:40 +00:00
keyboard: '',
2010-02-03 12:12:21 +00:00
menu: null, // fixme: is passing the menu to 100s of menu items really memory-neutral?
2010-02-04 09:50:45 +00:00
position: 0,
2010-02-03 12:12:21 +00:00
title: [],
})
.options($.extend(options, {
keyboard: parseKeyboard(options.keyboard || self.defaults.keyboard),
title: Ox.makeArray(options.title || self.defaults.title)
}))
2010-09-03 20:54:40 +00:00
.addClass('OxItem' + (self.options.disabled ? ' OxDisabled' : ''))
2010-02-03 12:12:21 +00:00
.attr({
2010-09-03 20:54:40 +00:00
id: Ox.toCamelCase(self.options.menu.options('id') + '/' + self.options.id)
2010-02-03 12:12:21 +00:00
})
2010-09-03 20:54:40 +00:00
.data('group', self.options.group); // fixme: why?
2010-02-03 12:12:21 +00:00
2010-09-03 08:47:40 +00:00
if (self.options.group && self.options.checked === null) {
self.options.checked = false;
}
2010-02-03 12:12:21 +00:00
// construct
that.append(
2010-09-03 20:54:40 +00:00
that.$status = $('<td>', {
'class': 'OxCell OxStatus',
html: self.options.checked ? oxui.symbols.check : ''
2010-02-03 12:12:21 +00:00
})
)
.append(
2010-09-03 20:54:40 +00:00
that.$icon = $('<td>', {
'class': 'OxCell OxIcon'
2010-02-02 16:03:11 +00:00
})
2010-02-03 12:12:21 +00:00
.append(self.options.icon ?
2010-09-03 20:54:40 +00:00
$('<img>', {
2010-02-04 08:02:23 +00:00
src: self.options.icon
2010-02-03 12:12:21 +00:00
}) : null
)
)
.append(
2010-09-03 20:54:40 +00:00
that.$title = $('<td>', {
'class': 'OxCell OxTitle',
2010-02-03 12:12:21 +00:00
html: self.options.title[0]
})
)
.append(
2010-09-03 20:54:40 +00:00
$('<td>', {
'class': 'OxCell OxModifiers',
2010-02-03 12:12:21 +00:00
html: $.map(self.options.keyboard.modifiers, function(modifier) {
2010-02-08 09:45:48 +00:00
return oxui.symbols[modifier];
2010-09-03 20:54:40 +00:00
}).join('')
2010-02-03 12:12:21 +00:00
})
)
.append(
2010-09-03 20:54:40 +00:00
$('<td>', {
'class': 'OxCell Ox' + (self.options.items.length ? 'Submenu' : 'Key'),
2010-02-05 05:20:13 +00:00
html: self.options.items.length ? oxui.symbols.triangle_right :
2010-02-08 09:45:48 +00:00
oxui.symbols[self.options.keyboard.key] ||
self.options.keyboard.key.toUpperCase()
2010-02-03 12:12:21 +00:00
})
2010-02-05 05:20:13 +00:00
);
2010-02-03 12:12:21 +00:00
function parseKeyboard(str) {
2010-09-03 20:54:40 +00:00
var modifiers = str.split(' '),
2010-02-03 12:12:21 +00:00
key = modifiers.pop();
return {
modifiers: modifiers,
key: key
2010-07-05 17:01:42 +00:00
};
2010-02-03 12:12:21 +00:00
}
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'checked') {
that.$status.html(value ? oxui.symbols.check : '')
} else if (key == 'disabled') {
that.toggleClass('OxDisabled'); // fixme: this will only work if onChange is only invoked on actual change
} else if (key == 'title') {
2010-07-24 01:32:08 +00:00
self.options.title = Ox.makeArray(value);
that.$title.html(self.options.title[0]);
2010-02-03 12:12:21 +00:00
}
}
2010-02-10 16:37:26 +00:00
that.toggle = function() {
// toggle id and title
};
2010-02-03 12:12:21 +00:00
that.toggleChecked = function() {
2010-09-03 08:47:40 +00:00
that.options({
checked: !self.options.checked
});
2010-02-03 12:12:21 +00:00
};
that.toggleDisabled = function() {
};
that.toggleTitle = function() {
2010-09-03 20:54:40 +00:00
Ox.print('s.o.t', self.options.title)
2010-02-03 12:12:21 +00:00
that.options({
2010-07-24 01:32:08 +00:00
title: self.options.title.reverse()
2010-02-10 16:37:26 +00:00
});
2010-02-03 12:12:21 +00:00
};
2010-02-02 16:03:11 +00:00
return that;
2010-02-03 12:12:21 +00:00
};
2010-02-02 16:03:11 +00:00
/*
============================================================================
2010-01-07 20:21:07 +00:00
Panels
============================================================================
*/
/*
----------------------------------------------------------------------------
Ox.CollapsePanel
----------------------------------------------------------------------------
*/
Ox.CollapsePanel = function(options, self) {
var self = self || {},
that = new Ox.Panel({}, self)
.defaults({
collapsed: false,
size: 20,
2010-09-03 20:54:40 +00:00
title: ''
2010-01-07 20:21:07 +00:00
})
.options(options)
2010-09-03 20:54:40 +00:00
.addClass('OxCollapsePanel'),
title = self.options.collapsed ?
[{id: 'expand', title: 'expand'}, {id: 'collapse', title: 'collapse'}] :
[{id: 'collapse', title: 'collapse'}, {id: 'expand', title: 'expand'}];
2010-01-07 20:21:07 +00:00
$titlebar = new Ox.Bar({
2010-09-03 20:54:40 +00:00
orientation: 'horizontal',
2010-01-07 20:21:07 +00:00
size: self.options.size,
})
.dblclick(dblclickTitlebar)
.appendTo(that),
$switch = new Ox.Button({
2010-09-03 20:54:40 +00:00
id: self.options.id + 'Switch',
style: 'symbol',
title: title,
type: 'image',
2010-01-07 20:21:07 +00:00
})
.click(toggleCollapsed)
.appendTo($titlebar),
$title = new Ox.Element()
2010-09-03 20:54:40 +00:00
.addClass('OxTitle')
2010-01-07 20:21:07 +00:00
.html(self.options.title/*.toUpperCase()*/)
.appendTo($titlebar);
that.$content = new Ox.Element()
2010-09-03 20:54:40 +00:00
.addClass('OxContent')
2010-01-07 20:21:07 +00:00
.appendTo(that);
// fixme: doesn't work, content still empty
// need to hide it if collapsed
if (self.options.collapsed) {
that.$content.css({
2010-09-03 20:54:40 +00:00
marginTop: -that.$content.height() + 'px'
2010-01-07 20:21:07 +00:00
});
}
function dblclickTitlebar(e) {
2010-09-03 20:54:40 +00:00
if (!$(e.target).hasClass('OxButton')) {
$switch.trigger('click');
2010-01-07 20:21:07 +00:00
}
}
function toggleCollapsed() {
2010-09-03 20:54:40 +00:00
var marginTop;
self.options.collapsed = !self.options.collapsed;
marginTop = self.options.collapsed ? -that.$content.height() : 0;
2010-01-07 20:21:07 +00:00
that.$content.animate({
2010-09-03 20:54:40 +00:00
marginTop: marginTop + 'px'
2010-01-07 20:21:07 +00:00
}, 200);
}
2010-09-03 20:54:40 +00:00
self.onChange = function(key, value) {
if (key == 'collapsed') {
} else if (key == 'title') {
2010-01-07 20:21:07 +00:00
$title.html(self.options.title);
}
};
return that;
};
/*
----------------------------------------------------------------------------
Ox.Panel
----------------------------------------------------------------------------
*/
Ox.Panel = function(options, self) {
var self = self || {},
that = new Ox.Element({}, self)
2010-09-03 20:54:40 +00:00
.addClass('OxPanel');
2010-01-07 20:21:07 +00:00
return that;
};
/*
----------------------------------------------------------------------------
Ox.SplitPanel
options:
2010-07-17 08:46:27 +00:00
elements: [{ array of one, two or three elements
collapsible: false, collapsible or not (only for outer elements)
collapsed: false, collapsed or not (only for collapsible elements)
element: {}, OxElement (if any element is resizable or
collapsible, all OxElements must have an id)
resizable: false, resizable or not (only for outer elements)
resize: [], array of sizes (only for resizable elements,
first value is min, last value is max,
2010-09-03 20:54:40 +00:00
other values are 'snappy' points in between)
2010-07-17 08:46:27 +00:00
size: 0 size in px (one element must have no size)
}],
2010-09-03 20:54:40 +00:00
orientation: '' 'horizontal' or 'vertical'
2010-07-17 08:46:27 +00:00
methods:
isCollapsed(id) element is collapsed or not
resize(id, size) resize element to size px
toggle(id) collapse or expand element
events:
resize
toggle
2010-01-07 20:21:07 +00:00
----------------------------------------------------------------------------
*/
Ox.SplitPanel = function(options, self) {
2010-07-06 18:28:58 +00:00
2010-01-07 20:21:07 +00:00
var self = self || {},
that = new Ox.Element({}, self) // fixme: Container
2010-01-07 20:21:07 +00:00
.defaults({
elements: [],
2010-09-03 20:54:40 +00:00
orientation: 'horizontal'
2010-01-07 20:21:07 +00:00
})
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxSplitPanel');
2010-07-17 08:46:27 +00:00
$.extend(self, {
dimensions: oxui.getDimensions(self.options.orientation),
edges: oxui.getEdges(self.options.orientation),
length: self.options.elements.length
});
2010-07-06 18:28:58 +00:00
that.$elements = [];
2010-01-07 20:21:07 +00:00
$.each(self.options.elements, function(i, v) {
2010-07-17 08:46:27 +00:00
self.options.elements[i] = $.extend({
collapsible: false,
collapsed: false,
resizable: false,
resize: [],
2010-09-03 20:54:40 +00:00
size: 'auto'
2010-07-17 08:46:27 +00:00
}, v);
2010-07-06 18:28:58 +00:00
that.$elements[i] = v.element
2010-07-17 08:46:27 +00:00
.css(self.edges[2], 0)
.css(self.edges[3], 0);
2010-07-06 18:28:58 +00:00
});
2010-07-07 07:18:38 +00:00
setSizes();
2010-07-06 18:28:58 +00:00
$.each(self.options.elements, function(i, v) {
2010-01-07 20:21:07 +00:00
//that.append(element)
2010-09-03 20:54:40 +00:00
//Ox.print('V: ', v, that.$elements[i])
2010-09-03 08:47:40 +00:00
that.$elements[i].appendTo(that.$element); // fixme: that.$content
2010-07-06 18:28:58 +00:00
if (v.collapsible || v.resizable) {
2010-09-03 20:54:40 +00:00
Ox.print('v.size', v.size)
2010-07-17 08:46:27 +00:00
var $resizebar = new Ox.Resizebar({
2010-07-06 18:28:58 +00:00
collapsible: v.collapsible,
2010-07-17 08:46:27 +00:00
edge: self.edges[i == 0 ? 0 : 1],
2010-07-06 18:28:58 +00:00
elements: i < 2 ?
[that.$elements[0], that.$elements[1]] :
[that.$elements[1], that.$elements[2]],
2010-09-03 20:54:40 +00:00
id: v.element.options('id'),
orientation: self.options.orientation == 'horizontal' ? 'vertical' : 'horizontal',
parent: that, // fixme: that.$content
2010-07-06 18:28:58 +00:00
resizable: v.resizable,
resize: v.resize,
size: v.size
})
2010-07-17 08:46:27 +00:00
.css(self.edges[i == 0 ? 0 : 1], v.size);
2010-09-03 20:54:40 +00:00
$resizebar[i == 0 ? 'insertAfter' : 'insertBefore'](that.$elements[i]);
2010-07-06 18:28:58 +00:00
}
2010-01-07 20:21:07 +00:00
});
2010-07-06 18:28:58 +00:00
2010-07-07 07:18:38 +00:00
function getPositionById(id) {
var position = -1;
$.each(self.options.elements, function(i, element) {
2010-09-03 20:54:40 +00:00
if (element.element.options('id') == id) {
2010-07-17 08:46:27 +00:00
position = i;
2010-07-07 07:18:38 +00:00
return false;
}
});
2010-09-03 20:54:40 +00:00
Ox.print('getPositionById', id, position);
2010-07-07 07:18:38 +00:00
return position;
}
2010-07-06 18:28:58 +00:00
function getSize(element) {
2010-07-07 07:18:38 +00:00
return element.size + element.resizable;
2010-07-06 18:28:58 +00:00
}
2010-07-07 07:18:38 +00:00
function setSizes() {
$.each(self.options.elements, function(i, v) {
2010-09-03 20:54:40 +00:00
v.size != 'auto' && that.$elements[i].css(self.dimensions[0], v.size + 'px');
2010-07-07 07:18:38 +00:00
if (i == 0) {
2010-07-17 08:46:27 +00:00
that.$elements[i].css(self.edges[0], 0);
2010-09-03 20:54:40 +00:00
v.size != 'auto' && that.$elements[i].css(
self.edges[1], (getSize(self.options.elements[1]) + (length == 3 ? getSize(self.options.elements[2]) : 0)) + 'px'
2010-07-07 07:18:38 +00:00
);
} else if (i == 1) {
2010-09-03 20:54:40 +00:00
self.options.elements[0].size != 'auto' && that.$elements[i].css(
self.edges[0], getSize(self.options.elements[0]) + 'px'
2010-07-07 07:18:38 +00:00
);
2010-09-03 20:54:40 +00:00
(self.options.elements[0].size != 'auto' || v.size != 'auto') && that.$elements[i].css(
self.edges[1], (self.length == 3 ? getSize(self.options.elements[2]) : 0) + 'px'
2010-07-07 07:18:38 +00:00
);
} else {
2010-07-17 08:46:27 +00:00
that.$elements[i].css(self.edges[1], 0);
2010-09-03 20:54:40 +00:00
v.size != 'auto' && that.$elements[i].css(
self.edges[0], (getSize(self.options.elements[0]) + getSize(self.options.elements[1])) + 'px'
2010-07-07 07:18:38 +00:00
);
}
});
}
2010-07-17 08:46:27 +00:00
that.isCollapsed = function(id) {
return self.options.elements[getPositionById(id)].collapsed;
};
2010-09-03 20:54:40 +00:00
that.replace = function(id, element) {
// one can pass pos instead of id
var pos = Ox.isNumber(id) ? id : getPositionById(id);
Ox.print('element', self.options.elements[pos].element, element)
self.options.elements[pos].element.replaceWith(element.$element.$element || element.$element);
self.options.elements[pos].element = element;
that.$elements[pos] = element
.css(self.edges[2], 0)
.css(self.edges[3], 0);
setSizes();
Ox.print(self.options.elements[pos])
};
2010-07-07 07:18:38 +00:00
that.resize = function(id, size) {
// one can pass pos instead of id
var pos = Ox.isNumber(id) ? id : getPositionById(id);
2010-09-03 20:54:40 +00:00
// Ox.print('pos', pos, self.options.elements, $.map(self.options.elements, function(v, i) { return v.element.options('id'); }))
Ox.print('pos', pos, 'size', size)
2010-07-07 07:18:38 +00:00
self.options.elements[pos].size = size;
setSizes();
return that;
2010-07-07 07:18:38 +00:00
};
2010-07-17 08:46:27 +00:00
that.toggle = function(id) {
2010-09-03 20:54:40 +00:00
Ox.print('toggle', id);
2010-07-17 08:46:27 +00:00
/*
// something like this is needed to load in collapsed state
if (Ox.isUndefined(self.options.position)) {
self.options.position = parseInt(self.options.parent.css(self.options.edge)) +
(self.options.collapsed ? self.options.size : 0);
}
var size = self.options.position -
(self.options.collapsed ? 0 : self.options.size),
animate = {};
2010-09-03 20:54:40 +00:00
Ox.print('s.o.e', self.options.edge);
2010-07-17 08:46:27 +00:00
*/
var pos = getPositionById(id),
size = self.options.elements[pos].collapsed ? 0 : self.options.elements[pos].size,
animate = {};
animate[self.edges[pos == 0 ? 0 : 1]] = size;
self.options.parent.animate(animate, 200, function() {
2010-09-03 20:54:40 +00:00
var i = (self.options.edge == 'left' || self.options.edge == 'top') ? 1 : 0;
that.triggerEvent('resize', self.options.elements[i][self.dimensions[1]]());
2010-07-17 08:46:27 +00:00
self.options.elements[pos].collapsed = !self.options.elements[pos].collapsed;
});
};
2010-01-07 20:21:07 +00:00
return that;
2010-07-06 18:28:58 +00:00
2010-01-07 20:21:07 +00:00
};
2010-02-10 16:37:26 +00:00
Ox.TabPanel = function(options, self) {
};
2010-02-20 08:29:03 +00:00
/*
============================================================================
Requests
============================================================================
*/
2010-01-27 12:30:00 +00:00
2010-02-20 08:29:03 +00:00
/*
----------------------------------------------------------------------------
Ox.LoadingIcon
----------------------------------------------------------------------------
*/
2010-01-27 12:30:00 +00:00
2010-02-20 08:29:03 +00:00
Ox.LoadingIcon = function(options, self) {
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('img', self)
2010-02-20 08:29:03 +00:00
.defaults({
2010-09-03 20:54:40 +00:00
size: 'medium'
2010-02-20 08:29:03 +00:00
})
.options(options || {})
.attr({
2010-09-03 20:54:40 +00:00
src: oxui.path + '/png/ox.ui.' + Ox.theme() + '/loading.png' // fixme: oxui.themePath needed?
2010-02-20 08:29:03 +00:00
})
.addClass(
2010-09-03 20:54:40 +00:00
'OxLoadingIcon Ox' + Ox.toTitleCase(self.options.size)
2010-02-20 08:29:03 +00:00
);
self.deg = 0;
2010-07-01 23:51:08 +00:00
self.interval = 0;
self.isRunning = false;
function clear() {
clearInterval(self.interval);
self.deg = 0;
self.interval = 0;
update();
}
2010-02-20 08:29:03 +00:00
function update() {
that.css({
2010-09-03 20:54:40 +00:00
MozTransform: 'rotate(' + self.deg + 'deg)',
WebkitTransform: 'rotate(' + self.deg + 'deg)'
2010-02-20 08:29:03 +00:00
});
}
that.start = function() {
2010-07-01 23:51:08 +00:00
self.isRunning = true;
clear();
that.animate({
opacity: 1
}, 250);
self.interval = setInterval(function() {
self.deg = (self.deg + 30) % 360;
update();
}, 83);
2010-09-03 08:47:40 +00:00
return that;
2010-02-20 08:29:03 +00:00
};
that.stop = function() {
2010-07-01 23:51:08 +00:00
that.animate({
opacity: 0
}, 250, function() {
!self.isRunning && clear();
self.isRunning = false;
});
2010-09-03 08:47:40 +00:00
return that;
2010-02-20 08:29:03 +00:00
}
return that;
}
/*
----------------------------------------------------------------------------
Ox.Progressbar
----------------------------------------------------------------------------
*/
2010-01-27 12:30:00 +00:00
2010-07-24 01:32:08 +00:00
/*
============================================================================
Miscellaneous
============================================================================
*/
/*
----------------------------------------------------------------------------
Ox.Tooltip
----------------------------------------------------------------------------
*/
Ox.Tooltip = function(options, self) {
var self = self || {},
2010-09-03 20:54:40 +00:00
that = new Ox.Element('div', self)
2010-07-24 01:32:08 +00:00
.defaults({
2010-09-03 20:54:40 +00:00
title: ''
2010-07-24 01:32:08 +00:00
})
.options(options || {})
2010-09-03 20:54:40 +00:00
.addClass('OxTooltip')
2010-09-03 08:47:40 +00:00
.html(self.options.title);
2010-07-24 01:32:08 +00:00
self.onChange = function(key, value) {
2010-09-03 20:54:40 +00:00
if (key == 'title') {
2010-07-24 01:32:08 +00:00
that.html(value);
}
};
that.hide = function() {
that.animate({
opacity: 0
2010-09-03 08:47:40 +00:00
}, 0, function() {
2010-07-24 01:32:08 +00:00
that.remove();
});
return that;
};
2010-09-03 08:47:40 +00:00
that.show = function(x, y) {
2010-07-24 01:32:08 +00:00
var left, top, width, height;
2010-09-03 20:54:40 +00:00
$('.OxTooltip').remove(); // fixme: don't use dom
2010-07-24 01:32:08 +00:00
that.appendTo($body);
width = that.width();
height = that.height();
2010-09-03 08:47:40 +00:00
left = Ox.limit(x - width / 2, 0, $document.width() - width);
top = y > $document.height() - height - 16 ? y - 32 : y + 16;
2010-07-24 01:32:08 +00:00
that.css({
2010-09-03 20:54:40 +00:00
left: left + 'px',
top: top + 'px'
2010-07-24 01:32:08 +00:00
})
.animate({
opacity: 1
2010-09-03 08:47:40 +00:00
}, 0);
2010-07-24 01:32:08 +00:00
return that;
};
return that;
};
2010-01-27 12:30:00 +00:00
2010-07-13 22:38:53 +00:00
})();