form elements rewrite, part 1

This commit is contained in:
rlx 2011-12-21 13:42:47 +00:00
parent cf567e5608
commit 7f83cd3141
30 changed files with 1061 additions and 958 deletions

View file

@ -8,6 +8,17 @@ Ox.load('UI', function() {
.css({margin: '16px'}) .css({margin: '16px'})
.appendTo(Ox.$body); .appendTo(Ox.$body);
Ox.Button({
title: 'Value'
})
.css({marginLeft: '16px'})
.bindEvent({
click: function() {
Ox.print($arrayInput.options('value'));
}
})
.appendTo(Ox.$body)
Ox.Button({ Ox.Button({
title: 'Reset' title: 'Reset'
}) })

View file

@ -6,6 +6,9 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
id: "panel" id: "panel"
}) })
.appendTo($body), .appendTo($body),
countries = Ox.sortASCII(Ox.map(Ox.COUNTRIES, function(country) {
return country.dissolved ? null : country.name;
}));
objects = { objects = {
"Button": [ "Button": [
{ {
@ -60,7 +63,8 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
{id: "off", title: "Off"}, {id: "off", title: "Off"},
{id: "on", title: "On"}, {id: "on", title: "On"},
], ],
width: 32 width: 32,
value: 'on'
}, },
title: "Multi-Title Selectable Text Button" title: "Multi-Title Selectable Text Button"
} }
@ -69,65 +73,21 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
{ {
options: { options: {
buttons: [ buttons: [
{ id: "", title: "add" }, 'Add', 'Remove', 'Close', 'Select',
{ id: "", title: "remove" }, 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown',
{ id: "", title: "close" }, 'Left', 'Right', 'Up', 'Down',
{ id: "", title: "select" }, 'Pause', 'PlayInToOut', 'GoToIn', 'GoToOut', 'SetIn', 'SetOut',
{ id: "", title: "arrowLeft" }, 'GoToPoster', 'SetPoster',
{ id: "", title: "arrowRight" }, 'Center', 'Zoom', 'Grow', 'Shrink', 'Fill', 'Fit',
{ id: "", title: "arrowUp" }, 'Unmute', 'VolumeUp', 'VolumeDown', 'Mute',
{ id: "", title: "arrowDown" }, 'Undo', 'Redo', 'Unlock', 'Lock',
{ id: "", title: "left" }, 'Volume', 'Mount', 'Unmount', 'Sync',
{ id: "", title: "right" }, 'Info', 'Warning', 'Help',
{ id: "", title: "up" }, 'Check', 'Embed', 'Bracket',
{ id: "", title: "down" }, 'Upload', 'Download',
{ id: "", title: "pause" }, 'Copyright', 'NoCopyright',
{ id: "", title: "playInToOut" }, 'Click', 'Delete', 'Edit', 'Find', 'Flag', 'Icon', 'Like',
{ id: "", title: "goToIn" }, 'Mail', 'Publish', 'Set', 'Star', 'User', 'View', 'Loading'
{ id: "", title: "goToOut" },
{ id: "", title: "setIn" },
{ id: "", title: "setOut" },
{ id: "", title: "goToPoster" },
{ id: "", title: "setPoster" },
{ id: "", title: "center" },
{ id: "", title: "zoom" },
{ id: "", title: "grow" },
{ id: "", title: "shrink" },
{ id: "", title: "fill" },
{ id: "", title: "fit" },
{ id: "", title: "unmute" },
{ id: "", title: "volumeUp" },
{ id: "", title: "volumeDown" },
{ id: "", title: "mute" },
{ id: "", title: "undo" },
{ id: "", title: "redo" },
{ id: "", title: "unlock" },
{ id: "", title: "lock" },
{ id: "", title: "volume" },
{ id: "", title: "mount" },
{ id: "", title: "unmount" },
{ id: "", title: "sync" },
{ id: "", title: "info" },
{ id: "", title: "warning" },
{ id: "", title: "help" },
{ id: "", title: "check" },
{ id: "", title: "embed" },
{ id: "", title: "bracket" },
{ id: "", title: "upload" },
{ id: "", title: "download" },
{ id: "", title: "click" },
{ id: "", title: "delete" },
{ id: "", title: "edit" },
{ id: "", title: "find" },
{ id: "", title: "flag" },
{ id: "", title: "icon" },
{ id: "", title: "like" },
{ id: "", title: "publish" },
{ id: "", title: "set" },
{ id: "", title: "star" },
{ id: "", title: "user" },
{ id: "", title: "view" },
{ id: "", title: "loading" }
], ],
id: "buttonGroupImage", id: "buttonGroupImage",
type: "image" type: "image"
@ -236,7 +196,8 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
id: "selectableButtonGroupAny", id: "selectableButtonGroupAny",
max: -1, max: -1,
min: 0, min: 0,
selectable: true selectable: true,
value: 'and1'
}, },
title: "Selectable ButtonGroup, select any" title: "Selectable ButtonGroup, select any"
}, },
@ -265,8 +226,10 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
], ],
"Checkbox": [ "Checkbox": [
{ {
options: {}, options: {
title: "Checkbox" value: true
},
title: "Checkbox",
}, },
{ {
options: { options: {
@ -326,6 +289,7 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
id: "CheckboxGroupAny", id: "CheckboxGroupAny",
max: -1, max: -1,
min: 0, min: 0,
value: 'and1',
width: 300 width: 300
}, },
title: "CheckboxGroup, select any" title: "CheckboxGroup, select any"
@ -400,6 +364,15 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
}, },
title: "Short DateTimeInput" title: "Short DateTimeInput"
}, },
{
options: {
format: 'medium',
id: "dateTimeInputMedium",
seconds: true,
weekday: true
},
title: "Medium DateTimeInput"
},
{ {
options: { options: {
ampm: true, ampm: true,
@ -486,8 +459,14 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
width: 208 width: 208
}) })
], ],
join: function(value) {
return value[1][0];
},
float: "left", float: "left",
id: "formElementGroupLabels" id: "formElementGroupLabels",
split: function(value) {
return [null, [value, null]];
}
}, },
title: "FormElementGroup (Select and Labels)" title: "FormElementGroup (Select and Labels)"
}, },
@ -495,30 +474,26 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
options: { options: {
elements: [ elements: [
new Ox.Select({ new Ox.Select({
id: "selectOne",
items: [ items: [
{id: "one", title: "Title"}, {id: "title", title: "Title"},
{id: "two", title: "Date"}, {id: "date", title: "Date"},
{id: "three", title: "Place"} {id: "place", title: "Place"}
], ],
overlap: "right", overlap: "right",
width: 128 width: 128
}), }),
new Ox.Select({ new Ox.Select({
id: "selectTwo",
items: [ items: [
{id: "one", title: "is"}, {id: "is", title: "is"},
{id: "two", title: "is between"}, {id: "is_between", title: "is between"},
{id: "three", title: "is not between"} {id: "is_not_between", title: "is not between"}
], ],
overlap: "right", overlap: "right",
width: 128 width: 128
}), }),
new Ox.InputGroup({ new Ox.InputGroup({
id: "input",
inputs: [ inputs: [
new Ox.DateInput({ new Ox.DateInput({
id: "inputOne",
width: { width: {
day: 36, day: 36,
month: 36, month: 36,
@ -526,7 +501,6 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
} }
}), }),
new Ox.DateInput({ new Ox.DateInput({
id: "inputTwo",
width: { width: {
day: 36, day: 36,
month: 36, month: 36,
@ -539,9 +513,9 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
] ]
}) })
], ],
id: "formElementGroupSelectSelectInput" id: "formElementGroupSelectInputGroup",
}, },
title: "FormElementGroup (two Selects, one Input)" title: "FormElementGroup (Selects and InputGroup)"
} }
], ],
"Input": [ "Input": [
@ -633,9 +607,7 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
}, },
{ {
options: { options: {
autocomplete: Ox.sortASCII(Ox.COUNTRIES.map(function(v, i) { autocomplete: countries,
return v.name;
})),
autocompleteReplace: true, autocompleteReplace: true,
id: "autocompleteReplace" id: "autocompleteReplace"
}, },
@ -643,9 +615,7 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
}, },
{ {
options: { options: {
autocomplete: Ox.sortASCII(Ox.COUNTRIES.map(function(v, i) { autocomplete: countries,
return v.name;
})),
autocompleteReplace: true, autocompleteReplace: true,
autocompleteReplaceCorrect: true, autocompleteReplaceCorrect: true,
id: "autocompleteReplaceCorrect" id: "autocompleteReplaceCorrect"
@ -654,9 +624,7 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
}, },
{ {
options: { options: {
autocomplete: Ox.sortASCII(Ox.COUNTRIES.map(function(v, i) { autocomplete: countries,
return v.name;
})),
autocompleteSelect: true, autocompleteSelect: true,
autocompleteSelectHighlight: true, autocompleteSelectHighlight: true,
id: "autocompleteSelect" id: "autocompleteSelect"
@ -665,9 +633,7 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
}, },
{ {
options: { options: {
autocomplete: Ox.sortASCII(Ox.COUNTRIES.map(function(v, i) { autocomplete: countries,
return v.name;
})),
autocompleteReplace: true, autocompleteReplace: true,
autocompleteSelect: true, autocompleteSelect: true,
autocompleteSelectHighlight: true, autocompleteSelectHighlight: true,
@ -677,9 +643,7 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
}, },
{ {
options: { options: {
autocomplete: $.map(Ox.COUNTRIES, function(v, i) { autocomplete: countries,
return v.name;
}),
autocompleteReplace: true, autocompleteReplace: true,
autocompleteReplaceCorrect: true, autocompleteReplaceCorrect: true,
autocompleteSelect: true, autocompleteSelect: true,
@ -761,6 +725,48 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
}, },
title: "InputGroup with Width" title: "InputGroup with Width"
}, },
{
options: {
id: "inputGroupWithSplitAndJoin",
inputs: [
Ox.Input({id: "width", placeholder: "Width"}),
Ox.Input({id: "height", placeholder: "Height"})
],
join: function(value) {
return value.join('x');
},
separators: [
{title: "x", width: 16}
],
split: function(value) {
return value.split('x');
},
value: '256x96',
width: 128
},
title: "InputGroup with Split and Join"
},
{
options: {
id: "inputGroupWithObjectValue",
inputs: [
Ox.Input({id: "width", placeholder: "Width"}),
Ox.Input({id: "height", placeholder: "Height"})
],
join: function(value) {
return {width: value[0], height: value[1]};
},
separators: [
{title: "x", width: 16}
],
split: function(value) {
return [value.width, value.height];
},
value: {width: 256, height: 96},
width: 128
},
title: "InputGroup with Object Value"
},
{ {
options: { options: {
id: "inputGroupUsernamePassword", id: "inputGroupUsernamePassword",
@ -818,10 +824,10 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
new Ox.Select({ new Ox.Select({
items: [ items: [
{id: "items", title: "items"}, {id: "items", title: "items"},
{}, //{},
{id: "hours", title: "hours"}, {id: "hours", title: "hours"},
{id: "days", title: "days"}, {id: "days", title: "days"},
{}, //{},
{id: "GB", title: "GB"}, {id: "GB", title: "GB"},
], ],
overlap: "left", overlap: "left",
@ -919,32 +925,34 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
size: 48, size: 48,
thumbSize: 32, thumbSize: 32,
thumbValue: true, thumbValue: true,
valueNames: ["Off", "On"] values: ["Off", "On"]
}, },
title: "Range with Value Names" title: "Range with Values"
}, },
{ {
options: { options: {
id: "rangeTrackColors", id: "rangeTrackColors",
max: 255, size: 360,
min: 0,
size: 400,
thumbSize: 40,
thumbValue: true, thumbValue: true,
trackColors: [ trackColors: [
"rgb(0, 0, 0)", "rgb(255, 0, 0)",
"rgb(255, 255, 255)" "rgb(255, 255, 0)",
"rgb(0, 255, 0)",
"rgb(0, 255, 255)",
"rgb(0, 0, 255)",
"rgb(255, 0, 255)"
], ],
values: ['Red', 'Yellow', 'Green', 'Cyan', 'Blue', 'Magenta']
}, },
title: "Range with Track Colors" title: "Range with Track Colors"
}, },
{ {
options: { options: {
id: "rangeTrackColorsColor", id: "rangeTrackGradientColor",
max: 359, max: 359,
min: 0, min: 0,
size: 400, size: 360,
thumbSize: 40, thumbSize: 36,
thumbValue: true, thumbValue: true,
trackColors: [ trackColors: [
"rgb(255, 0, 0)", "rgb(255, 0, 0)",
@ -954,41 +962,41 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
"rgb(0, 0, 255)", "rgb(0, 0, 255)",
"rgb(255, 0, 255)", "rgb(255, 0, 255)",
"rgb(255, 0, 0)" "rgb(255, 0, 0)"
] ],
trackGradient: true
}, },
title: "Range with Track Colors" title: "Range with Track Gradient"
},
{
options: {
id: "rangeTrackGradient",
max: 255,
min: 0,
size: 360,
thumbSize: 36,
thumbValue: true,
trackColors: [
"rgb(0, 0, 0)",
"rgb(255, 255, 255)"
],
trackGradient: true
},
title: "Range with Track Gradient"
}, },
{ {
options: { options: {
id: "rangeTrackImage", id: "rangeTrackImage",
size: 400, size: 360,
trackImages: ["png/timeline.png"] trackImages: ["png/timeline.png"]
}, },
title: "Range with Track Image" title: "Range with Track Image"
}, },
{
options: {
id: "rangeTrackImages",
max: 5,
size: 386,
thumbValue: true,
trackImages: [
"png/red.png",
"png/yellow.png",
"png/green.png",
"png/cyan.png",
"png/blue.png",
"png/magenta.png"
],
valueNames: ["Red", "Yellow", "Green", "Cyan", "Blue", "Magenta"]
},
title: "Range with Track Images"
},
{ {
options: { options: {
id: "rangeTrackImages", id: "rangeTrackImages",
max: 9, max: 9,
size: 240, size: 240,
thumbStyle: 'transparent',
trackImages: [ trackImages: [
"jpg/Children's Games.jpg", "jpg/Children's Games.jpg",
"jpg/Dulle Griet.jpg", "jpg/Dulle Griet.jpg",
@ -1006,6 +1014,13 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
}, },
], ],
"Select": [ "Select": [
{
options: {
id: 'simpleSelect',
items: ['foo', 'bar', 'baz']
},
title: 'Simple Select'
},
{ {
options: { options: {
id: "imageSelectOne", id: "imageSelectOne",
@ -1071,19 +1086,6 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
}, },
title: "Text Select, select any" title: "Text Select, select any"
}, },
{
options: {
id: "textSelectNone",
items: [
{id: "one", title: "Item One"},
{id: "two", title: "Item Two"},
{id: "three", title: "Item Three"}
],
selectable: false,
title: "Title..."
},
title: "Text Select, select none"
},
{ {
options: { options: {
id: "textSelectWidth", id: "textSelectWidth",
@ -1110,6 +1112,20 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
title: "Text Select with Max Width" title: "Text Select with Max Width"
} }
], ],
'SelectInput': [
{
options: {
id: 'selectInput',
items: [
{id: 'male', title: 'Male'},
{id: 'female', title: 'Female'},
{id: 'other', title: 'Other...'}
],
width: 256
},
title: 'SelectInput'
}
],
"TimeInput": [ "TimeInput": [
{ {
options: { options: {
@ -1167,7 +1183,7 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
// if (object != "PlaceInput") return; // if (object != "PlaceInput") return;
$.each(elements, function(i, element) { $.each(elements, function(i, element) {
var $div = $("<div>").appendTo($panel), var $div = $("<div>").appendTo($panel),
$label, $element, $button; $label, $element;
$label = Ox.Label({ $label = Ox.Label({
textAlign: "right", textAlign: "right",
title: element.title, title: element.title,
@ -1182,11 +1198,42 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
} catch(error) { } catch(error) {
} }
Ox.Button({
title: 'Options'
})
.addClass("margin")
.bindEvent({
click: function() {
var $dialog = Ox.Dialog({
buttons: [
Ox.Button({
id: 'close',
title: 'Close'
}).bindEvent({
click: function() { $dialog.close(); }
})
],
content: $('<div>')
.css({margin: '16px'})
.html(
JSON.stringify(Ox.map($element.options(), function(val, key) {
return Ox.isEqual(val, $element.defaults(key)) ? null : val;
}), void 0, 4)
.replace(/\n/g, '<br/>')
.replace(/\s/g, '&nbsp;')
),
height: 256,
title: "Options",
width: 384
}).open()
}
})
.appendTo($div);
$element = Ox[object](element.options) $element = Ox[object](element.options)
.addClass("margin") .addClass("margin")
.appendTo($div); .appendTo($div);
if (object != "Button" && object != "Label") { if (object != "Button" && object != "Label") {
$button = Ox.Button({ Ox.Button({
id: "id" + Ox.uid(), id: "id" + Ox.uid(),
title: "Value" title: "Value"
}) })
@ -1202,11 +1249,18 @@ Ox.load({UI: {}, Geo:{}, Unicode: {}}, function() {
click: function() { $dialog.close(); } click: function() { $dialog.close(); }
}) })
], ],
content: $('<div>').css({margin: '16px'}).html(Ox.isUndefined(value) ? "undefined" : value), content: $('<div>')
height: 128, .css({margin: '16px'})
id: "value", .html(
Ox.isUndefined(value)
? "undefined"
: JSON.stringify(value, void 0, 4)
.replace(/\n/g, '<br/>')
.replace(/\s/g, '&nbsp;')
),
height: 256,
title: "Value", title: "Value",
width: 256 width: 384
}) })
.open(); .open();
}) })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -930,12 +930,12 @@ OxRange
.OxRange > .OxTrack > .OxThumb { .OxRange > .OxTrack > .OxThumb {
float: left; float: left;
margin: -1px; margin: -1px;
//margin-left: -1px;
//margin-top: -1px;
text-align: center; text-align: center;
} }
.OxRange > .OxTrack > .OxThumb:first-child { .OxRange > .OxTrack > .OxThumb.OxTransparent {
//margin-top: -1px; border: 1px solid white;
background: transparent;
box-shadow: 0 0 1px white inset;
} }
/* /*
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View file

@ -328,16 +328,23 @@ Ox.Element = function(options, self) {
}; };
/*@ /*@
defaults <function> Sets the default options for an element object defaults <function> Gets or sets the default options for an element object
({key: value, ...}) -> <obj> This element object ({key: value, ...}) -> <obj> This element object
key <str> The name of the default option key <str> The name of the default option
value <val> The value of the default option value <val> The value of the default option
@*/ @*/
that.defaults = function(defaults) { that.defaults = function() {
// sets the default options var ret;
self.defaults = defaults; if (arguments.length == 0) {
self.options = defaults; ret = self.defaults;
return that; } else if (Ox.isString(arguments[0])) {
ret = self.defaults[arguments[0]];
} else {
self.defaults = arguments[0];
self.options = Ox.clone(self.defaults);
ret = that;
}
return ret;
}; };
/*@ /*@
@ -386,14 +393,6 @@ Ox.Element = function(options, self) {
return Ox.getset(self.options, arguments, self.setOption, that); return Ox.getset(self.options, arguments, self.setOption, that);
}; };
that.setElement = function($element) {
//$element[0].className = that.$element[0].className;
$element.addClass('OxElement').data({oxid: that.id});
that.$element.replaceWith($element);
that.$element = $element;
that[0] = that.$element[0];
};
/*@ /*@
removeElement <function> Removes an element object and its event handler removeElement <function> Removes an element object and its event handler
() -> <obj> This element () -> <obj> This element
@ -413,6 +412,22 @@ Ox.Element = function(options, self) {
return that; return that;
}; };
that.setElement = function($element) {
//$element[0].className = that.$element[0].className;
$element.addClass('OxElement').data({oxid: that.id});
that.$element.replaceWith($element);
that.$element = $element;
that[0] = that.$element[0];
};
that.toggleOption = function() {
var options = {};
Ox.toArray(arguments[0]).forEach(function(key) {
options[key] == !self.options[key];
});
that.options(options);
};
/*@ /*@
triggerEvent <function> Triggers an event triggerEvent <function> Triggers an event
(event) -> <object> This element object (event) -> <object> This element object

View file

@ -59,7 +59,7 @@ Ox.ArrayInput = function(options, self) {
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
self.options.sort && data.value !== '' && sortInputs(); self.options.sort && data.value !== '' && sortInputs();
self.options.value = that.value(); self.options.value = getValue();
that.triggerEvent('change', { that.triggerEvent('change', {
value: self.options.value value: self.options.value
}); });
@ -77,7 +77,7 @@ Ox.ArrayInput = function(options, self) {
var index = $(this).parent().data('index'); var index = $(this).parent().data('index');
if (self.$input[index].value() !== '') { if (self.$input[index].value() !== '') {
self.$input[index].options({value: ''}); self.$input[index].options({value: ''});
self.options.value = that.value(); self.options.value = getValue();
that.triggerEvent('change', { that.triggerEvent('change', {
value: self.options.value value: self.options.value
}); });
@ -106,6 +106,13 @@ Ox.ArrayInput = function(options, self) {
updateInputs(); updateInputs();
} }
function getValue() {
return Ox.map(self.$input, function($input) {
var value = $input.value();
return value === '' ? null : value;
});
};
function removeInput(index) { function removeInput(index) {
Ox.Log('Form', 'remove', index); Ox.Log('Form', 'remove', index);
[ [
@ -118,6 +125,18 @@ Ox.ArrayInput = function(options, self) {
updateInputs(); updateInputs();
} }
function setValue() {
if (self.options.value.length == 0) {
self.options.value = [''];
}
while (self.$input.length) {
removeInput(0);
}
self.options.value.forEach(function(value, i) {
addInput(i, value);
});
}
function setWidths() { function setWidths() {
self.$label && self.$label.options({width: self.options.width}) self.$label && self.$label.options({width: self.options.width})
self.$element.forEach(function($element, i) { self.$element.forEach(function($element, i) {
@ -151,15 +170,7 @@ Ox.ArrayInput = function(options, self) {
self.setOption = function(key, value) { self.setOption = function(key, value) {
if (key == 'value') { if (key == 'value') {
if (self.options.value.length == 0) { setValue();
self.options.value = [''];
}
while (self.$input.length) {
removeInput(0);
}
self.options.value.forEach(function(value, i) {
addInput(i, value);
});
} else if (key == 'width') { } else if (key == 'width') {
setWidths(); setWidths();
} }
@ -171,16 +182,6 @@ Ox.ArrayInput = function(options, self) {
}); });
}; };
// 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; return that;
}; };

View file

@ -1,5 +1,7 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript // vim: et:ts=4:sw=4:sts=4:ft=javascript
'use strict'; 'use strict';
/*@ /*@
Ox.Button <f:Ox.Element> Button Object Ox.Button <f:Ox.Element> Button Object
() -> <f> Button Object () -> <f> Button Object
@ -11,17 +13,16 @@ Ox.Button <f:Ox.Element> Button Object
id: <s|''> button id id: <s|''> button id
overlap <s|none> overlap overlap <s|none> overlap
selectable <b|false> is selecatable selectable <b|false> is selecatable
selected <b|false> is selected
size <s|medium> button size size <s|medium> button size
style <s|default> // can be default, checkbox, symbol, or tab style <s|default> // can be default, checkbox, symbol, or tab
title <s|a|''> title, can be array of titles title <s|a|''> title, can be array
tooltip <s|a|''> tooltip if multiple must be same number as titles tooltip <s|a|''> tooltip, can be array (per title)
type <s|text> button type, text or image, (for image, title must be symbolTitle.svg must be availabe) type <s|text> button type, text or image, (for image, title must be symbolTitle.svg must be availabe)
value <b|false> is selected
width <s|auto> button width width <s|auto> button width
self <o> Shared private variable self <o> Shared private variable
click <!> non-selectable button was clicked click <!> non-selectable button was clicked
deselect <!> selectable button was deselected change <!> selectable button was clicked
select <!> selectable button was selected
@*/ @*/
Ox.Button = function(options, self) { Ox.Button = function(options, self) {
@ -34,13 +35,13 @@ Ox.Button = function(options, self) {
id: '', id: '',
overlap: 'none', overlap: 'none',
selectable: false, selectable: false,
selected: false,
size: 'medium', size: 'medium',
// fixme: 'default' or ''? // fixme: 'default' or ''?
style: 'default', style: 'default',
title: '', title: '',
tooltip: '', tooltip: '',
type: 'text', type: 'text',
value: false,
width: 'auto' width: 'auto'
}) })
.options(options ? Ox.extend(Ox.clone(options), { .options(options ? Ox.extend(Ox.clone(options), {
@ -51,29 +52,30 @@ Ox.Button = function(options, self) {
disabled: self.options.disabled, disabled: self.options.disabled,
type: self.options.type == 'text' ? 'button' : 'image' type: self.options.type == 'text' ? 'button' : 'image'
}) })
.addClass('OxButton Ox' + Ox.toTitleCase(self.options.size) + .addClass(
(self.options.disabled ? ' OxDisabled': '') + 'OxButton Ox' + Ox.toTitleCase(self.options.size)
(self.options.selected ? ' OxSelected': '') + + (self.options.disabled ? ' OxDisabled': '')
(self.options.style != 'default' ? ' Ox' + Ox.toTitleCase(self.options.style) : '') + + (self.options.selectable && self.options.value ? ' OxSelected': '')
(self.options.overlap != 'none' ? ' OxOverlap' + Ox.toTitleCase(self.options.overlap) : '')) + (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' ? {} : { .css(self.options.width == 'auto' ? {} : {
width: (self.options.width - 14) + 'px' width: (self.options.width - 14) + 'px'
}) })
.mousedown(mousedown) .mousedown(mousedown)
.click(click); .click(click);
Ox.extend(self, Ox.isArray(self.options.title) ? { if (Ox.isArray(self.options.title)) {
selectedTitle: Ox.setPropertyOnce(self.options.title, 'selected'), self.options.title = self.options.title.map(function(title) {
titles: self.options.title return {
} : { id: title.id || title,
selectedTitle: 0, title: title.title || title
titles: [{ };
id: '', });
title: self.options.title self.options.value = self.options.value || self.options.title[0].id;
}] }
});
setTitle(self.titles[self.selectedTitle].title); setTitle();
if (options.tooltip) { if (options.tooltip) {
self.tooltips = Ox.toArray(options.tooltip); self.tooltips = Ox.toArray(options.tooltip);
@ -82,21 +84,14 @@ Ox.Button = function(options, self) {
function click() { function click() {
if (!self.options.disabled) { if (!self.options.disabled) {
var data = self.titles[self.selectedTitle]; if (Ox.isArray(self.options.title)) {
if (!self.options.selectable) {
that.triggerEvent('click', data);
} else {
//self.options.selected = !self.options.selected;
//that.toggleClass('OxSelected');
if (self.options.group) {
that.triggerEvent('select', data);
} else {
that.toggleSelected();
//that.triggerEvent('change', {selected: self.options.selected});
}
}
if (self.titles.length == 2) {
that.toggleTitle(); that.toggleTitle();
that.triggerEvent('change', {value: self.options.value});
} else if (self.options.selectable) {
that.toggleSelected();
that.triggerEvent('change', {value: self.options.value});
} else {
that.triggerEvent('click');
} }
} }
} }
@ -108,8 +103,10 @@ Ox.Button = function(options, self) {
} }
} }
function setTitle(title) { function setTitle() {
self.title = title; var title = Ox.isArray(self.options.title)
? Ox.getObjectById(self.options.title, self.options.value).title
: self.options.title;
if (self.options.type == 'image') { if (self.options.type == 'image') {
that.attr({ that.attr({
src: Ox.UI.getImageURL( src: Ox.UI.getImageURL(
@ -125,15 +122,12 @@ Ox.Button = function(options, self) {
if (key == 'disabled') { if (key == 'disabled') {
that.attr({disabled: value}) that.attr({disabled: value})
.toggleClass('OxDisabled'); .toggleClass('OxDisabled');
} else if (key == 'selected') {
if (value != that.hasClass('OxSelected')) { // fixme: neccessary?
that.toggleClass('OxSelected');
}
that.triggerEvent('change');
} else if (key == 'tooltip') { } else if (key == 'tooltip') {
that.$tooltip.options({title: value}); that.$tooltip.options({title: value});
} else if (key == 'title') { } else if (key == 'title') {
setTitle(value); setTitle();
} else if (key == 'value') {
self.options.selectable && that.toggleClass('OxSelected');
} else if (key == 'width') { } else if (key == 'width') {
that.$element.css({ that.$element.css({
width: (value - 14) + 'px' width: (value - 14) + 'px'
@ -141,37 +135,21 @@ Ox.Button = function(options, self) {
} }
}; };
/*@
toggleDisabled <f>
() -> <u> toggle disabled state
@*/
that.toggleDisabled = function() {
that.options({
disabled: !self.options.disabled
});
return that;
//self.options.disabled = !self.options.disabled;
}
/*@
toggleSelected <f>
() -> <u> toggle selected state
@*/
that.toggleSelected = function() { that.toggleSelected = function() {
that.options({ self.options.value = !self.options.value;
selected: !self.options.selected that.toggleClass('OxSelected');
}); };
return that;
//self.options.selected = !self.options.selected;
}
/*@ /*@
toggleTitle <f> toggleTitle <f>
() -> <u> toggle through titles () -> <o> toggle through titles
@*/ @*/
that.toggleTitle = function() { that.toggleTitle = function() {
self.selectedTitle = 1 - self.selectedTitle; self.options.value = self.options.title[
setTitle(self.titles[self.selectedTitle].title); 1 - Ox.getPositionById(self.options.title, self.options.value)
].id;
setTitle();
self.options.selectable && that.toggleClass('OxSelected');
// fixme: if the tooltip is visible // fixme: if the tooltip is visible
// we also need to call show() // we also need to call show()
that.$tooltip && that.$tooltip.options({ that.$tooltip && that.$tooltip.options({

View file

@ -27,10 +27,20 @@ Ox.ButtonGroup = function(options, self) {
size: 'medium', size: 'medium',
style: '', style: '',
type: 'text', type: 'text',
value: options.max != 1 ? [] : ''
}) })
.options(options || {}) .options(options || {})
.addClass('OxButtonGroup'); .addClass('OxButtonGroup');
self.options.buttons = self.options.buttons.map(function(button) {
return Ox.extend({
id: button.id || button,
title: button.title || button
}, self.options.selectable ? {
selected: Ox.toArray(self.options.value).indexOf(button.id || button) > -1
} : {});
});
if (self.options.selectable) { if (self.options.selectable) {
self.optionGroup = new Ox.OptionGroup( self.optionGroup = new Ox.OptionGroup(
self.options.buttons, self.options.buttons,
@ -39,58 +49,51 @@ Ox.ButtonGroup = function(options, self) {
'selected' 'selected'
); );
self.options.buttons = self.optionGroup.init(); self.options.buttons = self.optionGroup.init();
self.options.value = self.optionGroup.value();
} }
self.$buttons = []; self.$buttons = [];
self.options.buttons.forEach(function(button, position) { self.options.buttons.forEach(function(button, pos) {
var id = self.options.id + Ox.toTitleCase(button.id) var id = self.options.id + Ox.toTitleCase(button.id)
self.$buttons[position] = Ox.Button({ self.$buttons[pos] = Ox.Button({
disabled: button.disabled, disabled: button.disabled,
group: true, group: true,
id: id, id: id,
selectable: self.options.selectable, selectable: self.options.selectable,
selected: button.selected,
size: self.options.size, size: self.options.size,
style: self.options.style, style: self.options.style,
title: button.title, title: button.title,
tooltip: button.tooltip, tooltip: button.tooltip,
type: self.options.type type: self.options.type,
value: button.selected
}) })
.bindEvent('select', function() { .bindEvent('change', function() {
selectButton(position); self.options.selectable && toggleButton(pos);
}) })
.appendTo(that); .appendTo(that);
}); });
function selectButton(pos) { function toggleButton(pos) {
var toggled = self.optionGroup.toggle(pos); var toggled = self.optionGroup.toggle(pos);
if (toggled.length) { Ox.print('TOGGLED::', toggled)
toggled.forEach(function(pos) { if (!toggled.length) {
self.$buttons[pos].toggleSelected(); self.$buttons[pos].options({
value: !self.$buttons[pos].options('value')
}); });
} else {
toggled.forEach(function(i) {
i != pos && self.$buttons[i].options({
// FIXME: fix and use that.toggleOption()
value: !self.$buttons[i].options('value')
});
});
self.options.value = self.optionGroup.value();
that.triggerEvent('change', { that.triggerEvent('change', {
selected: self.optionGroup.selected().map(function(i) { value: self.options.value
return self.options.buttons[i].id;
})
}); });
} }
} }
that.select = function(id) {
// fixme: this doesn't work in cases where
// multiple buttons can be selected
var position = Ox.getPositionById(self.options.buttons, id);
if (position > -1) {
self.$buttons[position].trigger('click');
}
};
that.value = function() {
return self.optionGroup.selected().map(function(i) {
return self.options.buttons[i].id;
});
};
return that; return that;
}; };

View file

@ -6,16 +6,16 @@ Ox.Checkbox <f:Ox.Element> Checkbox Element
(options) -> <f> Checkbox Element (options) -> <f> Checkbox Element
(options, self) -> <f> Checkbox Element (options, self) -> <f> Checkbox Element
options <o> Options object options <o> Options object
checked <b> if true, checkbox is checked
disabled <b> if true, checkbox is disabled disabled <b> if true, checkbox is disabled
group <b> if true, checkbox is part of a group group <b> if true, checkbox is part of a group
id <s> element id id <s> element id
label <s> Label (on the left side) label <s> Label (on the left side)
labelWidth <n|64> Label width labelWidth <n|64> Label width
title <s> Title (on the right side) title <s> Title (on the right side)
value <b> if true, checkbox is checked
width <n> width in px width <n> width in px
self <o> Shared private variable self <o> Shared private variable
change <!> triggered when checked property changes, passes {checked, id, title} change <!> triggered when value changes
@*/ @*/
Ox.Checkbox = function(options, self) { Ox.Checkbox = function(options, self) {
@ -23,7 +23,6 @@ Ox.Checkbox = function(options, self) {
self = self || {}; self = self || {};
var that = Ox.Element({}, self) var that = Ox.Element({}, self)
.defaults({ .defaults({
checked: false,
disabled: false, disabled: false,
group: false, group: false,
id: '', id: '',
@ -31,6 +30,7 @@ Ox.Checkbox = function(options, self) {
labelWidth: 64, labelWidth: 64,
overlap: 'none', overlap: 'none',
title: '', title: '',
value: false,
width: 'auto' width: 'auto'
}) })
.options(options || {}) .options(options || {})
@ -72,27 +72,20 @@ Ox.Checkbox = function(options, self) {
self.$button = Ox.Button({ self.$button = Ox.Button({
disabled: self.options.disabled, disabled: self.options.disabled,
id: self.options.id + 'Button', id: self.options.id + 'Button',
title: [ title: ['none', 'check'],
{id: 'none', title: 'none', selected: !self.options.checked}, type: 'image',
{id: 'check', title: 'check', selected: self.options.checked} value: self.options.value ? 'check' : 'none'
],
type: 'image'
}) })
.addClass('OxCheckbox') .addClass('OxCheckbox')
.bindEvent({ .bindEvent({
click: clickButton change: clickButton
}) })
.appendTo(that); .appendTo(that);
function clickButton() { function clickButton() {
self.options.checked = !self.options.checked; self.options.value = !self.options.value;
// click will have toggled the button,
// if it is part of a group, we have to revert that
self.options.group && that.toggleChecked();
that.triggerEvent('change', { that.triggerEvent('change', {
checked: self.options.checked, value: self.options.value
id: self.options.id,
title: self.options.title
}); });
} }
@ -106,37 +99,20 @@ Ox.Checkbox = function(options, self) {
} }
self.setOption = function(key, value) { self.setOption = function(key, value) {
if (key == 'checked') { if (key == 'disabled') {
that.toggleChecked();
} else if (key == 'disabled') {
that.attr({disabled: value}); that.attr({disabled: value});
self.$button.options({disabled: value}); self.$button.options({disabled: value});
self.$title && self.$title.options({disabled: value}); self.$title && self.$title.options({disabled: value});
} else if (key == 'title') { } else if (key == 'title') {
self.$title.options({title: value}); self.$title.options({title: value});
} else if (key == 'value') {
self.$button.toggleTitle();
} else if (key == 'width') { } else if (key == 'width') {
that.css({width: value + 'px'}); that.css({width: value + 'px'});
self.$title && self.$title.options({width: getTitleWidth()}); self.$title && self.$title.options({width: getTitleWidth()});
} }
}; };
/*@
checked <f> get current checked state
() -> <b> returns self.options.checked
@*/
that.checked = function() {
return self.options.checked;
}
/*@
toggleChecked <f> toggle current checked state
() -> <f> toggle state, returns Checkbox Element
@*/
that.toggleChecked = function() {
self.$button.toggleTitle();
return that;
}
// fixme: added for forms, duplicated, checked() shouldn't be neccessary // fixme: added for forms, duplicated, checked() shouldn't be neccessary
that.value = function() { that.value = function() {
return self.options.checked; return self.options.checked;

View file

@ -1,5 +1,7 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript // vim: et:ts=4:sw=4:sts=4:ft=javascript
'use strict'; 'use strict';
/*@ /*@
Ox.CheckboxGroup <f:Ox.Element> CheckboxGroup Object Ox.CheckboxGroup <f:Ox.Element> CheckboxGroup Object
() -> <f> CheckboxGroup Object () -> <f> CheckboxGroup Object
@ -13,7 +15,7 @@ Ox.CheckboxGroup <f:Ox.Element> CheckboxGroup Object
width <n> width in px width <n> width in px
self <o> shared private variable self <o> shared private variable
change <!> triggered when checked property changes change <!> triggered when checked property changes
passes {checked, id, title} passes {id, title, value}
@*/ @*/
Ox.CheckboxGroup = function(options, self) { Ox.CheckboxGroup = function(options, self) {
@ -26,15 +28,25 @@ Ox.CheckboxGroup = function(options, self) {
max: 1, max: 1,
min: 1, min: 1,
type: 'group', type: 'group',
value: options.max != 1 ? [] : '',
width: 256 width: 256
}) })
.options(options || {}) .options(options || {})
.addClass('OxCheckboxGroup Ox' + Ox.toTitleCase(self.options.type)); .addClass('OxCheckboxGroup Ox' + Ox.toTitleCase(self.options.type));
self.options.checkboxes = self.options.checkboxes.map(function(checkbox) {
return {
checked: Ox.toArray(self.options.value).indexOf(checkbox.id || checkbox) > -1,
id: checkbox.id || checkbox,
title: checkbox.title || checkbox
};
});
self.optionGroup = new Ox.OptionGroup( self.optionGroup = new Ox.OptionGroup(
self.options.checkboxes, self.options.checkboxes,
self.options.min, self.options.min,
self.options.max self.options.max,
'checked'
); );
self.options.checkboxes = self.optionGroup.init(); self.options.checkboxes = self.optionGroup.init();
@ -48,37 +60,44 @@ Ox.CheckboxGroup = function(options, self) {
}); });
}; };
self.options.checkboxes.forEach(function(checkbox, index) { self.options.checkboxes.forEach(function(checkbox, pos) {
self.$checkboxes[index] = Ox.Checkbox(Ox.extend(checkbox, { self.$checkboxes[pos] = Ox.Checkbox(Ox.extend(checkbox, {
group: true, group: true,
id: checkbox.id, id: checkbox.id,
width: self.options.type == 'group' width: self.options.type == 'group'
? self.checkboxWidth[index] : self.options.width ? self.checkboxWidth[pos] : self.options.width,
value: checkbox.checked
})) }))
.bindEvent('change', function() { .bindEvent('change', function() {
change(index); toggleCheckbox(pos);
}) })
.appendTo(that); .appendTo(that);
}); });
function change(index) { function toggleCheckbox(pos) {
var toggled = self.optionGroup.toggle(index); var toggled = self.optionGroup.toggle(pos);
//Ox.Log('Form', 'change', index, 'toggled', toggled) Ox.Log('Form', 'change', pos, 'toggled', toggled)
if (toggled.length) { if (!toggled.length) {
toggled.forEach(function(index, i) { self.$checkboxes[pos].options({
self.$checkboxes[index].toggleChecked(); value: !self.$checkboxes[pos].options('value')
}); });
} else {
toggled.forEach(function(i) {
i != pos && self.$checkboxes[i].options({
// FIXME: fix and use that.toggleOption()
value: !self.$checkboxes[i].options('value')
});
});
self.options.value = self.optionGroup.value();
that.triggerEvent('change', { that.triggerEvent('change', {
checked: self.optionGroup.checked().map(function(v) { value: self.options.value
return self.options.checkboxes[v].id;
})
}); });
} }
} }
that.value = function() { that.value = function() {
return self.options.checkboxes.filter(function(checkbox) { return self.options.checkboxes.filter(function(checkbox) {
return checkbox.checked; return checkbox.value;
}).map(function(checkbox) { }).map(function(checkbox) {
return checkbox.id; return checkbox.id;
}); });

View file

@ -37,7 +37,7 @@ Ox.ColorInput = function(options, self) {
width: 40 width: 40
}) })
.css({ .css({
background: 'rgb(' + getRGB() + ')' background: 'rgb(' + getRGB().join(', ') + ')'
}); });
self.$inputs[4] = Ox.ColorPicker({ self.$inputs[4] = Ox.ColorPicker({
id: 'picker', id: 'picker',
@ -52,6 +52,9 @@ Ox.ColorInput = function(options, self) {
value: self.options.value[i] value: self.options.value[i]
}); });
}); });
self.$inputs[3].css({
background: 'rgb(' + getRGB().join(', ') + ')'
});
} }
}) })
.options({ .options({
@ -67,16 +70,16 @@ Ox.ColorInput = function(options, self) {
{title: '', width: 8}, {title: '', width: 8},
{title: '', width: 8} {title: '', width: 8}
], ],
value: self.options.value // fixme: it'd be nicer if this would be taken care of by passing self <-- but we're passing self! value: self.options.value
}) })
.bindEvent('change', change); .bindEvent('change', change);
function change() { function change() {
self.options.value = self.$inputs.map(function(v) { self.options.value = self.$inputs.map(function(input, i) {
return v.options('value'); return i < 3 ? input.options('value') : null;
}); });
self.$inputs[3].css({ self.$inputs[3].css({
background: 'rgb(' + getRGB() + ')' background: 'rgb(' + getRGB().join(', ') + ')'
}); });
} }

View file

@ -29,6 +29,7 @@ Ox.ColorPicker = function(options, self) {
Ox.loop(3, function(i) { Ox.loop(3, function(i) {
self.$ranges[i] = Ox.Range({ self.$ranges[i] = Ox.Range({
arrows: true, arrows: true,
changeOnDrag: true,
id: self.options.id + i, id: self.options.id + i,
max: self.options.mode == 'RGB' ? 255 : i == 0 ? 359 : 1, max: self.options.mode == 'RGB' ? 255 : i == 0 ? 359 : 1,
size: self.options.mode == 'RGB' ? 328 : 432, // 256|360 + 16 + 40 + 16 size: self.options.mode == 'RGB' ? 328 : 432, // 256|360 + 16 + 40 + 16
@ -36,6 +37,7 @@ Ox.ColorPicker = function(options, self) {
thumbSize: 40, thumbSize: 40,
thumbValue: true, thumbValue: true,
trackColors: getColors(i), trackColors: getColors(i),
trackGradient: true,
value: self.options.value[i] value: self.options.value[i]
}) })
.css({ .css({

View file

@ -21,31 +21,28 @@ Ox.DateInput = function(options, self) {
var that; var that;
self = Ox.extend(self || {}, { self = Ox.extend(self || {}, {
options: Ox.extend({ options: Ox.extend({
format: 'short', format: 'short',
value: Ox.formatDate(new Date(), '%F'), value: Ox.formatDate(new Date(), '%F'),
weekday: false, weekday: false,
width: { width: {
day: 32, day: 32,
month: options.format == 'long' ? 80 : (options.format == 'medium' ? 40 : 32), month: options.format == 'long' ? 80 : (options.format == 'medium' ? 40 : 32),
weekday: options.format == 'long' ? 80 : 40, weekday: options.format == 'long' ? 80 : 40,
year: 48 year: 48
} }
}, options) }, options || {})
}); });
Ox.extend(self, { self.formats = {
date: new Date(self.options.value.replace(/-/g, '/')), day: '%d',
formats: { month: self.options.format == 'short' ? '%m' :
day: '%d', (self.options.format == 'medium' ? '%b' : '%B'),
month: self.options.format == 'short' ? '%m' : weekday: self.options.format == 'long' ? '%A' : '%a',
(self.options.format == 'medium' ? '%b' : '%B'), year: '%Y'
weekday: self.options.format == 'long' ? '%A' : '%a', };
year: '%Y' self.months = self.options.format == 'long' ? Ox.MONTHS : Ox.SHORT_MONTHS;
}, self.weekdays = self.options.format == 'long' ? Ox.WEEKDAYS : Ox.SHORT_WEEKDAYS;
months: self.options.format == 'long' ? Ox.MONTHS : Ox.SHORT_MONTHS,
weekdays: self.options.format == 'long' ? Ox.WEEKDAYS : Ox.SHORT_WEEKDAYS
});
self.$input = Ox.extend(self.options.weekday ? { self.$input = Ox.extend(self.options.weekday ? {
weekday: Ox.Input({ weekday: Ox.Input({
@ -53,7 +50,6 @@ Ox.DateInput = function(options, self) {
autocompleteReplace: true, autocompleteReplace: true,
autocompleteReplaceCorrect: true, autocompleteReplaceCorrect: true,
id: 'weekday', id: 'weekday',
value: Ox.formatDate(self.date, self.formats.weekday),
width: self.options.width.weekday width: self.options.width.weekday
}) })
.bindEvent('autocomplete', changeWeekday), .bindEvent('autocomplete', changeWeekday),
@ -68,7 +64,6 @@ Ox.DateInput = function(options, self) {
autocompleteReplace: true, autocompleteReplace: true,
autocompleteReplaceCorrect: true, autocompleteReplaceCorrect: true,
id: 'day', id: 'day',
value: Ox.formatDate(self.date, self.formats.day),
textAlign: 'right', textAlign: 'right',
width: self.options.width.day width: self.options.width.day
}) })
@ -80,7 +75,6 @@ Ox.DateInput = function(options, self) {
autocompleteReplace: true, autocompleteReplace: true,
autocompleteReplaceCorrect: true, autocompleteReplaceCorrect: true,
id: 'month', id: 'month',
value: Ox.formatDate(self.date, self.formats.month),
textAlign: self.options.format == 'short' ? 'right' : 'left', textAlign: self.options.format == 'short' ? 'right' : 'left',
width: self.options.width.month width: self.options.width.month
}) })
@ -92,7 +86,6 @@ Ox.DateInput = function(options, self) {
autocompleteReplace: true, autocompleteReplace: true,
autocompleteReplaceCorrect: true, autocompleteReplaceCorrect: true,
id: 'year', id: 'year',
value: Ox.formatDate(self.date, self.formats.year),
textAlign: 'right', textAlign: 'right',
width: self.options.width.year width: self.options.width.year
}) })
@ -108,10 +101,7 @@ Ox.DateInput = function(options, self) {
] : [ ] : [
self.$input.month, self.$input.day, self.$input.year self.$input.month, self.$input.day, self.$input.year
]), ]),
joinValues: function(values) { join: join,
setValue();
return self.options.value;
},
separators: Ox.merge(self.options.weekday ? [ separators: Ox.merge(self.options.weekday ? [
{title: self.options.format == 'short' ? '' : ',', width: 8}, {title: self.options.format == 'short' ? '' : ',', width: 8},
] : [], self.options.format == 'short' ? [ ] : [], self.options.format == 'short' ? [
@ -119,11 +109,11 @@ Ox.DateInput = function(options, self) {
] : [ ] : [
{title: '', width: 8}, {title: ',', width: 8} {title: '', width: 8}, {title: ',', width: 8}
]), ]),
split: split,
value: self.options.value,
width: 0 width: 0
}), self); }), self);
//Ox.Log('Form', 'SELF', self)
function changeDay() { function changeDay() {
self.options.weekday && self.$input.weekday.options({ self.options.weekday && self.$input.weekday.options({
value: Ox.formatDate(new Date([ value: Ox.formatDate(new Date([
@ -132,7 +122,7 @@ Ox.DateInput = function(options, self) {
self.$input.year.options('value') self.$input.year.options('value')
].join(' ')), self.formats.weekday) ].join(' ')), self.formats.weekday)
}); });
setValue(); self.options.value = join();
} }
function changeMonthOrYear() { function changeMonthOrYear() {
@ -151,16 +141,16 @@ Ox.DateInput = function(options, self) {
}), }),
value: self.options.format == 'short' ? Ox.pad(day, 2) : day.toString() value: self.options.format == 'short' ? Ox.pad(day, 2) : day.toString()
}); });
setValue(); self.options.value = join();
} }
function changeWeekday() { function changeWeekday() {
var date = getDateInWeek( var date = getDateInWeek(
self.$input.weekday.options('value'), self.$input.weekday.options('value'),
self.$input.month.options('value'), self.$input.month.options('value'),
self.$input.day.options('value'), self.$input.day.options('value'),
self.$input.year.options('value') self.$input.year.options('value')
); );
self.$input.month.options({value: date.month}); self.$input.month.options({value: date.month});
self.$input.day.options({ self.$input.day.options({
autocomplete: Ox.range(1, Ox.getDaysInMonth(date.year, date.month) + 1).map(function(i) { autocomplete: Ox.range(1, Ox.getDaysInMonth(date.year, date.month) + 1).map(function(i) {
@ -169,7 +159,12 @@ Ox.DateInput = function(options, self) {
value: date.day value: date.day
}); });
self.$input.year.options({value: date.year}); self.$input.year.options({value: date.year});
setValue(); self.options.value = join();
Ox.print('self.options.value =', self.options.value)
}
function getDate(value) {
return new Date(self.options.value.replace(/-/g, '/'));
} }
function getDateInWeek(weekday, month, day, year) { function getDateInWeek(weekday, month, day, year) {
@ -183,8 +178,18 @@ Ox.DateInput = function(options, self) {
}; };
} }
function setValue() { function getValues() {
self.options.value = Ox.formatDate(new Date(self.options.format == 'short' ? [ var date = getDate();
return {
day: Ox.formatDate(date, self.formats.day),
month: Ox.formatDate(date, self.formats.month),
weekday: Ox.formatDate(date, self.formats.weekday),
year: Ox.formatDate(date, self.formats.year)
};
}
function join() {
return Ox.formatDate(new Date(self.options.format == 'short' ? [
self.$input.year.options('value'), self.$input.year.options('value'),
self.$input.month.options('value'), self.$input.month.options('value'),
self.$input.day.options('value') self.$input.day.options('value')
@ -195,28 +200,16 @@ Ox.DateInput = function(options, self) {
].join(' ')), '%F'); ].join(' ')), '%F');
} }
/* function split() {
function normalize() { var values = getValues();
var year = that.getInputById('year').options('value'), return Ox.merge(self.options.weekday ? [
month = that.getInputById('month').options('value'), values.weekday
day = that.getInputById('day').options('value') ] : [], self.options.format == 'short' ? [
return { values.year, values.month, values.day
year: year, ] : [
month: self.options.format == 'short' ? month : values.month, values.day, values.year
Ox.pad((format == 'medium' ? Ox.WEEKDAYS.map(function(v, i) { ])
return v.substr(0, 3);
}) : Ox.WEEKDAYS).indexOf(month), 2),
day: Ox.pad(day, 2)
}
} }
*/
/*
that.serialize = function() {
var normal = normalize();
return [normal.year, normal.month, normal.day].join('-');
}
*/
return that; return that;

View file

@ -17,47 +17,55 @@ Ox.DateTimeInput <f:Ox.Element> DateTimeInput Element
Ox.DateTimeInput = function(options, self) { Ox.DateTimeInput = function(options, self) {
self = self || {}; var that;
var that = Ox.Element({}, self) self = Ox.extend(self || {}, {
.defaults({ options: Ox.extend({
ampm: false, ampm: false,
format: 'short', format: 'short',
seconds: false, milliseconds: false,
value: Ox.formatDate(new Date(), '%F %T'), seconds: false,
weekday: false value: (function() {
}) var date = new Date();
.options(options || {}); return Ox.formatDate(
date,
'%F ' + (options.seconds || options.milliseconds ? '%T' : '%H:%M')
) + (options.milliseconds ? '.' + Ox.pad(date % 1000, 3) : '');
}()),
weekday: false
}, options || {})
});
self.values = self.options.value.split(' '); self.options.seconds = self.options.seconds || self.options.milliseconds;
//Ox.Log('Form', self.values)
that = Ox.InputGroup({ that = Ox.InputGroup({
inputs: [ inputs: [
Ox.DateInput({ Ox.DateInput({
format: self.options.format, format: self.options.format,
id: 'date', id: 'date',
value: self.values[0], weekday: self.options.weekday
weekday: self.options.weekday }),
}), Ox.TimeInput({
Ox.TimeInput({ ampm: self.options.ampm,
ampm: self.options.ampm, id: 'time',
id: 'time', seconds: self.options.seconds
value: self.values[1], })
seconds: self.options.seconds ],
}) join: join,
], separators: [
separators: [ {title: '', width: 8}
{title: '', width: 8} ],
], split: split,
value: self.options.value value: self.options.value
}) }, self);
.bindEvent('change', setValue);
function setValue() { function join() {
self.options.value = [ return that.options('inputs').map(function($input) {
self.options('inputs')[0].options('value'), return $input.options('value');
self.options('inputs')[1].options('value') }).join(' ');
].join(' '); }
function split() {
return self.options.value.split(' ');
} }
return that; return that;

View file

@ -24,17 +24,25 @@ Ox.FormElementGroup = function(options, self) {
id: '', id: '',
elements: [], elements: [],
float: 'left', float: 'left',
joinValues: null, join: null,
separators: [], separators: [],
split: null,
value: options.split ? '' : [],
width: 0 width: 0
}) })
.options(options || {}) .options(options || {})
.addClass('OxInputGroup'); .addClass('OxInputGroup');
if (Ox.isEmpty(self.options.value)) {
self.options.value = getValue();
} else {
setValue();
}
( (
self.options.float == 'left' ? self.options.float == 'left' ?
self.options.elements : Ox.clone(self.options.elements).reverse() self.options.elements : Ox.clone(self.options.elements).reverse()
).forEach(function($element, i) { ).forEach(function($element) {
$element.css({ $element.css({
float: self.options.float // fixme: make this a class float: self.options.float // fixme: make this a class
}) })
@ -42,12 +50,8 @@ Ox.FormElementGroup = function(options, self) {
autovalidate: function(data) { autovalidate: function(data) {
that.triggerEvent({autovalidate: data}); that.triggerEvent({autovalidate: data});
}, },
change: function(data) { change: change,
that.triggerEvent({change: {value: that.value()}}); submit: change,
},
submit: function(data) {
that.triggerEvent({change: {value: that.value()}});
},
validate: function(data) { validate: function(data) {
that.triggerEvent({validate: data}); that.triggerEvent({validate: data});
} }
@ -55,6 +59,13 @@ Ox.FormElementGroup = function(options, self) {
.appendTo(that); .appendTo(that);
}); });
function change(data) {
self.options.value = getValue();
that.triggerEvent('change', {
value: self.options.value
});
}
/* /*
if (self.options.width) { if (self.options.width) {
setWidths(); setWidths();
@ -66,16 +77,34 @@ Ox.FormElementGroup = function(options, self) {
}); });
*/ */
function getValue() {
var value = self.options.elements.map(function($element) {
return $element.options('value');
});
return self.options.join ? self.options.join(value) : value;
}
function getWidth() { function getWidth() {
} }
function setValue() {
var values = self.options.split
? self.options.split(self.options.value)
: self.options.value;
values.forEach(function(value, i) {
self.options.elements[i].options({value: value});
});
}
function setWidth() { function setWidth() {
} }
self.setOption = function(key, value) { self.setOption = function(key, value) {
if (key == 'value') {
setValue();
}
}; };
that.replaceElement = function(pos, element) { that.replaceElement = function(pos, element) {

View file

@ -593,9 +593,10 @@ Ox.Input = function(options, self) {
self.options.autovalidate && autovalidate(true); self.options.autovalidate && autovalidate(true);
self.options.placeholder && setPlaceholder(); self.options.placeholder && setPlaceholder();
self.options.validate && validate(); self.options.validate && validate();
if (self.bindKeyboard) { self.bindKeyboard && Ox.UI.$document.unbind('keydown', keydown);
Ox.UI.$document.unbind('keydown', keydown); self.options.value !== self.originalValue && that.triggerEvent('change', {
} value: self.options.value
});
// fixme: for some reason, if options.type is set, no change event fires // fixme: for some reason, if options.type is set, no change event fires
// as a workaround, blur sends a value. remove later... // as a workaround, blur sends a value. remove later...
!self.cancelled && !self.submitted && that.triggerEvent('blur', { !self.cancelled && !self.submitted && that.triggerEvent('blur', {
@ -768,7 +769,7 @@ Ox.Input = function(options, self) {
if (self.options.value === '') { if (self.options.value === '') {
if (self.options.type == 'password') { if (self.options.type == 'password') {
self.$placeholder.hide(); self.$placeholder.hide();
self.$input.show().focusInput(true); self.$input.show().focus();
} else { } else {
self.$input self.$input
.removeClass('OxPlaceholder') .removeClass('OxPlaceholder')

View file

@ -18,16 +18,24 @@ Ox.InputGroup <f:Ox.Element> InputGroup Object
Ox.InputGroup = function(options, self) { Ox.InputGroup = function(options, self) {
self = self || {}; self = self || {};
var that = Ox.Element({}, self) var that = Ox.Element({}, self)
.defaults({ .defaults({
id: '', id: '',
inputs: [], inputs: [],
joinValues: null, join: null,
separators: [], separators: [],
width: 0 split: null,
}) value: options.split ? '' : [],
.options(options || {}) width: 0
.addClass('OxInputGroup') })
.click(click); .options(options || {})
.addClass('OxInputGroup')
.click(click);
if (Ox.isEmpty(self.options.value)) {
self.options.value = getValue();
} else {
setValue();
}
if (self.options.width) { if (self.options.width) {
setWidths(); setWidths();
@ -41,7 +49,6 @@ Ox.InputGroup = function(options, self) {
self.$separator = []; self.$separator = [];
self.options.separators.forEach(function(v, i) { self.options.separators.forEach(function(v, i) {
self.options.id == 'debug' && Ox.Log('Form', 'separator #' + i + ' ' + self.options.inputs[i].options('id') + ' ' + self.options.inputs[i].options('width'))
self.$separator[i] = Ox.Label({ self.$separator[i] = Ox.Label({
textAlign: 'center', textAlign: 'center',
title: v.title, title: v.title,
@ -56,11 +63,10 @@ Ox.InputGroup = function(options, self) {
self.options.inputs.forEach(function($input, i) { self.options.inputs.forEach(function($input, i) {
$input.options({ $input.options({
id: self.options.id + Ox.toTitleCase($input.options('id')), id: self.options.id + Ox.toTitleCase($input.options('id') || '')
parent: that
}) })
.css({ .css({
marginLeft: -Ox.sum(self.options.inputs.map(function(v_, i_) { marginLeft: -Ox.sum(self.options.inputs.map(function($input, i_) {
return i_ > i ? self.options.inputs[i_ - 1].options('width') + return i_ > i ? self.options.inputs[i_ - 1].options('width') +
self.options.separators[i_ - 1].width : (i_ == i ? 16 : 0); self.options.separators[i_ - 1].width : (i_ == i ? 16 : 0);
})) + 'px' })) + 'px'
@ -75,13 +81,9 @@ Ox.InputGroup = function(options, self) {
function change(data) { function change(data) {
//Ox.Log('Form', 'InputGroup change') //Ox.Log('Form', 'InputGroup change')
var values = self.options.inputs.map(function($input) { self.options.value = getValue();
return $input.value();
});
that.triggerEvent('change', { that.triggerEvent('change', {
value: self.options.joinValues value: self.options.value
? self.options.joinValues(values)
: values
}); });
} }
@ -96,6 +98,13 @@ Ox.InputGroup = function(options, self) {
} }
} }
function getValue() {
var value = self.options.inputs.map(function($input) {
return $input.options('value');
});
return self.options.join ? self.options.join(value) : value;
}
function getWidth() { function getWidth() {
return Ox.sum(self.options.inputs.map(function(v) { return Ox.sum(self.options.inputs.map(function(v) {
return v.options('width'); return v.options('width');
@ -104,6 +113,15 @@ Ox.InputGroup = function(options, self) {
}));// + 2; // fixme: why + 2? }));// + 2; // fixme: why + 2?
} }
function setValue() {
var values = self.options.split
? self.options.split(self.options.value)
: self.options.value;
values.forEach(function(value, i) {
self.options.inputs[i].options({value: value});
});
}
function setWidths() { function setWidths() {
var length = self.options.inputs.length, var length = self.options.inputs.length,
inputWidths = Ox.divideInt( inputWidths = Ox.divideInt(
@ -123,6 +141,12 @@ Ox.InputGroup = function(options, self) {
that.triggerEvent('validate', data); that.triggerEvent('validate', data);
} }
self.setOption = function(key, value) {
if (key == 'value') {
setValue();
}
}
// fixme: is this used? // fixme: is this used?
that.getInputById = function(id) { that.getInputById = function(id) {
var input = null; var input = null;
@ -136,19 +160,6 @@ Ox.InputGroup = function(options, self) {
return input; return input;
}; };
that.value = function() {
var values = self.options.inputs.map(function(input) {
var ret = null;
['checked', 'selected', 'value'].forEach(function(v) {
input[v] && (ret = input[v]());
});
return ret;
});
return self.options.joinValues
? self.options.joinValues(values)
: values;
};
return that; return that;
}; };

View file

@ -9,7 +9,7 @@ Ox.OptionGroup <f> OptionGroup
items <a> array of items items <a> array of items
min <n> minimum number of selected items min <n> minimum number of selected items
max <n> maximum number of selected items max <n> maximum number of selected items
property <s|checked> property to check property <s|'checked'> property to check
@*/ @*/
Ox.OptionGroup = function(items, min, max, property) { Ox.OptionGroup = function(items, min, max, property) {
@ -36,28 +36,20 @@ Ox.OptionGroup = function(items, min, max, property) {
function getNumber() { function getNumber() {
// returns the number of checked items // returns the number of checked items
var num = 0; return items.reduce(function(prev, curr) {
items.forEach(function(item) { return prev + curr[property];
if (item[property]) { }, 0);
num++;
}
});
return num;
} }
/*@ /*@
[property] <f> returns an array with the positions of all checked item [property] <f> returns an array with the positions of all checked items
() -> <a> returns checked items () -> <a> positions of checked items
@*/ @*/
// FIXME: isn't value more useful in all cases?
this[property] = function() { this[property] = function() {
// returns an array with the positions of all checked item return Ox.map(items, function(item, i) {
var checked = []; return item[property] ? i : null;
items.forEach(function(item, i) { });
if (item[property]) {
checked.push(i);
}
})
return checked;
}; };
/*@ /*@
@ -115,6 +107,13 @@ Ox.OptionGroup = function(items, min, max, property) {
return toggled; return toggled;
} }
this.value = function() {
var value = Ox.map(items, function(item) {
return item[property] ? item.id : null;
});
return max == 1 ? (value.length ? value[0] : '') : value;
};
return this; return this;
} }

View file

@ -1,26 +1,30 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript // vim: et:ts=4:sw=4:sts=4:ft=javascript
'use strict'; 'use strict';
/*@ /*@
Ox.Range <f:Ox.Element> Range Object Ox.Range <f:Ox.Element> Range Object
() -> <f> Range Object () -> <f> Range Object
(options) -> <f> Range Object (options) -> <f> Range Object
(options, self) -> <f> Range Object (options, self) -> <f> Range Object
options <o> Options object options <o> Options object
arrows <b> if true, show arrows arrows <b> if true, show arrows
arrowStep <n> step when clicking arrows arrowStep <n> step when clicking arrows
arrowSymbols <a> arrow symbols, like ['minus', 'plus'] arrowSymbols <[s]> arrow symbols, like ['minus', 'plus']
max <n> maximum value max <n> maximum value
min <n> minimum value min <n> minimum value
orientation <s> 'horizontal' or 'vertical' orientation <s> 'horizontal' or 'vertical'
step <n> step between values step <n> step between values
size <n> width or height, in px size <n> width or height, in px
thumbSize <n> minimum width or height of thumb, in px thumbSize <n> minimum width or height of thumb, in px
thumbValue <b> if true, display value on thumb thumbStyle <s|'opaque'> Thumb style ('opaque' or 'transparent')
trackGradient <a> colors thumbValue <b> if true, display value on thumb
trackImages <s|[s]> one or multiple track background image URLs trackColors <[s]> CSS colors
trackStep <n> 0 (scroll here) or step when clicking track trackGradient <b|false> if true, display track colors as gradient
value <n> initial value trackImages <s|[s]> one or multiple track background image URLs
valueNames <a> value names to display on thumb trackStep <n> 0 (scroll here) or step when clicking track
value <n> initial value
values <[s]> values to display on thumb
self <o> shared private variable self <o> shared private variable
change <!> triggered on change of the range change <!> triggered on change of the range
@*/ @*/
@ -29,40 +33,51 @@ Ox.Range = function(options, self) {
self = self || {}; self = self || {};
var that = Ox.Element({}, self) var that = Ox.Element({}, self)
.defaults({ .defaults({
arrows: false, arrows: false,
arrowStep: 1, arrowStep: 1,
arrowSymbols: ['left', 'right'], arrowSymbols: ['left', 'right'],
changeOnDrag: true, changeOnDrag: false,
max: 100, max: 100,
min: 0, min: 0,
orientation: 'horizontal', orientation: 'horizontal',
step: 1, step: 1,
size: 128, // fixme: shouldn't this be width? size: 128, // fixme: shouldn't this be width?
thumbSize: 16, thumbSize: 16,
thumbValue: false, thumbStyle: 'default',
trackColors: [], thumbValue: false,
trackImages: [], trackColors: [],
trackStep: 0, trackGradient: false,
value: 0, trackImages: [],
valueNames: null, trackStep: 0,
}) value: 0,
.options(options || {}) values: [],
.addClass('OxRange') })
.css({ .options(options || {})
width: self.options.size + 'px' .addClass('OxRange')
}); .css({
width: self.options.size + 'px'
});
self.hasValues = !Ox.isEmpty(self.options.values);
if (self.hasValues) {
self.options.max = self.options.values.length - 1;
self.options.min = 0;
self.options.step = 1;
self.options.thumbValue = true;
self.options.value = Ox.isNumber(self.options.value)
? self.options.values[self.options.value] : self.options.value;
Ox.print('!!!$!!!', self.options.value)
}
self.options.arrowStep = options.arrowStep || self.options.step; self.options.arrowStep = options.arrowStep || self.options.step;
self.options.trackImages = Ox.isArray(self.options.trackImages) self.options.trackImages = Ox.toArray(self.options.trackImages);
? self.options.trackImages : [self.options.trackImages];
self.trackColors = self.options.trackColors.length;
self.trackImages = self.options.trackImages.length;
self.values = (
self.options.max - self.options.min + self.options.step
) / self.options.step;
Ox.extend(self, {
trackColors: self.options.trackColors.length,
trackImages: self.options.trackImages.length,
values: (self.options.max - self.options.min + self.options.step) /
self.options.step
});
setSizes(); setSizes();
if (self.options.arrows) { if (self.options.arrows) {
@ -130,12 +145,11 @@ Ox.Range = function(options, self) {
self.$thumb = Ox.Button({ self.$thumb = Ox.Button({
id: self.options.id + 'Thumb', id: self.options.id + 'Thumb',
title: self.options.thumbValue ? (self.options.valueNames ?
self.options.valueNames[self.options.value] :
self.options.value) : '',
width: self.thumbSize width: self.thumbSize
}) })
.addClass('OxThumb') .addClass('OxThumb' + (
self.options.thumbStyle == 'transparent' ? ' OxTransparent' : ''
))
.appendTo(self.$track); .appendTo(self.$track);
setThumb(); setThumb();
@ -145,7 +159,8 @@ Ox.Range = function(options, self) {
setValue( setValue(
self.options.value self.options.value
+ self.options.arrowStep * (i == 0 ? -1 : 1) * (data.shiftKey ? 2 : 1), + self.options.arrowStep * (i == 0 ? -1 : 1) * (data.shiftKey ? 2 : 1),
animate animate,
true
); );
} }
@ -156,12 +171,12 @@ Ox.Range = function(options, self) {
left: self.$track.offset().left, left: self.$track.offset().left,
offset: isThumb ? data.clientX - self.$thumb.offset().left - 8 /*self.thumbSize / 2*/ : 0 offset: isThumb ? data.clientX - self.$thumb.offset().left - 8 /*self.thumbSize / 2*/ : 0
}; };
setValue(getVal(data.clientX - self.drag.left - self.drag.offset), !isThumb); setValue(getValue(data.clientX - self.drag.left - self.drag.offset), !isThumb, true);
} }
function dragTrack(data) { function dragTrack(data) {
setValue( setValue(
getVal(data.clientX - self.drag.left - self.drag.offset), getValue(data.clientX - self.drag.left - self.drag.offset),
false, false,
self.options.changeOnDrag self.options.changeOnDrag
); );
@ -169,13 +184,14 @@ Ox.Range = function(options, self) {
function dragendTrack(data) { function dragendTrack(data) {
self.options.value = void 0; self.options.value = void 0;
setValue(getVal(data.clientX - self.drag.left - self.drag.offset)); setValue(getValue(data.clientX - self.drag.left - self.drag.offset), false, true);
} }
function getPx(val) { function getPx(value) {
var pxPerVal = (self.trackSize - self.thumbSize) / var pxPerValue = (self.trackSize - self.thumbSize)
(self.options.max - self.options.min); / (self.options.max - self.options.min);
return Math.ceil((val - self.options.min) * pxPerVal); value = self.hasValues ? self.options.values.indexOf(value) : value;
return Math.ceil((value - self.options.min) * pxPerValue);
} }
/* /*
@ -184,23 +200,30 @@ Ox.Range = function(options, self) {
} }
*/ */
function getVal(px) { function getValue(px) {
var px = self.trackSize / self.values >= 16 ? px : px - 8, var px = self.trackSize / self.values >= 16 ? px : px - 8,
valPerPx = (self.options.max - self.options.min) / valuePerPx = (self.options.max - self.options.min)
(self.trackSize - self.thumbSize); / (self.trackSize - self.thumbSize),
return Ox.limit(self.options.min + value = Ox.limit(
Math.floor(px * valPerPx / self.options.step) * self.options.step, self.options.min
self.options.min, self.options.max); + Math.floor(px * valuePerPx / self.options.step) * self.options.step,
self.options.min,
self.options.max
);
return self.hasValues ? self.options.values[value] : value;
} }
function setSizes() { function setSizes() {
self.trackSize = self.options.size - self.options.arrows * 32; self.trackSize = self.options.size - self.options.arrows * 32;
self.thumbSize = Math.max(self.trackSize / self.values, self.options.thumbSize); self.thumbSize = Math.max(self.trackSize / self.values, self.options.thumbSize);
self.trackImageWidths = self.trackImages == 1 ? [self.trackSize - 16] : self.trackImageWidths = self.trackImages == 1
Ox.divideInt(self.trackSize - 2, self.trackImages); ? [self.trackSize - 16]
self.trackColorsStart = self.thumbSize / 2 / self.options.size; : Ox.divideInt(self.trackSize - 2, self.trackImages);
self.trackColorsStep = (self.options.size - self.thumbSize) / self.trackColorStart = self.options.trackGradient
(self.trackColors - 1) / self.options.size; ? self.thumbSize / 2 / self.options.size : 0;
self.trackColorStep = self.options.trackGradient
? (self.options.size - self.thumbSize) / (self.trackColors - 1) / self.options.size
: 1 / self.trackColors;
that.css({ that.css({
width: self.options.size + 'px' width: self.options.size + 'px'
}); });
@ -208,53 +231,57 @@ Ox.Range = function(options, self) {
width: (self.trackSize - 2) + 'px' width: (self.trackSize - 2) + 'px'
}); });
if (self.$thumb) { if (self.$thumb) {
self.$thumb.options({ self.$thumb.options({width: self.thumbSize});
width: self.thumbSize
});
setThumb(); setThumb();
} }
} }
function setThumb(animate) { function setThumb(animate) {
self.$thumb.stop().animate({ self.$thumb.stop().animate({
marginLeft: (getPx(self.options.value) - 1) + 'px', marginLeft: getPx(self.options.value) - 1 + 'px',
//width: self.thumbSize + 'px' //width: self.thumbSize + 'px'
}, animate ? 250 : 0, function() { }, animate ? 250 : 0, function() {
if (self.options.thumbValue) { self.options.thumbValue && self.$thumb.options({
self.$thumb.options({ title: self.options.value
title: self.options.valueNames });
? self.options.valueNames[self.options.value]
: self.options.value
});
}
}); });
} }
function setTrackColors() { function setTrackColors() {
// fixme: remove outdated -webkit format, and add -o ['moz', 'o', 'webkit'].forEach(function(browser) {
self.$track.css({ self.$track.css({
backgroundImage: $.browser.mozilla ? background: '-' + browser + '-linear-gradient(left, '
('-moz-linear-gradient(left, ' + + self.options.trackColors[0] + ' 0%, '
self.options.trackColors[0] + ' 0%, ' + self.options.trackColors.map(function(v, i) { + self.options.trackColors.map(function(v, i) {
return v + ' ' + ((self.trackColorsStart + self.trackColorsStep * i) * 100) + '%'; var ret = v + ' ' + (
}).join(', ') + ', ' + self.options.trackColors[self.trackColors - 1] + ' 100%)') : self.trackColorStart + self.trackColorStep * i
('-webkit-gradient(linear, left top, right top, color-stop(0, ' + ) * 100 + '%';
self.options.trackColors[0] + '), ' + self.options.trackColors.map(function(v, i) { if (!self.options.trackGradient) {
return 'color-stop(' + (self.trackColorsStart + self.trackColorsStep * i) + ', ' + v + ')'; ret += ', ' + v + ' ' + (
}).join(', ') + ', color-stop(1, ' + self.options.trackColors[self.trackColors - 1] + '))') self.trackColorStart + self.trackColorStep * (i + 1)
) * 100 + '%';
}
return ret;
}).join(', ') + ', '
+ self.options.trackColors[self.trackColors - 1] + ' 100%)'
});
}); });
} }
function setValue(value, animate, trigger) { function setValue(value, animate, trigger) {
// fixme: toPrecision helps with imprecise results of divisions, // fixme: toPrecision helps with imprecise results of divisions,
// but won't work for very large values. And is 10 a good value? // but won't work for very large values. And is 10 a good value?
value = Ox.limit(value.toPrecision(10), self.options.min, self.options.max); value = Ox.limit(
trigger = trigger !== false; self.hasValues ? self.options.values.indexOf(value) : value.toPrecision(10),
self.options.min,
self.options.max
);
value = self.hasValues ? self.options.values[value] : value;
if (value != self.options.value) { if (value != self.options.value) {
//time = getTime(self.options.value, value); //time = getTime(self.options.value, value);
self.options.value = value; self.options.value = value;
setThumb(animate); setThumb(animate);
trigger && that.triggerEvent('change', {value: value}); trigger && that.triggerEvent('change', {value: self.options.value});
} }
} }
@ -268,15 +295,6 @@ Ox.Range = function(options, self) {
} }
} }
that.value = function() {
if (arguments.length == 0) {
return self.options.value;
} else {
self.options.type = arguments[0];
setThumb();
}
};
return that; return that;
}; };

View file

@ -10,7 +10,7 @@ Ox.Select <f:Ox.Element> Select Object
options <o> Options object options <o> Options object
disabled <b|false> If true, select is disabled disabled <b|false> If true, select is disabled
id <s> Element id id <s> Element id
items <a|[]> Items items <a|[]> Items (array of {id, title} or strings)
label <s|''> Label label <s|''> Label
labelWidth <n|64> Label width labelWidth <n|64> Label width
max <n|1> Maximum number of selected items max <n|1> Maximum number of selected items
@ -25,6 +25,7 @@ Ox.Select <f:Ox.Element> Select Object
(e) -> <string> Tooltip title (e) -> <string> Tooltip title
e <object> Mouse event e <object> Mouse event
type <s|'text'> Type ('text' or 'image') type <s|'text'> Type ('text' or 'image')
value <a|s> Selected id, or array of selected ids
width <s|n|'auto'> Width in px, or 'auto' width <s|n|'auto'> Width in px, or 'auto'
self <o> Shared private variable self <o> Shared private variable
click <!> Click event click <!> Click event
@ -33,8 +34,6 @@ Ox.Select <f:Ox.Element> Select Object
Ox.Select = function(options, self) { Ox.Select = function(options, self) {
// fixme: make selected a separate option
// fixme: selected item needs attribute "checked", not "selected" ... that's strange
self = self || {}; self = self || {};
var that = Ox.Element({ var that = Ox.Element({
tooltip: options.tooltip || '' tooltip: options.tooltip || ''
@ -47,18 +46,15 @@ Ox.Select = function(options, self) {
max: 1, max: 1,
maxWidth: 0, maxWidth: 0,
min: 1, min: 1,
overlap: 'none', // can be none, left or right overlap: 'none',
selectable: true,
size: 'medium', size: 'medium',
style: 'rounded', style: 'rounded',
title: '', title: '',
type: 'text', // can be 'text' or 'image' type: 'text',
value: '', value: options.max != 1 ? [] : '',
width: 'auto' width: 'auto'
}) })
// fixme: make default selection restorable // fixme: make default selection restorable
// or allow for extra action items below options
// fixme: passing value has no effect
.options(options) .options(options)
.addClass( .addClass(
'OxSelect Ox' + Ox.toTitleCase(self.options.size) 'OxSelect Ox' + Ox.toTitleCase(self.options.size)
@ -78,15 +74,22 @@ Ox.Select = function(options, self) {
Ox.Log('Form', 'Ox.Select', self.options); Ox.Log('Form', 'Ox.Select', self.options);
if (self.options.selectable) { self.options.items = self.options.items.map(function(item) {
self.optionGroup = new Ox.OptionGroup( return {
self.options.items, id: item.id || item,
self.options.min, title: item.title || item,
self.options.max checked: Ox.toArray(self.options.value).indexOf(item.id || item) > -1
); };
self.options.items = self.optionGroup.init(); });
self.checked = self.optionGroup.checked();
} self.optionGroup = new Ox.OptionGroup(
self.options.items,
self.options.min,
self.options.max,
'checked'
);
self.options.items = self.optionGroup.init();
self.options.value = self.optionGroup.value();
if (self.options.label) { if (self.options.label) {
self.$label = Ox.Label({ self.$label = Ox.Label({
@ -95,14 +98,11 @@ Ox.Select = function(options, self) {
title: self.options.label, title: self.options.label,
width: self.options.labelWidth width: self.options.labelWidth
}) })
.click(function() {
// fixme: ???
// that.focus();
})
.appendTo(that); .appendTo(that);
} }
if (self.options.type == 'text') { if (self.options.type == 'text') {
Ox.Log('Form', 'S.O.V.', self.options.value)
self.$title = $('<div>') self.$title = $('<div>')
.addClass('OxTitle') .addClass('OxTitle')
.css({ .css({
@ -110,7 +110,7 @@ Ox.Select = function(options, self) {
}) })
.html( .html(
self.options.title self.options.title
|| self.options.items[self.checked[0]].title || getItem(self.options.value).title
) )
.appendTo(that); .appendTo(that);
} }
@ -127,12 +127,12 @@ Ox.Select = function(options, self) {
self.$menu = Ox.Menu({ self.$menu = Ox.Menu({
element: self.$title || self.$button, element: self.$title || self.$button,
id: self.options.id + 'Menu', id: self.options.id + 'Menu',
items: [self.options.selectable ? { items: [{
group: self.options.id + 'Group', group: self.options.id + 'Group',
items: self.options.items, items: self.options.items,
max: self.options.max, max: self.options.max,
min: self.options.min min: self.options.min
} : self.options.items], }],
maxWidth: self.options.maxWidth, maxWidth: self.options.maxWidth,
side: 'bottom', // FIXME: should be edge side: 'bottom', // FIXME: should be edge
size: self.options.size size: self.options.size
@ -150,20 +150,18 @@ Ox.Select = function(options, self) {
} }
function changeMenu(data) { function changeMenu(data) {
//Ox.Log('Form', 'clickMenu: ', self.options.id, data) self.options.value = self.optionGroup.value();
if (self.options.selectable) { Ox.Log('Form', 'changeMenu: ', data, 'value:', self.options.value, 'checked:', self.optionGroup.checked())
self.checked = self.optionGroup.checked(); self.$title && self.$title.html(
self.options.value = data.checked.length ? data.checked[0].id : ''; self.options.title ? self.options.title : getItem(self.options.value).title
self.$title && self.$title.html( );
self.options.title ? self.options.title : data.checked[0].title that.triggerEvent('change', {
); value: self.options.value
that.triggerEvent('change', { });
selected: data.checked, }
value: self.options.value
}); function getItem(id) {
} else { return Ox.getObjectById(self.options.items, id);
that.triggerEvent('click', data);
}
} }
function getTitleWidth() { function getTitleWidth() {
@ -174,16 +172,18 @@ Ox.Select = function(options, self) {
} }
function hideMenu() { function hideMenu() {
//Ox.Log('Form', '%% hideMenu that', that, 'self', self) that.loseFocus();
that.removeClass('OxSelected'); that.removeClass('OxSelected');
// self.$button.removeClass('OxSelected');
//Ox.Log('Form', '%% hideMenu end')
} }
function loseFocus() { function loseFocus() {
that.loseFocus(); that.loseFocus();
} }
function selectItem() {
}
function showMenu() { function showMenu() {
that.gainFocus(); that.gainFocus();
that.addClass('OxSelected'); that.addClass('OxSelected');
@ -202,12 +202,18 @@ Ox.Select = function(options, self) {
self.$button.options({title: value}); self.$button.options({title: value});
} }
} else if (key == 'width') { } else if (key == 'width') {
Ox.Log('Form', 'SETTING WIDTH OPTION', value) Ox.Log('Form', 'SETTING WIDTH OPTION', value);
that.css({width: value - 2 + 'px'}); that.css({width: value - 2 + 'px'});
self.$title.css({width: getTitleWidth() + 'px'}); self.$title.css({width: getTitleWidth() + 'px'});
} else if (key == 'value') { } else if (key == 'value') {
Ox.Log('Form', 'SETTING VALUE OPTION', value) Ox.Log('Form', 'SETTING VALUE OPTION', value);
that.selectItem(value); if (self.options.type == 'text' && !self.options.title) {
self.$title.html(getItem(value).title);
}
Ox.toArray(value).forEach(function(value) {
self.$menu.checkItem(value);
});
self.options.value = self.optionGroup.value();
} }
}; };
@ -225,33 +231,17 @@ Ox.Select = function(options, self) {
self.superRemove(); self.superRemove();
}; };
// FIXME: selected() _and_ selectItem() _and_ value() ???
/*@ /*@
selected <f> gets selected item selected <f> gets selected item
() -> <o> returns object of selected items with id, title () -> <o> returns array of selected items with id and title
@*/ @*/
that.selected = function() { that.selected = function() {
return self.options.selectable ? self.optionGroup.checked().map(function(v) { return Ox.toArray(self.optionGroup.value()).map(function(id) {
return { return {
id: self.options.items[v].id, id: id,
title: self.options.items[v].title title: getItem(id).title
}; };
}) : []; });
};
/*@
selectItem <f> select item in group
(id) -> <u> select item by id
id <s> item id
@*/
that.selectItem = function(id) {
Ox.Log('Form', 'selectItem', id, self.options.items, self.options.items.length, Ox.getObjectById(self.options.items, id))
self.options.type == 'text' && self.$title.html(
Ox.getObjectById(self.options.items, id).title
);
self.$menu.checkItem(id);
self.checked = self.optionGroup.checked();
}; };
/* /*
@ -264,22 +254,6 @@ Ox.Select = function(options, self) {
}; };
*/ */
that.value = function() {
var selected;
if (arguments.length == 0) {
selected = that.selected();
return selected.length ? that.selected()[0].id : '';
} else {
that.selectItem(arguments[0]);
return that;
/*
Ox.Log('Form', 'ELSE');
that.selectItem(arguments[0]);
return that;
*/
}
};
return that; return that;
}; };

View file

@ -3,17 +3,17 @@
Ox.SelectInput = function(options, self) { Ox.SelectInput = function(options, self) {
var that; var that;
self = Ox.extend(self || {}, { self = Ox.extend(self || {}, {
options: Ox.extend({ options: Ox.extend({
inputWidth: 128, inputWidth: 128,
items: [], items: [],
label: '', label: '',
labelWidth: 128, labelWidth: 128,
max: 0, max: 1,
min: 1, min: 1,
placeholder: '', placeholder: '',
title: '', title: '',
value: options.max == 1 ? '' : [],
width: 384 width: 384
}, options) }, options)
}); });
@ -28,21 +28,26 @@ Ox.SelectInput = function(options, self) {
max: self.options.max, max: self.options.max,
min: self.options.min, min: self.options.min,
title: self.options.title, title: self.options.title,
value: self.options.value,
width: self.options.width width: self.options.width
}) })
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
if (self.options.title) { if (self.options.title) {
self.$select.options({title: data.selected[0].title}); self.$select.options({
title: Ox.getObjectById(self.options.items, data.value).title
});
} }
if (data.selected[0].id == self.other) { if (data.value != self.other) {
self.$select.options({width: self.otherWidth})
.addClass('OxOverlapRight');
self.$input.show();
} else {
self.$select.options({width: self.options.width}) self.$select.options({width: self.options.width})
.removeClass('OxOverlapRight') .removeClass('OxOverlapRight')
self.$input.hide(); self.$input.hide();
self.options.value = data.value
} else {
self.$select.options({width: self.otherWidth})
.addClass('OxOverlapRight');
self.$input.show().focusInput(true);
self.options.value = self.$input.options('value');
} }
} }
}); });
@ -51,6 +56,12 @@ Ox.SelectInput = function(options, self) {
placeholder: self.options.placeholder, placeholder: self.options.placeholder,
width: 0 width: 0
}) })
.bindEvent({
change: function(data) {
Ox.print('DATA:', data)
self.options.value = data.value;
}
})
.hide(); .hide();
that = Ox.FormElementGroup({ that = Ox.FormElementGroup({
@ -58,12 +69,19 @@ Ox.SelectInput = function(options, self) {
self.$select, self.$select,
self.$input self.$input
], ],
join: function(value) {
return value[value[0] == self.other ? 1 : 0]
},
split: function(value) {
return Ox.map(self.options.items, function(item, i) {
return i < item.length - 1 ? item.id : null;
}).indexOf(value) > -1 ? [value, ''] : [self.other, value];
},
width: self.options.width width: self.options.width
}); });
that.value = function() { self.setOption = function(key, value) {
return self.$select.value() == self.other // ...
? self.$input.value() : self.$select.value();
}; };
return that; return that;

View file

@ -18,34 +18,30 @@ Ox.TimeInput <f:Ox.Element> TimeInput Object
Ox.TimeInput = function(options, self) { Ox.TimeInput = function(options, self) {
// fixme: seconds get set even if options.seconds is false // fixme: seconds get set even if options.seconds is false
self = self || {}; var that;
var that = Ox.Element({}, self) self = Ox.extend(self || {}, {
.defaults({ options: Ox.extend({
ampm: false, ampm: false,
seconds: false, seconds: false,
milliseconds: false, milliseconds: false,
value: Ox.formatDate(new Date(), '%T'), value: (function() {
///* var date = new Date();
width: { return Ox.formatDate(
hours: 32, date,
minutes: 32, options.seconds || options.milliseconds ? '%T' : '%H:%M'
seconds: 32, ) + (options.milliseconds ? '.' + Ox.pad(date % 1000, 3) : '');
milliseconds: 40, }()),
ampm: 32 width: {
} hours: 32,
//*/ minutes: 32,
}) seconds: 32,
.options(options || {}); milliseconds: 40,
ampm: 32
}
}, options || {})
});
if (self.options.milliseconds) { self.options.seconds = self.options.seconds || self.options.milliseconds;
self.options.seconds = true;
if (self.options.value.indexOf('.') == -1) {
self.options.value += '.000';
}
}
self.date = getDate();
self.values = getValues();
self.$input = { self.$input = {
hours: Ox.Input({ hours: Ox.Input({
@ -56,7 +52,6 @@ Ox.TimeInput = function(options, self) {
autocompleteReplaceCorrect: true, autocompleteReplaceCorrect: true,
id: 'hours', id: 'hours',
textAlign: 'right', textAlign: 'right',
value: self.values.hours,
width: self.options.width.hours width: self.options.width.hours
}), }),
minutes: Ox.Input({ minutes: Ox.Input({
@ -67,7 +62,6 @@ Ox.TimeInput = function(options, self) {
autocompleteReplaceCorrect: true, autocompleteReplaceCorrect: true,
id: 'minutes', id: 'minutes',
textAlign: 'right', textAlign: 'right',
value: self.values.minutes,
width: self.options.width.minutes width: self.options.width.minutes
}), }),
seconds: Ox.Input({ seconds: Ox.Input({
@ -78,7 +72,6 @@ Ox.TimeInput = function(options, self) {
autocompleteReplaceCorrect: true, autocompleteReplaceCorrect: true,
id: 'seconds', id: 'seconds',
textAlign: 'right', textAlign: 'right',
value: self.values.seconds,
width: self.options.width.seconds width: self.options.width.seconds
}), }),
milliseconds: Ox.Input({ milliseconds: Ox.Input({
@ -89,7 +82,6 @@ Ox.TimeInput = function(options, self) {
autocompleteReplaceCorrect: true, autocompleteReplaceCorrect: true,
id: 'milliseconds', id: 'milliseconds',
textAlign: 'right', textAlign: 'right',
value: self.values.milliseconds,
width: self.options.width.milliseconds width: self.options.width.milliseconds
}), }),
ampm: Ox.Input({ ampm: Ox.Input({
@ -97,87 +89,89 @@ Ox.TimeInput = function(options, self) {
autocompleteReplace: true, autocompleteReplace: true,
autocompleteReplaceCorrect: true, autocompleteReplaceCorrect: true,
id: 'ampm', id: 'ampm',
value: self.values.ampm,
width: self.options.width.ampm width: self.options.width.ampm
}) })
}; };
that = Ox.InputGroup(Ox.extend(self.options, { that = Ox.InputGroup(Ox.extend(self.options, {
inputs: Ox.merge([ id: self.options.id,
self.$input.hours, inputs: Ox.merge([
self.$input.minutes, self.$input.hours,
], self.options.seconds ? [ self.$input.minutes,
self.$input.seconds ], self.options.seconds ? [
] : [], self.options.milliseconds ? [ self.$input.seconds
self.$input.milliseconds ] : [], self.options.milliseconds ? [
] : [], self.options.ampm ? [ self.$input.milliseconds
self.$input.ampm ] : [], self.options.ampm ? [
] : []), self.$input.ampm
joinValues: function(values) { ] : []),
setValue(); join: join,
return self.options.value; separators: Ox.merge([
}, {title: ':', width: 8},
separators: Ox.merge([ ], self.options.seconds ? [
{title: ':', width: 8}, {title: ':', width: 8}
], self.options.seconds ? [ ] : [], self.options.milliseconds ? [
{title: ':', width: 8} {title: '.', width: 8}
] : [], self.options.milliseconds ? [ ] : [], self.options.ampm ? [
{title: '.', width: 8} {title: '', width: 8}
] : [], self.options.ampm ? [ ] : []),
{title: '', width: 8} split: split,
] : []), value: self.options.value,
width: 0 width: 0
//width: self.options.width || 128 }), self);
}), self)
/*.bindEvent('change', setValue)*/;
setValue();
function getDate() { function getDate() {
return new Date('1970/01/01 ' + ( return new Date('1970/01/01 ' + (
self.options.milliseconds ? self.options.milliseconds
self.options.value.substr(0, self.options.value.length - 4) : ? self.options.value.substr(0, self.options.value.length - 4)
self.options.value : self.options.value
)); ));
} }
function getValues() { function getValues() {
self.date = getDate(); var date = getDate();
return { return {
ampm: Ox.formatDate(self.date, '%p'), ampm: Ox.formatDate(date, '%p'),
hours: Ox.formatDate(self.date, self.options.ampm ? '%I' : '%H'), hours: Ox.formatDate(date, self.options.ampm ? '%I' : '%H'),
milliseconds: self.options.milliseconds ? self.options.value.substr(-3) : '000', milliseconds: self.options.milliseconds ? self.options.value.substr(-3) : '000',
minutes: Ox.formatDate(self.date, '%M'), minutes: Ox.formatDate(date, '%M'),
seconds: Ox.formatDate(self.date, '%S') seconds: Ox.formatDate(date, '%S')
}; };
} }
function setValue() { function join() {
self.options.value = Ox.formatDate(new Date('1970/01/01 ' + [ return Ox.formatDate(
self.$input.hours.options('value'), new Date(
self.$input.minutes.options('value'), '1970/01/01 ' + [
self.options.seconds ? self.$input.seconds.options('value') : '00' self.$input.hours.options('value'),
].join(':') + (self.options.ampm ? ' ' + self.$input.ampm.options('value') : '')), self.$input.minutes.options('value'),
(self.options.seconds? '%T' : '%H:%M')) + self.options.seconds ? self.$input.seconds.options('value') : '00'
(self.options.milliseconds ? '.' + self.$input.milliseconds.options('value') : ''); ].join(':') + (
//Ox.Log('Form', 'SETVALUE', self.options.value); self.options.ampm ? ' ' + self.$input.ampm.options('value') : ''
)
),
(
self.options.seconds ? '%T' : '%H:%M'
) + (
self.options.milliseconds ? '.' + self.$input.milliseconds.options('value') : ''
)
);
} }
function setValues() { function split(value) {
self.values = getValues(); var values = getValues();
Ox.forEach(self.$input, function(v, k) { return Ox.merge([
self.$input[k].options({ values.hours,
value: self.values[k] values.minutes,
}); ], self.options.seconds ? [
}); values.seconds
] : [], self.options.milliseconds ? [
values.milliseconds
] : [], self.options.ampm ? [
values.ampm
] : []);
} }
self.setOption = function(key, value) {
if (key == 'value') {
setValues();
}
};
return that; return that;
}; };

View file

@ -31,56 +31,54 @@ Ox.Menu = function(options, self) {
self = self || {}; self = self || {};
var that = Ox.Element({}, self) var that = Ox.Element({}, self)
.defaults({ .defaults({
element: null, element: null,
id: '', id: '',
items: [], items: [],
mainmenu: null, mainmenu: null,
maxWidth: 0, maxWidth: 0,
offset: { offset: {
left: 0, left: 0,
top: 0 top: 0
}, },
parent: null, parent: null,
selected: -1, selected: -1,
side: 'bottom', // FIXME: should be 'edge' side: 'bottom', // FIXME: should be 'edge'
size: 'medium' // fixme: remove size: 'medium' // fixme: remove
}) })
.options(options || {}) .options(options || {})
.addClass( .addClass(
'OxMenu Ox' + Ox.toTitleCase(self.options.side) + 'OxMenu Ox' + Ox.toTitleCase(self.options.side) +
' Ox' + Ox.toTitleCase(self.options.size) ' Ox' + Ox.toTitleCase(self.options.size)
) )
.bind({ .bind({
click: click, click: click,
mouseenter: mouseenter, mouseenter: mouseenter,
mouseleave: mouseleave, mouseleave: mouseleave,
mousemove: mousemove, mousemove: mousemove,
mousewheel: mousewheel mousewheel: mousewheel
}) })
.bindEvent({ .bindEvent({
key_up: selectPreviousItem, key_up: selectPreviousItem,
key_down: selectNextItem, key_down: selectNextItem,
key_left: selectSupermenu, key_left: selectSupermenu,
key_right: selectSubmenu, key_right: selectSubmenu,
key_escape: hideMenu, key_escape: hideMenu,
key_enter: clickSelectedItem key_enter: clickSelectedItem
}), });
// menuHeight,
$item; // fixme: used?
self.itemHeight = self.options.size == 'small' self.itemHeight = self.options.size == 'small'
? 12 : self.options.size == 'medium' ? 16 : 20; ? 12 : self.options.size == 'medium' ? 16 : 20;
self.scrollSpeed = 1; self.scrollSpeed = 1;
// construct // render
that.items = []; that.items = [];
that.submenus = {}; that.submenus = {};
that.$scrollbars = []; that.$scrollbars = [];
that.$top = $('<div>') that.$top = $('<div>')
.addClass('OxTop') .addClass('OxTop')
.appendTo(that.$element); .appendTo(that.$element);
that.$scrollbars.up = constructScrollbar('up') that.$scrollbars.up = renderScrollbar('up')
.appendTo(that.$element); .appendTo(that.$element);
that.$container = $('<div>') that.$container = $('<div>')
.addClass('OxContainer') .addClass('OxContainer')
@ -88,8 +86,8 @@ Ox.Menu = function(options, self) {
that.$content = $('<table>') that.$content = $('<table>')
.addClass('OxContent') .addClass('OxContent')
.appendTo(that.$container); .appendTo(that.$container);
constructItems(self.options.items); renderItems(self.options.items);
that.$scrollbars.down = constructScrollbar('down') that.$scrollbars.down = renderScrollbar('down')
.appendTo(that.$element); .appendTo(that.$element);
that.$bottom = $('<div>') that.$bottom = $('<div>')
.addClass('OxBottom') .addClass('OxBottom')
@ -179,130 +177,6 @@ Ox.Menu = function(options, self) {
} }
} }
function constructItems(items) {
that.$content.empty();
scrollMenuUp();
self.optionGroups = {};
items.forEach(function(item, i) {
if (item.group) {
items[i] = item.items.map(function(v) {
return Ox.extend(v, {
group: item.group
});
});
self.optionGroups[item.group] = new Ox.OptionGroup(
items[i].filter(function(v) {
return 'id' in v;
}),
'min' in item ? item.min : 1,
'max' in item ? item.max : 1
);
}
});
items = Ox.flatten(items);
that.items = [];
items.forEach(function(item) {
var position;
if ('id' in item) {
that.items.push(
Ox.MenuItem(Ox.extend(item, {
maxWidth: self.options.maxWidth,
menu: that,
position: position = that.items.length
}))
.data('position', position)
.appendTo(that.$content)
); // fixme: jquery bug when passing {position: position}? does not return the object?;
if (item.items) {
that.submenus[item.id] = Ox.Menu({
element: that.items[position],
id: Ox.toCamelCase(self.options.id + '/' + item.id),
items: item.items,
mainmenu: self.options.mainmenu,
offset: {
left: 0,
top: -4
},
parent: that,
side: 'right',
size: self.options.size,
});
}
} else {
that.$content.append(constructSpace());
that.$content.append(constructLine());
that.$content.append(constructSpace());
}
});
if (!that.is(':hidden')) {
that.hideMenu();
that.showMenu();
}
}
function constructLine() {
return $('<tr>').append(
$('<td>', {
'class': 'OxLine',
colspan: 5
})
);
}
function constructScrollbar(direction) {
var interval,
speed = direction == 'up' ? -1 : 1;
return $('<div/>', {
'class': 'OxScrollbar Ox' + Ox.toTitleCase(direction),
html: Ox.UI.symbols['triangle_' + direction],
click: function() { // fixme: do we need to listen to click event?
return false;
},
mousedown: function() {
self.scrollSpeed = 2;
return false;
},
mouseenter: function() {
self.scrollSpeed = 1;
var $otherScrollbar = that.$scrollbars[direction == 'up' ? 'down' : 'up'];
$(this).addClass('OxSelected');
if ($otherScrollbar.is(':hidden')) {
$otherScrollbar.show();
that.$container.height(that.$container.height() - self.itemHeight);
if (direction == 'down') {
that.$content.css({
top: -self.itemHeight + 'px'
});
}
}
scrollMenu(speed);
interval = setInterval(function() {
scrollMenu(speed);
}, 100);
},
mouseleave: function() {
self.scrollSpeed = 1;
$(this).removeClass('OxSelected');
clearInterval(interval);
},
mouseup: function() {
self.scrollSpeed = 1;
return false;
}
});
}
function constructSpace() {
return $('<tr>').append(
$('<td>', {'class': 'OxSpace', colspan: 5})
);
}
function getElement(id) { function getElement(id) {
// fixme: needed? // fixme: needed?
return $('#' + Ox.toCamelCase(options.id + '/' + id)); return $('#' + Ox.toCamelCase(options.id + '/' + id));
@ -387,6 +261,130 @@ Ox.Menu = function(options, self) {
} }
} }
function renderItems(items) {
that.$content.empty();
scrollMenuUp();
self.optionGroups = {};
items.forEach(function(item, i) {
if (item.group) {
items[i] = item.items.map(function(v) {
return Ox.extend(v, {
group: item.group
});
});
self.optionGroups[item.group] = new Ox.OptionGroup(
items[i].filter(function(v) {
return 'id' in v;
}),
'min' in item ? item.min : 1,
'max' in item ? item.max : 1
);
}
});
items = Ox.flatten(items);
that.items = [];
items.forEach(function(item) {
var position;
if (!Ox.isEmpty(item)) {
that.items.push(
Ox.MenuItem(Ox.extend(item, {
maxWidth: self.options.maxWidth,
menu: that,
position: position = that.items.length
}))
.data('position', position)
.appendTo(that.$content)
); // fixme: jquery bug when passing {position: position}? does not return the object?;
if (item.items) {
that.submenus[item.id] = Ox.Menu({
element: that.items[position],
id: Ox.toCamelCase(self.options.id + '/' + item.id),
items: item.items,
mainmenu: self.options.mainmenu,
offset: {
left: 0,
top: -4
},
parent: that,
side: 'right',
size: self.options.size,
});
}
} else {
that.$content.append(renderSpace());
that.$content.append(renderLine());
that.$content.append(renderSpace());
}
});
if (!that.is(':hidden')) {
that.hideMenu();
that.showMenu();
}
}
function renderLine() {
return $('<tr>').append(
$('<td>', {
'class': 'OxLine',
colspan: 5
})
);
}
function renderScrollbar(direction) {
var interval,
speed = direction == 'up' ? -1 : 1;
return $('<div/>', {
'class': 'OxScrollbar Ox' + Ox.toTitleCase(direction),
html: Ox.UI.symbols['triangle_' + direction],
click: function() { // fixme: do we need to listen to click event?
return false;
},
mousedown: function() {
self.scrollSpeed = 2;
return false;
},
mouseenter: function() {
self.scrollSpeed = 1;
var $otherScrollbar = that.$scrollbars[direction == 'up' ? 'down' : 'up'];
$(this).addClass('OxSelected');
if ($otherScrollbar.is(':hidden')) {
$otherScrollbar.show();
that.$container.height(that.$container.height() - self.itemHeight);
if (direction == 'down') {
that.$content.css({
top: -self.itemHeight + 'px'
});
}
}
scrollMenu(speed);
interval = setInterval(function() {
scrollMenu(speed);
}, 100);
},
mouseleave: function() {
self.scrollSpeed = 1;
$(this).removeClass('OxSelected');
clearInterval(interval);
},
mouseup: function() {
self.scrollSpeed = 1;
return false;
}
});
}
function renderSpace() {
return $('<tr>').append(
$('<td>', {'class': 'OxSpace', colspan: 5})
);
}
function scrollMenu(speed) { function scrollMenu(speed) {
var containerHeight = that.$container.height(), var containerHeight = that.$container.height(),
contentHeight = that.$content.height(), contentHeight = that.$content.height(),
@ -550,7 +548,7 @@ Ox.Menu = function(options, self) {
self.setOption = function(key, value) { self.setOption = function(key, value) {
if (key == 'items') { if (key == 'items') {
constructItems(value); renderItems(value);
} else if (key == 'selected') { } else if (key == 'selected') {
that.$content.find('.OxSelected').removeClass('OxSelected'); that.$content.find('.OxSelected').removeClass('OxSelected');
selectItem(value); selectItem(value);

View file

@ -247,8 +247,6 @@ Forms
background: -moz-linear-gradient(top, rgb(160, 160, 160), rgb(192, 192, 192)); background: -moz-linear-gradient(top, rgb(160, 160, 160), rgb(192, 192, 192));
background: -o-linear-gradient(top, rgb(160, 160, 160), rgb(192, 192, 192)); background: -o-linear-gradient(top, rgb(160, 160, 160), rgb(192, 192, 192));
background: -webkit-linear-gradient(top, rgb(160, 160, 160), rgb(192, 192, 192)); background: -webkit-linear-gradient(top, rgb(160, 160, 160), rgb(192, 192, 192));
//background: -moz-linear-gradient(top, rgb(128, 128, 128), rgb(160, 160, 160) 10%, rgb(192, 192, 192));
//background: -webkit-gradient(linear, left top, left bottom, from(rgb(128, 128, 128)), color-stop(0.1, rgb(160, 160, 160)), to(rgb(192, 192, 192)));
color: rgb(32, 32, 32); color: rgb(32, 32, 32);
} }