openerp-dev-web team mailing list archive
-
openerp-dev-web team
-
Mailing list archive
-
Message #00086
[Merge] lp:~openerp-dev/openobject-client-web/improved-custom-filters into lp:openobject-client-web
sma (Open ERP) has proposed merging lp:~openerp-dev/openobject-client-web/improved-custom-filters into lp:openobject-client-web.
Requested reviews:
OpenERP SA's Web Client R&D (openerp-dev-web)
Custom Filters for search view are change now according to given link (Task 1).
http://piratepad.net/openerp-web-bugs
* Improve custom fiters, only one line: Columns, Custom Filter, Save filter, <select filter>, \h fill Clear, Search (Fp confirm).
* If i click on Custom filter it should display the box above like on http://trac.edgewall.org/query with 'and' and 'or'.
--
https://code.launchpad.net/~openerp-dev/openobject-client-web/improved-custom-filters/+merge/32975
Your team OpenERP SA's Web Client R&D is requested to review the proposed merge of lp:~openerp-dev/openobject-client-web/improved-custom-filters into lp:openobject-client-web.
=== modified file 'addons/openerp/controllers/search.py'
--- addons/openerp/controllers/search.py 2010-08-10 12:08:29 +0000
+++ addons/openerp/controllers/search.py 2010-08-18 10:51:43 +0000
@@ -184,42 +184,46 @@
frm = {}
error = ''
- values = {}
-
- for key, val in record.items():
- for field in val:
- fld = {}
- datas = {}
- res = proxy.fields_get(field)
-
- fld['value'] = val[field]
- fld['type'] = res[field].get('type')
-
- data[field] = fld
- try:
- frm = TinyForm(**data).to_python()
- except Exception, e:
- error = ustr(e)
- error_field = ustr(e.field)
- return dict(error=error, error_field=error_field)
-
- datas['rec'] = field
-
- if fld['type'] == 'many2one':
- datas['rec_val'] = fld['value']
- frm[field] = 'many2one'
- elif isinstance(frm[field], bool):
- if frm[field]:
- datas['rec_val'] = 1
+ All_values = {}
+
+ for k, v in record.items():
+ values = {}
+ for key, val in v.items():
+ for field in val:
+ fld = {}
+ datas = {}
+ res = proxy.fields_get(field)
+
+ fld['value'] = val[field]
+ fld['type'] = res[field].get('type')
+
+ data[field] = fld
+ try:
+ frm = TinyForm(**data).to_python()
+ except Exception, e:
+ error = ustr(e)
+ error_field = ustr(e.field)
+ return dict(error=error, error_field=error_field)
+
+ datas['rec'] = field
+
+ if fld['type'] == 'many2one':
+ datas['rec_val'] = fld['value']
+ frm[field] = 'many2one'
+ elif isinstance(frm[field], bool):
+ if frm[field]:
+ datas['rec_val'] = 1
+ else:
+ datas['rec_val'] = 0
else:
- datas['rec_val'] = 0
- else:
- datas['rec_val'] = frm[field]
-
- datas['type'] = fld['type']
- values[key] = datas
-
- return dict(frm=values, error=error)
+ datas['rec_val'] = frm[field]
+
+ datas['type'] = fld['type']
+ values[key] = datas
+
+ All_values[k] = values
+
+ return dict(frm=All_values, error=error)
@expose('json')
def eval_domain_filter(self, **kw):
@@ -275,28 +279,55 @@
search_data[field] = value
else:
search_data[field] = value.split('m2o_')[1]
+
+ def get_domain(x):
+ tempdomain = ""
+
+ if len(x)== 1:
+ if isinstance(x[0], (int, list)):
+ tempdomain += ",'" + ustr(x[0]) + "',"
+ else:
+ tempdomain += ",'" + x[0] + "',"
+
+ elif len(x) == 4:
+ if isinstance(x[3], (int, list)):
+ tempdomain += '[\'' + x[0] + '\', (\'' + x[1] + '\', \'' + x[2] + '\', ' + ustr(x[3]) + '\')]'
+ else:
+ tempdomain += '[\'' + x[0] + '\', (\'' + x[1] + '\', \'' + x[2] + '\', \'' + x[3] + '\')]'
+
+ elif len(x) == 3:
+ if isinstance(x[2], (int, list)):
+ tempdomain += '[(\'' + x[0] + '\', \'' + x[1] + '\', ' + ustr(x[2]) + ')]'
+ else:
+ tempdomain += '[(\'' + x[0] + '\', \'' + x[1] + '\', \'' + x[2] + '\')]'
+
+ return tempdomain
inner_domain = []
if custom_domains:
- tmp_domain = ''
-
+ tmp_domain = ''
custom_domains = eval(custom_domains)
- for inner in custom_domains:
- if len(inner) == 4:
- if isinstance(inner[3], (int, list)):
- tmp_domain += '[\'' + inner[0] + '\', (\'' + inner[1] + '\', \'' + inner[2] + '\', ' + ustr(inner[3]) + ')]'
- else:
- tmp_domain += '[\'' + inner[0] + '\', (\'' + inner[1] + '\', \'' + inner[2] + '\', \'' + inner[3] + '\')]'
- elif len(inner) == 3:
- if isinstance(inner[2], (int, list)):
- tmp_domain += '[(\'' + inner[0] + '\', \'' + inner[1] + '\', ' + ustr(inner[2]) + ')]'
- else:
- tmp_domain += '[(\'' + inner[0] + '\', \'' + inner[1] + '\', \'' + inner[2] + '\')]'
-
+ for i in custom_domains[:-1]:
+ if len(i):
+ i.insert(0, '|')
+
+ for i in custom_domains:
+ for inner in i:
+ if len(inner) == 1 and len([x for x in inner if isinstance(x, list)]) == 0:
+ tmp_domain += ",'" + inner[0] +"',"
+ elif len([x for x in inner if isinstance(x, list)]):
+ for d in inner:
+ tmp_domain += get_domain(d)
+ else:
+ tmp_domain += get_domain(inner)
+
if tmp_domain :
- cust_domain = tmp_domain.replace('][', ', ')
+ cust_domain = tmp_domain
+ if cust_domain.find('|') != -1 or cust_domain.find('&') != -1:
+ tmp_domain = tmp_domain.lstrip(',')
+ cust_domain = (tmp_domain).replace("][", ",").replace("[", "").replace("]", "")
+
inner_domain.extend(eval(cust_domain))
-
if len(inner_domain)>1 and inner_domain[-2] in ['&','|']:
if len(inner_domain) == 2:
inner_domain = [inner_domain[1]]
=== modified file 'addons/openerp/static/css/style.css'
--- addons/openerp/static/css/style.css 2010-08-18 08:49:56 +0000
+++ addons/openerp/static/css/style.css 2010-08-18 10:51:43 +0000
@@ -82,23 +82,22 @@
width: 0%;
}
-table#filter_table {
+table#filter_option_table {
margin: 0;
}
-table#filter_table td.filter_column {
- text-align: left;
+table#filter_option_table td.filter_column {
padding: 0;
}
-table#filter_table td.filter_column select {
+table#filter_option_table td.filter_column select {
width: 80px;
}
-table#filter_table td.filter_column input.qstring,
-table#filter_table td.filter_column select.filter_fields,
-table#filter_table td.filter_column select.expr,
-table#filter_table td.and_or select.select_andor {
+table#filter_option_table td.filter_column input.qstring,
+table#filter_option_table td.filter_column select.filter_fields,
+table#filter_option_table td.filter_column select.expr,
+table#filter_option_table td.and_or select.select_andor {
width: 100px;
-moz-border-radius: 3px 3px 3px 3px;
background: none repeat scroll 0 0 #FFFFFF;
@@ -106,19 +105,43 @@
vertical-align: middle;
}
-#filter_table .image_col {
+#filter_option_table .image_col {
padding-left: 0;
padding-right: 2px;
text-align: left;
}
-table#filter_table td.and_or {
+table#filter_option_table label.and_or {
padding-left: 5px;
text-align: left;
}
-table#filter_table td.and_or select {
- width: 55px;
+#filter_option_table td .filter-lsep {
+ float:left;
+ line-height:50%;
+ width:47%;
+}
+
+#filter_option_table td .filter-msep {
+ float:left;
+ text-align:center;
+ width:5%;
+}
+
+#filter_option_table td .filter-rsep {
+ float:right;
+ line-height:50%;
+ width:47%;
+}
+
+#filter_option_table td .filter-hr{
+ background-color:#CCCCCC;
+ border:medium none;
+ color:#CCCCCC;
+ height:1px;
+ margin:5px 0 !important;
+ overflow:hidden;
+ padding:0;
}
/* ============== SEARCH FORM start ==============*/
=== modified file 'addons/openerp/static/javascript/search.js'
--- addons/openerp/static/javascript/search.js 2010-08-10 12:08:29 +0000
+++ addons/openerp/static/javascript/search.js 2010-08-18 10:51:43 +0000
@@ -10,7 +10,7 @@
// It's based on Mozilla Public License Version (MPL) 1.1 with following
// restrictions:
//
-// - All names, links and logos of Tiny, OpenERP and Axelor must be
+// - All names, links and logos of Tiny, Open ERP and Axelor must be
// kept as in original distribution without any changes in all software
// screens, especially in start-up page and the software header, even if
// the application source code has been changed or updated or code has been
@@ -27,43 +27,243 @@
//
////////////////////////////////////////////////////////////////////////////////
-function add_filter_row() {
+function add_filter_row(elem) {
+
var filter_table = jQuery('#filter_table');
- var vals = ['AND', 'OR'];
+ var filter_opt_tbl = jQuery('#filter_option_table')
+ var $cls_tbody = jQuery(elem).closest("tbody")
- if(filter_table.is(':hidden')) {
- filter_table.show();
+ if (jQuery(filter_opt_tbl).find('tbody:visible').length == 1 && jQuery($cls_tbody).siblings().length == 1) {
+ if(filter_table.is(':hidden')) {
+ if (jQuery('label#filterlabel').text() == ''){
+ jQuery('label#filterlabel').text(jQuery('select.filter_fields_and option:selected').text())
+ jQuery('label#filterlabel').attr('value', jQuery(elem).val())
+ }
+ filter_table.show();
+ }
} else {
- var old_tr = filter_table.find('tr:last');
- old_tr.find('input.qstring').css('background', '#FFF');
+ var position_tr = jQuery($cls_tbody).find('tr:last').prev();
+
+ if (jQuery($cls_tbody).prev().attr('id') == 'filter_table') {
+ var position_tr = filter_table.find('tr:last');
+ }
+
+ var old_tr = jQuery(filter_opt_tbl).find('tbody:first').find('tr.filter_row_class:first')
+ old_tr.find('input.qstring').css('background', '#FFF');
var new_tr = old_tr.clone();
-
- var qstring = new_tr.find('input.qstring').css('background', '#fff').val('');
-
- var and_or = jQuery('<td>', {'class': 'and_or'}).appendTo(old_tr);
-
- var select_andor = jQuery('<select>', {
- 'class': 'select_andor'
- }).appendTo(and_or);
- jQuery.each(vals, function (index, label) {
- select_andor.append(jQuery('<option>').val(label).text(label));
+ new_tr.find('label#filterlabel').text(jQuery('select.filter_fields_and option:selected').text());
+ new_tr.find('label#filterlabel').attr('value', jQuery(elem).val());
+ new_tr.find('input.qstring').css('background', '#fff').val('');
+ if (new_tr.is(':hidden')) {
+ new_tr.show()
+ }
+
+ var index_row;
+ var $curr_body = position_tr.closest('tbody')
+ $curr_body.find('label.filterlabel').each(function(i, v) {
+ var theValue = jQuery(v).text();
+ if (theValue == jQuery('select.filter_fields_and option:selected').text()){
+ index_row = i
+ new_tr.find('select.expr').hide()
+ new_tr.find('label#filterlabel').hide()
+ new_tr.find('label.and_or').remove()
+
+ var select_andor = jQuery('<label>', {'class': 'and_or'}).text('OR');
+ select_andor.insertBefore(new_tr.find('input.qstring'));
+ }
});
- old_tr.after(new_tr);
+ if(index_row >= 0) {
+ position_tr = $curr_body.find('tr.filter_row_class')[index_row];
+ }
+
+ jQuery(position_tr).after(new_tr);
+ }
+
+ if (!jQuery('select.filter_fields_or').closest("tbody").siblings().length) {
+ jQuery('select#filter_fields_or').attr('disabled', true);
+ }else{
+ jQuery('select#filter_fields_or').attr('disabled', false);
+ }
+}
+
+function addOrBlock(elem){
+
+ var filter_option_table = jQuery('#filter_option_table');
+ var old_tr = jQuery('#filter_table').next('tbody.actions').find('tr.actions');
+ var tbody = filter_option_table.find('tbody:last');
+
+ var action_tr = old_tr.clone();
+ action_tr.find('select.filter_fields_or').parent().show();
+ action_tr.find('select.filter_fields_or').attr('disabled', false);
+ if (action_tr.is(':hidden')) {
+ action_tr.show();
+ }
+
+ var position_tr = filter_option_table.find('tr:last');
+ position_tr.find('select.filter_fields_or').parent().hide();
+
+ var newtbody = jQuery('<tbody>');
+ var tr = jQuery('<tr id="or">');
+ var td = jQuery('<td>', {'colspan': '4'});
+ td.append(jQuery('<div class="filter-lsep">').append(jQuery('<hr class="filter-hr"/>')));
+ td.append(jQuery('<div class="filter-msep">Or</div>'));
+ td.append(jQuery('<div class="filter-rsep">').append(jQuery('<hr class="filter-hr"/>')));
+ jQuery(tr).append(td)
+ jQuery(newtbody).append(tr)
+
+ var oldTr = filter_option_table.find('tr:first');
+ var new_tr = oldTr.clone();
+ new_tr.find('label#filterlabel').text(jQuery('select.filter_fields_or option:selected').text());
+ new_tr.find('label#filterlabel').attr('value', jQuery(elem).val());
+ new_tr.find('input.qstring').css('background', '#FFF').val('');
+
+ jQuery(tr).after(new_tr);
+ jQuery(new_tr).after(action_tr);
+ jQuery(tbody).after(newtbody);
+}
+
+function switch_searchView(d) {
+
+ var domain = eval(d)
+ var operators = [];
+ var tbodys = [];
+ var trs = 0;
+ var tbody = jQuery("<tbody/>");
+ var prev_row_field = '';
+ var old_tr = jQuery('#filter_option_table tbody:first').find('tr.filter_row_class:first');
+ var action_tbody = jQuery('#filter_option_table').find('tbody.actions');
+ var selection_options = jQuery('tbody.actions tr.actions').find('select.filter_fields_and:first');
+
+ jQuery('#filter_table').hide()
+
+ for (i=0; i<domain.length; i++) {
+
+ var item = domain[i];
+ if (item.length==1) {
+ operators.push(item);
+ }
+ else {
+ var new_tr = old_tr.clone();
+ var txt = jQuery(selection_options).find('option[value='+ item[0] + ']').text()
+ new_tr.find('label#filterlabel').text(txt);
+ new_tr.find('label#filterlabel').attr('value', item[0]);
+ new_tr.find('select.expr').val(item[1]);
+ old_tr.find('input.qstring').css('background', '#FFF').val('');
+ new_tr.find('input.qstring').attr('value', item[2]);
+
+ if (trs==0 || operators[operators.length-1]=='&') {
+ tbody.append(new_tr)
+ if (trs>0)
+ operators.splice(operators.length-1, 1);
+ }
+ else if(prev_row_field!=item[0] && operators[operators.length-1]=='|') {
+ tbodys.push(tbody);
+ tbody = jQuery("<tbody/>");
+ tbody.append(new_tr);
+ trs = 1;
+ operators.splice(operators.length-1, 1);
+ }
+ else if(prev_row_field==item[0] && operators[operators.length-1]=='|') {
+ new_tr.find('label#filterlabel').hide();
+ new_tr.find('select.expr').hide();
+ var select_andor = jQuery('<label>', {'class': 'and_or'}).text('OR');
+ select_andor.insertBefore(new_tr.find('input.qstring'));
+ tbody.append(new_tr);
+ operators.splice(operators.length-1, 1);
+ }
+ trs ++;
+ prev_row_field = item[0];
+ }
+ }
+
+ if (domain.length){
+ tbodys.push(tbody)
+ jQuery('#filters').toggleClass('group-expand group-collapse');
+ jQuery('#filter_option_table').toggle();
+ if (action_tbody.is(':visible')){
+ action_tbody.hide()
+ }
+ }
+
+ for (i=0; i<tbodys.length; i++) {
+
+ if (tbodys[i + 1]) {
+ var trOr = jQuery('<tr id="or">');
+ var td = jQuery('<td>', {'colspan': '4'});
+ td.append(jQuery('<div class="filter-lsep">').append(jQuery('<hr class="filter-hr"/>')));
+ td.append(jQuery('<div class="filter-msep">Or</div>'));
+ td.append(jQuery('<div class="filter-rsep">').append(jQuery('<hr class="filter-hr"/>')));
+ jQuery(trOr).append(td)
+ tbodys[i + 1].prepend(trOr)
+ }
+ if (tbodys[i - 1]) {
+ tbodys[i - 1].find('tr.actions td.filter_column').hide()
+ }
+
+ var actTr = action_tbody.find('tr.actions').clone(true);
+ actTr.find('select#filter_fields_or').attr('disabled', false);
+ jQuery(tbodys[i]).append(actTr)
+ $('#filter_option_table').append(tbodys[i])
}
}
function remove_filter_row(element) {
+
var node = jQuery(element).closest('tr');
+ var t = jQuery(node).closest('tbody')
+ var $paren = t.parent()
+ var prev_body = jQuery($paren.children('tbody')[t.index()-1])
+ var next_body = jQuery($paren.children('tbody')[t.index()+1])
+
+ if (t.find('tr.filter_row_class').length <= 1 && t.attr('id')!='filter_table') {
+
+ if (!(next_body.length >= 1) || !(prev_body.length >= 1)) {
+ jQuery(prev_body.find('td.filter_column')).show();
+ }
+
+ jQuery(node).closest('tbody').remove();
+
+ if (jQuery('#filter_option_table tbody:visible').length == 2 ) {
+ var body_next = jQuery('#filter_option_table').find('tbody:first')
+ jQuery(body_next).find('#or').remove()
+ }
+ }
+
if(node.is(':only-child')) {
+
+ if (jQuery('#filter_option_table tbody:visible').length >= 1 && node.closest("tbody").siblings().length > 1){
+ jQuery('#filter_table').next().hide()
+ jQuery('#filter_option_table').find('tr#or:first').hide()
+ }
+
node.find('input.qstring').css('background', '#FFF').val('');
- jQuery('#filter_table').hide();
+ jQuery('label#filterlabel').text('')
+ jQuery('label#filterlabel').attr('value', '')
+ jQuery('select#filter_fields_or').attr('disabled', true)
+ jQuery('#filter_table').hide();
+
} else {
+
if(node.is(':last-child')) {
node.prev().find('.and_or').remove();
}
- node.remove();
+
+ if(node.next().find('label.and_or').is(':visible')){
+ node.next().remove();
+ }
+ else{
+ if (jQuery('#filter_option_table tbody:visible').length == 0) {
+ jQuery('tbody.actions').show()
+ jQuery('tbody.actions').find('tr.actions').find('td.filter_column').show()
+ }
+
+ if (jQuery('#filter_option_table tbody:visible').length == 1){
+ jQuery('#filter_option_table').find('tr#or:first').hide()
+ }
+ node.remove();
+ }
}
}
@@ -74,86 +274,141 @@
function isOrderable(type) {
return jQuery.inArray(type, ['integer', 'float', 'date', 'datetime', 'boolean']) != -1;
}
-function display_Customfilters(all_domains, group_by_ctx) {
- var record = {};
-
- var children = jQuery('#filter_table tr.filter_row_class');
- children.each(function () {
- var $constraint_value = jQuery(this).find('input.qstring');
- var $fieldname = jQuery(this).find('select.filter_fields');
-
- var id = jQuery(this).parent().find('> .filter_row_class').index(this);
-
- if($constraint_value.val()) {
- var rec = {};
- rec[$fieldname.val()] = $constraint_value.val();
- record[id] = rec;
- }
+
+/**
+ * To return the keys of an object. use jQuery.keys(obj).
+*/
+jQuery.extend({
+ keys: function(obj){
+ var a = [];
+ $.each(obj, function(k){ a.push(k) });
+ return a;
+ }
+})
+
+function display_Customfilters(all_domains, group_by_ctx) {
+ var Allrecords = {};
+ var parent_tbody = jQuery('#filter_option_table > tbody')
+
+ parent_tbody.each(function () {
+ var children = jQuery(this).find('> .filter_row_class');
+ var record = {};
+ var pid = jQuery(this).index()
+
+ children.each(function () {
+ var $constraint_value = jQuery(this).find('input.qstring');
+ var $fieldname = jQuery(this).find('label.filterlabel');
+ var id = jQuery(this).parent().find('> .filter_row_class').index(this);
+
+ if($constraint_value.val()) {
+ var rec = {};
+ rec[$fieldname.attr('value')] = $constraint_value.val();
+ record[id] = rec;
+ }
+ });
+
+ if (jQuery.keys(record).length != 0){
+ Allrecords[pid] = record;
+ }
});
-
+
openobject.http.postJSON('/openerp/search/get', {
- record: serializeJSON(record),
+ record: serializeJSON(Allrecords),
_terp_model: jQuery('#_terp_model').val()
}).addCallback(function(obj) {
var custom_domain = [];
if(obj.error) {
+ var children = jQuery('#filter_option_table tbody').find('> .filter_row_class')
children.each(function () {
- if(jQuery(this).find('select.filter_fields').val() == obj['error_field']) {
+ if(jQuery(this).find('label.filterlabel').attr('value') == obj['error_field']) {
jQuery(this).find('input.qstring').css('background', '#f66').val(obj.error);
}
});
}
var form_result = obj.frm;
+ var tbody_keys = jQuery.keys(form_result)
+
if(form_result) {
// By property, we get incorrect ordering
- for(var index = 0; ; ++index) {
- if(!(index in form_result)) { break; }
-
- var return_record = form_result[index];
- var temp_domain = [];
-
- var $row = jQuery('tr.filter_row_class').eq(index);
-
- var type = return_record.type;
-
- var grouping = $row.find('select.select_andor').val();
- if(grouping) {
- temp_domain.push(grouping == 'AND' ? '&' : '|');
- }
-
- var field = return_record['rec'];
- var comparison = $row.find('select.expr').val();
- var value = return_record['rec_val'];
-
- switch (comparison) {
- case 'ilike':
- case 'not ilike':
- if(isOrderable(type)) {
- comparison = (comparison == 'ilike' ? '=' : '!=');
- }
- break;
- case '<':
- case '>':
- if(!isOrderable(type)) {
- comparison = '=';
- }
- break;
- case 'in':
- case 'not in':
- if(typeof value == 'string') {
- value = value.split(',');
- } else {
- /* very weird array-type construct
- looks a bit like [[6, 0, [list of ids here]]]
- */
- value = value[value.length - 1][value[value.length - 1].length - 1]
- }
- break;
- }
-
- temp_domain.push(field, comparison, value);
- custom_domain.push(temp_domain);
- }
+ for(var ind=0; ind<tbody_keys.length ;ind++){
+ var All_domain = [];
+ var group = []
+ var tbody_frm_ind = form_result[tbody_keys[ind]]; //tbody dictionary
+ var trs_keys = jQuery.unique(jQuery.keys(tbody_frm_ind)); //sort trs
+
+ for(index = 0; index<trs_keys.length ; index++) {
+ var return_record = tbody_frm_ind[trs_keys[index]];
+ var $curr_body = jQuery('#filter_option_table > tbody').eq(tbody_keys[ind]);
+ var $row = jQuery($curr_body.find('> .filter_row_class').eq(trs_keys[index]));
+ var $next_row = []
+
+ if (jQuery($row.next('tr.filter_row_class')).find('input.qstring').val() != ''){
+ $next_row = jQuery($row.next());
+ }
+
+ var type = return_record.type;
+ var temp_domain = [];
+ var grouping = $next_row.length != 0 ? $next_row.find('label.and_or').text(): null;
+
+ if (group.length==0) {
+ var new_grp = $curr_body.find('tr.filter_row_class:gt('+trs_keys[index]+')')
+ new_grp = new_grp.find('td.filter_column:not(:has(label))').find('input.qstring[value]')
+ if (new_grp.length){
+ group.push('&')
+ }
+ }
+ if(grouping) {
+ temp_domain.push(grouping == 'AND' ? '&' : '|');
+ }
+
+ var field = return_record['rec'];
+ var comparison = $row.find('select.expr').val();
+ var value = return_record['rec_val'];
+
+ switch (comparison) {
+ case 'ilike':
+ case 'not ilike':
+ if(isOrderable(type)) {
+ comparison = (comparison == 'ilike' ? '=' : '!=');
+ }
+ break;
+ case '<':
+ case '>':
+ if(!isOrderable(type)) {
+ comparison = '=';
+ }
+ break;
+ case 'in':
+ case 'not in':
+ if(typeof value == 'string') {
+ value = value.split(',');
+ } else {
+ /* very weird array-type construct
+ looks a bit like [[6, 0, [list of ids here]]]
+ */
+ value = value[value.length - 1][value[value.length - 1].length - 1]
+ }
+ break;
+ }
+
+ if ($row.find('label.and_or').length>0 || grouping){
+ temp_domain.push(field, comparison, value);
+ group.push(temp_domain);
+ }
+ else{
+ group.push(field, comparison, value)
+ }
+
+ if (!grouping) {
+ All_domain.push(group);
+ group = [];
+ }
+ }
+
+ if (All_domain.length) {
+ custom_domain.push(All_domain);
+ }
+ };
}
final_search_domain(serializeJSON(custom_domain), all_domains, group_by_ctx);
});
@@ -257,11 +512,9 @@
function search_filter(src, id) {
var all_domains = parse_filters(src, id);
- var filters = jQuery('#filter_table');
- if(filters.is(':visible') || jQuery('#_terp_filter_domain').val() != '[]') {
- if (filters.is(':hidden')){
- filters.show();
- }
+ var filters = jQuery('#filter_table');
+
+ if(filters.is(':visible') || jQuery('#_terp_filter_domain').val() != '[]') {
display_Customfilters(all_domains, group_by);
} else {
var custom_domain = jQuery('#_terp_filter_domain').val() || '[]';
=== modified file 'addons/openerp/widgets/search.py'
--- addons/openerp/widgets/search.py 2010-08-10 12:08:29 +0000
+++ addons/openerp/widgets/search.py 2010-08-18 10:51:43 +0000
@@ -217,7 +217,7 @@
template = "templates/search.mako"
javascript = [JSLink("openerp", "javascript/search.js", location=locations.bodytop)]
- params = ['fields_type', 'filters_list', 'operators_map', 'fields_list', 'filter_domain']
+ params = ['fields_type', 'filters_list', 'operators_map', 'fields_list', 'filter_domain', 'flt_domain']
member_widgets = ['frame']
_notebook = Notebook(name="search_notebook")
@@ -251,20 +251,13 @@
if isinstance (self.search_view, basestring):
self.search_view = eval(self.search_view)
-
+
if not self.search_view:
- self.search_view = cache.fields_view_get(self.model, view_id, 'search', ctx, True)
-
+ self.search_view = cache.fields_view_get(self.model, view_id, 'search', ctx, True)
+
self.fields_list = []
- fields = self.search_view['fields']
-
- for k,v in fields.items():
- if v['type'] in ('many2one', 'char', 'float', 'integer', 'date',
- 'datetime', 'selection', 'many2many', 'boolean',
- 'one2many') and v.get('selectable', False):
- self.fields_list.append((k, v['string'], v['type']))
- if self.fields_list:
- self.fields_list.sort(lambda x, y: cmp(x[1], y[1]))
+ fields = self.search_view.get('fields')
+
try:
dom = xml.dom.minidom.parseString(self.search_view['arch'])
except:
@@ -300,7 +293,15 @@
'translate': new_field['translate'],
'selectable': new_field['selectable']}
self.fields.update(field_dict)
-
+
+ for k,v in self.fields.items():
+ if v['type'] in ('many2one', 'char', 'float', 'integer', 'date',
+ 'datetime', 'selection', 'many2many', 'boolean',
+ 'one2many') and v.get('selectable', False):
+ self.fields_list.append((k, v['string'], v['type']))
+ if self.fields_list:
+ self.fields_list.sort(lambda x, y: cmp(x[1], y[1]))
+
self.frame = self.parse(model, dom, self.fields, values)
if self.frame:
self.frame = self.frame[0]
@@ -320,11 +321,9 @@
('=', _('is equal to')), ('<>', _('is not equal to')),
('>', _('greater than')), ('<', _('less than')),
('in', _('in')), ('not in', _('not in'))]
-
- if self.filter_domain == []:
- self.filter_domain += [(self.fields_list[0][0], self.operators_map[0][0], '')]
- else:
- self.custom_filter_domain = self.filter_domain
+
+ self.flt_domain = str(self.filter_domain).replace("(", "[").replace(')', ']')
+ self.custom_filter_domain = self.filter_domain
def parse(self, model=None, root=None, fields=None, values={}):
=== modified file 'addons/openerp/widgets/templates/search.mako'
--- addons/openerp/widgets/templates/search.mako 2010-08-04 08:22:51 +0000
+++ addons/openerp/widgets/templates/search.mako 2010-08-18 10:51:43 +0000
@@ -2,41 +2,69 @@
% if frame:
${display_member(frame)}
% endif
- <table id="filter_table" style="display: none;">
- % for f,k in enumerate(filter_domain):
- % if len(k) >1:
- <tr class="filter_row_class">
- <td class="image_col">
- <button onclick="remove_filter_row(this); return false;">
- <img alt="Remove filter row" src="/openerp/static/images/button-b-icons-remove.gif"/>
- </button>
- </td>
- <td align="right" class="filter_column">
- <select class="filter_fields">
- % for field in fields_list:
- <option kind="${field[2]}" value="${field[0]}" ${py.selector(field[0]==k[0])}>${field[1]}</option>
- % endfor
- </select>
- <select class="expr">
- % for operator, description in operators_map:
- <option value="${operator}" ${py.selector(operator==k[1])}>${description}</option>
- % endfor
- </select>
- <input type="text" class='qstring' value="${k[2] or ''}" />
- </td>
- % if len(filter_domain[f -1]) == 1:
- <td class="and_or">
- <select class="select_andor">
- % if filter_domain[f-1] == '&':
- <option value="AND">AND</option>
- %else:
- <option value="OR">OR</option>
- % endif
- </select>
- </td>
- % endif
- </tr>
- % endif
- % endfor
- </table>
+
+ <table>
+ <tr>
+ <td style="padding:4px; white-space:nowrap;">
+ <div id="filters" class="group-expand"><h2><span>Filters</span></h2></div>
+ <table id="filter_option_table" style="display:none;">
+ <tbody id="filter_table" style="display:none;">
+ <tr class="filter_row_class">
+ <td class="image_col">
+ <button onclick="remove_filter_row(this); return false;">
+ <img alt="Remove filter row" src="/openerp/static/images/button-b-icons-remove.gif"/>
+ </button>
+ </td>
+ <td class="filterlabel">
+ <label id="filterlabel" value="" class="filterlabel"></label>
+ </td>
+ <td>
+ <select class="expr">
+ % for operator, description in operators_map:
+ <option value="${operator}" >${description}</option>
+ % endfor
+ </select>
+ </td>
+ <td align="right" class="filter_column">
+ <input type="text" class='qstring' value="" />
+ </td>
+ </tr>
+ </tbody>
+ <tbody class="actions">
+ <tr class="actions">
+ <td style="white-space:nowrap;">
+ <label for="add_filter_and">And</label>
+ <select class="filter_fields_and" onchange="add_filter_row(this); return jQuery('select.filter_fields_and').val('');">
+ <option></option>
+ % for field in fields_list:
+ <option kind="${field[2]}" value="${field[0]}">${field[1]}</option>
+ % endfor
+ </select>
+ </td>
+ <td class="filter_column" colspan="2" style="text-align:right; white-space:nowrap;">
+ <label for="add_filter_or">OR</label>
+ <select id="filter_fields_or" disabled="disabled" class="filter_fields_or" onchange="addOrBlock(this); return jQuery('select.filter_fields_or').val('');">
+ <option></option>
+ % for field in fields_list:
+ <option kind="${field[2]}" value="${field[0]}">${field[1]}</option>
+ % endfor
+ </select>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </table>
+ <script type="text/javascript">
+ jQuery('#filters').click(function() {
+ jQuery(this).toggleClass('group-expand group-collapse');
+ jQuery('#filter_option_table').toggle();
+ });
+
+ jQuery(document).ready(function () {
+
+ switch_searchView("${flt_domain | n}");
+ });
+ </script>
</div>
=== modified file 'addons/openerp/widgets/templates/viewform.mako'
--- addons/openerp/widgets/templates/viewform.mako 2010-07-15 12:54:38 +0000
+++ addons/openerp/widgets/templates/viewform.mako 2010-08-18 10:51:43 +0000
@@ -25,19 +25,9 @@
<td valign="top">${display_member(search)}</td>
</tr>
<tr>
- <td class="view_form_options" align="left">
- <div>
- <button onclick="add_filter_row(); return false;">
- <img src="/openerp/static/images/button-b-icons-add.gif" alt="Add custom filtering row">
- </button>
- </div>
- <div>
- <button title="${_('Filter records.')}" onclick="search_filter(); return false;"
- >${_("Filter")}</button>
- <button title="${_('Clear all .')}" id="clear_all_filters" class="${css_clear}"
- onclick="new ListView('_terp_list').clear(); return false;"
- >${_("Clear")}</button>
- <div class="custom-filter">
+ <td class="view_form_options" align="left">
+ <div>
+
<button title="${_('Save Filter.')}"
onclick="save_filter(); return false;"
>${_("Save Filter")}</button>
@@ -50,7 +40,14 @@
<option value="${f[0]}">${f[1]}</option>
% endfor
</select>
- </div>
+
+ <div align="right">
+ <button title="${_('Filter records.')}" onclick="search_filter(); return false;"
+ >${_("Search")}</button>
+ <button title="${_('Clear all .')}" id="clear_all_filters" class="${css_clear}"
+ onclick="new ListView('_terp_list').clear(); return false;"
+ >${_("Clear")}</button>
+ </div>
</div>
</td>
</tr>
Follow ups