Browse Source
Merge pull request #357 from docmfried/web_widget_timepicker
Merge pull request #357 from docmfried/web_widget_timepicker
[9.0] New form view field web widget timepickerpull/411/head
Dave Lasley
9 years ago
committed by
GitHub
12 changed files with 1527 additions and 0 deletions
-
72web_widget_timepicker/README.rst
-
2web_widget_timepicker/__init__.py
-
29web_widget_timepicker/__openerp__.py
-
BINweb_widget_timepicker/images/form_view.png
-
BINweb_widget_timepicker/images/picker.png
-
BINweb_widget_timepicker/static/description/icon.png
-
3web_widget_timepicker/static/src/css/web_widget_timepicker.css
-
89web_widget_timepicker/static/src/js/web_widget_timepicker.js
-
72web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.css
-
1225web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.js
-
21web_widget_timepicker/static/src/xml/web_widget_timepicker.xml
-
14web_widget_timepicker/views/web_widget_timepicker_assets.xml
@ -0,0 +1,72 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
||||
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
|
||||
|
=============================== |
||||
|
Timepicker widget in form views |
||||
|
=============================== |
||||
|
|
||||
|
This module provides a timepicker widget for float fields. |
||||
|
It can be used as a replacement for the standard float_time widget in form views. |
||||
|
|
||||
|
|
||||
|
|picker| |
||||
|
|
||||
|
|
||||
|
The widget has the following default timepicker options: |
||||
|
|
||||
|
* the possible selection is based on 15 minute interval (step: 15) |
||||
|
* 24 hour mode in H:i format (timeFormat: 'H:i') |
||||
|
* scroll selection starts at current time (scrollDefault: 'now') |
||||
|
|
||||
|
|
||||
|
|formview| |
||||
|
|
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
In the form view declaration, put widget='timepicker' attribute in the field tag:: |
||||
|
|
||||
|
... |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="View name"> |
||||
|
... |
||||
|
<field name="name"/> |
||||
|
<field name="mytimefieldname" widget="timepicker"/> |
||||
|
... |
||||
|
</form> |
||||
|
</field> |
||||
|
... |
||||
|
|
||||
|
Additional jquery-timepicker plugin options can be specified by an options attribute:: |
||||
|
|
||||
|
... |
||||
|
<field name="mytimefieldname" widget="timepicker" options="{'step': '30', 'disableTextInput': false}"/> |
||||
|
... |
||||
|
|
||||
|
See the available options at `jquery-timepicker <https://github.com//jonthornton//jquery-timepicker#timepicker-plugin-for-jquery>`_. |
||||
|
|
||||
|
.. |picker| image:: ./images/picker.png |
||||
|
.. |formview| image:: ./images/form_view.png |
||||
|
|
||||
|
|
||||
|
Known issues / Roadmap |
||||
|
====================== |
||||
|
|
||||
|
* No validation on options. |
||||
|
|
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
* The module uses the `jquery-timepicker <https://cdnjs.com//libraries//jquery-timepicker>`_ plugin by Jon Thornton. This software is made available under the open source MIT License. © 2014 Jon Thornton and contributors |
||||
|
|
||||
|
* Odoo Community Association (OCA) |
||||
|
|
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Michael Fried <Michael.Fried@vividlab.de> |
@ -0,0 +1,2 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
@ -0,0 +1,29 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Vividlab (<http://www.vividlab.de>) |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
{ |
||||
|
"name": "Web Timepicker Widget", |
||||
|
"version": "9.0.1.0.0", |
||||
|
"author": "VividLab, Odoo Community Association (OCA)", |
||||
|
"license": "AGPL-3", |
||||
|
"category": "Web", |
||||
|
"website": "http://www.vividlab.de", |
||||
|
"installable": True, |
||||
|
"depends": [ |
||||
|
"web", |
||||
|
], |
||||
|
"css": [ |
||||
|
"static/src/lib/jquery.timerpicker/jquery.timepicker.css", |
||||
|
"static/src/css/web_widget_timepicker.css", |
||||
|
], |
||||
|
"js": [ |
||||
|
"static/src/lib/jquery.timerpicker/jquery.timepicker.js", |
||||
|
"static/src/js/web_widget_timepicker.js", |
||||
|
], |
||||
|
"data": [ |
||||
|
"views/web_widget_timepicker_assets.xml", |
||||
|
], |
||||
|
"qweb": [ |
||||
|
"static/src/xml/web_widget_timepicker.xml", |
||||
|
] |
||||
|
} |
After Width: 380 | Height: 178 | Size: 4.2 KiB |
After Width: 101 | Height: 177 | Size: 3.8 KiB |
After Width: 256 | Height: 256 | Size: 13 KiB |
@ -0,0 +1,3 @@ |
|||||
|
.oe_form_editable .oe_form .oe_form_field_time input { |
||||
|
width: 6em; |
||||
|
} |
@ -0,0 +1,89 @@ |
|||||
|
odoo.define('web_widget_timepicker', function (require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
var core = require('web.core'); |
||||
|
var formats = require('web.formats'); |
||||
|
var common = require('web.form_common'); |
||||
|
|
||||
|
var TimePickerField = common.AbstractField.extend(common.ReinitializeFieldMixin, { |
||||
|
is_field_number: true, |
||||
|
template: "TimePickerField", |
||||
|
internal_format: 'float_time', |
||||
|
widget_class: 'oe_form_field_time', |
||||
|
events: { |
||||
|
'change input': 'store_dom_value', |
||||
|
}, |
||||
|
init: function (field_manager, node) { |
||||
|
this._super(field_manager, node); |
||||
|
|
||||
|
this.internal_set_value(0); |
||||
|
|
||||
|
this.options = _.defaults( this.options, { |
||||
|
step: 15, |
||||
|
selectOnBlur: true, |
||||
|
timeFormat: 'H:i', |
||||
|
scrollDefault: 'now', |
||||
|
}); |
||||
|
}, |
||||
|
initialize_content: function() { |
||||
|
if(!this.get("effective_readonly")) { |
||||
|
this.$el.find('input').timepicker(this.options); |
||||
|
this.setupFocus(this.$('input')); |
||||
|
} |
||||
|
}, |
||||
|
is_syntax_valid: function() { |
||||
|
if (!this.get("effective_readonly") && this.$("input").size() > 0) { |
||||
|
try { |
||||
|
this.parse_value(this.$('input').val(),''); |
||||
|
return true; |
||||
|
} catch(e) { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
return true; |
||||
|
}, |
||||
|
is_false: function() { |
||||
|
return this.get('value') === '' || this._super(); |
||||
|
}, |
||||
|
focus: function() { |
||||
|
var input = this.$('input:first')[0]; |
||||
|
return input ? input.focus() : false; |
||||
|
}, |
||||
|
set_dimensions: function (height, width) { |
||||
|
this._super(height, width); |
||||
|
this.$('input').css({ |
||||
|
height: height, |
||||
|
width: width |
||||
|
}); |
||||
|
}, |
||||
|
store_dom_value: function () { |
||||
|
if (!this.get('effective_readonly')) { |
||||
|
this.internal_set_value( |
||||
|
this.parse_value( |
||||
|
this.$('input').val(),'')); |
||||
|
} |
||||
|
}, |
||||
|
parse_value: function(val, def) { |
||||
|
return formats.parse_value(val, {"widget": this.internal_format}, def); |
||||
|
}, |
||||
|
format_value: function(val, def) { |
||||
|
return formats.format_value(val, {"widget": this.internal_format}, def); |
||||
|
}, |
||||
|
render_value: function() { |
||||
|
var show_value = this.format_value(this.get('value'),''); |
||||
|
|
||||
|
if (!this.get("effective_readonly")) { |
||||
|
this.$input = this.$el.find('input'); |
||||
|
this.$input.val(show_value); |
||||
|
} else { |
||||
|
this.$(".oe_form_time_content").text(show_value); |
||||
|
} |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
core.form_widget_registry.add('timepicker', TimePickerField); |
||||
|
|
||||
|
return { |
||||
|
TimePickerField: TimePickerField, |
||||
|
}; |
||||
|
}); |
@ -0,0 +1,72 @@ |
|||||
|
.ui-timepicker-wrapper { |
||||
|
overflow-y: auto; |
||||
|
height: 150px; |
||||
|
width: 6.5em; |
||||
|
background: #fff; |
||||
|
border: 1px solid #ddd; |
||||
|
-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2); |
||||
|
-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2); |
||||
|
box-shadow:0 5px 10px rgba(0,0,0,0.2); |
||||
|
outline: none; |
||||
|
z-index: 10001; |
||||
|
margin: 0; |
||||
|
} |
||||
|
|
||||
|
.ui-timepicker-wrapper.ui-timepicker-with-duration { |
||||
|
width: 13em; |
||||
|
} |
||||
|
|
||||
|
.ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-30, |
||||
|
.ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-60 { |
||||
|
width: 11em; |
||||
|
} |
||||
|
|
||||
|
.ui-timepicker-list { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
list-style: none; |
||||
|
} |
||||
|
|
||||
|
.ui-timepicker-duration { |
||||
|
margin-left: 5px; color: #888; |
||||
|
} |
||||
|
|
||||
|
.ui-timepicker-list:hover .ui-timepicker-duration { |
||||
|
color: #888; |
||||
|
} |
||||
|
|
||||
|
.ui-timepicker-list li { |
||||
|
padding: 3px 0 3px 5px; |
||||
|
cursor: pointer; |
||||
|
white-space: nowrap; |
||||
|
color: #000; |
||||
|
list-style: none; |
||||
|
margin: 0; |
||||
|
} |
||||
|
|
||||
|
.ui-timepicker-list:hover .ui-timepicker-selected { |
||||
|
background: #fff; color: #000; |
||||
|
} |
||||
|
|
||||
|
li.ui-timepicker-selected, |
||||
|
.ui-timepicker-list li:hover, |
||||
|
.ui-timepicker-list .ui-timepicker-selected:hover { |
||||
|
background: #1980EC; color: #fff; |
||||
|
} |
||||
|
|
||||
|
li.ui-timepicker-selected .ui-timepicker-duration, |
||||
|
.ui-timepicker-list li:hover .ui-timepicker-duration { |
||||
|
color: #ccc; |
||||
|
} |
||||
|
|
||||
|
.ui-timepicker-list li.ui-timepicker-disabled, |
||||
|
.ui-timepicker-list li.ui-timepicker-disabled:hover, |
||||
|
.ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled { |
||||
|
color: #888; |
||||
|
cursor: default; |
||||
|
} |
||||
|
|
||||
|
.ui-timepicker-list li.ui-timepicker-disabled:hover, |
||||
|
.ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled { |
||||
|
background: #f2f2f2; |
||||
|
} |
1225
web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,21 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
|
||||
|
<templates id="template" xml:space="preserve"> |
||||
|
<t t-name="TimePickerField"> |
||||
|
<span t-att-class="'oe_form_field '+widget.widget_class" t-att-style="widget.node.attrs.style"> |
||||
|
<t t-if="!widget.get('effective_readonly')"> |
||||
|
<input t-att-type="'text'" |
||||
|
class="o_timepicker_input" |
||||
|
t-att-id="widget.id_for_label" |
||||
|
t-att-tabindex="widget.node.attrs.tabindex" |
||||
|
t-att-autofocus="widget.node.attrs.autofocus" |
||||
|
t-att-placeholder="widget.node.attrs.placeholder" |
||||
|
t-att-maxlength="widget.field.size"/> |
||||
|
<span class="fa fa-clock-o o_timepicker_button"/> |
||||
|
</t> |
||||
|
<t t-if="widget.get('effective_readonly')"> |
||||
|
<span class="oe_form_time_content"></span> |
||||
|
</t> |
||||
|
</span> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,14 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
|
||||
|
<openerp> |
||||
|
<data> |
||||
|
<template id="web_widget_timepicker_assets_backend" name="web_widget_timepicker assets" inherit_id="web.assets_backend"> |
||||
|
<xpath expr="." position="inside"> |
||||
|
<script type="text/javascript" src="/web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.js"></script> |
||||
|
<script type="text/javascript" src="/web_widget_timepicker/static/src/js/web_widget_timepicker.js"></script> |
||||
|
<link rel="stylesheet" href="/web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.css"/> |
||||
|
<link rel="stylesheet" href="/web_widget_timepicker/static/src/css/web_widget_timepicker.css"/> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
</data> |
||||
|
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue