1
0
Fork 0
forked from 0x2620/oxjs

form elements rewrite, part 1

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

View file

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

View file

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

View file

@ -27,10 +27,20 @@ Ox.ButtonGroup = function(options, self) {
size: 'medium',
style: '',
type: 'text',
value: options.max != 1 ? [] : ''
})
.options(options || {})
.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) {
self.optionGroup = new Ox.OptionGroup(
self.options.buttons,
@ -39,58 +49,51 @@ Ox.ButtonGroup = function(options, self) {
'selected'
);
self.options.buttons = self.optionGroup.init();
self.options.value = self.optionGroup.value();
}
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)
self.$buttons[position] = Ox.Button({
self.$buttons[pos] = Ox.Button({
disabled: button.disabled,
group: true,
id: id,
selectable: self.options.selectable,
selected: button.selected,
size: self.options.size,
style: self.options.style,
title: button.title,
tooltip: button.tooltip,
type: self.options.type
type: self.options.type,
value: button.selected
})
.bindEvent('select', function() {
selectButton(position);
.bindEvent('change', function() {
self.options.selectable && toggleButton(pos);
})
.appendTo(that);
});
function selectButton(pos) {
function toggleButton(pos) {
var toggled = self.optionGroup.toggle(pos);
if (toggled.length) {
toggled.forEach(function(pos) {
self.$buttons[pos].toggleSelected();
Ox.print('TOGGLED::', toggled)
if (!toggled.length) {
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', {
selected: self.optionGroup.selected().map(function(i) {
return self.options.buttons[i].id;
})
value: self.options.value
});
}
}
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;
};

View file

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

View file

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

View file

@ -37,7 +37,7 @@ Ox.ColorInput = function(options, self) {
width: 40
})
.css({
background: 'rgb(' + getRGB() + ')'
background: 'rgb(' + getRGB().join(', ') + ')'
});
self.$inputs[4] = Ox.ColorPicker({
id: 'picker',
@ -52,6 +52,9 @@ Ox.ColorInput = function(options, self) {
value: self.options.value[i]
});
});
self.$inputs[3].css({
background: 'rgb(' + getRGB().join(', ') + ')'
});
}
})
.options({
@ -67,16 +70,16 @@ Ox.ColorInput = function(options, self) {
{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);
function change() {
self.options.value = self.$inputs.map(function(v) {
return v.options('value');
self.options.value = self.$inputs.map(function(input, i) {
return i < 3 ? input.options('value') : null;
});
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) {
self.$ranges[i] = Ox.Range({
arrows: true,
changeOnDrag: true,
id: self.options.id + i,
max: self.options.mode == 'RGB' ? 255 : i == 0 ? 359 : 1,
size: self.options.mode == 'RGB' ? 328 : 432, // 256|360 + 16 + 40 + 16
@ -36,6 +37,7 @@ Ox.ColorPicker = function(options, self) {
thumbSize: 40,
thumbValue: true,
trackColors: getColors(i),
trackGradient: true,
value: self.options.value[i]
})
.css({

View file

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

View file

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

View file

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

View file

@ -593,9 +593,10 @@ Ox.Input = function(options, self) {
self.options.autovalidate && autovalidate(true);
self.options.placeholder && setPlaceholder();
self.options.validate && validate();
if (self.bindKeyboard) {
Ox.UI.$document.unbind('keydown', keydown);
}
self.bindKeyboard && 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
// as a workaround, blur sends a value. remove later...
!self.cancelled && !self.submitted && that.triggerEvent('blur', {
@ -768,7 +769,7 @@ Ox.Input = function(options, self) {
if (self.options.value === '') {
if (self.options.type == 'password') {
self.$placeholder.hide();
self.$input.show().focusInput(true);
self.$input.show().focus();
} else {
self.$input
.removeClass('OxPlaceholder')

View file

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

View file

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

View file

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

View file

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

View file

@ -3,17 +3,17 @@
Ox.SelectInput = function(options, self) {
var that;
self = Ox.extend(self || {}, {
options: Ox.extend({
inputWidth: 128,
items: [],
label: '',
labelWidth: 128,
max: 0,
max: 1,
min: 1,
placeholder: '',
title: '',
value: options.max == 1 ? '' : [],
width: 384
}, options)
});
@ -28,21 +28,26 @@ Ox.SelectInput = function(options, self) {
max: self.options.max,
min: self.options.min,
title: self.options.title,
value: self.options.value,
width: self.options.width
})
.bindEvent({
change: function(data) {
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) {
self.$select.options({width: self.otherWidth})
.addClass('OxOverlapRight');
self.$input.show();
} else {
if (data.value != self.other) {
self.$select.options({width: self.options.width})
.removeClass('OxOverlapRight')
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,
width: 0
})
.bindEvent({
change: function(data) {
Ox.print('DATA:', data)
self.options.value = data.value;
}
})
.hide();
that = Ox.FormElementGroup({
@ -58,12 +69,19 @@ Ox.SelectInput = function(options, self) {
self.$select,
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
});
that.value = function() {
return self.$select.value() == self.other
? self.$input.value() : self.$select.value();
self.setOption = function(key, value) {
// ...
};
return that;

View file

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