openerp-dev-web team mailing list archive
-
openerp-dev-web team
-
Mailing list archive
-
Message #04288
lp:~openerp-dev/openobject-client-web/trunk-fix-custom-filters-xmo into lp:openobject-client-web
Xavier (Open ERP) has proposed merging lp:~openerp-dev/openobject-client-web/trunk-fix-custom-filters-xmo into lp:openobject-client-web.
Requested reviews:
Maxime Glorieux (mgl)
Aline (OpenERP) (apr-tinyerp)
For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-client-web/trunk-fix-custom-filters-xmo/+merge/53764
Re-applied niv's custom filters fixes, plus some fixes performed since
--
https://code.launchpad.net/~openerp-dev/openobject-client-web/trunk-fix-custom-filters-xmo/+merge/53764
Your team OpenERP R&D Team is subscribed to branch lp:~openerp-dev/openobject-client-web/trunk-fix-custom-filters-xmo.
=== modified file 'addons/openerp/controllers/search.py'
--- addons/openerp/controllers/search.py 2011-03-11 16:53:08 +0000
+++ addons/openerp/controllers/search.py 2011-03-17 09:36:36 +0000
@@ -18,6 +18,7 @@
# You can see the MPL licence at: http://www.mozilla.org/MPL/MPL-1.1.html
#
###############################################################################
+import simplejson
from openerp.utils import expr_eval, TinyDict, TinyForm, TinyFormError
from openobject.i18n.format import convert_date_format_in_domain
import actions
@@ -195,17 +196,17 @@
record = kw.get('record')
record = eval(record)
+
proxy = rpc.RPCProxy(model)
data = {}
res = proxy.fields_get(False, rpc.get_session().context)
all_values = {}
+
errors = []
-
for k, v in record.items():
values = {}
for key, val in v.items():
- frm_datas = {}
for field in val:
fld = {
'value': val[field],
@@ -214,16 +215,13 @@
if fld['type'] == 'many2many':
fld['type'] = 'char'
datas = {field: fld}
- frm_datas[field] = fld
+
try:
- frm = TinyForm(**frm_datas).to_python()
+ TinyForm(**data).to_python()
except TinyFormError, e:
- error_field = e.field
- error = ustr(e)
- errors.append({e.field: error})
+ errors.append({e.field: ustr(e)})
except Exception, e:
- error = ustr(e)
- errors.append({field: error})
+ errors.append({field: ustr(e)})
datas['rec'] = field
@@ -347,7 +345,13 @@
if not custom_domains:
custom_domains = []
else:
- custom_domains = ast.literal_eval(custom_domains)
+ try:
+ # from JS custom filters, data is sent as JSON
+ custom_domains = simplejson.loads(custom_domains)
+ except simplejson.decoder.JSONDecodeError:
+ # from switchView, data is sent as Python literals
+ # (with unicode strings and keys)
+ custom_domains = ast.literal_eval(custom_domains)
# conversion of the pseudo domain from the javascript to a valid domain
ncustom_domain = []
=== modified file 'addons/openerp/static/javascript/search.js'
--- addons/openerp/static/javascript/search.js 2011-03-02 09:50:09 +0000
+++ addons/openerp/static/javascript/search.js 2011-03-17 09:36:36 +0000
@@ -18,67 +18,63 @@
// You can see the MPL licence at: http://www.mozilla.org/MPL/MPL-1.1.html
//
////////////////////////////////////////////////////////////////////////////////
-var OR_LINE = jQuery('<tr>', {'id': 'or'}).append(
- jQuery('<td>', {'colspan': 5}).append(
- jQuery('<div>', {'class': 'filter-lsep'}),
- jQuery('<hr>', {'class': 'filter-hr'}),
- jQuery('<div>', {'class': 'filter-msep'}).html(_('Or')),
- jQuery('<div>', {'class': 'filter-rsep'}),
- jQuery('<hr>', {'class': 'filter-hr'})
- )
- );
+var OR_LINE = '<tr id="or"><td colspan="5">' +
+ '<div class="filter-lsep"></div><hr class="filter-hr">' +
+ '<div class="filter-msep">Or</div>' +
+ '<div class="filter-rsep"></div><hr class="filter-hr">' +
+ '</td></tr>';
function add_filter_row(elem) {
-
- var $element = jQuery(elem);
- var $filter_table = jQuery(idSelector('filter_table'));
- var $filter_opt_tbl = jQuery(idSelector('filter_option_table'));
+ var $element = jQuery(elem);
+ var $filter_table = jQuery('#filter_table');
+ var $filter_opt_tbl = jQuery('#filter_option_table');
var $cls_tbody = $element.closest("tbody");
-
- var selected_txt = jQuery('option:selected', $element).text();
-
- if (jQuery('tbody:visible', $filter_opt_tbl).length == 1 &&
+ var selected_txt = $element.find('option:selected').text();
+
+ if ($filter_opt_tbl.find('tbody:visible').length == 1 &&
$cls_tbody.siblings().length == 1) {
if($filter_table.is(':hidden')) {
- var $filterlabel = jQuery(idSelector('filterlabel'));
+ var $filterlabel = jQuery('#filterlabel');
if ($filterlabel.text() == '') {
- $filterlabel.text(selected_txt).attr('value', $element.val());
+ $filterlabel.text(selected_txt)
+ .attr('value', $element.val());
}
$filter_table.show();
}
} else {
- var $position_tr = jQuery('tr:last', $cls_tbody).prev();
+ var $position_tr = $cls_tbody.find('tr:last').prev();
if ($cls_tbody.prev().attr('id') == 'filter_table') {
- $position_tr = jQuery('tr:last', $filter_table);
+ $position_tr = $filter_table.find('tr:last');
}
-
- var old_tr = jQuery('tbody:first tr.filter_row_class:first', $filter_opt_tbl);
- var new_tr = old_tr.clone();
- var new_tr_lbl = jQuery(idSelector('filterlabel'), new_tr).text(selected_txt).attr('value', $element.val());
-
- var new_tr_qstring = jQuery('input.qstring', new_tr);
- new_tr_qstring.val('');
- if (new_tr.is(':hidden')) {
- new_tr.show();
+ var $old_tr = $filter_opt_tbl.find('tbody:first tr.filter_row_class:first');
+
+ var $new_tr = $old_tr.clone();
+ var $new_tr_lbl = $new_tr.find('#filterlabel')
+ .text(selected_txt)
+ .attr('value', $element.val());
+
+ var $new_tr_qstring = $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');
-
- jQuery(idSelector('filterlabel'), $curr_body).each(function(k, v) {
+ $curr_body.find('#filterlabel').each(function(k, v) {
if (jQuery(v).text() != selected_txt) { return; }
index_row = k;
- jQuery('select.expr', new_tr).hide();
- new_tr_lbl.hide();
- jQuery('label.and_or', new_tr).remove();
- jQuery('<label>', {'class': 'and_or'}).text('OR').insertBefore(new_tr_qstring);
+ $new_tr.find('select.expr').hide();
+ $new_tr_lbl.hide();
+ $new_tr.find('label.and_or').remove();
+ jQuery('<label>', {'class': 'and_or'}).text('OR').insertBefore($new_tr_qstring);
});
if(index_row >= 0) {
- $position_tr = jQuery('tr.filter_row_class', $curr_body)[index_row];
+ $position_tr = $curr_body.find('tr.filter_row_class')[index_row];
}
- jQuery($position_tr).after(new_tr);
+ jQuery($position_tr).after($new_tr);
}
var select_or = jQuery('select.filter_fields_or');
@@ -90,21 +86,22 @@
}
function addOrBlock(elem){
- var $filter_option_table = jQuery(idSelector('filter_option_table'));
- jQuery('tr:last select.filter_fields_or', $filter_option_table).parent().hide();
+ var $filter_option_table = jQuery('#filter_option_table');
+ $filter_option_table.find('tr:last select.filter_fields_or').parent().hide();
var $newtbody = jQuery('<tbody>').append(OR_LINE);
$filter_option_table.append($newtbody);
- var $new_tr = jQuery('tr:first', $filter_option_table).clone();
- jQuery(idSelector('filterlabel'), $new_tr)
- .attr('value', jQuery(elem).val())
- .text(jQuery('select.filter_fields_or option:selected').text());
-
- jQuery('input.qstring', $new_tr).val('');
+
+ var $new_tr = $filter_option_table.find('tr:first').clone();
+ $new_tr.find('#filterlabel').attr('value', jQuery(elem).val())
+ .text(jQuery('select.filter_fields_or option:selected').text());
+ $new_tr.find('input.qstring').val('');
$newtbody.append($new_tr);
- var $action_tr = jQuery(idSelector('filter_table')).next('tbody.actions').find('tr.actions').clone();
- jQuery('select.filter_fields_or', $action_tr).attr('disabled', false).parent().show();
+ var $action_tr = jQuery('#filter_table')
+ .next('tbody.actions').find('tr.actions').clone();
+ $action_tr.find('select.filter_fields_or')
+ .attr('disabled', false).parent().show();
if ($action_tr.is(':hidden')) {
$action_tr.show();
}
@@ -263,22 +260,22 @@
jQuery.extend({
keys: function(obj){
var a = [];
- $.each(obj, function(k){ a.push(k) });
+ $.each(obj, function(k){ a.push(k); });
return a;
}
});
function display_Customfilters(all_domains, group_by_ctx) {
var Allrecords = {};
- var error = false;
- jQuery('tbody:visible',idSelector('filter_option_table')).each(function () {
+ jQuery('#filter_option_table > tbody:visible').each(function () {
+ var missing_field_value = false;
var record = {};
var pid = jQuery(this).index();
jQuery(this).children('.filter_row_class').each(function () {
- var $constraint_value = jQuery('input.qstring', this);
- var $fieldname = jQuery(idSelector('filterlabel'), this);
- var id = jQuery('.filter_row_class', jQuery(this).parent()).index(this);
+ var $constraint_value = jQuery(this).find('input.qstring');
+ var $fieldname = jQuery(this).find('#filterlabel');
+ var id = jQuery(this).parent().find('> .filter_row_class').index(this);
if($constraint_value.val()) {
var rec = {};
@@ -286,132 +283,175 @@
record[id] = rec;
} else {
$constraint_value.addClass('errorfield').val(_('Invalid Value')).click(function() {
- jQuery(this).val('').removeClass('errorfield')
+ jQuery(this).val('').removeClass('errorfield');
});
- error = true;
+ missing_field_value = true;
}
});
+ if(missing_field_value) { return; }
if (jQuery.keys(record).length != 0){
Allrecords[pid] = record;
}
});
-
- if (!error) {
- openobject.http.postJSON('/openerp/search/get', {
- record: serializeJSON(Allrecords),
- _terp_model: jQuery(idSelector('_terp_model')).val()
- }).addCallback(function(obj){
- var custom_domain = [];
- if (obj.errors.length) {
- for (er_field in obj.errors) {
- for (er in obj.errors[er_field]) {
- jQuery('tbody .filter_row_class', idSelector('filter_option_table')).each(function(){
- if (jQuery(idSelector('filterlabel'), this).attr('value') == er) {
- jQuery('input.qstring', this).addClass('errorfield').val(obj.errors[er_field][er]).click(function(){
- jQuery(this).val('').removeClass('errorfield');
- });
- }
- })
- }
- }
- return;
- }
- var form_result = obj.frm;
- var tbody_keys = jQuery.keys(form_result);
-
- if (form_result) {
- // By property, we get incorrect ordering
- 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 (var index = 0; index < trs_keys.length; index++) {
- var return_record = tbody_frm_ind[trs_keys[index]];
- var $curr_body = jQuery('tbody', idSelector('filter_option_table')).eq(tbody_keys[ind]);
- var $row = jQuery('.filter_row_class', $curr_body).eq(trs_keys[index]);
- var $next_row = [];
- if ($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 ? jQuery('label.and_or', $next_row).text() : null;
-
- if (group.length == 0) {
- var $new_grp = $curr_body.find('tr.filter_row_class:gt(' + trs_keys[index] + ')').find('td#filter_column:not(:has(label)) input.qstring[value]');
- if ($new_grp.length) {
- group.push('&')
- }
- }
- if (grouping) {
- temp_domain.push(grouping == 'AND' ? '&' : '|');
- }
-
- var field = return_record['rec'];
- var comparison = jQuery('select.expr', $row).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
- if (type == 'many2many') {
- /* 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]
- }
- else
- if (type == 'one2many') {
- value = value[0];
- }
- else {
- value = value;
- }
- break;
- }
-
- if (jQuery('label.and_or', $row).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);
- });
- }
+
+ openobject.http.postJSON('/openerp/search/get', {
+ record: serializeJSON(Allrecords),
+ _terp_model: jQuery('#_terp_model').val()
+ }).addCallback(function(obj) {
+ var custom_domain = [];
+ if(obj.errors.length) {
+ jQuery.each(obj.errors, function (i, error) {
+ for(var field in error) {
+ jQuery('#filter_option_table tbody .filter_row_class').each(function () {
+ if(jQuery(this).find('#filterlabel').attr('value') == field) {
+ jQuery(this).find('input.qstring').addClass('errorfield').val(error[field]).click(function () {
+ jQuery(this).val('').removeClass('errorfield');
+ });
+ }
+ });
+ }
+ });
+ return;
+ }
+
+ var form_result = obj.frm;
+ var tbody_keys = jQuery.keys(form_result);
+
+ if(form_result) {
+ // By property, we get incorrect ordering
+ 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(var 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 = $curr_body.find('> .filter_row_class').eq(trs_keys[index]);
+ var $next_row = [];
+
+ if ($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]+')')
+ .find('td#filter_column:not(:has(label)) 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'];
+
+ // if there are multiple values we must split them before conversion
+ var isMultipleValues = comparison == 'in' || comparison == 'not in';
+ var values;
+ if(isMultipleValues) {
+ values = value.split(',');
+ } else {
+ values = [value];
+ }
+ // converting values
+ var newValues = jQuery.map(values, function(valuePart, i) {
+ switch (type) {
+ case "string":
+ case "many2one":
+ case "many2many":
+ case "one2many":
+ case "date":
+ case "reference":
+ case "char":
+ case "text":
+ case "datetime":
+ case "time":
+ case "binary":
+ case "selection":
+ case "one2one":
+ return valuePart;
+ case "boolean":
+ switch(valuePart.toLowerCase().trim()) {
+ case 'true':
+ case 'yes':
+ case '1':
+ return true;
+ case 'false':
+ case 'no':
+ case '0':
+ return false;
+ default:
+ return Boolean(valuePart);
+ }
+ case "integer":
+ case "integer_big":
+ var intValue = parseInt(valuePart, 10);
+ if(! isNaN(intValue)) {
+ return intValue;
+ }
+ // remove value from resulting array
+ return;
+ case "float":
+ var floatValue = parseFloat(valuePart);
+ if(! isNaN(floatValue)) {
+ return floatValue;
+ }
+ return;
+ default:
+ return;
+ }
+ });
+ if(isMultipleValues) {
+ value = newValues;
+ } else {
+ value = newValues[0];
+ }
+
+ switch (comparison) {
+ case 'ilike':
+ case 'not ilike':
+ if(isOrderable(type)) {
+ comparison = (comparison == 'ilike' ? '=' : '!=');
+ }
+ break;
+ case '<':
+ case '>':
+ if(!isOrderable(type)) {
+ comparison = '=';
+ }
+ break;
+ }
+
+ if ($row.find('label.and_or').length || 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);
+ });
}
var group_by = [];
@@ -423,22 +463,22 @@
var domains = {};
var search_context = {};
var all_boxes = [];
- var $filter_list = jQuery(idSelector('filter_list'));
+ var $filter_list = jQuery('#filter_list');
var domain = 'None';
if (jQuery('div.group-data').length) {
- jQuery('button', 'div.group-data').each(function(){
+ jQuery('div.group-data button').each(function(){
if (jQuery(this).hasClass('active')) {
var _grp = jQuery(this).next('input').attr('group_by_ctx');
if (jQuery.inArray(_grp, group_by) < 0) {
- group_by.push(_grp)
+ group_by.push(_grp);
}
}
- })
+ });
}
- if (jQuery(idSelector('filter_list')).attr('selectedIndex') > 0) {
+ if (jQuery('#filter_list').attr('selectedIndex') > 0) {
all_domains['selection_domain'] = $filter_list.val();
var selected_index = $filter_list.attr('selectedIndex');
- var filter_grps = jQuery('option:selected', idSelector('filter_list')).attr('group_by');
+ var filter_grps = jQuery('#filter_list option:selected').attr('group_by');
if(selected_index > 0) {
if(filter_grps && filter_grps!='[]') {
group_by = eval(filter_grps);
Follow ups