@ -1,12 +1,17 @@
/*global openerp, _, $ */
openerp . web_m2x_options = function ( instance ) {
/ * C o p y r i g h t 2 0 1 6 0 k . i o , A C S O N E S A / N V
* * License AGPL - 3.0 or later ( http : //www.gnu.org/licenses/agpl). */
odoo . define ( 'web_m2x_options.web_m2x_options' , function ( require ) {
"use strict" ;
"use strict" ;
var QWeb = instance . web . qweb ,
_t = instance . web . _t ,
_lt = instance . web . _lt ;
var $ = require ( "$" ) ;
var core = require ( 'web.core' ) ,
data = require ( 'web.data' ) ,
Dialog = require ( 'web.Dialog' ) ,
Model = require ( 'web.Model' ) ,
form_relational = require ( 'web.form_relational' ) ,
_ = require ( '_' ) ,
_t = core . _t ;
var OPTIONS = [ 'web_m2x_options.create' ,
var OPTIONS = [ 'web_m2x_options.create' ,
'web_m2x_options.create_edit' ,
'web_m2x_options.create_edit' ,
@ -14,7 +19,40 @@ openerp.web_m2x_options = function (instance) {
'web_m2x_options.search_more' ,
'web_m2x_options.search_more' ,
'web_m2x_options.m2o_dialog' , ] ;
'web_m2x_options.m2o_dialog' , ] ;
instance . web . form . FieldMany2One = instance . web . form . FieldMany2One . extend ( {
var M2ODialog = Dialog . extend ( {
template : "M2ODialog" ,
init : function ( parent ) {
this . name = parent . string ;
this . _super ( parent , {
title : _ . str . sprintf ( _t ( "Create a %s" ) , parent . string ) ,
size : 'medium' ,
buttons : [
{ text : _t ( 'Create' ) , classes : 'btn-primary' , click : function ( ) {
if ( this . $ ( "input" ) . val ( ) !== '' ) {
this . getParent ( ) . _quick_create ( this . $ ( "input" ) . val ( ) ) ;
this . close ( ) ;
} else {
e . preventDefault ( ) ;
this . $ ( "input" ) . focus ( ) ;
}
} } ,
{ text : _t ( 'Create and edit' ) , classes : 'btn-primary' , close : true , click : function ( ) {
this . getParent ( ) . _search_create_popup ( "form" , undefined , this . getParent ( ) . _create_context ( this . $ ( "input" ) . val ( ) ) ) ;
} } ,
{ text : _t ( 'Cancel' ) , close : true }
]
} ) ;
} ,
start : function ( ) {
var text = _ . str . sprintf ( _t ( "You are creating a new %s, are you sure it does not exist yet?" ) , this . name ) ;
this . $ ( "p" ) . text ( text ) ;
this . $ ( "input" ) . val ( this . getParent ( ) . $input . val ( ) ) ;
} ,
} ) ;
form_relational . FieldMany2One . include ( {
start : function ( ) {
start : function ( ) {
this . _super . apply ( this , arguments ) ;
this . _super . apply ( this , arguments ) ;
@ -26,7 +64,7 @@ openerp.web_m2x_options = function (instance) {
if ( ! _ . isUndefined ( this . view ) && _ . isUndefined ( this . view . ir_options_loaded ) ) {
if ( ! _ . isUndefined ( this . view ) && _ . isUndefined ( this . view . ir_options_loaded ) ) {
this . view . ir_options_loaded = $ . Deferred ( ) ;
this . view . ir_options_loaded = $ . Deferred ( ) ;
this . view . ir_options = { } ;
this . view . ir_options = { } ;
( new instance . web . Model ( "ir.config_parameter" ) )
( new Model ( "ir.config_parameter" ) )
. query ( [ "key" , "value" ] ) . filter ( [ [ 'key' , 'in' , OPTIONS ] ] )
. query ( [ "key" , "value" ] ) . filter ( [ [ 'key' , 'in' , OPTIONS ] ] )
. all ( ) . then ( function ( records ) {
. all ( ) . then ( function ( records ) {
_ ( records ) . each ( function ( record ) {
_ ( records ) . each ( function ( record ) {
@ -57,12 +95,12 @@ openerp.web_m2x_options = function (instance) {
if ( this . is_option_set ( this . options . m2o_dialog ) ||
if ( this . is_option_set ( this . options . m2o_dialog ) ||
_ . isUndefined ( this . options . m2o_dialog ) && this . is_option_set ( this . view . ir_options [ 'web_m2x_options.m2o_dialog' ] ) ||
_ . isUndefined ( this . options . m2o_dialog ) && this . is_option_set ( this . view . ir_options [ 'web_m2x_options.m2o_dialog' ] ) ||
this . can_create && _ . isUndefined ( this . options . m2o_dialog ) && _ . isUndefined ( this . view . ir_options [ 'web_m2x_options.m2o_dialog' ] ) ) {
this . can_create && _ . isUndefined ( this . options . m2o_dialog ) && _ . isUndefined ( this . view . ir_options [ 'web_m2x_options.m2o_dialog' ] ) ) {
new instance . web . form . M2ODialog ( this ) . open ( ) ;
new M2ODialog ( this ) . open ( ) ;
}
}
} ,
} ,
get_search_result : function ( search_val ) {
get_search_result : function ( search_val ) {
var Objects = new instance . web . Model ( this . field . relation ) ;
var Objects = new Model ( this . field . relation ) ;
var def = $ . Deferred ( ) ;
var def = $ . Deferred ( ) ;
var self = this ;
var self = this ;
// add options limit used to change number of selections record
// add options limit used to change number of selections record
@ -77,30 +115,25 @@ openerp.web_m2x_options = function (instance) {
this . limit = this . options . limit ;
this . limit = this . options . limit ;
}
}
// add options search_more to force enable or disable search_more button
if ( this . is_option_set ( this . options . search_more ) || _ . isUndefined ( this . options . search_more ) && this . is_option_set ( self . view . ir_options [ 'web_m2x_options.search_more' ] ) ) {
this . search_more = true
}
// add options field_color and colors to color item(s) depending on field_color value
// add options field_color and colors to color item(s) depending on field_color value
this . field_color = this . options . field_color
this . field_color = this . options . field_color
this . colors = this . options . colors
this . colors = this . options . colors
var dataset = new instance . web . DataSet ( this , this . field . relation ,
var dataset = new data . DataSet ( this , this . field . relation ,
self . build_context ( ) ) ;
self . build_context ( ) ) ;
var blacklist = this . get_search_blacklist ( ) ;
var blacklist = this . get_search_blacklist ( ) ;
this . last_query = search_val ;
this . last_query = search_val ;
var search_result = this . orderer . add ( dataset . name_search (
var search_result = this . orderer . add ( dataset . name_search (
search_val ,
search_val ,
new instance . web . CompoundDomain (
new data . CompoundDomain (
self . build_domain ( ) , [ [ "id" , "not in" , blacklist ] ] ) ,
self . build_domain ( ) , [ [ "id" , "not in" , blacklist ] ] ) ,
'ilike' , this . limit + 1 ,
'ilike' , this . limit + 1 ,
self . build_context ( ) ) ) ;
self . build_context ( ) ) ) ;
var create_rights ;
var create_rights ;
if ( ! ( self . options && ( self . options . no_create || self . options . no_create_edit ) ) ) {
create_rights = new instance . web . Model ( this . field . relation ) . call (
if ( ! ( self . options && ( self . is_option_set ( self . options . create ) || self . is_option_set ( self . options . create_edit ) ) ) ) {
create_rights = new Model ( this . field . relation ) . call (
"check_access_rights" , [ "create" , false ] ) ;
"check_access_rights" , [ "create" , false ] ) ;
}
}
@ -120,13 +153,11 @@ openerp.web_m2x_options = function (instance) {
} ) ;
} ) ;
// Search result value colors
// Search result value colors
if ( self . colors && self . field_color ) {
if ( self . colors && self . field_color ) {
var value_ids = [ ] ;
var value_ids = [ ] ;
for ( var index in values ) {
for ( var index in values ) {
value_ids . push ( values [ index ] . id ) ;
value_ids . push ( values [ index ] . id ) ;
}
}
// RPC request to get field_color from Objects
// RPC request to get field_color from Objects
Objects . query ( [ self . field_color ] )
Objects . query ( [ self . field_color ] )
. filter ( [ [ 'id' , 'in' , value_ids ] ] )
. filter ( [ [ 'id' , 'in' , value_ids ] ] )
@ -136,7 +167,6 @@ openerp.web_m2x_options = function (instance) {
if ( values [ index_value ] . id == objects [ index ] . id ) {
if ( values [ index_value ] . id == objects [ index ] . id ) {
// Find value in values by comparing ids
// Find value in values by comparing ids
var value = values [ index_value ] ;
var value = values [ index_value ] ;
// Find color with field value as key
// Find color with field value as key
var color = self . colors [ objects [ index ] [ self . field_color ] ] || 'black' ;
var color = self . colors [ objects [ index ] [ self . field_color ] ] || 'black' ;
value . label = '<span style="color:' + color + '">' + value . label + '</span>' ;
value . label = '<span style="color:' + color + '">' + value . label + '</span>' ;
@ -149,8 +179,11 @@ openerp.web_m2x_options = function (instance) {
}
}
// search more... if more results that max
// search more... if more results that max
var can_search_more = ( self . options && self . is_option_set ( self . options . search_more ) ) ,
search_more_undef = _ . isUndefined ( self . options . search_more ) && _ . isUndefined ( self . view . ir_options [ 'web_m2x_options.search_more' ] ) ,
search_more = self . is_option_set ( self . view . ir_options [ 'web_m2x_options.search_more' ] ) ;
if ( values . length > self . limit || self . search_more ) {
if ( values . length > self . limit && ( can_search_more || search_more_undef || search_more ) ) {
values = values . slice ( 0 , self . limit ) ;
values = values . slice ( 0 , self . limit ) ;
values . push ( {
values . push ( {
label : _t ( "Search More..." ) ,
label : _t ( "Search More..." ) ,
@ -164,7 +197,7 @@ openerp.web_m2x_options = function (instance) {
self . _search_create_popup ( "search" , data ) ;
self . _search_create_popup ( "search" , data ) ;
} ) ;
} ) ;
} ,
} ,
classname : 'oe_m2o_dropdown_option'
classname : 'oe_m2o_dropdown_option o_m2o_dropdown_option '
} ) ;
} ) ;
}
}
@ -173,16 +206,12 @@ openerp.web_m2x_options = function (instance) {
var raw_result = _ ( data . result ) . map ( function ( x ) {
var raw_result = _ ( data . result ) . map ( function ( x ) {
return x [ 1 ] ;
return x [ 1 ] ;
} ) ;
} ) ;
var no_quick_create = (
self . options && ( self . options . no_create ||
self . options . no_quick_create )
)
var m2x_create_undef = _ . isUndefined ( self . view . ir_options [ 'web_m2x_options.create' ] )
var m2x_create = self . view . ir_options [ 'web_m2x_options.create' ] == "True"
if ( ! no_quick_create && ( ( m2x_create_undef && can_create ) ||
m2x_create ) ) {
var quick_create = self . is_option_set ( self . options . create ) || self . is_option_set ( self . options . quick_create ) ,
quick_create_undef = _ . isUndefined ( self . options . create ) && _ . isUndefined ( self . options . quick_create ) ,
m2x_create_undef = _ . isUndefined ( self . view . ir_options [ 'web_m2x_options.create' ] ) ,
m2x_create = self . is_option_set ( self . view . ir_options [ 'web_m2x_options.create' ] ) ;
var show_create = ( ! self . options && ( m2x_create_undef || m2x_create ) ) || ( self . options && ( quick_create || ( quick_create_undef && ( m2x_create_undef || m2x_create ) ) ) ) ;
if ( show_create ) {
if ( search_val . length > 0 &&
if ( search_val . length > 0 &&
! _ . include ( raw_result , search_val ) ) {
! _ . include ( raw_result , search_val ) ) {
@ -193,22 +222,18 @@ openerp.web_m2x_options = function (instance) {
action : function ( ) {
action : function ( ) {
self . _quick_create ( search_val ) ;
self . _quick_create ( search_val ) ;
} ,
} ,
classname : 'oe_m2o_dropdown_option'
classname : 'oe_m2o_dropdown_option o_m2o_dropdown_option '
} ) ;
} ) ;
}
}
}
}
// create...
// create...
var no_create_edit = (
self . options && ( self . options . no_create ||
self . options . no_create_edit )
)
var m2x_create_edit_undef = _ . isUndefined ( self . view . ir_options [ 'web_m2x_options.create_edit' ] )
var m2x_create_edit = self . view . ir_options [ 'web_m2x_options.create_edit' ] == "True"
if ( ! no_create_edit && ( ( m2x_create_edit_undef && can_create ) ||
m2x_create_edit ) ) {
var create_edit = self . is_option_set ( self . options . create ) || self . is_option_set ( self . options . create_edit ) ,
create_edit_undef = _ . isUndefined ( self . options . create ) && _ . isUndefined ( self . options . create_edit ) ,
m2x_create_edit_undef = _ . isUndefined ( self . view . ir_options [ 'web_m2x_options.create_edit' ] ) ,
m2x_create_edit = self . is_option_set ( self . view . ir_options [ 'web_m2x_options.create_edit' ] ) ;
var show_create_edit = ( ! self . options && ( m2x_create_edit_undef || m2x_create_edit ) ) || ( self . options && ( create_edit || ( create_edit_undef && ( m2x_create_edit_undef || m2x_create_edit ) ) ) ) ;
if ( show_create_edit ) {
values . push ( {
values . push ( {
label : _t ( "Create and Edit..." ) ,
label : _t ( "Create and Edit..." ) ,
action : function ( ) {
action : function ( ) {
@ -216,10 +241,9 @@ openerp.web_m2x_options = function (instance) {
"form" , undefined ,
"form" , undefined ,
self . _create_context ( search_val ) ) ;
self . _create_context ( search_val ) ) ;
} ,
} ,
classname : 'oe_m2o_dropdown_option'
classname : 'oe_m2o_dropdown_option o_m2o_dropdown_option '
} ) ;
} ) ;
}
}
// Check if colors specified to wait for RPC
// Check if colors specified to wait for RPC
if ( ! ( self . field_color && self . colors ) ) {
if ( ! ( self . field_color && self . colors ) ) {
def . resolve ( values ) ;
def . resolve ( values ) ;
@ -230,12 +254,19 @@ openerp.web_m2x_options = function (instance) {
}
}
} ) ;
} ) ;
instance . web . form . FieldMany2ManyTags . include ( {
form_relational . FieldMany2ManyTags . include ( {
events : {
'click .o_delete' : function ( e ) {
this . remove_id ( $ ( e . target ) . parent ( ) . data ( 'id' ) ) ;
} ,
'click .badge' : 'open_badge' ,
'mousedown .o_colorpicker span' : 'update_color' ,
'focusout .o_colorpicker' : 'close_color_picker' ,
} ,
show_error_displayer : function ( ) {
show_error_displayer : function ( ) {
if ( ( typeof this . options . m2o_dialog === 'undefined' && this . can_create ) ||
if ( ( typeof this . options . m2o_dialog === 'undefined' && this . can_create ) ||
this . options . m2o_dialog ) {
this . options . m2o_dialog ) {
new instance . web . form . M2ODialog ( this ) . open ( ) ;
new M2ODialog ( this ) . open ( ) ;
}
}
} ,
} ,
@ -249,7 +280,7 @@ openerp.web_m2x_options = function (instance) {
if ( _ . isUndefined ( this . view . ir_options_loaded ) ) {
if ( _ . isUndefined ( this . view . ir_options_loaded ) ) {
this . view . ir_options_loaded = $ . Deferred ( ) ;
this . view . ir_options_loaded = $ . Deferred ( ) ;
this . view . ir_options = { } ;
this . view . ir_options = { } ;
( new instance . web . Model ( "ir.config_parameter" ) )
( new Model ( "ir.config_parameter" ) )
. query ( [ "key" , "value" ] ) . filter ( [ [ 'key' , 'in' , OPTIONS ] ] )
. query ( [ "key" , "value" ] ) . filter ( [ [ 'key' , 'in' , OPTIONS ] ] )
. all ( ) . then ( function ( records ) {
. all ( ) . then ( function ( records ) {
_ ( records ) . each ( function ( record ) {
_ ( records ) . each ( function ( record ) {
@ -261,6 +292,20 @@ openerp.web_m2x_options = function (instance) {
return this . view . ir_options_loaded ;
return this . view . ir_options_loaded ;
} ,
} ,
is_option_set : function ( option ) {
if ( _ . isUndefined ( option ) ) {
return false
}
var is_string = typeof option === 'string'
var is_bool = typeof option === 'boolean'
if ( is_string ) {
return option === 'true' || option === 'True'
} else if ( is_bool ) {
return option
}
return false
} ,
/ * *
/ * *
* Call this method to search using a string .
* Call this method to search using a string .
* /
* /
@ -279,12 +324,12 @@ openerp.web_m2x_options = function (instance) {
this . limit = this . options . limit ;
this . limit = this . options . limit ;
}
}
var dataset = new instance . web . DataSet ( this , this . field . relation , self . build_context ( ) ) ;
var dataset = new data . DataSet ( this , this . field . relation , self . build_context ( ) ) ;
var blacklist = this . get_search_blacklist ( ) ;
var blacklist = this . get_search_blacklist ( ) ;
this . last_query = search_val ;
this . last_query = search_val ;
return this . orderer . add ( dataset . name_search (
return this . orderer . add ( dataset . name_search (
search_val , new instance . web . CompoundDomain ( self . build_domain ( ) , [ [ "id" , "not in" , blacklist ] ] ) ,
search_val , new data . CompoundDomain ( self . build_domain ( ) , [ [ "id" , "not in" , blacklist ] ] ) ,
'ilike' , this . limit + 1 , self . build_context ( ) ) ) . then ( function ( data ) {
'ilike' , this . limit + 1 , self . build_context ( ) ) ) . then ( function ( data ) {
self . last_search = data ;
self . last_search = data ;
// possible selections for the m2o
// possible selections for the m2o
@ -304,6 +349,7 @@ openerp.web_m2x_options = function (instance) {
values . push ( {
values . push ( {
label : _t ( "Search More..." ) ,
label : _t ( "Search More..." ) ,
action : function ( ) {
action : function ( ) {
// limit = 80 for improving performance, similar
// limit = 80 for improving performance, similar
// to Odoo implementation here:
// to Odoo implementation here:
// https://github.com/odoo/odoo/commit/8c3cdce539d87775b59b3f2d5ceb433f995821bf
// https://github.com/odoo/odoo/commit/8c3cdce539d87775b59b3f2d5ceb433f995821bf
@ -311,18 +357,16 @@ openerp.web_m2x_options = function (instance) {
self . _search_create_popup ( "search" , data ) ;
self . _search_create_popup ( "search" , data ) ;
} ) ;
} ) ;
} ,
} ,
classname : 'oe_m2o_dropdown_option'
classname : 'oe_m2o_dropdown_option o_m2o_dropdown_option '
} ) ;
} ) ;
}
}
// quick create
// quick create
var no_quick_create = (
self . options && ( self . options . no_create ||
self . options . no_quick_create )
)
var m2x_create_undef = _ . isUndefined ( self . view . ir_options [ 'web_m2x_options.create' ] )
var m2x_create = self . view . ir_options [ 'web_m2x_options.create' ] == "True"
if ( ! no_quick_create && ( m2x_create_undef || m2x_create ) ) {
var quick_create = self . is_option_set ( self . options . create ) || self . is_option_set ( self . options . quick_create ) ,
quick_create_undef = _ . isUndefined ( self . options . create ) && _ . isUndefined ( self . options . quick_create ) ,
m2x_create_undef = _ . isUndefined ( self . view . ir_options [ 'web_m2x_options.create' ] ) ,
m2x_create = self . is_option_set ( self . view . ir_options [ 'web_m2x_options.create' ] ) ;
var show_create = ( ! self . options && ( m2x_create_undef || m2x_create ) ) || ( self . options && ( quick_create || ( quick_create_undef && ( m2x_create_undef || m2x_create ) ) ) ) ;
if ( show_create ) {
var raw_result = _ ( data . result ) . map ( function ( x ) { return x [ 1 ] ; } ) ;
var raw_result = _ ( data . result ) . map ( function ( x ) { return x [ 1 ] ; } ) ;
if ( search_val . length > 0 && ! _ . include ( raw_result , search_val ) ) {
if ( search_val . length > 0 && ! _ . include ( raw_result , search_val ) ) {
@ -332,27 +376,25 @@ openerp.web_m2x_options = function (instance) {
action : function ( ) {
action : function ( ) {
self . _quick_create ( search_val ) ;
self . _quick_create ( search_val ) ;
} ,
} ,
classname : 'oe_m2o_dropdown_option'
classname : 'oe_m2o_dropdown_option o_m2o_dropdown_option '
} ) ;
} ) ;
}
}
}
}
// create...
// create...
var no_create_edit = (
self . options && ( self . options . no_create ||
self . options . no_create_edit )
)
var m2x_create_edit_undef = _ . isUndefined ( self . view . ir_options [ 'web_m2x_options.create_edit' ] )
var m2x_create_edit = self . view . ir_options [ 'web_m2x_options.create_edit' ] == "True"
if ( ! no_create_edit && ( m2x_create_edit_undef || m2x_create_edit ) ) {
var create_edit = self . is_option_set ( self . options . create ) || self . is_option_set ( self . options . create_edit ) ,
create_edit_undef = _ . isUndefined ( self . options . create ) && _ . isUndefined ( self . options . create_edit ) ,
m2x_create_edit_undef = _ . isUndefined ( self . view . ir_options [ 'web_m2x_options.create_edit' ] ) ,
m2x_create_edit = self . is_option_set ( self . view . ir_options [ 'web_m2x_options.create_edit' ] ) ;
var show_create_edit = ( ! self . options && ( m2x_create_edit_undef || m2x_create_edit ) ) || ( self . options && ( create_edit || ( create_edit_undef && ( m2x_create_edit_undef || m2x_create_edit ) ) ) ) ;
if ( show_create_edit ) {
values . push ( {
values . push ( {
label : _t ( "Create and Edit..." ) ,
label : _t ( "Create and Edit..." ) ,
action : function ( ) {
action : function ( ) {
self . _search_create_popup ( "form" , undefined , self . _create_context ( search_val ) ) ;
self . _search_create_popup ( "form" , undefined , self . _create_context ( search_val ) ) ;
} ,
} ,
classname : 'oe_m2o_dropdown_option'
classname : 'oe_m2o_dropdown_option o_m2o_dropdown_option '
} ) ;
} ) ;
}
}
@ -360,29 +402,24 @@ openerp.web_m2x_options = function (instance) {
} )
} )
} ,
} ,
render_value : function ( )
{
open_badge : function ( ev ) {
var self = this ;
var self = this ;
return jQuery . when ( this . _super . apply ( this , arguments ) )
. then ( function ( )
{
if ( self . options . open )
{
self . $el . find ( '.oe_tag' )
. css ( 'cursor' , 'pointer' )
. click ( function ( e )
{
var id = parseInt ( jQuery ( this ) . attr ( 'data-id' ) ) ;
self . do_action ( {
type : 'ir.actions.act_window' ,
res_model : self . field . relation ,
views : [ [ false , 'form' ] ] ,
res_id : id ,
} ) ;
var open = ( self . options && self . is_option_set ( self . options . open ) ) ;
if ( open ) {
self . mutex . exec ( function ( ) {
var id = parseInt ( $ ( ev . handleObj . selector ) . attr ( 'data-id' ) ) ;
self . do_action ( {
type : 'ir.actions.act_window' ,
res_model : self . field . relation ,
views : [ [ false , 'form' ] ] ,
res_id : id ,
target : "new"
} ) ;
} ) ;
}
} ) ;
} . bind ( this ) ) ;
} else {
self . open_color_picker ( ev ) ;
}
} ,
} ,
} ) ;
} ;
} ) ;
} ) ;