add Ox.ArrayInput, more Ox.ListMap UI
This commit is contained in:
parent
ce3bdb46d6
commit
6a33b9cb97
8 changed files with 381 additions and 101 deletions
|
@ -581,14 +581,17 @@ Ox.load('Geo', function() {
|
|||
},
|
||||
{
|
||||
options: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
type: "float"
|
||||
},
|
||||
title: "Float Input (0.0 - 100.0)"
|
||||
},
|
||||
{
|
||||
options: {
|
||||
min: 0,
|
||||
max: 255,
|
||||
type: "integer"
|
||||
type: "int"
|
||||
},
|
||||
title: "Integer Input (0 - 255)"
|
||||
},
|
||||
|
@ -596,8 +599,7 @@ Ox.load('Geo', function() {
|
|||
options: {
|
||||
clear: true,
|
||||
id: "integerClear",
|
||||
max: 255,
|
||||
type: "integer"
|
||||
type: "int"
|
||||
},
|
||||
title: "Integer Input with Clear Button"
|
||||
},
|
||||
|
@ -605,8 +607,7 @@ Ox.load('Geo', function() {
|
|||
options: {
|
||||
arrows: true,
|
||||
id: "integerArrows",
|
||||
max: 255,
|
||||
type: "integer"
|
||||
type: "int"
|
||||
},
|
||||
title: "Integer Input with Arrows"
|
||||
},
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
Ox.load('UI', {
|
||||
debug: true,
|
||||
hideScreen: true,
|
||||
showScreen: true,
|
||||
theme: 'modern'
|
||||
}, function() {
|
||||
|
||||
Ox.getJSON('json/cities100000.json', function(data) {
|
||||
Ox.load('Geo', function() {
|
||||
|
||||
Ox.getJSON('json/cities1000000.json', function(data) {
|
||||
|
||||
var listmap = new Ox.ListMap({
|
||||
height: window.innerHeight,
|
||||
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 > 5000000 ? {size: 20, color: [255, 64, 0]} :
|
||||
city.population > 2000000 ? {size: 18, color: [255, 96, 0]} :
|
||||
|
@ -23,10 +24,10 @@ Ox.load('UI', {
|
|||
latSize = size / Ox.EARTH_CIRCUMFERENCE * 360,
|
||||
lngSize = size * Ox.getDegreesPerMeter(city.latitude);
|
||||
return {
|
||||
countryCode: city.country_code == 'XK' ? 'RS-KO' : city.country_code,
|
||||
countryCode: countryCode,
|
||||
editable: true,
|
||||
flag: city.country_code,
|
||||
geoname: city.name,
|
||||
flag: countryCode,
|
||||
geoname: city.name + ', ' + Ox.getCountryByCode(countryCode).name,
|
||||
markerColor: marker.color,
|
||||
markerSize: marker.size,
|
||||
name: city.name,
|
||||
|
@ -49,6 +50,7 @@ Ox.load('UI', {
|
|||
}
|
||||
})
|
||||
.appendTo(Ox.UI.$body);
|
||||
|
||||
$(window).resize(function() {
|
||||
Ox.print('RESIZE', window.innerHeight)
|
||||
listmap.options({
|
||||
|
@ -58,5 +60,8 @@ Ox.load('UI', {
|
|||
});
|
||||
|
||||
window.listmap = listmap;
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
|
@ -1088,6 +1088,9 @@ Maps
|
|||
position: absolute;
|
||||
}
|
||||
|
||||
.OxMap .OxRange .OxArrow {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.OxMapButton {
|
||||
position: absolute;
|
||||
|
|
151
source/Ox.UI/js/Form/Ox.ArrayInput.js
Normal file
151
source/Ox.UI/js/Form/Ox.ArrayInput.js
Normal 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;
|
||||
|
||||
};
|
|
@ -5,7 +5,7 @@ Ox.Input <f:Ox.Element> Input Element
|
|||
(options) -> <f> Input Element
|
||||
(options, self) -> <f> Input Element
|
||||
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
|
||||
autocomplete <a> array of possible values, or
|
||||
<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
|
||||
autocompleteSelectHighlight <b> if true, value in menu is highlighted
|
||||
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
|
||||
<f> function(key, value, blur, callback), returns value
|
||||
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')
|
||||
id <s> element id
|
||||
key <s> to be passed to autocomplete and autovalidate functions
|
||||
max <n> max value if type is 'integer' or 'float'
|
||||
min <n> min value if type is 'integer' or 'float'
|
||||
max <n> max value if type is 'int' or 'float'
|
||||
min <n> min value if type is 'int' or 'float'
|
||||
name <s> will be displayed by autovalidate function ('invalid ' + name)
|
||||
overlap <s> '', 'left' or 'right', will cause padding and negative margin
|
||||
picker <o> picker object
|
||||
|
@ -48,7 +48,7 @@ Ox.Input <f:Ox.Element> Input Element
|
|||
trackValues <b> boolean
|
||||
serialize <f> function used to serialize value in submit
|
||||
textAlign <s> 'left', 'center' or 'right'
|
||||
type <s> 'float', 'integer', 'password', 'text', 'textarea'
|
||||
type <s> 'float', 'int', 'password', 'text', 'textarea'
|
||||
value <s> string
|
||||
validate <f> remote validation
|
||||
width <n> px
|
||||
|
@ -74,10 +74,11 @@ Ox.Input = function(options, self) {
|
|||
autovalidate: null,
|
||||
changeOnKeypress: false,
|
||||
clear: false,
|
||||
decimals: 0,
|
||||
disabled: false,
|
||||
key: '',
|
||||
min: 0,
|
||||
max: 100,
|
||||
min: -Infinity,
|
||||
max: Infinity,
|
||||
label: '',
|
||||
labelWidth: 64,
|
||||
overlap: 'none',
|
||||
|
@ -97,6 +98,7 @@ Ox.Input = function(options, self) {
|
|||
' OxOverlap' + Ox.toTitleCase(self.options.overlap) : ''
|
||||
)*/
|
||||
)
|
||||
.css({width: self.options.width + 'px'})
|
||||
.bindEvent($.extend(self.options.type == 'textarea' ? {} : {
|
||||
key_enter: submit
|
||||
}, {
|
||||
|
@ -114,15 +116,17 @@ Ox.Input = function(options, self) {
|
|||
}
|
||||
|
||||
// fixme: set to min, not 0
|
||||
// fixme: validate self.options.value !
|
||||
if (self.options.type == 'float') {
|
||||
self.decimals = Ox.repeat('0', self.options.decimals || 1)
|
||||
$.extend(self.options, {
|
||||
autovalidate: 'float',
|
||||
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, {
|
||||
autovalidate: 'integer',
|
||||
autovalidate: 'int',
|
||||
textAlign: 'right',
|
||||
value: self.options.value || '0'
|
||||
});
|
||||
|
@ -176,7 +180,8 @@ Ox.Input = function(options, 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,
|
||||
inputWidth: getInputWidth()
|
||||
});
|
||||
|
@ -449,48 +454,57 @@ Ox.Input = function(options, self) {
|
|||
|
||||
function autovalidateTypeFunction(type, value) {
|
||||
// fixme: remove trailing zeroes on blur
|
||||
// /(^\-?\d+\.?\d{0,8}$)/('-13000.12345678')
|
||||
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 (value.indexOf('.') != value.lastIndexOf('.')) {
|
||||
value = oldValue;
|
||||
} else {
|
||||
if (self.autovalidateFloatFlag) {
|
||||
if (Ox.endsWith(value, '.')) {
|
||||
value = value.substr(0, value.length - 1);
|
||||
}
|
||||
self.autovalidateFloatFlag = false;
|
||||
}
|
||||
while (value[0] == '0' && value[1] != '.') {
|
||||
value = value.substr(1);
|
||||
}
|
||||
while (Ox.startsWith(value, '.')) {
|
||||
if (Ox.startsWith(value, '..')) {
|
||||
value = value.substr(1);
|
||||
} else {
|
||||
value = '0' + value;
|
||||
}
|
||||
}
|
||||
if (Ox.endsWith(value, '.')) {
|
||||
value += '0';
|
||||
cursor = [value.length - 1, value.length];
|
||||
self.autovalidateFloatFlag = true;
|
||||
//Ox.print('--float--', value)
|
||||
if (value === '') {
|
||||
value = '0.' + self.decimals;
|
||||
cursor = [0, value.length];
|
||||
} else if (value == '-') {
|
||||
value = '-0.' + self.decimals;
|
||||
cursor = [1, value.length];
|
||||
} else if (value == '.') {
|
||||
value = '0.' + self.decimals;
|
||||
cursor = [2, value.length];
|
||||
} else if (!/\./(value)) {
|
||||
value += '.' + self.decimals
|
||||
cursor = [value.indexOf('.'), value.length];
|
||||
} else if (/^\./(value)) {
|
||||
value = '0' + value;
|
||||
cursor = [2, value.length];
|
||||
} else if (/\.$/(value)) {
|
||||
//Ox.print('$$$$$$$$$$$')
|
||||
value += self.decimals;
|
||||
cursor = [value.indexOf('.') + 1, value.length];
|
||||
} else if (/\./(value) && self.options.decimals) {
|
||||
length = value.split('.')[1].length;
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
value = $.map(value.split(''), function(v) {
|
||||
return regexp(v) ? v : null;
|
||||
}).join('');
|
||||
if (type == 'integer') {
|
||||
while (value.length > 1 && Ox.startsWith(value, '0')) {
|
||||
value = value.substr(1);
|
||||
} else {
|
||||
if (value === '') {
|
||||
value = '0';
|
||||
cursor = [0, 1];
|
||||
}
|
||||
}
|
||||
if (value === '') {
|
||||
value = type == 'float' ? '0.0' : '0';
|
||||
cursor = [0, value.length];
|
||||
} else if (value > self.options.max) {
|
||||
while (/^0\d/(value)) {
|
||||
value = value.substr(1, value.length);
|
||||
}
|
||||
if (!regexp.test(value) || value < self.options.min || value > self.options.max) {
|
||||
value = oldValue;
|
||||
cursor = oldCursor;
|
||||
}
|
||||
autovalidateCallback(value, cursor);
|
||||
}
|
||||
|
@ -549,8 +563,8 @@ Ox.Input = function(options, self) {
|
|||
self.options.placeholder && setPlaceholder();
|
||||
self.options.validate && validate();
|
||||
if (self.bindKeyboard) {
|
||||
Ox.UI.$document.unbind('keydown', keypress);
|
||||
Ox.UI.$document.unbind('keypress', keypress);
|
||||
Ox.UI.$document.unbind('keydown', keydown);
|
||||
//Ox.UI.$document.unbind('keypress', keypress);
|
||||
}
|
||||
that.triggerEvent('blur');
|
||||
}
|
||||
|
@ -572,7 +586,7 @@ Ox.Input = function(options, self) {
|
|||
var value = '';
|
||||
if (self.options.type == 'float') {
|
||||
value = '0.0';
|
||||
} else if (self.options.type == 'integer') {
|
||||
} else if (self.options.type == 'int') {
|
||||
value = '0'
|
||||
}
|
||||
self.$input.val(value);
|
||||
|
@ -615,7 +629,7 @@ Ox.Input = function(options, self) {
|
|||
|
||||
function deselectMenu() {
|
||||
return;
|
||||
Ox.print('deselectMenu')
|
||||
//Ox.print('deselectMenu')
|
||||
self.options.value = self.oldValue;
|
||||
self.$input.val(self.options.value);
|
||||
cursor(self.oldCursor);
|
||||
|
@ -636,8 +650,8 @@ Ox.Input = function(options, self) {
|
|||
if (self.bindKeyboard) {
|
||||
//Ox.print('binding...')
|
||||
// fixme: different in webkit and firefox (?), see keyboard handler, need generic function
|
||||
Ox.UI.$document.keydown(keypress);
|
||||
Ox.UI.$document.keypress(keypress);
|
||||
Ox.UI.$document.keydown(keydown);
|
||||
//Ox.UI.$document.keypress(keypress);
|
||||
self.options.autocompleteSelect && setTimeout(autocomplete, 0); // fixme: why is the timeout needed?
|
||||
}
|
||||
that.triggerEvent('focus');
|
||||
|
@ -651,7 +665,7 @@ Ox.Input = function(options, self) {
|
|||
(self.options.style == 'rounded' ? 14 : 6);
|
||||
}
|
||||
|
||||
function keypress(event) {
|
||||
function keydown(event) {
|
||||
var oldCursor = cursor(),
|
||||
oldValue = self.options.value,
|
||||
newValue = oldValue.substr(0, oldCursor[0] - 1),
|
||||
|
@ -664,7 +678,8 @@ Ox.Input = function(options, self) {
|
|||
) { // fixme: can't 13 and 27 return false?
|
||||
setTimeout(function() { // wait for val to be set
|
||||
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;
|
||||
self.$input.val(value);
|
||||
}
|
||||
|
@ -697,7 +712,7 @@ Ox.Input = function(options, self) {
|
|||
function selectMenu(event, data) {
|
||||
var pos = cursor();
|
||||
//if (self.options.value) {
|
||||
Ox.print('selectMenu', pos, data.title)
|
||||
//Ox.print('selectMenu', pos, data.title)
|
||||
self.options.value = data.title
|
||||
self.$input.val(self.options.value);
|
||||
cursor(pos[0], self.options.value.length);
|
||||
|
@ -778,6 +793,7 @@ Ox.Input = function(options, self) {
|
|||
self.$input.val(value);
|
||||
setPlaceholder();
|
||||
} else if (key == 'width') {
|
||||
that.css({width: self.options.width + 'px'});
|
||||
inputWidth = getInputWidth();
|
||||
self.$input.css({
|
||||
width: inputWidth + 'px'
|
||||
|
@ -1535,8 +1551,8 @@ Ox.InputElement_ = function(options, self) {
|
|||
}
|
||||
}
|
||||
if (self.bindKeyboard) {
|
||||
Ox.UI.$document.unbind('keydown', keypress);
|
||||
Ox.UI.$document.unbind('keypress', keypress);
|
||||
Ox.UI.$document.unbind('keydown', keydown);
|
||||
//Ox.UI.$document.unbind('keypress', keypress);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1585,14 +1601,13 @@ Ox.InputElement_ = function(options, self) {
|
|||
}
|
||||
if (self.bindKeyboard) {
|
||||
// fixme: different in webkit and firefox (?), see keyboard handler, need generic function
|
||||
Ox.UI.$document.keydown(keypress);
|
||||
Ox.UI.$document.keypress(keypress);
|
||||
Ox.UI.$document.keydown(keydown);
|
||||
//Ox.print('calling autosuggest...')
|
||||
self.options.autosuggest && setTimeout(autosuggestCall, 0); // fixme: why is the timeout needed?
|
||||
}
|
||||
}
|
||||
|
||||
function keypress(event) {
|
||||
function keydown(event) {
|
||||
//Ox.print('keyCode', event.keyCode)
|
||||
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
|
||||
|
|
|
@ -35,6 +35,8 @@ Ox.Label = function(options, self) {
|
|||
self.setOption = function(key, value) {
|
||||
if (key == 'title') {
|
||||
that.html(value);
|
||||
} else if (key == 'width') {
|
||||
that.css({width: self.options.width - 14 + 'px'})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ Ox.ListMap <f:Ox.Element> ListMap Object
|
|||
Ox.ListMap = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element({}, self)
|
||||
that = Ox.Element({}, self)
|
||||
.defaults({
|
||||
addPlace: null,
|
||||
height: 256,
|
||||
|
@ -187,13 +187,13 @@ Ox.ListMap = function(options, self) {
|
|||
}
|
||||
];
|
||||
|
||||
self.$toolbar = new Ox.Bar({
|
||||
self.$listToolbar = Ox.Bar({
|
||||
size: 24
|
||||
});
|
||||
|
||||
self.$findElement = new Ox.FormElementGroup({
|
||||
self.$findElement = Ox.FormElementGroup({
|
||||
elements: [
|
||||
self.$findSelect = new Ox.Select({
|
||||
self.$findSelect = Ox.Select({
|
||||
items: [
|
||||
{id: 'all', title: 'Find: All'},
|
||||
{id: 'name', title: 'Find: Name'},
|
||||
|
@ -203,16 +203,16 @@ Ox.ListMap = function(options, self) {
|
|||
overlap: 'right',
|
||||
width: 128
|
||||
}),
|
||||
self.$findInput = new Ox.Input({
|
||||
self.$findInput = Ox.Input({
|
||||
clear: true,
|
||||
width: 192
|
||||
})
|
||||
]
|
||||
})
|
||||
.css({float: 'right', margin: '4px'})
|
||||
.appendTo(self.$toolbar)
|
||||
.appendTo(self.$listToolbar)
|
||||
|
||||
self.$list = new Ox.TextList({
|
||||
self.$list = Ox.TextList({
|
||||
columns: self.columns,
|
||||
columnsRemovable: true,
|
||||
columnsVisible: true,
|
||||
|
@ -233,19 +233,95 @@ Ox.ListMap = function(options, self) {
|
|||
select: selectItem
|
||||
});
|
||||
|
||||
self.$statusbar = new Ox.Bar({
|
||||
size: 24
|
||||
self.$listStatusbar = Ox.Bar({
|
||||
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.$placeForm = Ox.Form({
|
||||
items: self.$placeFormItems,
|
||||
width: 240
|
||||
})
|
||||
.css({margin: '8px'});
|
||||
|
||||
self.$status = new Ox.Element()
|
||||
.css({paddingTop: '4px', margin: 'auto', textAlign: 'center'})
|
||||
.appendTo(self.$statusbar);
|
||||
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 = [
|
||||
Math.round(self.options.width * 0.25),
|
||||
Math.round(self.options.width * 0.5),
|
||||
Math.round(self.options.width * 0.75)
|
||||
];
|
||||
*/
|
||||
|
||||
if (Ox.isArray(self.options.places)) {
|
||||
init(self.options.places)
|
||||
|
@ -266,15 +342,15 @@ Ox.ListMap = function(options, self) {
|
|||
|
||||
function init(places) {
|
||||
//Ox.print('PLACES', places)
|
||||
self.$map = new Ox.Map({
|
||||
self.$map = Ox.Map({
|
||||
clickable: true,
|
||||
editable: true,
|
||||
findPlaceholder: 'Find on Map',
|
||||
height: self.options.height,
|
||||
places: places,
|
||||
statusbar: true,
|
||||
//statusbar: true,
|
||||
toolbar: true,
|
||||
width: self.mapResize[1],
|
||||
width: self.options.width - 514,//self.mapResize[1],
|
||||
zoombar: true
|
||||
})
|
||||
.bindEvent({
|
||||
|
@ -290,31 +366,51 @@ Ox.ListMap = function(options, self) {
|
|||
selectplace: selectPlace
|
||||
});
|
||||
that.$element.replaceWith(
|
||||
that.$element = new Ox.SplitPanel({
|
||||
that.$element = Ox.SplitPanel({
|
||||
elements: [
|
||||
{
|
||||
element: new Ox.SplitPanel({
|
||||
element: Ox.SplitPanel({
|
||||
elements: [
|
||||
{
|
||||
element: self.$toolbar,
|
||||
element: self.$listToolbar,
|
||||
size: 24
|
||||
},
|
||||
{
|
||||
element: self.$list
|
||||
},
|
||||
{
|
||||
element: self.$statusbar,
|
||||
size: 24
|
||||
element: self.$listStatusbar,
|
||||
size: 16
|
||||
}
|
||||
],
|
||||
orientation: 'vertical'
|
||||
})
|
||||
}),
|
||||
resizable: true,
|
||||
resize: [256, 384, 512],
|
||||
size: 256
|
||||
},
|
||||
{
|
||||
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'
|
||||
|
|
17
source/Ox.js
17
source/Ox.js
|
@ -1,6 +1,6 @@
|
|||
// 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:
|
||||
|
@ -194,13 +194,18 @@ Ox.merge = function(arr) {
|
|||
|
||||
/*@
|
||||
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'])
|
||||
['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) {
|
||||
var len, matches = {}, sort = {};
|
||||
Ox.sort = function(arr, fn) {
|
||||
var len, matches = {}, sort = {},
|
||||
values = fn ? arr.map(fn) : arr;
|
||||
// find leading numbers
|
||||
arr.forEach(function(val, i) {
|
||||
values.forEach(function(val, i) {
|
||||
var match = /^\d+/(val);
|
||||
matches[val] = match ? match[0] : '';
|
||||
});
|
||||
|
@ -209,7 +214,7 @@ Ox.sort = function(arr) {
|
|||
return val.length;
|
||||
}));
|
||||
// pad leading numbers, and make lower case
|
||||
arr.forEach(function(val) {
|
||||
values.forEach(function(val) {
|
||||
sort[val] = (
|
||||
matches[val] ?
|
||||
Ox.pad(matches[val], len) + val.toString().substr(matches[val].length) :
|
||||
|
@ -217,6 +222,8 @@ Ox.sort = function(arr) {
|
|||
).toLowerCase();
|
||||
});
|
||||
return arr.sort(function(a, b) {
|
||||
a = fn ? fn(a) : a;
|
||||
b = fn ? fn(b) : b;
|
||||
var ret = 0;
|
||||
if (sort[a] < sort[b]) {
|
||||
ret = -1;
|
||||
|
|
Loading…
Reference in a new issue