layui在odoo12上的應用,用widget覆蓋原字段視圖


layui是一個前端框架,提供了許多前端的組件等,layui的詳情自己官網地址:https://www.layui.com/doc/去查看

下面說一下最近用layui遇到的問題和解決方式:

問題:近期做項目時候遇到一個需要將odoo的日期字段,用一個日期范圍去代替。

解決方式:layui提供了日期范圍選擇的組件,直接去layui官網找到相關案例,然后在本地定義組件去替換日期字段,詳細如下:

  1、前端視圖

    在字段中新增widget屬性,用自定義的layui組件覆蓋原xml字段視圖

    <field name="start_end" widget="date_range_select"/>

    在模板template中新增一個模板:

    <t t-name="datetime_inline">

      <div class="layui-inline" style="width: 100%">

        <input type="text" class="layui-input" id="datetime_inline" placeholder=" - "/>

      </div>

    </t>

    在js文件中新增date_range_select文件,內容如下

odoo.define("date_range_select", function (require) {
"use strict";

var AbstractField = require('web.AbstractField');
var field_registry = require('web.field_registry');

var date_range_select = AbstractField.extend({

template: 'datetime_inline',

init: function () {
this._super.apply(this, arguments);
},

start: function () {
var self = this;
setTimeout(function () {
if(self.mode==='readonly'){
self.el.innerHTML="<span>" +self.value + "</span>"
}
layui.use('laydate', function () {
var laydate = layui.laydate;
laydate.render({
elem: '#datetime_inline',
range: true,
format: 'yyyy/MM/dd',
done: function (value, date, endDate) {
self._setValue(value)
}
});
console.log('查看self', self)
})
},100);
},
});

field_registry.add('date_range_select', date_range_select);

return date_range_select
});
   到這里 就定義完了一個日期選擇組件

    注意:form、tree視圖都要加上widget

  2、后端模型

    容易采坑:由於剛開始后端模型中定義的start_end字段為Date類型,然而我們的前端字段已經被覆蓋成了日期范圍,得到的值是一個字符串,而不再是原來的耽擱日期,

      所以后端模型無法 直接存儲我們的日期范圍這個值,所以需要將原來的Date字段,更改為Char字段去存儲這個值,另外再新增start_date,end_date兩個字段,

      存儲開始結束日期,便於之后搜索視圖中使用

  3、搜索視圖

    由於我們的日期字段被修改為日期范圍,搜索的時候也是搜索一個日期范圍,所以在搜索視圖上也要做修改,用前端js實現過濾記錄。我剛開始也想過在后端做過濾,

    被否決了,原因是在后端做過濾,牽扯到當前頁面已經加載完成,如果要在后端做搜索過濾就會涉及到做異步加載的問題,所以就在前端直接做過濾搜索了

    1、在搜索模型中新增一個搜索模型,將對應的時間范圍字段自定義一個名字為:date_range_select,  

      <div class="col-lg-3 col-sm-6 col-12">
<span for="date_range_select" options="{'placeholder': '時間控件選擇'}"/>
</div>

    2、注冊我們定義的控件名字,將我們的組件指向layui定好的date類型,由於別人前期已經將date類型更改為日期范圍,所以此處可以跳過一步         

      else if (this.field.name === 'date_range_select') {

        type = 'date'

      }

    3、新增js文件search_pannel_extend.js 內容為:

