mirror of https://github.com/OCA/web.git
[10.0][MIG]migrate web_widget_timepicker
parent
f33cf1292c
commit
b97d2f1cda
|
@ -2,7 +2,6 @@
|
|||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
|
||||
|
||||
===============================
|
||||
Timepicker widget in form views
|
||||
===============================
|
||||
|
@ -52,16 +51,10 @@ See the available options at `jquery-timepicker <https://github.com//jonthornton
|
|||
.. |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
|
||||
* The module uses the `jquery-timepicker <https://github.com//jonthornton//jquery-timepicker#timepicker-plugin-for-jquery>`_. plugin by Jon Thornton. This software is made available under the open source MIT License. © 2014 Jon Thornton and contributors
|
||||
|
||||
* Odoo Community Association (OCA)
|
||||
|
||||
|
@ -70,3 +63,20 @@ Contributors
|
|||
------------
|
||||
|
||||
* Michael Fried <Michael.Fried@vividlab.de>
|
||||
* Kaushal Prajapati <kbprajapati@live.com>
|
||||
|
||||
|
||||
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.
|
|
@ -3,12 +3,14 @@
|
|||
# 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)",
|
||||
"version": "10.0.1.0.0",
|
||||
"author": "VividLab, "
|
||||
"Odoo Community Association (OCA), "
|
||||
"Kaushal Prajapati",
|
||||
"license": "AGPL-3",
|
||||
"category": "Web",
|
||||
"website": "http://www.vividlab.de",
|
||||
'installable': False,
|
||||
'installable': True,
|
||||
"depends": [
|
||||
"web",
|
||||
],
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
.oe_form_editable .oe_form .oe_form_field_time input {
|
||||
.o_form_editable .o_form_field_time input {
|
||||
width: 6em;
|
||||
}
|
||||
.o_form_field_time{
|
||||
display: -webkit-inline-box !important;
|
||||
}
|
||||
|
|
|
@ -3,22 +3,22 @@ odoo.define('web_widget_timepicker', function (require) {
|
|||
|
||||
var core = require('web.core');
|
||||
var formats = require('web.formats');
|
||||
var common = require('web.form_common');
|
||||
var common = require('web.form_common');
|
||||
|
||||
var TimePickerField = common.AbstractField.extend(common.ReinitializeFieldMixin, {
|
||||
is_field_number: true,
|
||||
is_field_number: true,
|
||||
template: "TimePickerField",
|
||||
internal_format: 'float_time',
|
||||
widget_class: 'oe_form_field_time',
|
||||
widget_class: 'o_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, {
|
||||
this.options = _.defaults(this.options, {
|
||||
step: 15,
|
||||
selectOnBlur: true,
|
||||
timeFormat: 'H:i',
|
||||
|
@ -27,14 +27,14 @@ odoo.define('web_widget_timepicker', function (require) {
|
|||
},
|
||||
initialize_content: function() {
|
||||
if(!this.get("effective_readonly")) {
|
||||
this.$el.find('input').timepicker(this.options);
|
||||
this.setupFocus(this.$('input'));
|
||||
}
|
||||
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(),'');
|
||||
this.parse_value(this.$('input').val(), '');
|
||||
return true;
|
||||
} catch(e) {
|
||||
return false;
|
||||
|
@ -55,28 +55,28 @@ odoo.define('web_widget_timepicker', function (require) {
|
|||
height: height,
|
||||
width: width
|
||||
});
|
||||
},
|
||||
},
|
||||
store_dom_value: function () {
|
||||
if (!this.get('effective_readonly')) {
|
||||
this.internal_set_value(
|
||||
this.parse_value(
|
||||
this.$('input').val(),''));
|
||||
this.$('input').val(), ''));
|
||||
}
|
||||
},
|
||||
parse_value: function(val, def) {
|
||||
return formats.parse_value(val, {"widget": this.internal_format}, 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'),'');
|
||||
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);
|
||||
this.$(".o_form_time_content").text(show_value);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -84,6 +84,6 @@ odoo.define('web_widget_timepicker', function (require) {
|
|||
core.form_widget_registry.add('timepicker', TimePickerField);
|
||||
|
||||
return {
|
||||
TimePickerField: TimePickerField,
|
||||
TimePickerField: TimePickerField,
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.ui-timepicker-wrapper {
|
||||
overflow-y: auto;
|
||||
height: 150px;
|
||||
max-height: 150px;
|
||||
width: 6.5em;
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
|
@ -69,4 +69,4 @@ li.ui-timepicker-selected .ui-timepicker-duration,
|
|||
.ui-timepicker-list li.ui-timepicker-disabled:hover,
|
||||
.ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* jquery-timepicker v1.10.1 - A jQuery timepicker plugin inspired by Google Calendar. It supports both mouse and keyboard navigation.
|
||||
* jquery-timepicker v1.11.11 - A jQuery timepicker plugin inspired by Google Calendar. It supports both mouse and keyboard navigation.
|
||||
* Copyright (c) 2015 Jon Thornton - http://jonthornton.github.com/jquery-timepicker/
|
||||
* License: MIT
|
||||
*/
|
||||
|
@ -30,6 +30,58 @@
|
|||
hrs: 'hrs'
|
||||
};
|
||||
|
||||
var _DEFAULTS = {
|
||||
appendTo: 'body',
|
||||
className: null,
|
||||
closeOnWindowScroll: false,
|
||||
disableTextInput: false,
|
||||
disableTimeRanges: [],
|
||||
disableTouchKeyboard: false,
|
||||
durationTime: null,
|
||||
forceRoundTime: false,
|
||||
maxTime: null,
|
||||
minTime: null,
|
||||
noneOption: false,
|
||||
orientation: 'l',
|
||||
roundingFunction: function(seconds, settings) {
|
||||
if (seconds === null) {
|
||||
return null;
|
||||
} else if (typeof settings.step !== "number") {
|
||||
// TODO: nearest fit irregular steps
|
||||
return seconds;
|
||||
} else {
|
||||
var offset = seconds % (settings.step*60); // step is in minutes
|
||||
|
||||
var start = settings.minTime || 0;
|
||||
|
||||
// adjust offset by start mod step so that the offset is aligned not to 00:00 but to the start
|
||||
offset -= start % (settings.step * 60);
|
||||
|
||||
if (offset >= settings.step*30) {
|
||||
// if offset is larger than a half step, round up
|
||||
seconds += (settings.step*60) - offset;
|
||||
} else {
|
||||
// round down
|
||||
seconds -= offset;
|
||||
}
|
||||
|
||||
return _moduloSeconds(seconds, settings);
|
||||
}
|
||||
},
|
||||
scrollDefault: null,
|
||||
selectOnBlur: false,
|
||||
show2400: false,
|
||||
showDuration: false,
|
||||
showOn: ['click', 'focus'],
|
||||
showOnFocus: true,
|
||||
step: 30,
|
||||
stopScrollPropagation: false,
|
||||
timeFormat: 'g:ia',
|
||||
typeaheadHighlight: true,
|
||||
useSelect: false,
|
||||
wrapHours: true
|
||||
};
|
||||
|
||||
var methods = {
|
||||
init: function(options)
|
||||
{
|
||||
|
@ -39,13 +91,13 @@
|
|||
|
||||
// pick up settings from data attributes
|
||||
var attributeOptions = [];
|
||||
for (var key in $.fn.timepicker.defaults) {
|
||||
for (var key in _DEFAULTS) {
|
||||
if (self.data(key)) {
|
||||
attributeOptions[key] = self.data(key);
|
||||
}
|
||||
}
|
||||
|
||||
var settings = $.extend({}, $.fn.timepicker.defaults, attributeOptions, options);
|
||||
var settings = $.extend({}, _DEFAULTS, options, attributeOptions);
|
||||
|
||||
if (settings.lang) {
|
||||
_lang = $.extend(_lang, settings.lang);
|
||||
|
@ -70,8 +122,10 @@
|
|||
if (settings.disableTextInput) {
|
||||
self.on('keydown.timepicker', _disableTextInputHandler);
|
||||
}
|
||||
self.on('cut.timepicker', _keyuphandler);
|
||||
self.on('paste.timepicker', _keyuphandler);
|
||||
|
||||
_formatValue.call(self.get(0));
|
||||
_formatValue.call(self.get(0), null, 'initial');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -165,6 +219,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
// if not found or disabled, intelligently find first selectable element
|
||||
if (!selected.length || selected.hasClass('ui-timepicker-disabled')) {
|
||||
selected = list.find('li:not(.ui-timepicker-disabled):first');
|
||||
}
|
||||
|
||||
if (selected && selected.length) {
|
||||
var topOffset = list.scrollTop() + selected.position().top - selected.outerHeight();
|
||||
list.scrollTop(topOffset);
|
||||
|
@ -243,6 +302,8 @@
|
|||
|
||||
self.data('timepicker-settings', settings);
|
||||
|
||||
_formatValue.call(self.get(0), {'type':'change'}, 'initial');
|
||||
|
||||
if (list) {
|
||||
list.remove();
|
||||
self.data('timepicker-list', false);
|
||||
|
@ -308,7 +369,9 @@
|
|||
prettyTime = value;
|
||||
}
|
||||
|
||||
_setTimeValue(self, prettyTime);
|
||||
self.val(prettyTime);
|
||||
_formatValue.call(self.get(0), {'type':'change'}, 'initial');
|
||||
|
||||
if (self.data('timepicker-list')) {
|
||||
_setSelected(self, self.data('timepicker-list'));
|
||||
}
|
||||
|
@ -507,8 +570,8 @@
|
|||
row.text(timeString);
|
||||
} else {
|
||||
var row = $('<li />');
|
||||
row.addClass(timeInt % 86400 < 43200 ? 'ui-timepicker-am' : 'ui-timepicker-pm');
|
||||
row.data('time', (timeInt <= 86400 ? timeInt : timeInt % 86400));
|
||||
row.addClass((timeInt % _ONE_DAY) < (_ONE_DAY / 2) ? 'ui-timepicker-am' : 'ui-timepicker-pm');
|
||||
row.data('time', _moduloSeconds(timeInt, settings));
|
||||
row.text(timeString);
|
||||
}
|
||||
|
||||
|
@ -570,7 +633,7 @@
|
|||
appendTo.append(wrapped_list);
|
||||
_setSelected(self, list);
|
||||
|
||||
list.on('mousedown touchstart', 'li', function(e) {
|
||||
list.on('mousedown click', 'li', function(e) {
|
||||
|
||||
// hack: temporarily disable the focus handler
|
||||
// to deal with the fact that IE fires 'focus'
|
||||
|
@ -592,8 +655,8 @@
|
|||
if (_selectValue(self)) {
|
||||
self.trigger('hideTimepicker');
|
||||
|
||||
list.on('mouseup.timepicker touchend.timepicker', 'li', function(e) {
|
||||
list.off('mouseup.timepicker touchend.timepicker');
|
||||
list.on('mouseup.timepicker click.timepicker', 'li', function(e) {
|
||||
list.off('mouseup.timepicker click.timepicker');
|
||||
wrapped_list.hide();
|
||||
});
|
||||
}
|
||||
|
@ -640,13 +703,21 @@
|
|||
// event handler to decide whether to close timepicker
|
||||
function _closeHandler(e)
|
||||
{
|
||||
var target = $(e.target);
|
||||
var input = target.closest('.ui-timepicker-input');
|
||||
if (input.length === 0 && target.closest('.ui-timepicker-wrapper').length === 0) {
|
||||
methods.hide();
|
||||
$(document).unbind('.ui-timepicker');
|
||||
$(window).unbind('.ui-timepicker');
|
||||
if (e.target == window) {
|
||||
// mobile Chrome fires focus events against window for some reason
|
||||
return;
|
||||
}
|
||||
|
||||
var target = $(e.target);
|
||||
|
||||
if (target.closest('.ui-timepicker-input').length || target.closest('.ui-timepicker-wrapper').length) {
|
||||
// active timepicker was focused. ignore
|
||||
return;
|
||||
}
|
||||
|
||||
methods.hide();
|
||||
$(document).unbind('.ui-timepicker');
|
||||
$(window).unbind('.ui-timepicker');
|
||||
}
|
||||
|
||||
function _hideKeyboard(self)
|
||||
|
@ -685,7 +756,8 @@
|
|||
{
|
||||
list.find('li').removeClass('ui-timepicker-selected');
|
||||
|
||||
var timeValue = _time2int(_getTimeValue(self), self.data('timepicker-settings'));
|
||||
var settings = self.data('timepicker-settings');
|
||||
var timeValue = _time2int(_getTimeValue(self), settings);
|
||||
if (timeValue === null) {
|
||||
return;
|
||||
}
|
||||
|
@ -699,19 +771,26 @@
|
|||
list.scrollTop(list.scrollTop() + selected.position().top - selected.outerHeight());
|
||||
}
|
||||
|
||||
selected.addClass('ui-timepicker-selected');
|
||||
if (settings.forceRoundTime || selected.data('time') === timeValue) {
|
||||
selected.addClass('ui-timepicker-selected');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function _formatValue(e, origin)
|
||||
{
|
||||
if (this.value === '' || origin == 'timepicker') {
|
||||
if (origin == 'timepicker') {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = $(this);
|
||||
|
||||
if (this.value === '') {
|
||||
_setTimeValue(self, null, origin);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.is(':focus') && (!e || e.type != 'change')) {
|
||||
return;
|
||||
}
|
||||
|
@ -726,8 +805,8 @@
|
|||
|
||||
var rangeError = false;
|
||||
// check that the time in within bounds
|
||||
if (settings.minTime !== null && seconds < settings.minTime
|
||||
&& settings.maxTime !== null && seconds > settings.maxTime) {
|
||||
if ((settings.minTime !== null && settings.maxTime !== null)
|
||||
&& (seconds < settings.minTime || seconds > settings.maxTime)) {
|
||||
rangeError = true;
|
||||
}
|
||||
|
||||
|
@ -740,17 +819,21 @@
|
|||
});
|
||||
|
||||
if (settings.forceRoundTime) {
|
||||
seconds = settings.roundingFunction(seconds, settings);
|
||||
var roundSeconds = settings.roundingFunction(seconds, settings);
|
||||
if (roundSeconds != seconds) {
|
||||
seconds = roundSeconds;
|
||||
origin = null;
|
||||
}
|
||||
}
|
||||
|
||||
var prettyTime = _int2time(seconds, settings);
|
||||
|
||||
if (rangeError) {
|
||||
if (_setTimeValue(self, prettyTime, 'error')) {
|
||||
if (_setTimeValue(self, prettyTime, 'error') || e && e.type == 'change') {
|
||||
self.trigger('timeRangeError');
|
||||
}
|
||||
} else {
|
||||
_setTimeValue(self, prettyTime);
|
||||
_setTimeValue(self, prettyTime, origin);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -779,7 +862,7 @@
|
|||
self.data('ui-timepicker-value', value);
|
||||
if (source == 'select') {
|
||||
self.trigger('selectTime').trigger('changeTime').trigger('change', 'timepicker');
|
||||
} else if (source != 'error') {
|
||||
} else if (['error', 'initial'].indexOf(source) == -1) {
|
||||
self.trigger('changeTime');
|
||||
}
|
||||
|
||||
|
@ -830,6 +913,7 @@
|
|||
|
||||
case 13: // return
|
||||
if (_selectValue(self)) {
|
||||
_formatValue.call(self.get(0), {'type':'change'});
|
||||
methods.hide.apply(this);
|
||||
}
|
||||
|
||||
|
@ -909,6 +993,17 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
if (e.type === 'paste' || e.type === 'cut') {
|
||||
setTimeout(function () {
|
||||
if (settings.typeaheadHighlight) {
|
||||
_setSelected(self, list);
|
||||
} else {
|
||||
list.hide();
|
||||
}
|
||||
}, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.keyCode) {
|
||||
|
||||
case 96: // numpad numerals
|
||||
|
@ -1124,10 +1219,11 @@
|
|||
return null;
|
||||
}
|
||||
|
||||
var unboundedHour = parseInt(time[2]*1, 10);
|
||||
var hour = (unboundedHour > 24) ? unboundedHour % 24 : unboundedHour;
|
||||
var hour = parseInt(time[2]*1, 10);
|
||||
var ampm = time[1] || time[5];
|
||||
var hours = hour;
|
||||
var minutes = ( time[3]*1 || 0 );
|
||||
var seconds = ( time[4]*1 || 0 );
|
||||
|
||||
if (hour <= 12 && ampm) {
|
||||
var isPm = (ampm == _lang.pm || ampm == _lang.PM);
|
||||
|
@ -1137,10 +1233,17 @@
|
|||
} else {
|
||||
hours = (hour + (isPm ? 12 : 0));
|
||||
}
|
||||
} else if (settings) {
|
||||
var t = hour * 3600 + minutes * 60 + seconds;
|
||||
if (t >= _ONE_DAY + (settings.show2400 ? 1 : 0)) {
|
||||
if (settings.wrapHours === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
hours = hour % 24;
|
||||
}
|
||||
}
|
||||
|
||||
var minutes = ( time[3]*1 || 0 );
|
||||
var seconds = ( time[4]*1 || 0 );
|
||||
var timeInt = hours*3600 + minutes*60 + seconds;
|
||||
|
||||
// if no am/pm provided, intelligently guess based on the scrollDefault
|
||||
|
@ -1158,6 +1261,14 @@
|
|||
return ("0" + n).slice(-2);
|
||||
}
|
||||
|
||||
function _moduloSeconds(seconds, settings) {
|
||||
if (seconds == _ONE_DAY && settings.show2400) {
|
||||
return seconds;
|
||||
}
|
||||
|
||||
return seconds%_ONE_DAY;
|
||||
}
|
||||
|
||||
// Plugin entry
|
||||
$.fn.timepicker = function(method)
|
||||
{
|
||||
|
@ -1172,54 +1283,4 @@
|
|||
else if(typeof method === "object" || !method) { return methods.init.apply(this, arguments); }
|
||||
else { $.error("Method "+ method + " does not exist on jQuery.timepicker"); }
|
||||
};
|
||||
// Global defaults
|
||||
$.fn.timepicker.defaults = {
|
||||
appendTo: 'body',
|
||||
className: null,
|
||||
closeOnWindowScroll: false,
|
||||
disableTextInput: false,
|
||||
disableTimeRanges: [],
|
||||
disableTouchKeyboard: false,
|
||||
durationTime: null,
|
||||
forceRoundTime: false,
|
||||
maxTime: null,
|
||||
minTime: null,
|
||||
noneOption: false,
|
||||
orientation: 'l',
|
||||
roundingFunction: function(seconds, settings) {
|
||||
if (seconds === null) {
|
||||
return null;
|
||||
} else if (typeof settings.step !== "number") {
|
||||
// TODO: nearest fit irregular steps
|
||||
return seconds;
|
||||
} else {
|
||||
var offset = seconds % (settings.step*60); // step is in minutes
|
||||
|
||||
if (offset >= settings.step*30) {
|
||||
// if offset is larger than a half step, round up
|
||||
seconds += (settings.step*60) - offset;
|
||||
} else {
|
||||
// round down
|
||||
seconds -= offset;
|
||||
}
|
||||
|
||||
if (seconds == _ONE_DAY && settings.show2400) {
|
||||
return seconds;
|
||||
}
|
||||
|
||||
return seconds%_ONE_DAY;
|
||||
}
|
||||
},
|
||||
scrollDefault: null,
|
||||
selectOnBlur: false,
|
||||
show2400: false,
|
||||
showDuration: false,
|
||||
showOn: ['click', 'focus'],
|
||||
showOnFocus: true,
|
||||
step: 30,
|
||||
stopScrollPropagation: false,
|
||||
timeFormat: 'g:ia',
|
||||
typeaheadHighlight: true,
|
||||
useSelect: false
|
||||
};
|
||||
}));
|
||||
}));
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<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">
|
||||
<span t-att-class="'o_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"
|
||||
|
@ -14,7 +14,7 @@
|
|||
<span class="fa fa-clock-o o_timepicker_button"/>
|
||||
</t>
|
||||
<t t-if="widget.get('effective_readonly')">
|
||||
<span class="oe_form_time_content"></span>
|
||||
<span class="o_form_time_content"/>
|
||||
</t>
|
||||
</span>
|
||||
</t>
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
<?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>
|
||||
<odoo>
|
||||
<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 type="text/javascript"
|
||||
src="/web_widget_timepicker/static/src/js/web_widget_timepicker.js"/>
|
||||
<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>
|
||||
</odoo>
|
||||
|
|
Loading…
Reference in New Issue