filter rewrite, allow for nested conditions

This commit is contained in:
rlx 2011-06-02 01:04:52 +00:00
parent c2794a6d35
commit d660e0e30a

View file

@ -110,11 +110,6 @@ Ox.Filter = function(options, self) {
float: 'left',
});
self.$buttons = [];
self.$conditions = $.map(self.options.query.conditions, function(condition, i) {
return constructCondition(condition, i);
});
self.$limit = Ox.InputGroup({
inputs: [
Ox.Checkbox({
@ -201,42 +196,38 @@ Ox.Filter = function(options, self) {
]
});
self.$items = Ox.merge([self.$operator], self.$conditions, [self.$limit, self.$view, self.$save]);
self.$items = [self.$operator, self.$limit, self.$view, self.$save];
self.$form = Ox.Form({
items: self.$items
});
renderConditions();
that.$element = self.$form.$element;
function addCondition(pos, isInGroup) {
var key = self.options.findKeys[0];
self.options.query.conditions.splice(pos, 0, {
key: key.id,
value: '',
operator: self.conditionOperators[key.type][0].id
});
self.$conditions.splice(pos, 0, constructCondition({}, pos, isInGroup));
updateConditions();
self.$form.addItem(pos + 1, self.$conditions[pos]);
function addCondition(pos, subpos, isGroup) {
subpos = Ox.isUndefined(subpos) ? -1 : subpos;
var key = self.options.findKeys[0],
condition = {
key: key.id,
value: '',
operator: self.conditionOperators[key.type][0].id
};
if (isGroup) {
condition = {
conditions: [condition],
operator: self.options.query.operator == '&' ? '|' : '&'
};
}
if (subpos == -1) {
self.options.query.conditions.splice(pos, 0, condition);
} else {
self.options.query.conditions[pos].conditions.splice(subpos, 0, condition);
}
renderConditions();
}
function addGroup(pos) {
self.$form.addItem(pos + 1, constructGroup(pos));
self.options.query.conditions.splice(pos + 1, 0, {
conditions: [
{
key: '?',
value: '?',
operator: '?'
}
],
operator: '?'
});
addCondition(pos + 1, true);
}
function changeConditionKey(pos, key) {
Ox.print('changeConditionKey', pos, key);
function changeConditionKey(pos, subpos, key) {
Ox.print('changeConditionKey', pos, subpos, key);
var oldOperator = self.options.query.conditions[pos].operator,
oldType = Ox.getObjectById(
self.options.findKeys, self.options.query.conditions[pos].key
@ -269,83 +260,15 @@ Ox.Filter = function(options, self) {
that.$element.find('.OxGroupLabel').html(self.options.query.operator == '&' ? 'and' : 'or');
}
function constructButtons(isGroup, isInGroup) {
return Ox.merge([
new Ox.Button({
disabled: self.options.query.conditions.length == 1,
id: 'remove',
title: 'remove',
type: 'image'
})
.css({margin: '0 4px 0 ' + (isGroup ? '264px' : '8px')})
.bind({
click: function() {
removeCondition($(this).parent().data('position'));
}
}),
Ox.Button({
id: 'add',
title: 'add',
type: 'image'
})
.css({margin: '0 ' + (isInGroup ? '0' : '4px') + ' 0 4px'})
.bind({
click: function() {
Ox.print('add', $(this).parent().data('position'))
addCondition($(this).parent().data('position') + 1)
}
})
], isInGroup ? [] : [
Ox.Button({
id: 'addgroup',
title: 'bracket',
type: 'image'
})
.css({margin: '0 0 0 4px'})
.bind({
click: function() {
addGroup($(this).parent().data('position') + 1)
}
})
]);
}
function constructCondition(condition, pos, isInGroup) {
var $condition = {};
return $condition = Ox.FormElementGroup({
elements: Ox.merge([
Ox.Select({
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),
constructInput()
], constructButtons(false, isInGroup))
})
.css({marginLeft: isInGroup ? '24px' : 0})
.data({position: pos});
}
function constructConditionOperator(pos, selected) {
function constructConditionOperator(pos, subpos, selected) {
subpos = Ox.isUndefined(subpos) ? -1 : subpos;
Ox.print('constructConditionOperator', pos, subpos)
var condition = subpos == -1
? self.options.query.conditions[pos]
: self.options.query.conditions[pos].conditions[subpos];
return Ox.Select({
items: $.map(self.conditionOperators[getConditionType(
Ox.getObjectById(
self.options.findKeys,
self.options.query.conditions[pos].key
).type
Ox.getObjectById(self.options.findKeys, condition.key).type
)], function(operator) {
return {
checked: operator.id == selected, // fixme: should be "selected", not "checked"
@ -363,49 +286,8 @@ Ox.Filter = function(options, self) {
});
}
function constructGroup() {
// fixme: duplicated
return Ox.FormElementGroup({
elements: [
Ox.Label({
title: self.options.query.operator == '&' ? 'and' : 'or',
overlap: 'right',
width: 48
}).addClass('OxGroupLabel'),
Ox.FormElementGroup({
elements: Ox.merge([
Ox.Select({
items: $.map(self.operators, function(operator) {
return {
checked: operator.id != self.options.query.operator,
id: operator.id,
// fixme: should be operator.title,
// but is passed by reference to some select,
// which makes it an array
title: operator.title[0]
};
}),
width: 48
})
.bindEvent({
change: changeOperator
}),
Ox.Label({
overlap: 'left',
title: 'of the following conditions',
width: 160
})
], constructButtons(true)),
float: 'right',
width: 208
})
],
float: 'left',
});
}
function constructInput(isBetween) {
var $input
var $input;
if (!isBetween) {
$input = Ox.Input({
width: 288
@ -417,17 +299,6 @@ Ox.Filter = function(options, self) {
id: 'start',
width: 128
}),
/*
Ox.TimeInput({
id: 'start',
//seconds: true,
width: {
hours: 38,
minutes: 37,
seconds: 37
}
}),
*/
Ox.DateInput({
id: 'end',
width: {
@ -453,16 +324,170 @@ Ox.Filter = function(options, self) {
return type;
}
function removeCondition(pos) {
self.options.query.conditions.splice(pos, 1);
self.$conditions.splice(pos, 1);
updateConditions();
self.$form.removeItem(pos + 1);
function removeCondition(pos, subpos) {
Ox.print('removeCondition', pos, subpos)
subpos = Ox.isUndefined(subpos) ? -1 : subpos;
if (subpos == -1) {
self.options.query.conditions.splice(pos, 1);
} else {
self.options.query.conditions[pos].conditions.splice(subpos, 1);
}
renderConditions();
}
function renderButtons(pos, subpos) {
var isGroup = subpos == -1 && self.options.query.conditions[pos].conditions;
return Ox.merge([
new Ox.Button({
disabled: self.options.query.conditions.length == 1,
id: 'remove',
title: 'remove',
type: 'image'
})
.css({margin: '0 4px 0 ' + (isGroup ? '296px' : '8px')})
.bind({
click: function() {
removeCondition(
$(this).parent().data('position'),
$(this).parent().data('subposition')
);
}
}),
Ox.Button({
id: 'add',
title: 'add',
type: 'image'
})
.css({margin: '0 ' + (subpos == -1 ? '4px' : '0') + ' 0 4px'})
.bind({
click: function() {
if (subpos == -1) {
addCondition($(this).parent().data('position') + 1);
} else {
addCondition(
$(this).parent().data('position'),
$(this).parent().data('subposition') + 1
);
}
}
})
], subpos == -1 ? [
Ox.Button({
id: 'addgroup',
title: 'bracket',
type: 'image'
})
.css({margin: '0 0 0 4px'})
.bind({
click: function() {
addCondition($(this).parent().data('position') + 1, -1, true)
}
})
] : []);
}
function renderCondition(condition, pos, subpos) {
subpos = Ox.isUndefined(subpos) ? -1 : subpos;
Ox.print('renderCondition', condition, pos, subpos)
var $condition = Ox.FormElementGroup({
elements: Ox.merge([
Ox.Select({
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'),
$condition.data('subposition'),
data.selected[0].id
);
}
}),
constructConditionOperator(pos, subpos),
constructInput()
], renderButtons(pos, subpos))
})
.css({marginLeft: subpos == -1 ? 0 : '24px'})
.data({position: pos, subpostion: subpos});
return $condition;
}
function renderConditions() {
Ox.print('renderConditions', self.options.query)
var $conditions = [];
while (self.$form.options('items').length > 4) {
self.$form.removeItem(1);
}
self.options.query.conditions.forEach(function(condition, pos) {
if (!condition.conditions) {
$conditions.push(renderCondition(condition, pos));
} else {
$conditions.push(renderGroup(condition, pos));
condition.conditions.forEach(function(subcondition, subpos) {
$conditions.push(renderCondition(subcondition, pos, subpos));
});
}
});
$conditions.forEach(function($condition, pos) {
self.$form.addItem(1 + pos, $condition);
});
}
function renderGroup(condition, pos) {
var subpos = -1;
var $condition = Ox.FormElementGroup({
elements: Ox.merge([
Ox.Label({
title: self.options.query.operator == '&' ? 'and' : 'or',
overlap: 'right',
width: 48
}).addClass('OxGroupLabel'),
Ox.FormElementGroup({
elements: [
Ox.Select({
items: $.map(self.operators, function(operator) {
return {
checked: operator.id != self.options.query.operator,
id: operator.id,
// fixme: should be operator.title,
// but is passed by reference to some select,
// which makes it an array
title: operator.title[0]
};
}),
width: 48
})
.bindEvent({
change: changeOperator
}),
Ox.Label({
overlap: 'left',
title: 'of the following conditions',
width: 160
})
],
float: 'right',
width: 208
}),
], renderButtons(pos, subpos, true)),
float: 'left',
})
.data({position: pos, subposition: subpos});
return $condition;
}
function updateConditions() {
self.$conditions.forEach(function(condition, pos) {
condition.data({position: pos});
condition.data({position: pos, subposition: -1});
});
self.$conditions[0].options('elements')[3].options({
disabled: self.options.query.conditions.length == 1