odoo.define('search_pannel_extend', function (require) {
'use strict';

var widgetRegistry = require('web.widget_registry');
var search_pannel_default = require('layui_search_panel');
var core = require('web.core');
var proposition = require('layui_search_proposition');
var layui_search_proposition = proposition.layui_search_proposition;
var pyeval = require('web.py_utils');
var Widget = require('web.Widget');
var framework = require('web.framework');
var crash_manager = require('web.crash_manager');
var session = require('web.session');

search_pannel_default.include({
events: _.extend({}, search_pannel_default.prototype.events, {
'click .add_new': '_AddRecord',
'click .export': '_Export',
'click .import': '_Import'
}),

/**
* 新增記錄
* @private
*/
_AddRecord: function (event) {
var self = this;
event.stopPropagation();
this.do_action({
name: '新增',
type: 'ir.actions.act_window',
view_type: 'form',
view_mode: 'form',
res_model: this.getParent().model_name,
views: [[false, 'form']],
flags: {mode: 'edit'},
target: 'new',
context: {'dialog_size': $(event.currentTarget).attr("dialog_size") || 'large'}
}, {
on_close: function () {
self.trigger_up('reload');
}
})
},

/**
* 導出
* @private
*/
_Export: function (event) {
var self = this;
var ids = self.get_records();
if (ids.length > 0) {
this.do_action({
'name': '導出',
'type': 'ir.actions.act_url',
'url': $(event.currentTarget).attr("url") + '?ids=' + JSON.stringify(ids),
'target': 'new',
'tfs_close': true
})
} else {
layer.msg('請勾選需要導出的行!', {icon: 2});
}
},

get_records: function () {
// 獲取勾選項
var self = this;
var records = [];
var records_list = self.getParent().getParent().getSelectedRecords().map(function (record) {
records.push(record.res_id)
});
return records
},

/**
* 導入
* @private
*/
_Import: function (event) {
var self = this;
this.do_action({
name: '導入',
type: 'ir.actions.client',
tag: 'file_import',
context: {'dialog_size': 'medium', 'url': $(event.currentTarget).attr("url")},
target: 'new'
}, {
on_close: function () {
self.trigger_up('reload');
}
})
}
});
  
// 日期范圍選擇控件擴展
var date_range_select_search_pannel = search_pannel_default.extend({

events: _.extend({}, search_pannel_default.prototype.events, {
'click .report_repair': "_DateRange"
}),

// 日期范圍
_DateRange: function () {
var self = this;
this._rpc({
model: 'ir.model.data',
method: 'xmlid_to_res_id',
args: ['repairManageForXian.outsource_manage_project_form']
}).then(function (view_form_id) {
self.do_action({
name: '日期范圍',
type: 'ir.actions.act_window',
view_type: 'form',
view_mode: 'form',
res_model: 'repair_manage.outsource_manage_project',
views: [[view_form_id, 'form']],
target: 'new'
}, {
on_close: function () {
self.trigger_up('reload');
}
})
})
},

// 讀取模板,同時讀取屬性並構造搜索對象
renderElement: function () {
var $el;
var bHaveExt = false;
this.propositions = [];
$el = $(core.qweb.render(this.pannel_template, {widget: this}).trim());
var fields_place_holders = $el.find("[for]");
for (var i = 0; i < fields_place_holders.length; i++) {
var holder = fields_place_holders[i];
var filed_name = $(holder).attr('for');
var options = $(holder).attr('options') || "{'range': true}"; //因xml模板傳過來為string類型,故此不能用Obj
options = pyeval.py_eval(options);
options.funcs = {};
var field = this.fields[filed_name];
// 如果有字段或者為聚合搜索輸入框則渲染
if (field || filed_name === 'date_range_select') {
// 因原有field會被frozen凍結,所以需要復制一份調用
var copy_field = Object.assign({}, field);
// odoo12這里field沒有name屬性
copy_field.name = filed_name;
var prop = new layui_search_proposition(this, copy_field, options);
prop.replace(holder);
this.propositions.push(prop);
bHaveExt = true
}
}
this._replaceElement($el);
},

commit_search: function () {
var domains = [];
_.each(this.propositions, function (proposition) {
var domain = proposition.get_domain();
console.log(domain)
if (!domain) {
return
} else if (domain.length == 2){
domains.push([
['start_date', '<=', domain[1][2]],
['end_date', '>=', domain[0][2]]
])
} else {
domains.push(domain)
}

});
this.trigger_up('search', {
domains: domains
});
}

});
widgetRegistry.add('date_range_select_search_pannel', date_range_select_search_pannel);
return {
date_range_select_search_pannel: date_range_select_search_pannel
}
到這里 就全部結束了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM