This commit is contained in:
Sanj 2011-12-30 21:45:02 +05:30
commit 6789df65e6
18 changed files with 369 additions and 164 deletions

View file

@ -22,9 +22,7 @@ Ox.API = function(options, callback) {
api: function(callback) { api: function(callback) {
Ox.Request.send({ Ox.Request.send({
url: self.options.url, url: self.options.url,
data: { data: {action: 'api'},
action: 'api'
},
callback: callback callback: callback
}); });
}, },

View file

@ -18,6 +18,7 @@ Ox.App = function(options) {
var self = { var self = {
options: Ox.extend({ options: Ox.extend({
name: 'App',
timeout: 60000, timeout: 60000,
type: 'POST', type: 'POST',
url: '/api/' url: '/api/'
@ -39,6 +40,8 @@ Ox.App = function(options) {
}); });
}); });
that.localStorage = Ox.localStorage(self.options.name);
function getUserData() { function getUserData() {
return { return {
document: { document: {

View file

@ -119,9 +119,7 @@ Ox.Theme = (function() {
}); });
}); });
} }
if (localStorage) { Ox.localStorage('Ox')('theme', theme);
localStorage.OxTheme = theme;
}
return that; return that;
} }

View file

@ -88,7 +88,11 @@ Ox.CheckboxGroup = function(options, self) {
self.options.value = self.optionGroup.value(); self.options.value = self.optionGroup.value();
that.triggerEvent('change', { that.triggerEvent('change', {
title: Ox.isString(self.options.value) title: Ox.isString(self.options.value)
? (
self.options.value
? Ox.getObjectById(self.options.checkboxes, self.options.value).title ? Ox.getObjectById(self.options.checkboxes, self.options.value).title
: ''
)
: self.options.value.map(function(value) { : self.options.value.map(function(value) {
return Ox.getObjectById(self.options.checkboxes, value).title; return Ox.getObjectById(self.options.checkboxes, value).title;
}), }),

View file

@ -25,7 +25,10 @@ Ox.Form = function(options, self) {
items: [], items: [],
// FIXME: don't pass function, // FIXME: don't pass function,
// listen to event instead! // listen to event instead!
submit: null submit: null,
validate: function(valid) {
return Ox.every(valid);
}
}) })
.options(options || {}) // fixme: the || {} can be done once, in the options function .options(options || {}) // fixme: the || {} can be done once, in the options function
.addClass('OxForm'); .addClass('OxForm');
@ -33,20 +36,14 @@ Ox.Form = function(options, self) {
Ox.extend(self, { Ox.extend(self, {
$items: [], $items: [],
$messages: [], $messages: [],
formIsValid: false,
itemIds: [], itemIds: [],
itemIsValid: [] itemIsValid: []
}); });
self.options.items.forEach(function(item, i) { self.options.items.forEach(function(item, i) {
var validateItem = item.options('validate'); validateItem(i, function(valid) {
if (validateItem) { self.itemIsValid[i] = valid;
validateItem(item.value(), function(data) {
self.itemIsValid[i] = data.valid;
}); });
} else {
self.itemIsValid[i] = item.value !== '';
}
self.itemIds[i] = item.options('id') || item.id; self.itemIds[i] = item.options('id') || item.id;
self.$items[i] = Ox.FormItem({element: item}).appendTo(that); self.$items[i] = Ox.FormItem({element: item}).appendTo(that);
item.bindEvent({ item.bindEvent({
@ -79,6 +76,9 @@ Ox.Form = function(options, self) {
id: self.itemIds[i], id: self.itemIds[i],
data: data data: data
}); });
validateItem(i, function(valid) {
validateForm(i, valid);
});
}, },
submit: function(data) { submit: function(data) {
self.formIsValid && that.submit(); self.formIsValid && that.submit();
@ -95,6 +95,8 @@ Ox.Form = function(options, self) {
}); });
}); });
self.formIsValid = self.options.validate(self.itemIsValid);
function getItemIndexById(id) { function getItemIndexById(id) {
return self.itemIds.indexOf(id); return self.itemIds.indexOf(id);
} }
@ -107,8 +109,7 @@ Ox.Form = function(options, self) {
function validateForm(pos, valid) { function validateForm(pos, valid) {
self.itemIsValid[pos] = valid; self.itemIsValid[pos] = valid;
Ox.Log('Form', 'VALID???', self.itemIsValid) if (self.options.validate(self.itemIsValid) != self.formIsValid) {
if (Ox.every(self.itemIsValid) != self.formIsValid) {
self.formIsValid = !self.formIsValid; self.formIsValid = !self.formIsValid;
that.triggerEvent('validate', { that.triggerEvent('validate', {
valid: self.formIsValid valid: self.formIsValid
@ -116,6 +117,18 @@ Ox.Form = function(options, self) {
} }
} }
function validateItem(pos, callback) {
var item = self.options.items[pos],
validate = item.options('validate');
if (validate) {
validate(item.value(), function(data) {
callback(data.valid);
});
} else {
callback(item.value && !Ox.isEmpty(item.value));
}
}
that.addItem = function(pos, item) { that.addItem = function(pos, item) {
Ox.Log('Form', 'addItem', pos) Ox.Log('Form', 'addItem', pos)
self.options.items.splice(pos, 0, item); self.options.items.splice(pos, 0, item);
@ -138,6 +151,10 @@ Ox.Form = function(options, self) {
self.options.submit(that.values(), submitCallback); self.options.submit(that.values(), submitCallback);
}; };
that.valid = function() {
return self.formIsValid;
};
that.values = function() { // fixme: can this be private? that.values = function() { // fixme: can this be private?
/* /*
get/set form values get/set form values
@ -147,9 +164,8 @@ Ox.Form = function(options, self) {
var values = {}; var values = {};
if (arguments.length == 0) { if (arguments.length == 0) {
self.$items.forEach(function($item, i) { self.$items.forEach(function($item, i) {
//Ox.print('??????-??', self.itemIds[i], self.$items[i].value(), Ox.typeOf(self.$items[i].value()))
values[self.itemIds[i]] = self.$items[i].value(); values[self.itemIds[i]] = self.$items[i].value();
//fixme: make the following work
//values[self.itemIds[i]] = self.$items[i].value();
}); });
//Ox.Log('Form', 'VALUES', values) //Ox.Log('Form', 'VALUES', values)
return values; return values;
@ -157,7 +173,7 @@ Ox.Form = function(options, self) {
Ox.Log('Form', 'SET FORM VALUES', arguments[0]) Ox.Log('Form', 'SET FORM VALUES', arguments[0])
Ox.forEach(arguments[0], function(value, key) { Ox.forEach(arguments[0], function(value, key) {
var index = getItemIndexById(key); var index = getItemIndexById(key);
//index > -1 && Ox.Log('Form', ':::::::', key, value) index > -1 && Ox.Log('Form', ':::::::', key, value)
index > -1 && self.options.items[index].value(value); index > -1 && self.options.items[index].value(value);
}); });
return that; return that;

View file

@ -115,11 +115,7 @@ Ox.FormElementGroup = function(options, self) {
that.value = function() { that.value = function() {
var values = self.options.elements.map(function(element) { var values = self.options.elements.map(function(element) {
var ret = null; return element.value();
['checked', 'selected', 'value'].forEach(function(v) {
element[v] && (ret = element[v]());
});
return ret;
}); });
return self.options.joinValues return self.options.joinValues
? self.options.joinValues(values) ? self.options.joinValues(values)

View file

@ -45,19 +45,9 @@ Ox.FormPanel = function(options, self) {
width: 240 width: 240
} }
], ],
items: function(data, callback) { items: self.options.form.map(function(section) {
setTimeout(function() { return {title: section.title, valid: false};
callback({ }),
data: {
items: Ox.isEmpty(data)
? self.sections.length
: self.options.form.map(function(section) {
return {title: section.title, valid: section.valid};
})
}
});
}, 250);
},
max: 1, max: 1,
min: 1, min: 1,
selected: [self.sections[0].id], selected: [self.sections[0].id],
@ -90,7 +80,7 @@ Ox.FormPanel = function(options, self) {
.append( .append(
$('<div>') $('<div>')
.css({marginBottom: '8px', fontWeight: 'bold'}) .css({marginBottom: '8px', fontWeight: 'bold'})
.html(section.title) .html((i + 1) + '. ' + section.title)
) )
.append( .append(
$('<div>') $('<div>')
@ -99,27 +89,22 @@ Ox.FormPanel = function(options, self) {
) )
.append( .append(
self.$forms[i] = Ox.Form({ self.$forms[i] = Ox.Form({
items: section.items items: section.items,
validate: section.validate
}) })
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
var valid; Ox.Log('FORM', '---CHANGE---', data, self.$forms[i].valid())
if (section.validate) { self.$list.value(section.title, 'valid', self.$forms[i].valid());
valid = section.validate(section.title, data); that.triggerEvent('change', {
self.$list.value(section.title, 'valid', valid); section: section.title,
that.triggerEvent('validate', { data: data
title: section.title,
data: {valid: valid}
}); });
}
//var valid = section.validate(section.title, data);
//self.$list.value(section.title, 'valid', valid);
//that.triggerEvent('change', data);
}, },
validate: function(data) { validate: function(data) {
self.$list.value(section.title, 'valid', data.valid); self.$list.value(section.title, 'valid', data.valid);
that.triggerEvent('validate', { that.triggerEvent('validate', {
title: section.title, section: section.title,
data: data data: data
}); });
} }
@ -129,6 +114,11 @@ Ox.FormPanel = function(options, self) {
.appendTo(self.$section); .appendTo(self.$section);
}); });
self.$forms.forEach(function($form, i) {
Ox.print(self.sections[i], 'valid', $form.valid());
self.$list.value(self.sections[i], 'valid', $form.valid());
});
self.$sections[0].show(); self.$sections[0].show();
that.$element = Ox.SplitPanel({ that.$element = Ox.SplitPanel({
@ -157,6 +147,44 @@ Ox.FormPanel = function(options, self) {
return index; return index;
} }
that.renderPrintVersion = function(title) {
var $printVersion = $('<div>').css({overflowY: 'auto'});
$printVersion.append(
$('<div>')
.addClass('OxFormSectionTitle')
.css({
height: '16px',
padding: '16px 16px 8px 16px',
fontWeight: 'bold'
})
.html(title)
);
self.$sections.forEach(function($section, i) {
// jQuery bug: textarea html/val does not survive cloning
// http://bugs.jquery.com/ticket/3016
var $clone = $section.clone(true),
textareas = {
section: $section.find('textarea'),
clone: $clone.find('textarea')
};
textareas.section.each(function(i) {
$(textareas.clone[i]).val($(this).val());
});
$printVersion
.append(
$('<div>').css({
height: '1px',
margin: '8px 0 8px 0',
background: 'rgb(128, 128, 128)'
})
)
.append(
$clone.show()
);
});
return $printVersion;
};
that.values = function() { that.values = function() {
var values = {}; var values = {};
self.options.form.forEach(function(section, i) { self.options.form.forEach(function(section, i) {

View file

@ -869,7 +869,7 @@ Ox.Input = function(options, self) {
that.clearInput = function() { that.clearInput = function() {
clear(); clear();
return that; return that;
} };
/*@ /*@
focusInput <f> Focus input element focusInput <f> Focus input element
@ -1654,6 +1654,7 @@ Ox.InputElement_ = function(options, self) {
self.options.autosuggestSubmit && submit(); self.options.autosuggestSubmit && submit();
} }
// FIXME: make this public!
function cursor(start, end) { function cursor(start, end) {
/* /*
cursor() returns [start, end] cursor() returns [start, end]

View file

@ -15,11 +15,8 @@ Ox.ObjectArrayInput = function(options, self) {
.options(options || {}) .options(options || {})
.addClass('OxObjectArrayInput'); .addClass('OxObjectArrayInput');
if (self.options.value.length == 0) { if (Ox.isEmpty(self.options.value)) {
self.options.value = [{}]; self.options.value = [getDefaultValue()];
self.options.inputs.forEach(function(input) {
self.options.value[0][input.options.id] = '';
});
} }
self.$element = []; self.$element = [];
@ -28,11 +25,10 @@ Ox.ObjectArrayInput = function(options, self) {
self.$addButton = []; self.$addButton = [];
self.buttonWidth = self.options.width / 2 - 4; self.buttonWidth = self.options.width / 2 - 4;
self.options.value.forEach(function(value, i) { setValue(self.options.value);
addInput(i, value);
});
function addInput(index, value) { function addInput(index, value) {
Ox.print('ADD INPUT', index, value)
self.$element.splice(index, 0, Ox.Element() self.$element.splice(index, 0, Ox.Element()
.css({ .css({
width: self.options.width + 'px', width: self.options.width + 'px',
@ -50,11 +46,16 @@ Ox.ObjectArrayInput = function(options, self) {
.bindEvent(input.events || {}); .bindEvent(input.events || {});
}), }),
labelWidth: self.options.labelWidth, labelWidth: self.options.labelWidth,
value: value,
width: self.options.width width: self.options.width
}) })
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
// ... var index = $(this).parent().data('index');
self.options.value[index] = self.$input[index].value();
that.triggerEvent('change', {
value: self.options.value
});
} }
}) })
.appendTo(self.$element[index]) .appendTo(self.$element[index])
@ -70,6 +71,10 @@ Ox.ObjectArrayInput = function(options, self) {
var index = $(this).parent().data('index'); var index = $(this).parent().data('index');
if (self.$input.length > 1) { if (self.$input.length > 1) {
removeInput(index); removeInput(index);
self.options.value = getValue();
that.triggerEvent('change', {
value: self.options.value
});
} }
} }
}) })
@ -84,7 +89,11 @@ Ox.ObjectArrayInput = function(options, self) {
.bind({ .bind({
click: function() { click: function() {
var index = $(this).parent().data('index'); var index = $(this).parent().data('index');
addInput(index + 1); addInput(index + 1, getDefaultValue());
self.options.value = getValue();
that.triggerEvent('change', {
value: self.options.value
});
} }
}) })
.appendTo(self.$element[index]) .appendTo(self.$element[index])
@ -92,6 +101,20 @@ Ox.ObjectArrayInput = function(options, self) {
updateInputs(); updateInputs();
} }
function getDefaultValue() {
var value = {};
self.options.inputs.forEach(function(input) {
value[input.options.id] = '';
});
return value;
}
function getValue() {
return self.$input.map(function($input) {
return $input.value();
});
}
function removeInput(index) { function removeInput(index) {
[ [
'input', 'removeButton', 'addButton', 'element' 'input', 'removeButton', 'addButton', 'element'
@ -103,6 +126,16 @@ Ox.ObjectArrayInput = function(options, self) {
updateInputs(); updateInputs();
} }
function setValue(value) {
while (self.$element.length) {
removeInput(0);
}
value.forEach(function(value, i) {
addInput(i, value);
});
}
function updateInputs() { function updateInputs() {
var length = self.$element.length; var length = self.$element.length;
self.$element.forEach(function($element, i) { self.$element.forEach(function($element, i) {
@ -121,17 +154,10 @@ Ox.ObjectArrayInput = function(options, self) {
self.setOption = function(key, value) { self.setOption = function(key, value) {
if (key == 'value') { if (key == 'value') {
// ... setValue(value);
} }
}; };
// FIXME: remove
that.value = function() {
return self.$input.map(function($input) {
return $input.value();
});
};
return that; return that;
}; };

View file

@ -7,6 +7,7 @@ Ox.ObjectInput = function(options, self) {
.defaults({ .defaults({
elements: [], elements: [],
labelWidth: 128, labelWidth: 128,
value: {},
width: 256 width: 256
}) })
.options(options || {}) .options(options || {})
@ -16,6 +17,12 @@ Ox.ObjectInput = function(options, self) {
height: self.options.elements.length * 24 - 8 + 'px' height: self.options.elements.length * 24 - 8 + 'px'
}); });
if (Ox.isEmpty(self.options.value)) {
self.options.value = getValue();
} else {
setValue(self.options.value);
}
self.options.elements.forEach(function($element) { self.options.elements.forEach(function($element) {
$element.options({ $element.options({
labelWidth: self.options.labelWidth, labelWidth: self.options.labelWidth,
@ -23,10 +30,7 @@ Ox.ObjectInput = function(options, self) {
}) })
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
self.options.value = {}; self.options.value = getValue();
self.options.elements.forEach(function(element) {
self.options.value[element.options('id')] = element.value();
});
that.triggerEvent('change', { that.triggerEvent('change', {
value: self.options.value value: self.options.value
}); });
@ -35,9 +39,23 @@ Ox.ObjectInput = function(options, self) {
.appendTo(that); .appendTo(that);
}); });
function getValue() {
var value = {};
self.options.elements.forEach(function(element) {
value[element.options('id')] = element.value();
});
return value;
}
function setValue(value) {
self.options.elements.forEach(function(element) {
element.value(value[element.options('id')]);
});
}
self.setOption = function(key, value) { self.setOption = function(key, value) {
if (key == 'value') { if (key == 'value') {
// ... setValue(value);
} }
}; };

View file

@ -110,8 +110,7 @@ Ox.Select = function(options, self) {
width: getTitleWidth() + 'px' width: getTitleWidth() + 'px'
}) })
.html( .html(
self.options.title self.options.title || getItem(self.options.value).title
|| getItem(self.options.value).title
) )
.appendTo(that); .appendTo(that);
} }
@ -153,10 +152,11 @@ Ox.Select = function(options, self) {
function changeMenu(data) { function changeMenu(data) {
self.options.value = self.optionGroup.value(); self.options.value = self.optionGroup.value();
self.$title && self.$title.html( self.$title && self.$title.html(
self.options.title ? self.options.title : getItem(self.options.value).title self.options.title || getItem(self.options.value).title
); );
that.triggerEvent('change', { that.triggerEvent('change', {
title: Ox.isArray(self.options.value) title: Ox.isEmpty(self.options.value) ? ''
: Ox.isArray(self.options.value)
? self.options.value.map(function(value) { ? self.options.value.map(function(value) {
return getItem(value).title; return getItem(value).title;
}) })
@ -207,15 +207,13 @@ 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);
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);
if (self.options.type == 'text' && !self.options.title) { if (self.options.type == 'text' && !self.options.title) {
self.$title.html(getItem(value).title); self.$title.html(getItem(value).title);
} }
Ox.toArray(value).forEach(function(value) { value !== '' && Ox.toArray(value).forEach(function(value) {
self.$menu.checkItem(value); self.$menu.checkItem(value);
}); });
self.options.value = self.optionGroup.value(); self.options.value = self.optionGroup.value();

View file

@ -10,7 +10,7 @@ Ox.SelectInput = function(options, self) {
label: '', label: '',
labelWidth: 128, labelWidth: 128,
max: 1, max: 1,
min: 1, min: 0,
placeholder: '', placeholder: '',
title: '', title: '',
value: options.max == 1 ? '' : [], value: options.max == 1 ? '' : [],
@ -27,28 +27,14 @@ Ox.SelectInput = function(options, self) {
labelWidth: self.options.labelWidth, labelWidth: self.options.labelWidth,
max: self.options.max, max: self.options.max,
min: self.options.min, min: self.options.min,
title: self.options.title, title: getTitle(),
value: self.options.value, value: self.options.value,
width: self.options.width width: self.options.width
}) })
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
if (self.options.title) { self.options.value = getValue();
self.$select.options({ setValue(self.isOther);
title: Ox.getObjectById(self.options.items, data.value).title
});
}
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.value();
}
} }
}); });
@ -63,11 +49,14 @@ Ox.SelectInput = function(options, self) {
}) })
.hide(); .hide();
setValue();
that = Ox.FormElementGroup({ that = Ox.FormElementGroup({
elements: [ elements: [
self.$select, self.$select,
self.$input self.$input
], ],
id: self.options.id,
join: function(value) { join: function(value) {
return value[value[0] == self.other ? 1 : 0] return value[value[0] == self.other ? 1 : 0]
}, },
@ -79,8 +68,62 @@ Ox.SelectInput = function(options, self) {
width: self.options.width width: self.options.width
}); });
function getTitle() {
var value = self.$select ? self.$select.value() : self.options.value;
return Ox.isEmpty(value)
? self.options.title
: Ox.getObjectById(self.options.items, value).title;
}
function getValue() {
self.isOther = self.$select.value() == self.other;
return !self.isOther ? self.$select.value() : self.$input.value();
}
function setValue(isOther) {
Ox.print('SET VALUE', isOther)
if (
(!self.options.value && isOther !== true)
|| Ox.map(self.options.items, function(item) {
return item.id != self.other ? item.id : null;
}).indexOf(self.options.value) > -1
) {
self.$select.options({
title: !self.options.value
? self.options.title
: Ox.getObjectById(self.options.items, self.options.value).title,
value: self.options.value,
width: self.options.width
})
.removeClass('OxOverlapRight');
self.$input.hide().value('');
} else {
self.$select.options({
title: Ox.getObjectById(self.options.items, self.other).title,
value: self.other,
width: self.otherWidth
})
.addClass('OxOverlapRight');
self.$input.show().value(self.options.value);
}
self.$select.options({title: getTitle()});
}
self.setOption = function(key, value) { self.setOption = function(key, value) {
// ... if (key == 'value') {
setValue();
}
};
that.value = function() {
if (arguments.length == 0) {
return getValue();
} else {
self.options.value = arguments[0];
Ox.print('SOV:::', self.options.value)
setValue();
return that;
}
}; };
return that; return that;

View file

@ -14,33 +14,44 @@ Ox.Spreadsheet = function(options, self) {
rowTitleType: 'str', rowTitleType: 'str',
rowTitleWidth: 128, rowTitleWidth: 128,
title: '', title: '',
value: [] value: {}
}) })
.options(options || {}) .options(options || {})
.addClass('OxSpreadsheet'); .addClass('OxSpreadsheet');
self.values = []; if (Ox.isEmpty(self.options.value)) {
self.options.rows.forEach(function(row, r) { self.options.value = {
self.values.push([]); columns: [],
self.options.columns.forEach(function(column, c) { rows: [],
self.values[r].push(0); values: []
}
Ox.loop(4, function(i) {
self.options.value.columns.push('');
self.options.value.rows.push('');
self.options.value.values.push([0, 0, 0, 0]);
});
} else if (Ox.isEmpty(self.options.value.values)) {
self.options.value.rows.forEach(function(row, r) {
self.options.value.values.push([]);
self.options.value.columns.forEach(function(column, c) {
self.options.value.values[r].push(0);
}); });
}); });
self.sums = getSums(); }
renderSpreadsheet(); renderSpreadsheet();
function addColumn(index) { function addColumn(index) {
self.options.columns.splice(index, 0, ''); self.options.value.columns.splice(index, 0, '');
self.values.forEach(function(columns) { self.options.value.values.forEach(function(columns) {
columns.splice(index, 0, 0); columns.splice(index, 0, 0);
}); });
renderSpreadsheet(); renderSpreadsheet();
} }
function addRow(index) { function addRow(index) {
self.options.rows.splice(index, 0, ''); self.options.value.rows.splice(index, 0, '');
self.values.splice(index, 0, Ox.repeat([0], self.columns)); self.options.value.values.splice(index, 0, Ox.repeat([0], self.columns));
renderSpreadsheet(); renderSpreadsheet();
} }
@ -50,7 +61,7 @@ Ox.Spreadsheet = function(options, self) {
row: Ox.repeat([0], self.rows), row: Ox.repeat([0], self.rows),
sheet: 0 sheet: 0
}; };
self.values.forEach(function(columns, r) { self.options.value.values.forEach(function(columns, r) {
columns.forEach(function(value, c) { columns.forEach(function(value, c) {
sums.column[c] += value; sums.column[c] += value;
sums.row[r] += value; sums.row[r] += value;
@ -61,23 +72,23 @@ Ox.Spreadsheet = function(options, self) {
} }
function removeColumn(index) { function removeColumn(index) {
self.options.columns.splice(index, 1); self.options.value.columns.splice(index, 1);
self.values.forEach(function(columns) { self.options.value.values.forEach(function(columns) {
columns.splice(index, 1); columns.splice(index, 1);
}); });
renderSpreadsheet(); renderSpreadsheet();
} }
function removeRow(index) { function removeRow(index) {
self.options.rows.splice(index, 1); self.options.value.rows.splice(index, 1);
self.values.splice(index, 1); self.options.value.values.splice(index, 1);
renderSpreadsheet(); renderSpreadsheet();
} }
function renderSpreadsheet() { function renderSpreadsheet() {
self.columns = self.options.columns.length; self.columns = self.options.value.columns.length;
self.rows = self.options.rows.length; self.rows = self.options.value.rows.length;
self.sums = getSums(); self.sums = getSums();
self.$input = {}; self.$input = {};
@ -88,9 +99,9 @@ Ox.Spreadsheet = function(options, self) {
height: 16 * (self.rows + 2) + 'px' height: 16 * (self.rows + 2) + 'px'
}); });
Ox.merge([self.options.title], Ox.clone(self.options.rows), ['Total']).forEach(function(row, r) { Ox.merge([self.options.title], Ox.clone(self.options.value.rows), ['Total']).forEach(function(row, r) {
r--; r--;
Ox.merge([''], Ox.clone(self.options.columns), ['Total']).forEach(function(column, c) { Ox.merge([''], Ox.clone(self.options.value.columns), ['Total']).forEach(function(column, c) {
c--; c--;
if (r == -1) { if (r == -1) {
if (c == -1 || c == self.columns) { if (c == -1 || c == self.columns) {
@ -131,7 +142,7 @@ Ox.Spreadsheet = function(options, self) {
}) })
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
self.options.columns[c] = data.value; self.options.value.columns[c] = data.value;
triggerChangeEvent(); triggerChangeEvent();
} }
}) })
@ -169,7 +180,7 @@ Ox.Spreadsheet = function(options, self) {
}) })
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
self.options.rows[r] = data.value; self.options.value.rows[r] = data.value;
triggerChangeEvent(); triggerChangeEvent();
} }
}) })
@ -197,13 +208,13 @@ Ox.Spreadsheet = function(options, self) {
value: isSheetSum ? self.sums.sheet value: isSheetSum ? self.sums.sheet
: isColumnSum ? self.sums.column[c] : isColumnSum ? self.sums.column[c]
: isRowSum ? self.sums.row[r] : isRowSum ? self.sums.row[r]
: self.values[r][c], : self.options.value.values[r][c],
width: self.options.columnWidth width: self.options.columnWidth
}) })
.appendTo(that); .appendTo(that);
!isSum && self.$input[id].bindEvent({ !isSum && self.$input[id].bindEvent({
change: function(data) { change: function(data) {
self.values[r][c] = parseInt(data.value); self.options.value.values[r][c] = parseInt(data.value);
self.sums = getSums(); self.sums = getSums();
self.$input[c + ',' + self.rows].value(self.sums.column[c]); self.$input[c + ',' + self.rows].value(self.sums.column[c]);
self.$input[self.columns + ',' + r].value(self.sums.row[r]); self.$input[self.columns + ',' + r].value(self.sums.row[r]);
@ -220,18 +231,10 @@ Ox.Spreadsheet = function(options, self) {
function triggerChangeEvent() { function triggerChangeEvent() {
that.triggerEvent('change', { that.triggerEvent('change', {
value: that.value() value: self.options.value
}); });
} }
that.value = function() {
return {
columns: self.options.columns,
rows: self.options.rows,
values: self.values
};
};
return that; return that;
}; };

View file

@ -65,6 +65,7 @@
'Check', 'Embed', 'Bracket', 'Check', 'Embed', 'Bracket',
'Upload', 'Download', 'Upload', 'Download',
'Copyright', 'NoCopyright', 'Copyright', 'NoCopyright',
'List', 'Grid', 'Map', 'Calendar',
'Click', 'Delete', 'Edit', 'Find', 'Flag', 'Icon', 'Like', 'Click', 'Delete', 'Edit', 'Find', 'Flag', 'Icon', 'Like',
'Mail', 'Publish', 'Set', 'Star', 'User', 'View', 'Loading' 'Mail', 'Publish', 'Set', 'Star', 'User', 'View', 'Loading'
].forEach(function(symbol) { ].forEach(function(symbol) {

View file

@ -643,7 +643,9 @@ Ox.some <f> Tests if one or more elements of a collection satisfy a given condit
true true
@*/ @*/
Ox.some = function(obj, fn) { Ox.some = function(obj, fn) {
return Ox.filter(Ox.values(obj), fn).length > 0; return Ox.filter(Ox.values(obj), fn || function(v) {
return v;
}).length > 0;
}; };
/*@ /*@

View file

@ -125,13 +125,56 @@ Ox.load = function() {
}); });
}; };
/*@
Ox.localStorage <o> localStorage wrapper
() -> <o> key:value pairs
(key) -> <*> value
(key, val) -> <f> localStorage object
({key, val}) -> <f> localStorage object
@*/
Ox.localStorage = function(namespace) {
// Ox.Log calls this before Ox.isUndefined is defined
if (localStorage === void 0) {
localStorage = {};
}
function storage(key, val) {
var ret, value;
if (arguments.length == 0) {
ret = {};
Ox.forEach(localStorage, function(val, key) {
if (Ox.startsWith(key, namespace + '.')) {
ret[key.substr(namespace.length + 1)] = JSON.parse(val);
}
});
} else if (arguments.length == 1 && !Ox.isObject(key)) {
value = localStorage[namespace + '.' + key];
ret = Ox.isUndefined(value) ? void 0 : JSON.parse(value);
} else {
args = Ox.makeObject(arguments);
Ox.forEach(args, function(val, key) {
localStorage[namespace + '.' + key] = JSON.stringify(val);
});
ret = this;
}
return ret;
};
storage.delete = function(key) {
var keys = arguments.length == 0
? Object.keys(storage())
: [key];
keys.forEach(function(key) {
delete localStorage[namespace + '.' + key];
});
};
return storage;
};
/*@ /*@
Ox.Log <f> Logging module Ox.Log <f> Logging module
@*/ @*/
Ox.Log = (function() { Ox.Log = (function() {
var log = localStorage && localStorage.OxLog var storage = Ox.localStorage('Ox'),
? JSON.parse(localStorage.OxLog) log = storage('Log') || {filter: [], filterEnabled: true},
: {filter: [], filterEnabled: true},
that = function() { that = function() {
var ret; var ret;
if (arguments.length == 0) { if (arguments.length == 0) {
@ -141,16 +184,11 @@ Ox.Log = (function() {
} }
return ret; return ret;
}; };
function save() {
if (localStorage) {
localStorage.OxLog = JSON.stringify(log);
}
}
that.filter = function(val) { that.filter = function(val) {
if (!Ox.isUndefined(val)) { if (!Ox.isUndefined(val)) {
that.filter.enable(); that.filter.enable();
log.filter = Ox.toArray(val); log.filter = Ox.toArray(val);
save(); storage('Log', log);
} }
return log.filter; return log.filter;
}; };
@ -159,11 +197,11 @@ Ox.Log = (function() {
}; };
that.filter.disable = function() { that.filter.disable = function() {
log.filterEnabled = false; log.filterEnabled = false;
save(); storage('Log', log);
}; };
that.filter.enable = function() { that.filter.enable = function() {
log.filterEnabled = true; log.filterEnabled = true;
save(); storage('Log', log);
}; };
that.filter.remove = function(val) { that.filter.remove = function(val) {
val = Ox.toArray(val); val = Ox.toArray(val);
@ -176,9 +214,7 @@ Ox.Log = (function() {
if (!log.filterEnabled || log.filter.indexOf(args[0]) > -1) { if (!log.filterEnabled || log.filter.indexOf(args[0]) > -1) {
date = new Date(); date = new Date();
args.unshift( args.unshift(
Ox.formatDate(date, '%H:%M:%S.') + (+date).toString().substr(-3)/*, Ox.formatDate(date, '%H:%M:%S.') + (+date).toString().substr(-3)
(arguments.callee.caller && arguments.callee.caller.name)
|| '(anonymous)'*/
); );
window.console && window.console.log.apply(window.console, args); window.console && window.console.log.apply(window.console, args);
ret = args.join(' '); ret = args.join(' ');

View file

@ -137,6 +137,36 @@ Ox.isEqual = function(a, b) {
return isEqual; return isEqual;
}; };
/*@
Ox.isFalsy <f> Returns true for undefined, null, false, 0, '', [], {}
(value) -> <b> True if the value is falsy
value <*> Any value
> Ox.isFalsy(void 0)
true
> Ox.isFalsy(null)
true
> Ox.isFalsy(false)
true
> Ox.isFalsy(0)
true
> Ox.isFalsy('')
true
> Ox.isFalsy([])
true
> Ox.isFalsy({})
true
> Ox.isFalsy(NaN)
false
> Ox.isFalsy(function() {})
false
> Ox.isFalsy(/ /)
false
@*/
Ox.isFalsy = function(val) {
return (!val && !Ox.isNaN(val))
|| (Ox.isEmpty(val) && !Ox.isFunction(val));
};
/*@ /*@
Ox.isFunction <f> Tests if a value is a function Ox.isFunction <f> Tests if a value is a function
(value) -> <b> True if the value is a function (value) -> <b> True if the value is a function
@ -261,8 +291,7 @@ Ox.isUndefined <f> Tests if a value is undefined
@*/ @*/
Ox.isUndefined = function(val) { Ox.isUndefined = function(val) {
// fixme: val === void 0 is also nice return val === void 0;
return typeof val == 'undefined';
}; };
/*@ /*@

View file

@ -32,7 +32,7 @@ def build_oxjs(geo):
for theme in ['classic', 'modern']: for theme in ['classic', 'modern']:
path = source_path + 'Ox.UI/themes/' + theme + '/svg/' path = source_path + 'Ox.UI/themes/' + theme + '/svg/'
for filename in os.listdir(path): for filename in os.listdir(path):
if not filename[0] in '._': if not filename[0] in '._' and not filename.endswith('~'):
key = theme + '/' + filename[:-4] key = theme + '/' + filename[:-4]
imageURLs[key] = os.path.join(path, filename).replace(source_path, '') imageURLs[key] = os.path.join(path, filename).replace(source_path, '')
data = re.sub('\n\s+', '', read_file(path + filename)) data = re.sub('\n\s+', '', read_file(path + filename))
@ -46,7 +46,8 @@ def build_oxjs(geo):
ui_files = {'build': [], 'dev': []} ui_files = {'build': [], 'dev': []}
for path, dirnames, filenames in os.walk(source_path): for path, dirnames, filenames in os.walk(source_path):
for filename in filenames: for filename in filenames:
if not '_' in path and not filename[0] in '._'\ if not '_' in path and not filename[0] in '._' \
and not filename.endswith('~') \
and (geo or not '/Ox.Geo/' in path): and (geo or not '/Ox.Geo/' in path):
# write copies in build path # write copies in build path
source = os.path.join(path, filename) source = os.path.join(path, filename)
@ -77,6 +78,7 @@ def build_oxjs(geo):
write_link(link_source, link_target) write_link(link_source, link_target)
# Ox.js # Ox.js
# FIXME: Document what exactly the following dependecies are!
filenames = [ filenames = [
['Fallback.js', 'Core.js'], ['Fallback.js', 'Core.js'],
['Collection.js', 'Math.js'] ['Collection.js', 'Math.js']
@ -90,7 +92,9 @@ def build_oxjs(geo):
data[1].append(js_dir + filename) data[1].append(js_dir + filename)
filenames = filenames[0] + filenames[1] filenames = filenames[0] + filenames[1]
for filename in os.listdir(source_path + js_dir): for filename in os.listdir(source_path + js_dir):
if not filename in filenames: if not filename in filenames \
and not filename.startswith('.') \
and not filename.endswith('~'):
filenames.append(filename) filenames.append(filename)
for filename in filenames: for filename in filenames:
js += read_file(source_path + js_dir + filename) + '\n' js += read_file(source_path + js_dir + filename) + '\n'
@ -109,6 +113,7 @@ def build_oxjs(geo):
# svgs are loaded as URLs or dataURLs # svgs are loaded as URLs or dataURLs
# browser images appear before load # browser images appear before load
if path != root and not '_' in path and not filename[0] in '._'\ if path != root and not '_' in path and not filename[0] in '._'\
and not filename.endswith('~') \
and not 'jquery' in filename\ and not 'jquery' in filename\
and not ('/themes/' in path and filename.endswith('.css'))\ and not ('/themes/' in path and filename.endswith('.css'))\
and not filename.endswith('.svg')\ and not filename.endswith('.svg')\