Holger Brunn
5 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 342 additions and 0 deletions
-
82web_widget_date_interval/README.rst
-
3web_widget_date_interval/__init__.py
-
22web_widget_date_interval/__openerp__.py
-
15web_widget_date_interval/demo/ir_module_module.xml
-
BINweb_widget_date_interval/static/description/icon.png
-
0web_widget_date_interval/static/src/css/web_widget_date_interval.css
-
155web_widget_date_interval/static/src/js/web_widget_date_interval.js
-
54web_widget_date_interval/static/src/xml/web_widget_date_interval.xml
-
11web_widget_date_interval/views/templates.xml
@ -0,0 +1,82 @@ |
|||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.png |
|||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
|||
:alt: License: AGPL-3 |
|||
|
|||
============== |
|||
Date intervals |
|||
============== |
|||
|
|||
This module was written to allow users to select some visual presentation of an interval instead of selecting a begin or end date. |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
To use this module, use the widget ``date_interval`` on the field representing the begin of the interval. Make sure to also add the field representing the end of the interval, usually as hidden. Also add an ``options`` dictionary where you at least set the keys ``type`` and ``end_field``. |
|||
|
|||
Depending on the type, you can add more configuration in the widget options, see below for a list depending on the interval type. |
|||
|
|||
weeknumber_iso |
|||
-------------- |
|||
|
|||
``hide_years`` |
|||
if this is set, don't show a year selection |
|||
``years_before`` |
|||
allow the user to move to N years before the current date (or the field's value) |
|||
``years_after`` |
|||
allow the user to move to N years after the current date (or the field's value) |
|||
``week_type`` |
|||
`select` (default) will render a dropdown for weeks, `buttons` will show buttons |
|||
``weeks_before`` |
|||
allow the user to move to N weeks before the current date (or the field's value) if ``week_type`` has value `buttons` |
|||
``weeks_after`` |
|||
allow the user to move to N weeks after the current date (or the field's value) if ``week_type`` has value `buttons` |
|||
|
|||
|
|||
Example:: |
|||
|
|||
<field name="date_start" widget="date_interval" options="{'type': 'weeknumber_iso', 'end_field': 'date_end'}" /> |
|||
|
|||
The module's demo data adds this to the form of model constraints. |
|||
|
|||
Roadmap |
|||
======= |
|||
|
|||
* add more interval types |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues |
|||
<https://github.com/OCA/web/issues>`_. In case of trouble, please |
|||
check there if your issue has already been reported. If you spotted it first, |
|||
help us smashing it by providing a detailed and welcomed feedback. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Images |
|||
------ |
|||
|
|||
* Odoo Community Association: `Icon <https://odoo-community.org/logo.png>`_. |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Holger Brunn <hbrunn@therp.nl> |
|||
|
|||
Do not contact contributors directly about support or help with technical issues. |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
OCA, or the Odoo Community Association, is a nonprofit organization whose |
|||
mission is to support the collaborative development of Odoo features and |
|||
promote its widespread use. |
|||
|
|||
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
@ -0,0 +1,22 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
{ |
|||
"name": "Date intervals", |
|||
"version": "8.0.1.0.0", |
|||
"author": "Therp BV,Odoo Community Association (OCA)", |
|||
"license": "AGPL-3", |
|||
"category": "Hidden/Dependency", |
|||
"summary": "Widget to conveniently specify date intervals", |
|||
"website": "https://github.com/OCA/web", |
|||
"depends": [ |
|||
'web', |
|||
], |
|||
"data": [ |
|||
"demo/ir_module_module.xml", |
|||
'views/templates.xml', |
|||
], |
|||
"qweb": [ |
|||
"static/src/xml/web_widget_date_interval.xml", |
|||
], |
|||
} |
@ -0,0 +1,15 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<openerp> |
|||
<data> |
|||
<record id="view_model_constraint_form" model="ir.ui.view"> |
|||
<field name="model">ir.model.constraint</field> |
|||
<field name="inherit_id" ref="base.view_model_constraint_form" /> |
|||
<field name="arch" type="xml"> |
|||
<field name="date_init" position="attributes"> |
|||
<attribute name="widget">date_interval</attribute> |
|||
<attribute name="options">{'type': 'weeknumber_iso', 'end_field': 'date_update'}</attribute> |
|||
</field> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</openerp> |
After Width: 128 | Height: 128 | Size: 9.2 KiB |
@ -0,0 +1,155 @@ |
|||
// -*- coding: utf-8 -*-
|
|||
// © 2017 Therp BV <http://therp.nl>
|
|||
// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|||
|
|||
/* eslint require-jsdoc:0 */ |
|||
|
|||
openerp.web_widget_date_interval = function (instance) { |
|||
"use strict"; |
|||
instance.web.form.widgets.add( |
|||
'date_interval', |
|||
'instance.web_widget_date_interval.FieldDateInterval'); |
|||
instance.web_widget_date_interval.FieldDateInterval = |
|||
instance.web.form.AbstractField.extend( |
|||
instance.web.form.ReinitializeFieldMixin, |
|||
{ |
|||
events: { |
|||
'click .weeknumber_iso .years button': |
|||
'weeknumber_iso_onchange_year', |
|||
'change .weeknumber_iso .weeks select': |
|||
'weeknumber_iso_onchange_week', |
|||
'click .weeknumber_iso .weeks button': |
|||
'weeknumber_iso_onchange_week', |
|||
}, |
|||
default_options: { |
|||
type: 'weeknumber_iso', |
|||
years_before: 5, |
|||
years_after: 5, |
|||
weeks_before: 5, |
|||
weeks_after: 5, |
|||
hide_years: false, |
|||
week_type: 'select', |
|||
}, |
|||
template: 'FieldDateInterval', |
|||
className: 'oe_form_date_interval', |
|||
init: function () { |
|||
this._super.apply(this, arguments); |
|||
this.options = _.extend( |
|||
{}, this.default_options, this.options |
|||
); |
|||
if (!this.options.end_field) { |
|||
throw new Error( |
|||
'Pass an end field in the options dictionary'); |
|||
} |
|||
this.on('change:value', this, this.reinitialize); |
|||
}, |
|||
_get_date: function () { |
|||
return instance.web.str_to_date( |
|||
instance.web.parse_value( |
|||
this.get_value(), this, Date.now() |
|||
).substring(0, 10) |
|||
); |
|||
}, |
|||
weeknumber_iso_weeknumber: function (date) { |
|||
// GetISOWeek looks at the UTC time, but users expect walltime
|
|||
var local = date.clone().clearTime().add(12).hours(); |
|||
return parseInt(local.getISOWeek(), 10); |
|||
}, |
|||
weeknumber_iso_year: function (date) { |
|||
// The ISO year of a week is the year of the week's thursday
|
|||
var _date = date.clone(); |
|||
if (!_date.is().monday()) { |
|||
_date.last().monday(); |
|||
} |
|||
return _date.next().thursday().getFullYear(); |
|||
}, |
|||
weeknumber_iso_get_years: function () { |
|||
if (this.options.hide_years) { |
|||
return []; |
|||
} |
|||
var result = [], |
|||
years_before = this.options.years_before, |
|||
years_after = this.options.years_after, |
|||
current_date = this._get_date(); |
|||
for ( |
|||
var year=current_date.getFullYear() - years_before; |
|||
year <= current_date.getFullYear() + years_after; |
|||
year++ |
|||
) { |
|||
result.push(year); |
|||
} |
|||
return result; |
|||
}, |
|||
weeknumber_iso_get_weeks: function () { |
|||
var result = [], |
|||
last_day = this._get_date(), |
|||
min_week = 1, |
|||
max_week = 52; |
|||
if (!last_day.is().december()) { |
|||
last_day.december(); |
|||
} |
|||
last_day.moveToLastDayOfMonth(); |
|||
if (this.weeknumber_iso_weeknumber(last_day) > 1) { |
|||
max_week = this.weeknumber_iso_weeknumber(last_day); |
|||
} |
|||
if (this.options.week_type === 'buttons') { |
|||
min_week = Math.max( |
|||
min_week, |
|||
this.weeknumber_iso_weeknumber(this._get_date()) - |
|||
this.options.weeks_before |
|||
); |
|||
max_week = Math.min( |
|||
max_week, |
|||
this.weeknumber_iso_weeknumber(this._get_date()) + |
|||
this.options.weeks_after |
|||
); |
|||
} |
|||
for (var week=min_week; week <= max_week; week++) { |
|||
result.push(week); |
|||
} |
|||
return result; |
|||
}, |
|||
weeknumber_iso_date_from_week: function (year, week) { |
|||
// Pick any date within 'year', then change the week
|
|||
return new Date(year, 5, 1).setWeek(week); |
|||
}, |
|||
weeknumber_iso_onchange_year: function (e) { |
|||
var year = parseInt(jQuery(e.currentTarget).data('year'), 10); |
|||
var week = this.weeknumber_iso_weeknumber(this._get_date()); |
|||
var monday = this.weeknumber_iso_date_from_week(year, week); |
|||
return this.weeknumber_iso_update_interval(monday); |
|||
}, |
|||
weeknumber_iso_onchange_week: function (e) { |
|||
var week = parseInt( |
|||
jQuery(e.currentTarget).val() || |
|||
jQuery(e.currentTarget).data('week'), |
|||
10 |
|||
); |
|||
var year = this.weeknumber_iso_year(this._get_date()); |
|||
var monday = this.weeknumber_iso_date_from_week(year, week); |
|||
return this.weeknumber_iso_update_interval(monday); |
|||
}, |
|||
weeknumber_iso_update_interval: function (start) { |
|||
return this.update_interval( |
|||
start.is().monday() ? start : start.last().monday(), |
|||
start.clone().next().sunday() |
|||
); |
|||
}, |
|||
update_interval: function (start, end) { |
|||
var start_str = instance.web.auto_date_to_str( |
|||
start, this.field.type |
|||
), |
|||
end_str = instance.web.auto_date_to_str( |
|||
end, |
|||
this.field_manager.fields[this.options.end_field] |
|||
.field.type |
|||
); |
|||
this.field_manager.fields[this.name].set_value(start_str); |
|||
this.field_manager.fields[this.options.end_field].set_value( |
|||
end_str |
|||
); |
|||
this.reinitialize(); |
|||
}, |
|||
} |
|||
); |
|||
}; |
@ -0,0 +1,54 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<templates> |
|||
<div t-name="FieldDateInterval"> |
|||
<t t-set="date" t-value="widget._get_date()" /> |
|||
<div t-if="widget.options.type == 'weeknumber_iso'" class="weeknumber_iso"> |
|||
<div t-if="!widget.get('effective_readonly')" class="years"> |
|||
<button |
|||
t-foreach="widget.weeknumber_iso_get_years()" |
|||
t-as="year" |
|||
t-att-data-year="year" |
|||
t-attf-class="oe_button oe_form_button" |
|||
t-att-disabled="widget.weeknumber_iso_year(date) == year ? 'disable' : null" |
|||
t-attf-title="Year {{year}}" |
|||
> |
|||
<t |
|||
t-esc="year" |
|||
/> |
|||
</button> |
|||
</div> |
|||
<div t-if="!widget.get('effective_readonly')" class="oe_form_field oe_form_field_selection oe_form_required weeks"> |
|||
<select t-if="widget.options.week_type == 'select'" title="Select ISO week"> |
|||
<option |
|||
t-foreach="widget.weeknumber_iso_get_weeks()" |
|||
t-as="week" |
|||
t-att-value="week" |
|||
t-att-selected="widget.weeknumber_iso_weeknumber(date) == week ? 'selected' : undefined" |
|||
> |
|||
<t |
|||
t-esc="week" |
|||
/> |
|||
</option> |
|||
</select> |
|||
<t t-if="widget.options.week_type == 'buttons'"> |
|||
<button |
|||
t-foreach="widget.weeknumber_iso_get_weeks()" |
|||
t-as="week" |
|||
t-att-data-week="week" |
|||
t-attf-class="oe_button oe_form_button" |
|||
t-att-disabled="widget.weeknumber_iso_weeknumber(date) == week ? 'disable' : null" |
|||
t-attf-title="ISO week {{week}}" |
|||
> |
|||
<t |
|||
t-esc="week" |
|||
/> |
|||
</button> |
|||
</t> |
|||
</div> |
|||
<t t-if="widget.get('effective_readonly')"> |
|||
<t t-esc="widget.weeknumber_iso_year(date)" />, |
|||
week <t t-esc="widget.weeknumber_iso_weeknumber(date)" /> |
|||
</t> |
|||
</div> |
|||
</div> |
|||
</templates> |
@ -0,0 +1,11 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<openerp> |
|||
<data> |
|||
<template id="assets_backend" name="web_widget_date_interval assets" inherit_id="web.assets_backend"> |
|||
<xpath expr="." position="inside"> |
|||
<script type="text/javascript" src="/web_widget_date_interval/static/src/js/web_widget_date_interval.js"></script> |
|||
<link rel="stylesheet" href="/web_widget_date_interval/static/src/css/web_widget_date_interval.css"/> |
|||
</xpath> |
|||
</template> |
|||
</data> |
|||
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue