add Ox.ArrayInput, more Ox.ListMap UI

This commit is contained in:
rolux 2011-05-21 19:56:15 +02:00
parent ce3bdb46d6
commit 6a33b9cb97
8 changed files with 381 additions and 101 deletions

View file

@ -581,14 +581,17 @@ Ox.load('Geo', function() {
}, },
{ {
options: { options: {
min: 0,
max: 100,
type: "float" type: "float"
}, },
title: "Float Input (0.0 - 100.0)" title: "Float Input (0.0 - 100.0)"
}, },
{ {
options: { options: {
min: 0,
max: 255, max: 255,
type: "integer" type: "int"
}, },
title: "Integer Input (0 - 255)" title: "Integer Input (0 - 255)"
}, },
@ -596,8 +599,7 @@ Ox.load('Geo', function() {
options: { options: {
clear: true, clear: true,
id: "integerClear", id: "integerClear",
max: 255, type: "int"
type: "integer"
}, },
title: "Integer Input with Clear Button" title: "Integer Input with Clear Button"
}, },
@ -605,8 +607,7 @@ Ox.load('Geo', function() {
options: { options: {
arrows: true, arrows: true,
id: "integerArrows", id: "integerArrows",
max: 255, type: "int"
type: "integer"
}, },
title: "Integer Input with Arrows" title: "Integer Input with Arrows"
}, },

View file

@ -1,16 +1,17 @@
Ox.load('UI', { Ox.load('UI', {
debug: true, debug: true,
hideScreen: true,
showScreen: true,
theme: 'modern' theme: 'modern'
}, function() { }, function() {
Ox.getJSON('json/cities100000.json', function(data) { Ox.load('Geo', function() {
Ox.getJSON('json/cities1000000.json', function(data) {
var listmap = new Ox.ListMap({ var listmap = new Ox.ListMap({
height: window.innerHeight, height: window.innerHeight,
places: data.map(function(city) { places: data.map(function(city) {
var marker = city.population > 20000000 ? {size: 24, color: [255, 0, 0]} : var countryCode = city.country_code == 'XK' ? 'RS-KO' : city.country_code,
marker = city.population > 20000000 ? {size: 24, color: [255, 0, 0]} :
city.population > 10000000 ? {size: 22, color: [255, 32, 0]} : city.population > 10000000 ? {size: 22, color: [255, 32, 0]} :
city.population > 5000000 ? {size: 20, color: [255, 64, 0]} : city.population > 5000000 ? {size: 20, color: [255, 64, 0]} :
city.population > 2000000 ? {size: 18, color: [255, 96, 0]} : city.population > 2000000 ? {size: 18, color: [255, 96, 0]} :
@ -23,10 +24,10 @@ Ox.load('UI', {
latSize = size / Ox.EARTH_CIRCUMFERENCE * 360, latSize = size / Ox.EARTH_CIRCUMFERENCE * 360,
lngSize = size * Ox.getDegreesPerMeter(city.latitude); lngSize = size * Ox.getDegreesPerMeter(city.latitude);
return { return {
countryCode: city.country_code == 'XK' ? 'RS-KO' : city.country_code, countryCode: countryCode,
editable: true, editable: true,
flag: city.country_code, flag: countryCode,
geoname: city.name, geoname: city.name + ', ' + Ox.getCountryByCode(countryCode).name,
markerColor: marker.color, markerColor: marker.color,
markerSize: marker.size, markerSize: marker.size,
name: city.name, name: city.name,
@ -49,6 +50,7 @@ Ox.load('UI', {
} }
}) })
.appendTo(Ox.UI.$body); .appendTo(Ox.UI.$body);
$(window).resize(function() { $(window).resize(function() {
Ox.print('RESIZE', window.innerHeight) Ox.print('RESIZE', window.innerHeight)
listmap.options({ listmap.options({
@ -58,5 +60,8 @@ Ox.load('UI', {
}); });
window.listmap = listmap; window.listmap = listmap;
}); });
});
}); });

View file

@ -1088,6 +1088,9 @@ Maps
position: absolute; position: absolute;
} }
.OxMap .OxRange .OxArrow {
border-radius: 0;
}
.OxMapButton { .OxMapButton {
position: absolute; position: absolute;

View file

@ -0,0 +1,151 @@
Ox.ArrayInput = function(options, self) {
self = self || {};
var that = Ox.Element({}, self)
.defaults({
label: '',
max: 0,
sort: false,
value: [],
width: 256
})
.options(options || {});
if (self.options.value.length == 0) {
self.options.value = [''];
}
if (self.options.label) {
self.$label = Ox.Label({
title: self.options.label,
width: self.options.width
})
.appendTo(that);
}
self.$element = [];
self.$input = [];
self.$removeButton = [];
self.$addButton = [];
self.options.value.forEach(function(value, i) {
addInput(i, value);
});
function addInput(i, value, focus) {
Ox.print('add', i)
self.$element.splice(i, 0, Ox.Element()
.css({height: '16px', marginTop: self.options.label || i > 0 ? '8px' : 0})
.data({index: i}));
if (i == 0) {
self.$element[i].appendTo(that);
} else {
Ox.print(i, self.$element)
self.$element[i].insertAfter(self.$element[i - 1]);
}
self.$input.splice(i, 0, Ox.Input({
value: value,
width: self.options.width - 48
})
.css({float: 'left'})
.bindEvent({
change: function(data) {
self.options.sort && data.value !== '' && sortInputs();
}
})
.appendTo(self.$element[i]));
focus && self.$input[i].focusInput();
self.$removeButton.splice(i, 0, Ox.Button({
disabled: self.$input.length == 1,
title: 'remove',
type: 'image'
})
.css({float: 'left', marginLeft: '8px'})
.bind({
click: function() {
removeInput($(this).parent().data('index'));
}
})
.appendTo(self.$element[i]));
self.$addButton.splice(i, 0, Ox.Button({
disabled: i == self.options.max - 1,
title: 'add',
type: 'image'
})
.css({float: 'left', marginLeft: '8px'})
.bind({
click: function() {
addInput($(this).parent().data('index') + 1, '', true);
}
})
.appendTo(self.$element[i]));
self.$input.length > 1 && self.$removeButton[0].options({disabled: false});
self.$input.length == self.options.max && self.$addButton.forEach(function($button) {
$button.options({disabled: true});
});
updateIndices();
}
function removeInput(i) {
Ox.print('remove', i);
['input', 'removeButton', 'addButton', 'element'].forEach(function(element) {
var key = '$' + element;
self[key][i].removeElement();
self[key].splice(i, 1);
});
self.$input.length == 1 && self.$removeButton[0].options({disabled: true});
self.$input.length == self.options.max - 1 && self.$addButton.forEach(function($button) {
$button.options({disabled: false});
});
updateIndices();
}
function setWidths() {
self.$label && self.$label.options({width: self.options.width})
self.$element.forEach(function($element, i) {
$element.css({width: self.options.width + 'px'});
self.$input[i].options({width: self.options.width - 48});
});
}
function sortInputs() {
Ox.sort(self.$element, function($element) {
return self.$input[$element.data('index')].value();
}).forEach(function($element) {
$element.detach();
});
self.$element.forEach(function($element, i) {
$element.data({index: i}).appendTo(that);
});
}
function updateIndices() {
self.$element.forEach(function($element, i) {
Ox.print(i, $element)
$element.data({index: i});
});
/*
self.$input.forEach(function($input, i) {
$input.options({value: i});
});
*/
}
self.setOption = function(key, value) {
if (key == 'width') {
setWidths();
}
}
// fixme: can't we generally use options.value for this?
that.value = function() {
if (arguments.length == 0) {
return Ox.map(self.$input, function($input) {
var value = $input.value();
return value === '' ? null : value;
});
}
};
return that;
};

View file

@ -5,7 +5,7 @@ Ox.Input <f:Ox.Element> Input Element
(options) -> <f> Input Element (options) -> <f> Input Element
(options, self) -> <f> Input Element (options, self) -> <f> Input Element
options <o> Options object options <o> Options object
arrows <b> if true, and type is 'float' or 'integer', display arrows arrows <b> if true, and type is 'float' or 'int', display arrows
arrowStep <n> step when clicking arrows arrowStep <n> step when clicking arrows
autocomplete <a> array of possible values, or autocomplete <a> array of possible values, or
<f> function(key, value, callback), returns one or more values <f> function(key, value, callback), returns one or more values
@ -14,7 +14,7 @@ Ox.Input <f:Ox.Element> Input Element
autocompleteSelect <b> if true, menu is displayed autocompleteSelect <b> if true, menu is displayed
autocompleteSelectHighlight <b> if true, value in menu is highlighted autocompleteSelectHighlight <b> if true, value in menu is highlighted
autocompleteSelectSubmit <b> if true, submit input on menu selection autocompleteSelectSubmit <b> if true, submit input on menu selection
autocorrect <s|r|f|null> ('email', 'float', 'integer', 'phone', 'url'), or autocorrect <s|r|f|null> ('email', 'float', 'int', 'phone', 'url'), or
<r> regexp(value), or <r> regexp(value), or
<f> function(key, value, blur, callback), returns value <f> function(key, value, blur, callback), returns value
autovalidate <f> --remote validation-- autovalidate <f> --remote validation--
@ -24,8 +24,8 @@ Ox.Input <f:Ox.Element> Input Element
height <n> px (for type='textarea' and type='range' with orientation='horizontal') height <n> px (for type='textarea' and type='range' with orientation='horizontal')
id <s> element id id <s> element id
key <s> to be passed to autocomplete and autovalidate functions key <s> to be passed to autocomplete and autovalidate functions
max <n> max value if type is 'integer' or 'float' max <n> max value if type is 'int' or 'float'
min <n> min value if type is 'integer' or 'float' min <n> min value if type is 'int' or 'float'
name <s> will be displayed by autovalidate function ('invalid ' + name) name <s> will be displayed by autovalidate function ('invalid ' + name)
overlap <s> '', 'left' or 'right', will cause padding and negative margin overlap <s> '', 'left' or 'right', will cause padding and negative margin
picker <o> picker object picker <o> picker object
@ -48,7 +48,7 @@ Ox.Input <f:Ox.Element> Input Element
trackValues <b> boolean trackValues <b> boolean
serialize <f> function used to serialize value in submit serialize <f> function used to serialize value in submit
textAlign <s> 'left', 'center' or 'right' textAlign <s> 'left', 'center' or 'right'
type <s> 'float', 'integer', 'password', 'text', 'textarea' type <s> 'float', 'int', 'password', 'text', 'textarea'
value <s> string value <s> string
validate <f> remote validation validate <f> remote validation
width <n> px width <n> px
@ -74,10 +74,11 @@ Ox.Input = function(options, self) {
autovalidate: null, autovalidate: null,
changeOnKeypress: false, changeOnKeypress: false,
clear: false, clear: false,
decimals: 0,
disabled: false, disabled: false,
key: '', key: '',
min: 0, min: -Infinity,
max: 100, max: Infinity,
label: '', label: '',
labelWidth: 64, labelWidth: 64,
overlap: 'none', overlap: 'none',
@ -97,6 +98,7 @@ Ox.Input = function(options, self) {
' OxOverlap' + Ox.toTitleCase(self.options.overlap) : '' ' OxOverlap' + Ox.toTitleCase(self.options.overlap) : ''
)*/ )*/
) )
.css({width: self.options.width + 'px'})
.bindEvent($.extend(self.options.type == 'textarea' ? {} : { .bindEvent($.extend(self.options.type == 'textarea' ? {} : {
key_enter: submit key_enter: submit
}, { }, {
@ -114,15 +116,17 @@ Ox.Input = function(options, self) {
} }
// fixme: set to min, not 0 // fixme: set to min, not 0
// fixme: validate self.options.value !
if (self.options.type == 'float') { if (self.options.type == 'float') {
self.decimals = Ox.repeat('0', self.options.decimals || 1)
$.extend(self.options, { $.extend(self.options, {
autovalidate: 'float', autovalidate: 'float',
textAlign: 'right', textAlign: 'right',
value: self.options.value || '0.0' value: self.options.value || '0.' + self.decimals
}); });
} else if (self.options.type == 'integer') { } else if (self.options.type == 'int') {
$.extend(self.options, { $.extend(self.options, {
autovalidate: 'integer', autovalidate: 'int',
textAlign: 'right', textAlign: 'right',
value: self.options.value || '0' value: self.options.value || '0'
}); });
@ -176,7 +180,8 @@ Ox.Input = function(options, self) {
} }
$.extend(self, { $.extend(self, {
bindKeyboard: self.options.autocomplete || self.options.autovalidate || self.options.changeOnKeypress, bindKeyboard: self.options.autocomplete || self.options.autovalidate ||
self.options.changeOnKeypress,
hasPasswordPlaceholder: self.options.type == 'password' && self.options.placeholder, hasPasswordPlaceholder: self.options.type == 'password' && self.options.placeholder,
inputWidth: getInputWidth() inputWidth: getInputWidth()
}); });
@ -449,48 +454,57 @@ Ox.Input = function(options, self) {
function autovalidateTypeFunction(type, value) { function autovalidateTypeFunction(type, value) {
// fixme: remove trailing zeroes on blur // fixme: remove trailing zeroes on blur
// /(^\-?\d+\.?\d{0,8}$)/('-13000.12345678')
var cursor, var cursor,
regexp = type == 'float' ? /[\d\.]/ : /\d/; length,
regexp = type == 'float' ? new RegExp(
'(^' + (self.options.min < 0 ? '\\-?' : '') + '\\d+\\.?\\d' +
(self.options.decimals ? '{0,' + self.options.decimals + '}' : '*')
+ '$)'
) : new RegExp('(^' + (self.options.min < 0 ? '\\-?' : '') + '\\d+)');
if (type == 'float') { if (type == 'float') {
if (value.indexOf('.') != value.lastIndexOf('.')) { //Ox.print('--float--', value)
value = oldValue; if (value === '') {
} else { value = '0.' + self.decimals;
if (self.autovalidateFloatFlag) { cursor = [0, value.length];
if (Ox.endsWith(value, '.')) { } else if (value == '-') {
value = value.substr(0, value.length - 1); value = '-0.' + self.decimals;
} cursor = [1, value.length];
self.autovalidateFloatFlag = false; } else if (value == '.') {
} value = '0.' + self.decimals;
while (value[0] == '0' && value[1] != '.') { cursor = [2, value.length];
value = value.substr(1); } else if (!/\./(value)) {
} value += '.' + self.decimals
while (Ox.startsWith(value, '.')) { cursor = [value.indexOf('.'), value.length];
if (Ox.startsWith(value, '..')) { } else if (/^\./(value)) {
value = value.substr(1); value = '0' + value;
} else { cursor = [2, value.length];
value = '0' + value; } else if (/\.$/(value)) {
} //Ox.print('$$$$$$$$$$$')
} value += self.decimals;
if (Ox.endsWith(value, '.')) { cursor = [value.indexOf('.') + 1, value.length];
value += '0'; } else if (/\./(value) && self.options.decimals) {
cursor = [value.length - 1, value.length]; length = value.split('.')[1].length;
self.autovalidateFloatFlag = true; if (length > self.options.decimals) {
value = value.substr(0, value.indexOf('.') + 1 + self.options.decimals);
cursor = [oldCursor[0] + 1, oldCursor[1] + 1];
} else if (length < self.options.decimals) {
value += Ox.repeat('0', self.options.decimals - length);
cursor = [value.indexOf('.') + 1 + length, value.length];
} }
} }
} } else {
value = $.map(value.split(''), function(v) { if (value === '') {
return regexp(v) ? v : null; value = '0';
}).join(''); cursor = [0, 1];
if (type == 'integer') {
while (value.length > 1 && Ox.startsWith(value, '0')) {
value = value.substr(1);
} }
} }
if (value === '') { while (/^0\d/(value)) {
value = type == 'float' ? '0.0' : '0'; value = value.substr(1, value.length);
cursor = [0, value.length]; }
} else if (value > self.options.max) { if (!regexp.test(value) || value < self.options.min || value > self.options.max) {
value = oldValue; value = oldValue;
cursor = oldCursor;
} }
autovalidateCallback(value, cursor); autovalidateCallback(value, cursor);
} }
@ -549,8 +563,8 @@ Ox.Input = function(options, self) {
self.options.placeholder && setPlaceholder(); self.options.placeholder && setPlaceholder();
self.options.validate && validate(); self.options.validate && validate();
if (self.bindKeyboard) { if (self.bindKeyboard) {
Ox.UI.$document.unbind('keydown', keypress); Ox.UI.$document.unbind('keydown', keydown);
Ox.UI.$document.unbind('keypress', keypress); //Ox.UI.$document.unbind('keypress', keypress);
} }
that.triggerEvent('blur'); that.triggerEvent('blur');
} }
@ -572,7 +586,7 @@ Ox.Input = function(options, self) {
var value = ''; var value = '';
if (self.options.type == 'float') { if (self.options.type == 'float') {
value = '0.0'; value = '0.0';
} else if (self.options.type == 'integer') { } else if (self.options.type == 'int') {
value = '0' value = '0'
} }
self.$input.val(value); self.$input.val(value);
@ -615,7 +629,7 @@ Ox.Input = function(options, self) {
function deselectMenu() { function deselectMenu() {
return; return;
Ox.print('deselectMenu') //Ox.print('deselectMenu')
self.options.value = self.oldValue; self.options.value = self.oldValue;
self.$input.val(self.options.value); self.$input.val(self.options.value);
cursor(self.oldCursor); cursor(self.oldCursor);
@ -636,8 +650,8 @@ Ox.Input = function(options, self) {
if (self.bindKeyboard) { if (self.bindKeyboard) {
//Ox.print('binding...') //Ox.print('binding...')
// fixme: different in webkit and firefox (?), see keyboard handler, need generic function // fixme: different in webkit and firefox (?), see keyboard handler, need generic function
Ox.UI.$document.keydown(keypress); Ox.UI.$document.keydown(keydown);
Ox.UI.$document.keypress(keypress); //Ox.UI.$document.keypress(keypress);
self.options.autocompleteSelect && setTimeout(autocomplete, 0); // fixme: why is the timeout needed? self.options.autocompleteSelect && setTimeout(autocomplete, 0); // fixme: why is the timeout needed?
} }
that.triggerEvent('focus'); that.triggerEvent('focus');
@ -651,7 +665,7 @@ Ox.Input = function(options, self) {
(self.options.style == 'rounded' ? 14 : 6); (self.options.style == 'rounded' ? 14 : 6);
} }
function keypress(event) { function keydown(event) {
var oldCursor = cursor(), var oldCursor = cursor(),
oldValue = self.options.value, oldValue = self.options.value,
newValue = oldValue.substr(0, oldCursor[0] - 1), newValue = oldValue.substr(0, oldCursor[0] - 1),
@ -664,7 +678,8 @@ Ox.Input = function(options, self) {
) { // fixme: can't 13 and 27 return false? ) { // fixme: can't 13 and 27 return false?
setTimeout(function() { // wait for val to be set setTimeout(function() { // wait for val to be set
var value = self.$input.val(); var value = self.$input.val();
if (self.options.autocompleteReplace && hasDeletedSelectedEnd) { if ((self.options.autocompleteReplace || self.options.decimals) && hasDeletedSelectedEnd) {
//Ox.print('HAS DELETED SELECTED END', event.keyCode)
value = newValue; value = newValue;
self.$input.val(value); self.$input.val(value);
} }
@ -697,7 +712,7 @@ Ox.Input = function(options, self) {
function selectMenu(event, data) { function selectMenu(event, data) {
var pos = cursor(); var pos = cursor();
//if (self.options.value) { //if (self.options.value) {
Ox.print('selectMenu', pos, data.title) //Ox.print('selectMenu', pos, data.title)
self.options.value = data.title self.options.value = data.title
self.$input.val(self.options.value); self.$input.val(self.options.value);
cursor(pos[0], self.options.value.length); cursor(pos[0], self.options.value.length);
@ -778,6 +793,7 @@ Ox.Input = function(options, self) {
self.$input.val(value); self.$input.val(value);
setPlaceholder(); setPlaceholder();
} else if (key == 'width') { } else if (key == 'width') {
that.css({width: self.options.width + 'px'});
inputWidth = getInputWidth(); inputWidth = getInputWidth();
self.$input.css({ self.$input.css({
width: inputWidth + 'px' width: inputWidth + 'px'
@ -1535,8 +1551,8 @@ Ox.InputElement_ = function(options, self) {
} }
} }
if (self.bindKeyboard) { if (self.bindKeyboard) {
Ox.UI.$document.unbind('keydown', keypress); Ox.UI.$document.unbind('keydown', keydown);
Ox.UI.$document.unbind('keypress', keypress); //Ox.UI.$document.unbind('keypress', keypress);
} }
} }
@ -1585,14 +1601,13 @@ Ox.InputElement_ = function(options, self) {
} }
if (self.bindKeyboard) { if (self.bindKeyboard) {
// fixme: different in webkit and firefox (?), see keyboard handler, need generic function // fixme: different in webkit and firefox (?), see keyboard handler, need generic function
Ox.UI.$document.keydown(keypress); Ox.UI.$document.keydown(keydown);
Ox.UI.$document.keypress(keypress);
//Ox.print('calling autosuggest...') //Ox.print('calling autosuggest...')
self.options.autosuggest && setTimeout(autosuggestCall, 0); // fixme: why is the timeout needed? self.options.autosuggest && setTimeout(autosuggestCall, 0); // fixme: why is the timeout needed?
} }
} }
function keypress(event) { function keydown(event) {
//Ox.print('keyCode', event.keyCode) //Ox.print('keyCode', event.keyCode)
if (event.keyCode != 9 && event.keyCode != 13 && event.keyCode != 27) { // fixme: can't 13 and 27 return false? 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 setTimeout(function() { // fixme: document what this timeout is for

View file

@ -35,6 +35,8 @@ Ox.Label = function(options, self) {
self.setOption = function(key, value) { self.setOption = function(key, value) {
if (key == 'title') { if (key == 'title') {
that.html(value); that.html(value);
} else if (key == 'width') {
that.css({width: self.options.width - 14 + 'px'})
} }
} }

View file

@ -18,7 +18,7 @@ Ox.ListMap <f:Ox.Element> ListMap Object
Ox.ListMap = function(options, self) { Ox.ListMap = function(options, self) {
var self = self || {}, var self = self || {},
that = new Ox.Element({}, self) that = Ox.Element({}, self)
.defaults({ .defaults({
addPlace: null, addPlace: null,
height: 256, height: 256,
@ -187,13 +187,13 @@ Ox.ListMap = function(options, self) {
} }
]; ];
self.$toolbar = new Ox.Bar({ self.$listToolbar = Ox.Bar({
size: 24 size: 24
}); });
self.$findElement = new Ox.FormElementGroup({ self.$findElement = Ox.FormElementGroup({
elements: [ elements: [
self.$findSelect = new Ox.Select({ self.$findSelect = Ox.Select({
items: [ items: [
{id: 'all', title: 'Find: All'}, {id: 'all', title: 'Find: All'},
{id: 'name', title: 'Find: Name'}, {id: 'name', title: 'Find: Name'},
@ -203,16 +203,16 @@ Ox.ListMap = function(options, self) {
overlap: 'right', overlap: 'right',
width: 128 width: 128
}), }),
self.$findInput = new Ox.Input({ self.$findInput = Ox.Input({
clear: true, clear: true,
width: 192 width: 192
}) })
] ]
}) })
.css({float: 'right', margin: '4px'}) .css({float: 'right', margin: '4px'})
.appendTo(self.$toolbar) .appendTo(self.$listToolbar)
self.$list = new Ox.TextList({ self.$list = Ox.TextList({
columns: self.columns, columns: self.columns,
columnsRemovable: true, columnsRemovable: true,
columnsVisible: true, columnsVisible: true,
@ -233,19 +233,95 @@ Ox.ListMap = function(options, self) {
select: selectItem select: selectItem
}); });
self.$statusbar = new Ox.Bar({ self.$listStatusbar = Ox.Bar({
size: 24 size: 16
});
self.$status = Ox.Element()
.css({paddingTop: '2px', margin: 'auto', fontSize: '9px', textAlign: 'center'})
.html(self.options.places.length + ' Place' + (self.options.places.length == 1 ? '' : 's'))
.appendTo(self.$listStatusbar);
self.$placeToolbar = Ox.Bar({
size: 24
});
self.$newPlaceButton = Ox.Button({
id: 'newPlace',
title: 'New Place',
width: 80
})
.css({float: 'left', margin: '4px'})
.appendTo(self.$placeToolbar);
self.$placeFormItems = Ox.merge([
Ox.Input({
id: 'name',
label: 'Name',
labelWidth: 64,
width: 240
}),
Ox.Input({
id: 'geoname',
label: 'Geoname',
labelWidth: 64,
width: 240
}),
Ox.ArrayInput({
id: 'alternativeNames',
label: 'Alternative Names',
max: 10,
//sort: true,
values: [],
width: 240
}),
], ['Latitude', 'Longitude', 'South', 'West', 'North', 'East'].map(function(v) {
var key = (
v == 'Latitude' ? 'lat' : v == 'Longitude' ? 'lng' : v
).toLowerCase(),
max = ['Latitude', 'South', 'North'].indexOf(v) > -1 ? Ox.MAX_LATITUDE : 180;
return Ox.Input({
decimals: 8,
label: v,
labelWidth: 80,
min: -max,
max: max,
type: 'float',
value: self.options.places[0][key].toFixed(8),
width: 240
}); });
}));
self.$status = new Ox.Element() self.$placeForm = Ox.Form({
.css({paddingTop: '4px', margin: 'auto', textAlign: 'center'}) items: self.$placeFormItems,
.appendTo(self.$statusbar); width: 240
})
.css({margin: '8px'});
self.$placeStatusbar = Ox.Bar({
size: 16
})
.addClass('OxVideoPlayer'); // fixme!
self.$savePlaceButton = Ox.Button({
disabled: true,
id: 'savePlace',
title: 'check',
style: 'symbol',
tooltip: 'Save Place',
type: 'image',
//width: 80
})
.css({float: 'right'})
.appendTo(self.$placeStatusbar);
/*
self.mapResize = [ self.mapResize = [
Math.round(self.options.width * 0.25), Math.round(self.options.width * 0.25),
Math.round(self.options.width * 0.5), Math.round(self.options.width * 0.5),
Math.round(self.options.width * 0.75) Math.round(self.options.width * 0.75)
]; ];
*/
if (Ox.isArray(self.options.places)) { if (Ox.isArray(self.options.places)) {
init(self.options.places) init(self.options.places)
@ -266,15 +342,15 @@ Ox.ListMap = function(options, self) {
function init(places) { function init(places) {
//Ox.print('PLACES', places) //Ox.print('PLACES', places)
self.$map = new Ox.Map({ self.$map = Ox.Map({
clickable: true, clickable: true,
editable: true, editable: true,
findPlaceholder: 'Find on Map', findPlaceholder: 'Find on Map',
height: self.options.height, height: self.options.height,
places: places, places: places,
statusbar: true, //statusbar: true,
toolbar: true, toolbar: true,
width: self.mapResize[1], width: self.options.width - 514,//self.mapResize[1],
zoombar: true zoombar: true
}) })
.bindEvent({ .bindEvent({
@ -290,31 +366,51 @@ Ox.ListMap = function(options, self) {
selectplace: selectPlace selectplace: selectPlace
}); });
that.$element.replaceWith( that.$element.replaceWith(
that.$element = new Ox.SplitPanel({ that.$element = Ox.SplitPanel({
elements: [ elements: [
{ {
element: new Ox.SplitPanel({ element: Ox.SplitPanel({
elements: [ elements: [
{ {
element: self.$toolbar, element: self.$listToolbar,
size: 24 size: 24
}, },
{ {
element: self.$list element: self.$list
}, },
{ {
element: self.$statusbar, element: self.$listStatusbar,
size: 24 size: 16
} }
], ],
orientation: 'vertical' orientation: 'vertical'
}) }),
resizable: true,
resize: [256, 384, 512],
size: 256
}, },
{ {
element: self.$map, element: self.$map,
resizable: true, },
resize: self.mapResize, {
size: self.mapResize[1] collapsible: true,
element: Ox.SplitPanel({
elements: [
{
element: self.$placeToolbar,
size: 24
},
{
element: self.$placeForm
},
{
element: self.$placeStatusbar,
size: 16
}
],
orientation: 'vertical'
}),
size: 256
} }
], ],
orientation: 'horizontal' orientation: 'horizontal'

View file

@ -1,6 +1,6 @@
// vim: et:ts=4:sw=4:sts=4:ft=js // vim: et:ts=4:sw=4:sts=4:ft=js
// OxJS (c) 2011 Ox2620, dual-licensed GPL/MIT, see http://oxjs.org for details // OxJS (c) 2011 0x2620, dual-licensed GPL/MIT, see http://oxjs.org for details
/* /*
Some conventions: Some conventions:
@ -194,13 +194,18 @@ Ox.merge = function(arr) {
/*@ /*@
Ox.sort <f> Sorts an array, handling leading digits and ignoring capitalization Ox.sort <f> Sorts an array, handling leading digits and ignoring capitalization
arr <a> Array
fn <f|u> Optional map function that returns the value for the array element
> Ox.sort(['10', '9', 'B', 'a']) > Ox.sort(['10', '9', 'B', 'a'])
['9', '10', 'a', 'B'] ['9', '10', 'a', 'B']
> Ox.sort([{id: 0, name: '80 Days'}, {id: 1, name: '8 Women'}], function(v) {return v.name});
[{id: 1, name: '8 Women'}, {id: 0, name: '80 Days'}]
@*/ @*/
Ox.sort = function(arr) { Ox.sort = function(arr, fn) {
var len, matches = {}, sort = {}; var len, matches = {}, sort = {},
values = fn ? arr.map(fn) : arr;
// find leading numbers // find leading numbers
arr.forEach(function(val, i) { values.forEach(function(val, i) {
var match = /^\d+/(val); var match = /^\d+/(val);
matches[val] = match ? match[0] : ''; matches[val] = match ? match[0] : '';
}); });
@ -209,7 +214,7 @@ Ox.sort = function(arr) {
return val.length; return val.length;
})); }));
// pad leading numbers, and make lower case // pad leading numbers, and make lower case
arr.forEach(function(val) { values.forEach(function(val) {
sort[val] = ( sort[val] = (
matches[val] ? matches[val] ?
Ox.pad(matches[val], len) + val.toString().substr(matches[val].length) : Ox.pad(matches[val], len) + val.toString().substr(matches[val].length) :
@ -217,6 +222,8 @@ Ox.sort = function(arr) {
).toLowerCase(); ).toLowerCase();
}); });
return arr.sort(function(a, b) { return arr.sort(function(a, b) {
a = fn ? fn(a) : a;
b = fn ? fn(b) : b;
var ret = 0; var ret = 0;
if (sort[a] < sort[b]) { if (sort[a] < sort[b]) {
ret = -1; ret = -1;