[MERGE] niv custom filters

bzr revid: al@openerp.com-20110329152425-580vhch31f8cmy6v
This commit is contained in:
Antony Lesuisse
2011-03-29 17:24:25 +02:00
4 changed files with 334 additions and 11 deletions
+1 -1
View File
@@ -13,7 +13,7 @@
<script type="text/javascript" src="/base/static/LABjs/LAB.js"></script>
<script>
$LAB
.setOptions({UsePreloading:false})
.setOptions({UsePreloading:false})
.script('/base/static/openerp/js/base.js')
.script('/base/static/qweb/qweb.js')
.script('/base/static/underscore/underscore.js')
+57 -5
View File
@@ -341,15 +341,67 @@
<t t-if="filters.length" t-raw="filters.render(defaults)"/>
</div>
</t>
<t t-name="SearchView.group">
<div t-att-class="'searchview_group ' + (attrs.expand == '0' ? 'folded' : 'expanded')"
<t t-name="SearchView.util.expand">
<div t-att-class="'searchview_group ' + (expand == '0' ? 'folded' : 'expanded')"
t-att-id="element_id">
<a t-if="attrs.string" class="searchview_group_string" href="#">
<t t-esc="attrs.string"/>
<a t-if="label" class="searchview_group_string" href="#">
<t t-esc="label"/>
</a>
<div class="searchview_group_content">
<t t-call="SearchView.render_lines"/>
<t t-raw="content"/>
</div>
</div>
</t>
<t t-name="SearchView.group">
<t t-call="SearchView.util.expand">
<t t-set="expand" t-value="attrs.expand"/>
<t t-set="label" t-value="attrs.string"/>
<t t-set="content">
<t t-call="SearchView.render_lines"/>
</t>
</t>
</t>
<t t-name="SearchView.extended_search">
<t t-call="SearchView.util.expand">
<t t-set="expand" t-value="false"/>
<t t-set="label" t-value="'Extended Filters'"/>
<t t-set="content">
<div class="searchview_extended_groups_list"></div>
<button class="searchview_extended_add_group">Add group of conditions</button>
</t>
</t>
</t>
<t t-name="SearchView.extended_search.group">
<div t-att-id="element_id">
<select class="searchview_extended_group_choice">
<option value="all">All</option>
<option value="any">Any</option>
<option value="none">None</option>
</select>
<div class="searchview_extended_propositions_list">
</div>
<button class="searchview_extended_add_proposition">Add condition</button>
<button class="searchview_extended_delete_group">Delete this group</button>
</div>
</t>
<t t-name="SearchView.extended_search.proposition">
<div t-att-id="element_id">
<select class="searchview_extended_prop_field">
<t t-foreach="attrs.fields" t-as="field">
<option t-att="{'selected': field === attrs.selected ? 'selected' : null}"
t-att-value="field.name">
<t t-esc="field.obj.string"/>
</option>
</t>
</select>
<select class="searchview_extended_prop_op">
</select>
<span class="searchview_extended_prop_value">
</span>
<button class="searchview_extended_delete_prop">Delete this condition</button>
</div>
</t>
<t t-name="SearchView.extended_search.proposition.char">
<input t-att-id="element_id"></input>
</t>
</templates>
+273 -4
View File
@@ -393,6 +393,90 @@ openerp.base.DataRecord = openerp.base.Controller.extend({
}
});
/**
* Base class for widgets. Handle rendering (based on a QWeb template), identifier
* generation, parenting and destruction of the widget.
*/
openerp.base.BaseWidget = openerp.base.Controller.extend({
/**
* The name of the QWeb template that will be used for rendering. Must be redifined
* in subclasses or the render() method can not be used.
*
* @type string
*/
template: null,
/**
* The prefix used to generate an id automatically. Should be redifined in subclasses.
* If it is not defined, a default identifier will be used.
*
* @type string
*/
identifier_prefix: 'generic-identifier',
/**
* Contructor. Also initialize the identifier.
*
* @params {openerp.base.search.BaseWidget} parent The parent widget.
*/
init: function (parent) {
this.children = [];
this.parent = parent;
if(parent != null) {
parent.children.push(this);
}
this.make_id(this.identifier_prefix);
},
/**
* Sets and returns a globally unique identifier for the widget.
*
* If a prefix is appended, the identifier will be appended to it.
*
* @params sections prefix sections, empty/falsy sections will be removed
*/
make_id: function () {
this.element_id = _.uniqueId(_.toArray(arguments).join('_'));
return this.element_id;
},
/**
* "Starts" the widgets. Called at the end of the rendering, this allows
* to get a jQuery object referring to the DOM ($element attribute).
*/
start: function () {
this._super();
var tmp = document.getElementById(this.element_id)
this.$element = tmp != null ? $(tmp) : null;
},
/**
* "Stops" the widgets. Called when the view destroys itself, this
* lets the widgets clean up after themselves.
*/
stop: function () {
var tmp_children = this.children;
this.children = [];
_.each(tmp_children, function(x) {
x.stop();
});
if(this.$element != null) {
this.$element.remove();
}
if(this.parent != null) {
var _this = this;
this.parent.children = _.reject(this.parent.children, function(x) { return x === _this;});
this.parent = null;
}
this._super();
},
/**
* Render the widget. This.template must be defined.
* The content of the current object is passed as context to the template.
*
* @param {object} additional Additional context arguments to pass to the template.
*/
render: function (additional) {
return QWeb.render(this.template, _.extend({}, this,
additional != null ? additional : {}));
}
});
openerp.base.SearchView = openerp.base.Controller.extend({
init: function(session, element_id, dataset, view_id, defaults) {
this._super(session, element_id);
@@ -514,6 +598,11 @@ openerp.base.SearchView = openerp.base.Controller.extend({
data.fields_view['arch'].children,
data.fields_view.fields);
// for extended search view
var ext = new openerp.base.search.ExtendedSearch(null, data.fields_view.fields);
lines.push([ext]);
this.inputs.push(ext);
var render = QWeb.render("SearchView", {
'view': data.fields_view['arch'],
'lines': lines,
@@ -714,6 +803,13 @@ openerp.base.search.FilterGroup = openerp.base.search.Widget.extend({
});
}
});
openerp.base.search.add_expand_listener = function($root) {
$root.find('a.searchview_group_string').click(function (e) {
$root.toggleClass('folded expanded');
e.stopPropagation();
e.preventDefault();
});
};
openerp.base.search.Group = openerp.base.search.Widget.extend({
template: 'SearchView.group',
// TODO: contain stuff
@@ -731,14 +827,185 @@ openerp.base.search.Group = openerp.base.search.Widget.extend({
.chain()
.flatten()
.each(function (widget) { widget.start(); });
var $root = this.$element;
$root.find('a.searchview_group_string').click(function (e) {
$root.toggleClass('folded expanded');
openerp.base.search.add_expand_listener(this.$element);
}
});
openerp.base.search.ExtendedSearch = openerp.base.BaseWidget.extend({
template: 'SearchView.extended_search',
identifier_prefix: 'extended-search',
init: function (parent, fields) {
this._super(parent);
this.fields = fields;
},
add_group: function(group) {
var group = new openerp.base.search.ExtendedSearchGroup(this, this.fields);
var render = group.render({});
this.$element.find('.searchview_extended_groups_list').append(render);
group.start();
},
start: function () {
this._super();
var _this = this;
openerp.base.search.add_expand_listener(this.$element);
this.add_group();
this.$element.find('.searchview_extended_add_group').click(function (e) {
_this.add_group();
e.stopPropagation();
e.preventDefault();
});
}
},
get_context: function() {
return null;
},
get_domain: function() {
if(this.$element.hasClass("folded")) {
return null;
}
var domain = _.reduce(this.children,
function(mem, x) { return mem.concat(x.get_domain());}, []);
return domain;
}
});
openerp.base.search.ExtendedSearchGroup = openerp.base.BaseWidget.extend({
template: 'SearchView.extended_search.group',
identifier_prefix: 'extended-search-group',
init: function (parent, fields) {
this._super(parent);
this.fields = fields;
},
add_prop: function() {
var prop = new openerp.base.search.ExtendedSearchProposition(this, this.fields);
var render = prop.render({});
this.$element.find('.searchview_extended_propositions_list').append(render);
prop.start();
},
start: function () {
this._super();
var _this = this;
this.add_prop();
this.$element.find('.searchview_extended_add_proposition').click(function (e) {
_this.add_prop();
e.stopPropagation();
e.preventDefault();
});
var delete_btn = this.$element.find('.searchview_extended_delete_group');
delete_btn.click(function (e) {
_this.stop();
e.stopPropagation();
e.preventDefault();
});
},
get_domain: function() {
var props = _(this.children).chain().map(function(x) {
return x.get_proposition();
}).compact().value();
var choice = this.$element.find(".searchview_extended_group_choice").val();
var op = choice == "all" ? "&" : "|";
var domain = [].concat(choice == "none" ? ['!'] : [],
_.map(_.range(_.max([0,props.length - 1])), function(x) { return op; }),
props);
return domain;
}
});
openerp.base.search.extended_filters_types = {
char: {
operators: [
{value: "ilike", text: "contains"},
{value: "not like", text: "doesn't contain"},
{value: "=", text: "is equal to"},
{value: "!=", text: "is not equal to"},
{value: ">", text: "greater than"},
{value: "<", text: "less than"},
{value: ">=", text: "greater or equal than"},
{value: "<=", text: "less or equal than"},
],
build_component: function(parent) {
return new openerp.base.search.ExtendedSearchProposition.Char(parent);
}
}
};
openerp.base.search.ExtendedSearchProposition = openerp.base.BaseWidget.extend({
template: 'SearchView.extended_search.proposition',
identifier_prefix: 'extended-search-proposition',
init: function (parent, fields) {
this._super(parent);
this.fields = _(fields).chain()
.map(function(val,key) {return {name:key, obj:val};})
.sortBy(function(x) {return x.obj.string;}).value();
this.attrs = {_: _, fields: this.fields, selected: null};
this.value_component = null;
},
start: function () {
this._super();
this.set_selected(this.fields.length > 0 ? this.fields[0] : null);
var _this = this;
this.$element.find(".searchview_extended_prop_field").change(function(e) {
_this.changed();
e.stopPropagation();
e.preventDefault();
});
var delete_btn = this.$element.find('.searchview_extended_delete_prop');
delete_btn.click(function (e) {
_this.stop();
e.stopPropagation();
e.preventDefault();
});
},
changed: function() {
var nval = this.$element.find(".searchview_extended_prop_field").val();
if(this.attrs.selected == null || nval != this.attrs.selected.name) {
this.set_selected(_.detect(this.fields, function(x) {return x.name == nval;}));
}
},
set_selected: function(selected) {
var _this = this;
if(this.attrs.selected != null) {
this.value_component.stop();
this.value_component = null;
this.$element.find('.searchview_extended_prop_op').html('');
}
this.attrs.selected = selected;
if(selected == null) {
return;
}
var type = selected.obj.type;
var extended_filters_types = openerp.base.search.extended_filters_types;
type = type in extended_filters_types ? type : "char";
_.each(extended_filters_types[type].operators, function(operator) {
option = jQuery('<option/>');
option.attr('value', operator.value);
option.text(operator.text);
option.appendTo(_this.$element.find('.searchview_extended_prop_op'));
});
this.value_component = extended_filters_types[type].build_component(this);
var render = this.value_component.render({});
this.$element.find('.searchview_extended_prop_value').html(render);
this.value_component.start();
},
get_proposition: function() {
if ( this.attrs.selected == null)
return null;
var field = this.attrs.selected.name;
var op = this.$element.find('.searchview_extended_prop_op').val();
var value = this.value_component.get_value();
return [field, op, value];
}
});
openerp.base.search.ExtendedSearchProposition.Char = openerp.base.BaseWidget.extend({
template: 'SearchView.extended_search.proposition.char',
identifier_prefix: 'extended-search-proposition-char',
get_value: function() {
var val = this.$element.val();
return val;
}
});
openerp.base.search.Input = openerp.base.search.Widget.extend({
init: function (view) {
this._super(view);
@@ -1073,6 +1340,8 @@ openerp.base.ListView = openerp.base.Controller.extend({
openerp.base.TreeView = openerp.base.Controller.extend({
});
openerp.base.Widget = openerp.base.Controller.extend({
// TODO Change this to init: function(view, node) { and use view.session and a new element_id for the super
// it means that widgets are special controllers
+3 -1
View File
@@ -182,7 +182,9 @@ var QWeb = {
g_att[o[0]] = new String(o[1]);
} else if (o.constructor == Object) {
for (var i in o) {
g_att[i] = new String(o[i]);
if(o[i]!=null) {
g_att[i] = new String(o[i]);
}
}
}
}