Ox.Filter, round 2
This commit is contained in:
parent
44530bceb9
commit
358c1ecebb
2 changed files with 384 additions and 230 deletions
|
@ -1226,6 +1226,10 @@ Format functions
|
|||
================================================================================
|
||||
*/
|
||||
|
||||
Ox.formatColor = function() {
|
||||
|
||||
};
|
||||
|
||||
Ox.formatCurrency = function(num, str, dec) {
|
||||
return str + formatNumber(num, dec);
|
||||
};
|
||||
|
@ -1511,6 +1515,10 @@ Ox.formatValue = function(num, str) {
|
|||
return val;
|
||||
};
|
||||
|
||||
Ox.formatUnit = function(num, str) {
|
||||
return num + ' ' + str;
|
||||
};
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
Geo functions
|
||||
|
|
|
@ -2085,71 +2085,80 @@ requires
|
|||
============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
*/
|
||||
Ox.Filter = function(options, self) {
|
||||
|
||||
/***
|
||||
Options:
|
||||
Methods:
|
||||
Events:
|
||||
***/
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element('div', self)
|
||||
.defaults({
|
||||
keys: [],
|
||||
findKeys: [],
|
||||
query: {
|
||||
conditions: [],
|
||||
operator: '&'
|
||||
}
|
||||
},
|
||||
sortKeys: [],
|
||||
viewKeys: []
|
||||
})
|
||||
.options(options || {});
|
||||
|
||||
Ox.print('s.o', self.options)
|
||||
Ox.print('Ox.Filter self.options', self.options)
|
||||
|
||||
$.extend(self, {
|
||||
conditionOperators: {
|
||||
date: [
|
||||
{id: '', title: 'is'},
|
||||
{id: '!', title: 'is not'},
|
||||
{id: '<', title: 'is before'},
|
||||
{id: '>', title: 'is after'},
|
||||
{id: '>&<', title: 'is between'},
|
||||
{id: '<|>', title: 'is not between'}
|
||||
],
|
||||
list: [
|
||||
{id: '', title: 'is'},
|
||||
{id: '!', title: 'is not'}
|
||||
],
|
||||
number: [
|
||||
{id: '', title: 'is'},
|
||||
{id: '!', title: 'is not'},
|
||||
{id: '<', title: 'is less than'},
|
||||
{id: '>', title: 'is greater than'},
|
||||
{id: '>&<', title: 'is between'},
|
||||
{id: '<|>', title: 'is not between'}
|
||||
],
|
||||
string: [
|
||||
{id: '=', title: 'is'},
|
||||
{id: '!=', title: 'is not'},
|
||||
{id: '^', title: 'begins with'},
|
||||
{id: '$', title: 'ends with'},
|
||||
{id: '', title: 'contains'},
|
||||
{id: '!', title: 'does not contain'}
|
||||
],
|
||||
text: [
|
||||
{id: '', title: 'contains'},
|
||||
{id: '!', title: 'does not contain'}
|
||||
]
|
||||
},
|
||||
operators: [
|
||||
{id: '&', title: 'all'},
|
||||
{id: '|', title: 'any'}
|
||||
]
|
||||
});
|
||||
|
||||
if (!self.options.query.conditions.length) {
|
||||
self.options.query.conditions = [{
|
||||
key: self.options.keys[0].id,
|
||||
value: ''
|
||||
key: self.options.findKeys[0].id,
|
||||
value: '',
|
||||
operator: self.conditionOperators[
|
||||
getConditionType(self.options.findKeys[0].type)
|
||||
][0].id
|
||||
}];
|
||||
}
|
||||
|
||||
$.extend(self, {
|
||||
operators: [
|
||||
{title: 'all', operator: '&'},
|
||||
{title: 'any', operator: '|'}
|
||||
],
|
||||
relations: {
|
||||
date: [
|
||||
{title: 'is', operator: '='},
|
||||
{title: 'is not', operator: '!'},
|
||||
{title: 'is before', operator: '<'},
|
||||
{title: 'is after', operator: '>'},
|
||||
{title: 'is between', operator: '>&<'},
|
||||
{title: 'is not between', operator: '<|>'}
|
||||
],
|
||||
list: [
|
||||
{title: 'is', operator: '='},
|
||||
{title: 'is not', operator: '!'}
|
||||
],
|
||||
number: [
|
||||
{title: 'is', operator: '='},
|
||||
{title: 'is not', operator: '!'},
|
||||
{title: 'is less than', operator: '<'},
|
||||
{title: 'is greater than', operator: '>'},
|
||||
{title: 'is between', operator: '>&<'},
|
||||
{title: 'is not between', operator: '<|>'}
|
||||
],
|
||||
string: [
|
||||
{title: 'is', operator: '='},
|
||||
{title: 'is not', operator: '!='},
|
||||
{title: 'begins with', operator: '^'},
|
||||
{title: 'ends with', operator: '$'},
|
||||
{title: 'contains', operator: ''},
|
||||
{title: 'does not contain', operator: '!'}
|
||||
],
|
||||
text: [
|
||||
{title: 'contains', operator: ''},
|
||||
{title: 'does not contain', operator: '!'}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
self.$operator = new Ox.FormElementGroup({
|
||||
elements: [
|
||||
new Ox.Label({
|
||||
|
@ -2157,18 +2166,24 @@ requires
|
|||
overlap: 'right',
|
||||
width: 48
|
||||
}),
|
||||
new Ox.FormElementGroup({
|
||||
elements: [
|
||||
new Ox.Select({
|
||||
items: [
|
||||
{id: 'all', title: 'all'},
|
||||
{id: 'any', title: 'any'},
|
||||
],
|
||||
overlap: 'right',
|
||||
items: self.operators,
|
||||
width: 48
|
||||
})
|
||||
.bindEvent({
|
||||
change: changeOperator
|
||||
}),
|
||||
new Ox.Label({
|
||||
overlap: 'left',
|
||||
title: 'of the following conditions',
|
||||
width: 160
|
||||
}),
|
||||
})
|
||||
],
|
||||
float: 'right',
|
||||
width: 208
|
||||
})
|
||||
],
|
||||
float: 'left',
|
||||
});
|
||||
|
@ -2205,40 +2220,109 @@ requires
|
|||
width: 120
|
||||
}),
|
||||
new Ox.Select({
|
||||
/*
|
||||
items: $.map(self.options.keys, function(key) {
|
||||
return {id: key.id, title: key.title};
|
||||
}),
|
||||
*/
|
||||
items: [
|
||||
{id: "title", title: "Title"},
|
||||
{id: "director", title: "Director"}
|
||||
],
|
||||
items: self.options.sortKeys,
|
||||
width: 128
|
||||
}),
|
||||
new Ox.FormElementGroup({
|
||||
elements: [
|
||||
new Ox.Select({
|
||||
items: [
|
||||
{id: 'ascending', title: 'ascending'},
|
||||
{id: 'descending', title: 'descending'}
|
||||
],
|
||||
width: 96
|
||||
}),
|
||||
new Ox.Label({
|
||||
overlap: 'left',
|
||||
title: 'order',
|
||||
width: 72
|
||||
})
|
||||
],
|
||||
float: 'right',
|
||||
width: 168
|
||||
})
|
||||
],
|
||||
separators: [
|
||||
{title: 'Limit to', width: 56},
|
||||
{title: 'sorted by', width: 64}
|
||||
{title: 'sorted by', width: 64},
|
||||
{title: 'in', width: 32}
|
||||
]
|
||||
});
|
||||
|
||||
self.$items = $.merge($.merge([self.$operator], self.$conditions), [self.$limit]);
|
||||
self.$view = new Ox.InputGroup({
|
||||
inputs: [
|
||||
new Ox.Checkbox({
|
||||
width: 16
|
||||
}),
|
||||
new Ox.Select({
|
||||
items: self.options.viewKeys,
|
||||
width: 128
|
||||
})
|
||||
],
|
||||
separators: [
|
||||
{title: 'By default, view', width: 112}
|
||||
]
|
||||
});
|
||||
|
||||
that = new Ox.Form({
|
||||
self.$save = new Ox.InputGroup({
|
||||
inputs: [
|
||||
new Ox.Checkbox({
|
||||
width: 16
|
||||
}),
|
||||
new Ox.Input({
|
||||
id: 'list',
|
||||
width: 128
|
||||
})
|
||||
],
|
||||
separators: [
|
||||
{title: 'Save as Smart List', width: 112}
|
||||
]
|
||||
});
|
||||
|
||||
self.$items = $.merge($.merge([self.$operator], self.$conditions), [self.$limit, self.$view, self.$save]);
|
||||
|
||||
self.$form = new Ox.Form({
|
||||
items: self.$items
|
||||
}, $.extend({}, self));
|
||||
});
|
||||
that.$element = self.$form.$element;
|
||||
|
||||
function addCondition(pos) {
|
||||
var key = self.options.keys[0];
|
||||
var key = self.options.findKeys[0];
|
||||
self.options.query.conditions.splice(pos, 0, {
|
||||
key: key.id,
|
||||
value: '',
|
||||
operator: self.relations[key.type][0].operator
|
||||
operator: self.conditionOperators[key.type][0].id
|
||||
});
|
||||
self.$conditions.splice(pos, 0, constructCondition({}, pos));
|
||||
updateConditions();
|
||||
that.addItem(pos + 1, self.$conditions[pos]);
|
||||
self.$form.addItem(pos + 1, self.$conditions[pos]);
|
||||
}
|
||||
|
||||
function changeConditionKey(pos, key) {
|
||||
Ox.print('changeConditionKey', pos, key);
|
||||
var oldOperator = self.options.query.conditions[pos].operator,
|
||||
oldType = Ox.getObjectById(
|
||||
self.options.findKeys, self.options.query.conditions[pos].key
|
||||
).type,
|
||||
newType = Ox.getObjectById(
|
||||
self.options.findKeys, key
|
||||
).type,
|
||||
oldConditionType = getConditionType(oldType),
|
||||
newConditionType = getConditionType(newType);
|
||||
changeConditionType = oldConditionType != newConditionType;
|
||||
Ox.print('old new', oldConditionType, newConditionType)
|
||||
self.options.query.conditions[pos].key = key;
|
||||
if (changeConditionType) {
|
||||
self.$conditions[pos].replaceElement(1, constructConditionOperator(pos, oldOperator));
|
||||
}
|
||||
}
|
||||
|
||||
function changeConditionOperator(pos, operator) {
|
||||
|
||||
}
|
||||
|
||||
function changeOperator(event, data) {
|
||||
self.options.query.operator = data.selected[0].id;
|
||||
}
|
||||
|
||||
function constructCondition(condition, pos) {
|
||||
|
@ -2246,17 +2330,23 @@ requires
|
|||
return $condition = new Ox.FormElementGroup({
|
||||
elements: [
|
||||
new Ox.Select({
|
||||
items: $.extend({}, self.options.keys), // fixme: Ox.Menu messes with keys
|
||||
overlap: 'right',
|
||||
width: 128
|
||||
}),
|
||||
new Ox.Select({
|
||||
items: $.map(self.relations[self.options.keys[0].type], function(relation) {
|
||||
return {id: relation.title, title: relation.title}
|
||||
}),
|
||||
items: $.map(self.options.findKeys, function(key) {
|
||||
return {
|
||||
id: key.id,
|
||||
title: key.title
|
||||
};
|
||||
}),
|
||||
//items: $.extend({}, self.options.findKeys), // fixme: Ox.Menu messes with keys
|
||||
overlap: 'right',
|
||||
width: 128
|
||||
})
|
||||
.bindEvent({
|
||||
change: function(event, data) {
|
||||
Ox.print('event', event)
|
||||
changeConditionKey($condition.data('position'), data.selected[0].id);
|
||||
}
|
||||
}),
|
||||
constructConditionOperator(pos),
|
||||
new Ox.Input({
|
||||
width: 256
|
||||
}),
|
||||
|
@ -2282,6 +2372,7 @@ requires
|
|||
.css({margin: '0 4px 0 4px'})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
Ox.print('add', $(this).parent().parent().data('position'))
|
||||
addCondition($condition.data('position') + 1)
|
||||
}
|
||||
}),
|
||||
|
@ -2291,17 +2382,54 @@ requires
|
|||
tooltip: 'Add Group of Conditions',
|
||||
type: 'image'
|
||||
})
|
||||
.css({margin: '0 0 0 4px'}),
|
||||
.css({margin: '0 0 0 4px'})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
|
||||
}
|
||||
})
|
||||
]
|
||||
})
|
||||
.data({position: pos});
|
||||
}
|
||||
|
||||
function constructConditionOperator(pos, selected) {
|
||||
return new Ox.Select({
|
||||
items: $.map(self.conditionOperators[getConditionType(
|
||||
Ox.getObjectById(
|
||||
self.options.findKeys,
|
||||
self.options.query.conditions[pos].key
|
||||
).type
|
||||
)], function(operator) {
|
||||
return {
|
||||
checked: operator.id == selected, // fixme: should be "selected", not "checked"
|
||||
id: operator.operator,
|
||||
title: operator.title
|
||||
};
|
||||
}),
|
||||
overlap: 'right',
|
||||
width: 128
|
||||
})
|
||||
.bindEvent({
|
||||
change: function(event, data) {
|
||||
changeConditionOperator(/*$condition.data('position')*/ pos, data.selected[0].id)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getConditionType(type) {
|
||||
type = Ox.isArray(type) ? type[0] : type;
|
||||
if (['float', 'integer', 'year'].indexOf(type) > 1) {
|
||||
type = 'number';
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function removeCondition(pos) {
|
||||
self.options.query.conditions.splice(pos, 1);
|
||||
self.$conditions.splice(pos, 1);
|
||||
updateConditions();
|
||||
that.removeItem(pos + 1);
|
||||
self.$form.removeItem(pos + 1);
|
||||
}
|
||||
|
||||
function updateConditions() {
|
||||
|
@ -2317,9 +2445,11 @@ requires
|
|||
|
||||
};
|
||||
|
||||
Ox.Form = function(options, self) {
|
||||
|
||||
/**
|
||||
*/
|
||||
Ox.Form = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element('div', self)
|
||||
.defaults({
|
||||
|
@ -2437,8 +2567,6 @@ requires
|
|||
|
||||
};
|
||||
|
||||
/**
|
||||
*/
|
||||
Ox.FormItem = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
|
@ -2471,6 +2599,8 @@ requires
|
|||
Form Elements
|
||||
*/
|
||||
|
||||
Ox.Button = function(options, self) {
|
||||
|
||||
/**
|
||||
methods:
|
||||
toggleDisabled enable/disable button
|
||||
|
@ -2482,7 +2612,7 @@ requires
|
|||
deselect selectable button was deselected
|
||||
select selectable button was selected
|
||||
*/
|
||||
Ox.Button = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element('input', self)
|
||||
.defaults({
|
||||
|
@ -2632,6 +2762,8 @@ requires
|
|||
|
||||
};
|
||||
|
||||
Ox.ButtonGroup = function(options, self) {
|
||||
|
||||
/**
|
||||
options
|
||||
buttons array of buttons
|
||||
|
@ -2643,7 +2775,7 @@ requires
|
|||
events:
|
||||
change {id, value} selection within a group changed
|
||||
*/
|
||||
Ox.ButtonGroup = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element({}, self)
|
||||
.defaults({
|
||||
|
@ -2705,6 +2837,8 @@ requires
|
|||
return that;
|
||||
};
|
||||
|
||||
Ox.Checkbox = function(options, self) {
|
||||
|
||||
/**
|
||||
options
|
||||
disabled boolean, if true, checkbox is disabled
|
||||
|
@ -2721,8 +2855,6 @@ requires
|
|||
change triggered when checked property changes
|
||||
passes {checked, id, title}
|
||||
*/
|
||||
Ox.Checkbox = function(options, self) {
|
||||
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element('div', self)
|
||||
|
@ -2810,6 +2942,8 @@ requires
|
|||
|
||||
};
|
||||
|
||||
Ox.CheckboxGroup = function(options, self) {
|
||||
|
||||
/**
|
||||
options
|
||||
checkboxes [] array of checkboxes
|
||||
|
@ -2820,7 +2954,6 @@ requires
|
|||
change triggered when checked property changes
|
||||
passes {checked, id, title}
|
||||
*/
|
||||
Ox.CheckboxGroup = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element('div', self)
|
||||
|
@ -2880,6 +3013,8 @@ requires
|
|||
|
||||
};
|
||||
|
||||
Ox.Input = function(options, self) {
|
||||
|
||||
/**
|
||||
options
|
||||
arrows boolearn, if true, and type is 'float' or 'integer', display arrows
|
||||
|
@ -2894,7 +3029,7 @@ requires
|
|||
autocorrect string ('email', 'float', 'integer', 'phone', 'url'), or
|
||||
regexp(value), or
|
||||
function(key, value, blur, callback), returns value
|
||||
auto validate --remote validation--
|
||||
autovalidate --remote validation--
|
||||
clear boolean, if true, has clear button
|
||||
disabled boolean, if true, is disabled
|
||||
height integer, px (for type='textarea' and type='range' with orientation='horizontal')
|
||||
|
@ -2933,7 +3068,7 @@ requires
|
|||
change
|
||||
submit
|
||||
*/
|
||||
Ox.Input = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element('div', self)
|
||||
.defaults({
|
||||
|
@ -3809,6 +3944,8 @@ requires
|
|||
|
||||
};
|
||||
|
||||
Ox.DateInput = function(options, self) {
|
||||
|
||||
/**
|
||||
options:
|
||||
format: 'short'
|
||||
|
@ -3821,7 +3958,6 @@ requires
|
|||
year: 48
|
||||
}
|
||||
*/
|
||||
Ox.DateInput = function(options, self) {
|
||||
|
||||
var self = $.extend(self || {}, {
|
||||
options: $.extend({
|
||||
|
@ -4402,6 +4538,8 @@ requires
|
|||
|
||||
}
|
||||
|
||||
Ox.Range = function(options, self) {
|
||||
|
||||
/**
|
||||
options
|
||||
arrows boolean if true, show arrows
|
||||
|
@ -4420,7 +4558,7 @@ requires
|
|||
value number initial value
|
||||
valueNames array value names to display on thumb
|
||||
*/
|
||||
Ox.Range = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element({}, self)
|
||||
.defaults({
|
||||
|
@ -4851,10 +4989,14 @@ requires
|
|||
}
|
||||
|
||||
self.onChange = function(key, value) {
|
||||
if (key == 'trackColors') {
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
that.replaceElement = function(pos, element) {
|
||||
Ox.print('Ox.FormElementGroup replaceElement', pos, element)
|
||||
self.options.elements[pos].replaceWith(element.$element);
|
||||
self.options.elements[pos] = element;
|
||||
};
|
||||
|
||||
that.value = function() {
|
||||
return $.map(self.options.elements, function(element) {
|
||||
|
@ -7817,6 +7959,8 @@ requires
|
|||
.options(options || {})
|
||||
.addClass('OxTextList');
|
||||
|
||||
Ox.print('Ox.TextList self.options', self.options)
|
||||
|
||||
$.each(self.options.columns, function(i, v) { // fixme: can this go into a generic ox.js function?
|
||||
// fixme: and can't these just remain undefined?
|
||||
if (Ox.isUndefined(v.align)) {
|
||||
|
@ -8012,7 +8156,7 @@ requires
|
|||
isSelected = self.options.sort[0].key == self.options.columns[i].id;
|
||||
that.sortList(
|
||||
self.options.columns[i].id, isSelected ?
|
||||
(self.options.sort[0].operator === '' ? '-' : '') :
|
||||
(self.options.sort[0].operator == '+' ? '-' : '+') :
|
||||
self.options.columns[i].operator
|
||||
);
|
||||
}
|
||||
|
@ -8050,7 +8194,7 @@ requires
|
|||
$order = $('<div>')
|
||||
.addClass('OxOrder')
|
||||
.html(oxui.symbols['triangle_' + (
|
||||
v.operator === '' ? 'up' : 'down'
|
||||
v.operator == '+' ? 'up' : 'down'
|
||||
)])
|
||||
.click(function() {
|
||||
$(this).prev().trigger('click')
|
||||
|
@ -8367,7 +8511,7 @@ requires
|
|||
var pos = getColumnPositionById(id);
|
||||
//Ox.print(id, pos)
|
||||
that.$titles[pos].next().html(oxui.symbols[
|
||||
'triangle_' + (self.options.sort[0].operator === '' ? 'up' : 'down')
|
||||
'triangle_' + (self.options.sort[0].operator == '+' ? 'up' : 'down')
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -9423,7 +9567,7 @@ requires
|
|||
that.items = [];
|
||||
$.each(items, function(i, item) {
|
||||
var position;
|
||||
if (item.id) {
|
||||
if ('id' in item) {
|
||||
that.items.push(new Ox.MenuItem($.extend(item, {
|
||||
menu: that,
|
||||
position: position = that.items.length
|
||||
|
@ -9941,9 +10085,11 @@ requires
|
|||
title: Ox.makeArray(options.title || self.defaults.title)
|
||||
}))
|
||||
.addClass('OxItem' + (self.options.disabled ? ' OxDisabled' : ''))
|
||||
/*
|
||||
.attr({
|
||||
id: Ox.toCamelCase(self.options.menu.options('id') + '/' + self.options.id)
|
||||
})
|
||||
*/
|
||||
.data('group', self.options.group); // fixme: why?
|
||||
|
||||
if (self.options.group && self.options.checked === null) {
|
||||
|
|
Loading…
Reference in a new issue