From 18aa62efb2449d3558e5310f7fe14fc323eea766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20D=C3=ADaz?= Date: Tue, 5 Feb 2019 05:01:40 +0100 Subject: [PATCH] [11.0][MIG] web_widget_timepicker --- web_widget_timepicker/README.rst | 91 +- web_widget_timepicker/__init__.py | 1 - web_widget_timepicker/__manifest__.py | 23 +- web_widget_timepicker/images/form_view.png | Bin 4281 -> 0 bytes web_widget_timepicker/images/picker.png | Bin 3868 -> 0 bytes web_widget_timepicker/readme/CONTRIBUTORS.rst | 3 + web_widget_timepicker/readme/CREDITS.rst | 3 + web_widget_timepicker/readme/DESCRIPTION.rst | 2 + web_widget_timepicker/readme/USAGE.rst | 20 + .../static/src/css/web_widget_timepicker.css | 6 - .../static/src/js/web_widget_timepicker.js | 139 +- .../jquery.timepicker/jquery.timepicker.css | 72 - .../jquery.timepicker/jquery.timepicker.js | 1286 ----------------- .../static/src/xml/web_widget_timepicker.xml | 21 - .../views/web_widget_timepicker_assets.xml | 30 +- 15 files changed, 133 insertions(+), 1564 deletions(-) delete mode 100644 web_widget_timepicker/images/form_view.png delete mode 100644 web_widget_timepicker/images/picker.png create mode 100644 web_widget_timepicker/readme/CONTRIBUTORS.rst create mode 100644 web_widget_timepicker/readme/CREDITS.rst create mode 100644 web_widget_timepicker/readme/DESCRIPTION.rst create mode 100644 web_widget_timepicker/readme/USAGE.rst delete mode 100644 web_widget_timepicker/static/src/css/web_widget_timepicker.css delete mode 100644 web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.css delete mode 100644 web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.js delete mode 100644 web_widget_timepicker/static/src/xml/web_widget_timepicker.xml diff --git a/web_widget_timepicker/README.rst b/web_widget_timepicker/README.rst index d7fc5b89..6116781d 100644 --- a/web_widget_timepicker/README.rst +++ b/web_widget_timepicker/README.rst @@ -1,82 +1,19 @@ -.. 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 +This file is going to be generated by oca-gen-addon-readme. -=============================== -Timepicker widget in form views -=============================== +Manual changes will be overwritten. -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. +Please provide content in the readme directory: + DESCRIPTION.rst (required) + INSTALL.rst (optional) + CONFIGURE.rst (optional) + USAGE.rst (optional, highly recommended) + DEVELOP.rst (optional) + ROADMAP.rst (optional) + HISTORY.rst (optional, recommended) + CONTRIBUTORS.rst (optional, highly recommended) + CREDITS.rst (optional) -|picker| +Content of this README will also be drawn from the addon manifest, from keys such as name, authors, maintainers, development_status, and license. - -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:: - - ... - -
- ... - - - ... - - - ... - -Additional jquery-timepicker plugin options can be specified by an options attribute:: - - ... - - ... - -See the available options at `jquery-timepicker `_. - -.. |picker| image:: ./images/picker.png -.. |formview| image:: ./images/form_view.png - - -Credits -======= - -* The module uses the `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 -* Kaushal Prajapati - - -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. +A good, one sentence summary in the manifest is also highly recommended. diff --git a/web_widget_timepicker/__init__.py b/web_widget_timepicker/__init__.py index 2977e4d6..d9d1f13d 100644 --- a/web_widget_timepicker/__init__.py +++ b/web_widget_timepicker/__init__.py @@ -1,2 +1 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/web_widget_timepicker/__manifest__.py b/web_widget_timepicker/__manifest__.py index 23e4f302..4a0e8a6c 100644 --- a/web_widget_timepicker/__manifest__.py +++ b/web_widget_timepicker/__manifest__.py @@ -1,31 +1,20 @@ -# -*- coding: utf-8 -*- -# © 2016 Vividlab () +# Copyright 2016 Vividlab () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { "name": "Web Timepicker Widget", - "version": "10.0.1.0.0", + "version": "11.0.1.0.0", "author": "VividLab, " - "Odoo Community Association (OCA), " - "Kaushal Prajapati", + "Kaushal Prajapati, " + "Alexandre Díaz, " + "Odoo Community Association (OCA)", "license": "AGPL-3", "category": "Web", - "website": "http://www.vividlab.de", + "website": "https://github.com/OCA/web/", '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", - ] } diff --git a/web_widget_timepicker/images/form_view.png b/web_widget_timepicker/images/form_view.png deleted file mode 100644 index 1feae7a16f5819d2732226fb0a3d5e5d3e5f73f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4281 zcmd^Ci#t@?`ya<~bU7ubP7<0TDdkpFC*f42vN17gN*N5wZNyAbG$wLOLz>)1no82- zPJ@g~CC0dn)C6qz23Fn^}g$~KJUAq9fz{B zUbAZRDg*+t=Hv-W2LwVc41OCE{Omnfq(>- ziz5JF0MrH4QU{y{PNPvM6x!MGoQsPy+QsDp0C)lb9sq6tr*Xh(9{?4ILVIIeJODi2 zb$P-a1^77t-e{Dc3nmZ+grI;M7$DHa;kt_h9$th80zI5Vz0bJ1x+07z#>NyRkcPl9 zkpvb1PyokB07C{YBmu4u052NKI}PxE0^k`y$V=3Xd<-GWFPx@I7O9e_RcR8{V$hhv z11JoDTnePI@X<8)I96c%^Nlbl{5g!#35J&BzegdAm$7}#sG0=fH({g>5NLc07QGEXutU0@Np6;HLralDs(& zT-#}0+$_Qn124+G4l!{Mix3qRl^hjS^z`nFqNS2f6GazvkV}Q+Qc)ZWZlSnp$%ER# zs$vnNfkA0#pfo@f9+XrM(YTT{E<|gG()dvNI8;{0%i=+=xgutVm@(AA7#d;>K`%v6 z(V(PQ0x=8AYK+UP&PKkf`%B9!CFXI3Q4LU=oP$QLqkJLOG|ruduL}SkH_op@8`3p8V4l} z&`>=Dwah{s2HI@~)1H9*29@hBgX za3QE(Hv10*EiE4$92AU<3WY+ENF)$R1|`rC1c@L>A`(F35@>c9euI`}Q&UslA-G89 z=jUZI8BBf`z01yUoFIq}c8*Ik|HTF2C{fggAz69l#5n>2v9@lh%CQ4pc)-F=xvSxZ>uGC+g!piCc~J4fXd+@8Sj!h~NJ>X?X-4;xeA8_)y(R^^Jk6g8WyS zrPS@anI`x>M&OWuSz2Cxvwp!`PEr zKX>x;-gh(=~Fkn#B-$F?)~aSb{X%DSR4x4n3Dz ztM2$`t&{nw=zukeN^j$bkH&K1f8B=+R#T|Xil09qD4A$xCl9D1hlV|a-)o#7;uPkm z6LMQm2G#ou`-U7=UA~<$H!``0IK2CosN3+Q!mw^PhpnQB-PfO*xLYM6VoHmpHSysOd)alRy25emJV1Y) zoO;r8J#c}4gFXCczTiOL!dm;eCifWz*G`{2%!=KwAc(xV_-KYc%MCvKSp3QNvQy(O z(+{Rc^iRX^b;t}~shjF;*pajj5^7G=jc~ee28QY)v3eR!1Ed8T>TZ0wYR%<#t7qOe zvhs<*uO^%TbHXAx!?!*nRrxrc`+;HT@av&ZV~bm4^&^S&%IVhC+$WFk5$dvkS3s>@ zx!FvhrQ)KxTNVy$)xd za6k7^coS27V@b|^FUYa|k;3E1YEQl*b);k;m6vNL`@>4ro^<9eDe`m9||!J>O+e>zqCwR@lPV!+N7 zTk_^;)^BPzjOeJeE^La4%L~ifkhWN1$+a@C+G3QX4QL9q@9&UQo`Obi=9C!RZ(_$c zR%hCMcHAbU4fs9N0DB(=dx`tY&3+vzv=CC4+GeqFaiz>RRHczetF)}%ME1|} zsI_7`7FT#}(TF~1Xat|=m`8CgaXQ*2YSWLmH<9w+b&k!UD|Xt>{Ja1wYqOX$1vlEY z!tGYK{Qfy$*X(WdFRkM2jI++v6pis8fgLH*-PkMAn8)!@^#T$KT=m?;KI-N45B;aM zN5)*kN%hjvcMOtLe0?(evEgt@ht^@RH}QiGGORH|KlXTqw+%@=9_p0f5;Cg5uBLaX z+vZe;tnKfWm^z*Q;d-{FVsE(Mox;qc{@K3|G>_OH3l&qp4TR9MCgvW{#doqkFz#q7 zvIM?LH687V3wsK8Dl(;r{(JQ1Bf8DR*n8Q72LRv-++%xkFmwoaZn5 zwJ_n8t#St8r<%gfhaY+_a1$RRt3GYF0@qOKZTP8#@2@k&Ij2PZuj>8oDb1@|QhvA<=FaV5OX8xn+_H5?^5acR1}s`b6pVY z&B!mA__C_;qROTeyiVs6f9tO%D>b=}duEPZZdCyba$lD*uyN`3CnpO|t~)bf2yUxt zQLLN2mwglPedR26sJ4mU%+!_j@fg&%iqANab3g zL2ugj(4zi_+q(lB>!0~k;8m$$^L`gazT^rk$@W0~Am#6N9J=aenMZsdDXJSNA`NpCWkPm`+tis;qcBjutQZX zXWycG&rWM}j|8tS6ozU?TRQiA+2|sqIu|`mE;RD@W*hFPHFRmUXCwRT%TY>V%~r3Oz8#sYwW^qnxCZ&2y{Mr5eD<9i~X}wT6 zMKU)H21JWDpFyFwJV`g*Cnr5@3X5qcM-cLggJL*J0?!%} zdW_P`ShM99@oM<;m+eeeYcx$M2PBwa4yg~r+`=t`6B-a>t@lH#t4#m3`iM#<&UQJ* zDMA|E)IGoKhJ5tpk)yZ%>cYIP8;MD~%w2-AZZBrzE<-l$Czzy~6b*dO!5yKx^c*vv zl|O+B&|`NQv6`LXb8Gh z>GTPeef=!dvJzEtB@k;b%r zbZb5JhSF11#Q3#kiCuNB>sGk-(lVpv%{i44V-Gi77n#aY^7ZSP z?@)s8EzQwVgf|8SIb~?OsBkU*CytF+L;1rAG_*5M=CgYQh)5X3{;d1g)YOpSVL!h+ zwoctRn&!8&9=@9le43M!?{nY4J~r%Pd_1$BPqXfsh|=U*w`SB^Gm0m7G@+KYq}KW; zgG|ndrO@_H4GawQ^JA@JdzB_0Nxn=>CBoiyBX`y&>Hjz&nku(Tp}(OCYN(MwA^n!J=EXV$06yG-(e{Cu5~u+9@VZr3&uF> zG!{hi{Q1;tg}D}$K`r3<lt zwZ&S$OehSL<--_xwqvzK&o!SvAQ7TVkwNOe-M0?O#C-h0X?c0QMpV6-rGXi+@W24< z%dw&QHR8I}W8FbSg$)$7U7@}T+mK{5Ix`7{`i*_ zPoaQ?pb~tGQ($uh(Y{A5|Af%+2!0&fTlHaghB6Y23n!J*_|GzZmHiJJF?23<)yqUh zRK%FwHbf|VhU@;bol3k~Z%AoB6Rf$lu#pWLdJ$gxb!2vSh4OQcgF)aco*&_U03F10 zhb)C8yEv;_;|`sH*gTGZulK87kppubMVh?$K72dmX0in5Smc}IzJvRwaIkjT5! zs_gpD#Rb)mc2Ax(fRh(G9G1#i1Xzuxab6b8#otO*LjxsU6`nkKAcrwSheW6drtT4762=afQ5QhwWJl6dDwAl?J z5<$V3L~p&Cb{urLe?uSLD`Ir@Dt(u=X?i+~HPU{vGLj}`plShb(j+u>mgP+E5K+24%_#88pD5a~Ofp8R_H z`sD#zOvl3ODf1K?8t=lwLQ!!syt=aTWj@eHa)>@Zd%+O?13v2VX4W`6H!~swHTvRn z7d2pWR2XQEU z(+&vA)QWW#OEZ6#;xqOaVl zfCLF2@Gtm!d&jnSN;u6t8_nj2FkpYC%;xxf|%V{9NEI**sqaaV>7jDhsF%(fs;XseXF}jlIWE;7hhJ%pRsil z-;n@X)Xbta(qX7LeRV)8z}xl7Qubwt+(i0tlDc~I-H>@lMSE@D0#a7D%(g>%oPwq% zjT5kVf-?>gR=M|W@d$m`A+P051iKh+hEUU)5U2-D^NuDf=TS!2RWcT{$1!LHsXa~9 zm8I$=J7~{&-9zX&Nu#S?zEa+!>AU`(qnWNIbIsre~WER7Vp?%a=nIjCz4&P zk3Z*uw{#EO5jehYb`1U)$ZCNO2OX*nClL;6O5%sZ=3+~TT%i9Db9A^szoO%U`l&4l zX-xiY3p7tV&c&RBt1ls*BIWcKf!Vs?B{AT^L)4y9YX@Pxbb#_9$|beq`z%;m4>V-M#4PbmTuRDU-S}!b(J-I~Ju-Ir)o}?G z++Cn>S4Fei(%NJ5IV><=c$nJ+=}hC6S45>` zLyto#>;T+y4+lCU~F%_=1X|!;s}#0{h%_bAwU0Uf?N8otaijHh)P!43$L~$ z3f+s7x6X9_Nb8RDd6$Q6Y)Sfld)qq`v1GDs-^bfl;kMvi>+#I$FwUt)_@Kem3-G1^ zOdDN*B4uPy0$bjPYg#43{xE$h=bRK0#Cn~i;IS=)S=~3AH7<8=C#7QB4yXm4ydRL- z+63f2uo>BmA1r4Z=mINW0gb%y{dmYDhD`@R_b{@XN%}Fo2S%?rX2vvF8cV-v2dq#>1iz5-AkuwvesUS90W#u zC8wO-xMH5TchPu4m6#zzZe1v0VeOUZ!6_0FH_3mz+8?PP=1Nx9pbUe$zk>m*X|dNn z5{J4*X{;&Qm;KOlA-^`cou<8$9((P4LkWxz2>OWHo^Sto1SMu4kXHN1==+Id(3F=F zPx`&{$Y`K?s|Kna!t1Pp>o-XW!2b?^W%|@-x+`2r7nqCbcJ(~a8>$zA`)GPN_VV`H zpi_FR;j)|>R5X3C0Zbz|vtS1>{b$hppFH#5u)G6(J{kKh;QJSCSeL_+WpvAaX?dhJ zL|EAPlR6$`1w)L)hx#dKH{AG@W{_a-rtae}GxV^B{?KTg@5|(8or2WVm%E=gF8Uxt z_dgiNck#8s9G;7*g1Gn!N}twP2^9XO{O}+U=3+?_jav^amkfaT_{T}h-3IV9>t6Q1 z+7Gg-3t9Tf7nQp8aB@o7h3^E|@8Xh_tbH(|VT0cjb?_#LN60>nc`6ykpiJ-Y#}El@ z$I(RLdG+5tXN1{1(R2OY(mBhF{Ie*^Bn^8Vkm48^Lcsw%Wclk{Wb{V1az z0_OwUsNr3MN;j zx{jF|jq&>4TQ1(OO!uOt`9l#VXgYYteumy>RH|IgH)hkAsbwD+ZcEMS=V9wJj&StxxrpFUx_R^Fr)1cB28#L{Sj|I6S1+P1Y;3yG7Ut$d zVK4$aKB@Ci9YY|#ain@sN$$+#*nVSW3CPIE6xGz6Gg7TMU;awMeI{mSaA1H8s}UvP zWUXtsPRd$7Ui;czzp^4<^K*|Sf8oNRr1kG zTkUF-h~@Q89Yv&d3(po@e+F+EC-+f*89n zHM@HM)kqO}1*Xl9$uO1T1dHO*1$pHk?!}*j@mP01+sSmx>j~VRe%H8~}69{i(aL+N653X!&<{{u+sOm6@H diff --git a/web_widget_timepicker/readme/CONTRIBUTORS.rst b/web_widget_timepicker/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..2226c9c8 --- /dev/null +++ b/web_widget_timepicker/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* Michael Fried +* Kaushal Prajapati +* Alexandre Díaz diff --git a/web_widget_timepicker/readme/CREDITS.rst b/web_widget_timepicker/readme/CREDITS.rst new file mode 100644 index 00000000..1aca81fa --- /dev/null +++ b/web_widget_timepicker/readme/CREDITS.rst @@ -0,0 +1,3 @@ +* The module uses the `datetime-picker `_. plugin by Jonathan Peterson. This software is made available under the open source MIT License. Copyright (c) 2015 Jonathan Peterson + +* Odoo Community Association (OCA) diff --git a/web_widget_timepicker/readme/DESCRIPTION.rst b/web_widget_timepicker/readme/DESCRIPTION.rst new file mode 100644 index 00000000..39e20ae4 --- /dev/null +++ b/web_widget_timepicker/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +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. diff --git a/web_widget_timepicker/readme/USAGE.rst b/web_widget_timepicker/readme/USAGE.rst new file mode 100644 index 00000000..a848ae29 --- /dev/null +++ b/web_widget_timepicker/readme/USAGE.rst @@ -0,0 +1,20 @@ +In the form view declaration, put widget='timepicker' attribute in the field tag:: + + ... + +
+ ... + + + ... + + + ... + +Additional bootstrap datetime-picker plugin options can be specified by an options attribute:: + + ... + + ... + +See the available options at `datetime-picker `_. diff --git a/web_widget_timepicker/static/src/css/web_widget_timepicker.css b/web_widget_timepicker/static/src/css/web_widget_timepicker.css deleted file mode 100644 index 69a5616e..00000000 --- a/web_widget_timepicker/static/src/css/web_widget_timepicker.css +++ /dev/null @@ -1,6 +0,0 @@ -.o_form_editable .o_form_field_time input { - width: 6em; -} -.o_form_field_time{ - display: -webkit-inline-box !important; -} diff --git a/web_widget_timepicker/static/src/js/web_widget_timepicker.js b/web_widget_timepicker/static/src/js/web_widget_timepicker.js index 0bd96c21..791faf65 100644 --- a/web_widget_timepicker/static/src/js/web_widget_timepicker.js +++ b/web_widget_timepicker/static/src/js/web_widget_timepicker.js @@ -1,89 +1,96 @@ +/* Copyright 2016 Vividlab + * Copyright 2017 Kaushal Prajapati + * Copyright 2019 Alexandre Díaz + * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */ odoo.define('web_widget_timepicker', function (require) { - "use strict"; + 'use strict'; - var core = require('web.core'); - var formats = require('web.formats'); - var common = require('web.form_common'); + var field_registry = require('web.field_registry'); + var field_utils = require('web.field_utils'); + var basic_fields = require('web.basic_fields'); + var datepicker = require('web.datepicker'); + var FieldDate = basic_fields.FieldDate; - var TimePickerField = common.AbstractField.extend(common.ReinitializeFieldMixin, { - is_field_number: true, - template: "TimePickerField", - internal_format: 'float_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); + var TimeWidget = datepicker.DateWidget.extend({ + type_of_date: "float_time", - 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')); + _onShow: function () { + if (this.$input.val().length !== 0 && this.isValid()) { + var value = this.$input.val(); + this.picker.date(new moment(value, this.options.format)); + this.$input.select(); } }, - 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; - } + + setValue: function (value) { + this.set({'value': value}); + var formatted_value = value ? this._formatClient(value) : null; + this.$input.val(formatted_value); + if (this.picker) { + var fdate = new moment(formatted_value, this.options.format); + this.picker.date(fdate && fdate.isValid() + ? fdate : new moment()); } - return true; }, - is_false: function() { - return this.get('value') === '' || this._super(); + + getValue: function () { + var value = this.get('value'); + return value ? this._formatClient(value) : null; }, - focus: function() { - var input = this.$('input:first')[0]; - return input ? input.focus() : false; + + changeDatetime: function () { + if (this.isValid()) { + var oldValue = this.getValue(); + this._setValueFromUi(); + var newValue = this.getValue(); + if (oldValue && newValue && newValue !== oldValue) { + this.trigger("datetime_changed"); + } + } }, - set_dimensions: function (height, width) { - this._super(height, width); - this.$('input').css({ - height: height, - width: width + }); + + var FieldTimePicker = FieldDate.extend({ + supportedFieldTypes: ['float'], + floatTimeFormat: "HH:mm", + + init: function () { + this._super.apply(this, arguments); + var defDate = null; + if (this.value) { + defDate = new moment(this._formatValue(this.value), + this.floatTimeFormat); + } + // Hard-Coded Format: Field is an float and conversion only accept + // HH:mm format + this.datepickerOptions = _.extend(this.datepickerOptions, { + format: this.floatTimeFormat, + defaultDate: defDate && defDate.isValid() + ? defDate : new moment(), }); }, - store_dom_value: function () { - if (!this.get('effective_readonly')) { - this.internal_set_value( - this.parse_value( - this.$('input').val(), '')); - } + + _isSameValue: function (value) { + return value === this.value; }, - parse_value: function(val, def) { - return formats.parse_value(val, {"widget": this.internal_format}, def); + + _makeDatePicker: function () { + return new TimeWidget(this, this.datepickerOptions); }, - format_value: function(val, def) { - return formats.format_value(val, {"widget": this.internal_format}, def); + + _formatValue: function (value) { + return field_utils.format.float_time(value); }, - 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.$(".o_form_time_content").text(show_value); - } + _parseValue: function (value) { + return field_utils.parse.float_time(value); }, }); - core.form_widget_registry.add('timepicker', TimePickerField); - + field_registry.add('timepicker', FieldTimePicker); return { - TimePickerField: TimePickerField, + TimeWidget: TimeWidget, + FieldTimePicker: FieldTimePicker, }; }); diff --git a/web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.css b/web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.css deleted file mode 100644 index 78e1415e..00000000 --- a/web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.css +++ /dev/null @@ -1,72 +0,0 @@ -.ui-timepicker-wrapper { - overflow-y: auto; - max-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; -} \ No newline at end of file diff --git a/web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.js b/web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.js deleted file mode 100644 index b9e4f9ab..00000000 --- a/web_widget_timepicker/static/src/lib/jquery.timepicker/jquery.timepicker.js +++ /dev/null @@ -1,1286 +0,0 @@ -/*! - * 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 - */ - - -(function (factory) { - if (typeof exports === "object" && exports && - typeof module === "object" && module && module.exports === exports) { - // Browserify. Attach to jQuery module. - factory(require("jquery")); - } else if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['jquery'], factory); - } else { - // Browser globals - factory(jQuery); - } -}(function ($) { - var _ONE_DAY = 86400; - var _lang = { - am: 'am', - pm: 'pm', - AM: 'AM', - PM: 'PM', - decimal: '.', - mins: 'mins', - hr: 'hr', - 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) - { - return this.each(function() - { - var self = $(this); - - // pick up settings from data attributes - var attributeOptions = []; - for (var key in _DEFAULTS) { - if (self.data(key)) { - attributeOptions[key] = self.data(key); - } - } - - var settings = $.extend({}, _DEFAULTS, options, attributeOptions); - - if (settings.lang) { - _lang = $.extend(_lang, settings.lang); - } - - settings = _parseSettings(settings); - self.data('timepicker-settings', settings); - self.addClass('ui-timepicker-input'); - - if (settings.useSelect) { - _render(self); - } else { - self.prop('autocomplete', 'off'); - if (settings.showOn) { - for (var i in settings.showOn) { - self.on(settings.showOn[i]+'.timepicker', methods.show); - } - } - self.on('change.timepicker', _formatValue); - self.on('keydown.timepicker', _keydownhandler); - self.on('keyup.timepicker', _keyuphandler); - if (settings.disableTextInput) { - self.on('keydown.timepicker', _disableTextInputHandler); - } - self.on('cut.timepicker', _keyuphandler); - self.on('paste.timepicker', _keyuphandler); - - _formatValue.call(self.get(0), null, 'initial'); - } - }); - }, - - show: function(e) - { - var self = $(this); - var settings = self.data('timepicker-settings'); - - if (e) { - e.preventDefault(); - } - - if (settings.useSelect) { - self.data('timepicker-list').focus(); - return; - } - - if (_hideKeyboard(self)) { - // block the keyboard on mobile devices - self.blur(); - } - - var list = self.data('timepicker-list'); - - // check if input is readonly - if (self.prop('readonly')) { - return; - } - - // check if list needs to be rendered - if (!list || list.length === 0 || typeof settings.durationTime === 'function') { - _render(self); - list = self.data('timepicker-list'); - } - - if (_isVisible(list)) { - return; - } - - self.data('ui-timepicker-value', self.val()); - _setSelected(self, list); - - // make sure other pickers are hidden - methods.hide(); - - // position the dropdown relative to the input - list.show(); - var listOffset = {}; - - if (settings.orientation.match(/r/)) { - // right-align the dropdown - listOffset.left = self.offset().left + self.outerWidth() - list.outerWidth() + parseInt(list.css('marginLeft').replace('px', ''), 10); - } else { - // left-align the dropdown - listOffset.left = self.offset().left + parseInt(list.css('marginLeft').replace('px', ''), 10); - } - - var verticalOrientation; - if (settings.orientation.match(/t/)) { - verticalOrientation = 't'; - } else if (settings.orientation.match(/b/)) { - verticalOrientation = 'b'; - } else if ((self.offset().top + self.outerHeight(true) + list.outerHeight()) > $(window).height() + $(window).scrollTop()) { - verticalOrientation = 't'; - } else { - verticalOrientation = 'b'; - } - - if (verticalOrientation == 't') { - // position the dropdown on top - list.addClass('ui-timepicker-positioned-top'); - listOffset.top = self.offset().top - list.outerHeight() + parseInt(list.css('marginTop').replace('px', ''), 10); - } else { - // put it under the input - list.removeClass('ui-timepicker-positioned-top'); - listOffset.top = self.offset().top + self.outerHeight() + parseInt(list.css('marginTop').replace('px', ''), 10); - } - - list.offset(listOffset); - - // position scrolling - var selected = list.find('.ui-timepicker-selected'); - - if (!selected.length) { - var timeInt = _time2int(_getTimeValue(self)); - if (timeInt !== null) { - selected = _findRow(self, list, timeInt); - } else if (settings.scrollDefault) { - selected = _findRow(self, list, settings.scrollDefault()); - } - } - - // 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); - } else { - list.scrollTop(0); - } - - // prevent scroll propagation - if(settings.stopScrollPropagation) { - $(document).on('wheel.ui-timepicker', '.ui-timepicker-wrapper', function(e){ - e.preventDefault(); - var currentScroll = $(this).scrollTop(); - $(this).scrollTop(currentScroll + e.originalEvent.deltaY); - }); - } - - // attach close handlers - $(document).on('touchstart.ui-timepicker mousedown.ui-timepicker', _closeHandler); - $(window).on('resize.ui-timepicker', _closeHandler); - if (settings.closeOnWindowScroll) { - $(document).on('scroll.ui-timepicker', _closeHandler); - } - - self.trigger('showTimepicker'); - - return this; - }, - - hide: function(e) - { - var self = $(this); - var settings = self.data('timepicker-settings'); - - if (settings && settings.useSelect) { - self.blur(); - } - - $('.ui-timepicker-wrapper').each(function() { - var list = $(this); - if (!_isVisible(list)) { - return; - } - - var self = list.data('timepicker-input'); - var settings = self.data('timepicker-settings'); - - if (settings && settings.selectOnBlur) { - _selectValue(self); - } - - list.hide(); - self.trigger('hideTimepicker'); - }); - - return this; - }, - - option: function(key, value) - { - if (typeof key == 'string' && typeof value == 'undefined') { - return $(this).data('timepicker-settings')[key]; - } - - return this.each(function(){ - var self = $(this); - var settings = self.data('timepicker-settings'); - var list = self.data('timepicker-list'); - - if (typeof key == 'object') { - settings = $.extend(settings, key); - } else if (typeof key == 'string') { - settings[key] = value; - } - - settings = _parseSettings(settings); - - self.data('timepicker-settings', settings); - - _formatValue.call(self.get(0), {'type':'change'}, 'initial'); - - if (list) { - list.remove(); - self.data('timepicker-list', false); - } - - if (settings.useSelect) { - _render(self); - } - }); - }, - - getSecondsFromMidnight: function() - { - return _time2int(_getTimeValue(this)); - }, - - getTime: function(relative_date) - { - var self = this; - - var time_string = _getTimeValue(self); - if (!time_string) { - return null; - } - - var offset = _time2int(time_string); - if (offset === null) { - return null; - } - - if (!relative_date) { - relative_date = new Date(); - } - - // construct a Date from relative date, and offset's time - var time = new Date(relative_date); - time.setHours(offset / 3600); - time.setMinutes(offset % 3600 / 60); - time.setSeconds(offset % 60); - time.setMilliseconds(0); - - return time; - }, - - isVisible: function() { - var self = this; - var list = self.data('timepicker-list'); - return !!(list && _isVisible(list)); - }, - - setTime: function(value) - { - var self = this; - var settings = self.data('timepicker-settings'); - - if (settings.forceRoundTime) { - var prettyTime = _roundAndFormatTime(_time2int(value), settings) - } else { - var prettyTime = _int2time(_time2int(value), settings); - } - - if (value && prettyTime === null && settings.noneOption) { - prettyTime = value; - } - - self.val(prettyTime); - _formatValue.call(self.get(0), {'type':'change'}, 'initial'); - - if (self.data('timepicker-list')) { - _setSelected(self, self.data('timepicker-list')); - } - - return this; - }, - - remove: function() - { - var self = this; - - // check if this element is a timepicker - if (!self.hasClass('ui-timepicker-input')) { - return; - } - - var settings = self.data('timepicker-settings'); - self.removeAttr('autocomplete', 'off'); - self.removeClass('ui-timepicker-input'); - self.removeData('timepicker-settings'); - self.off('.timepicker'); - - // timepicker-list won't be present unless the user has interacted with this timepicker - if (self.data('timepicker-list')) { - self.data('timepicker-list').remove(); - } - - if (settings.useSelect) { - self.show(); - } - - self.removeData('timepicker-list'); - - return this; - } - }; - - // private methods - - function _isVisible(elem) - { - var el = elem[0]; - return el.offsetWidth > 0 && el.offsetHeight > 0; - } - - function _parseSettings(settings) - { - if (settings.minTime) { - settings.minTime = _time2int(settings.minTime); - } - - if (settings.maxTime) { - settings.maxTime = _time2int(settings.maxTime); - } - - if (settings.durationTime && typeof settings.durationTime !== 'function') { - settings.durationTime = _time2int(settings.durationTime); - } - - if (settings.scrollDefault == 'now') { - settings.scrollDefault = function() { - return settings.roundingFunction(_time2int(new Date()), settings); - } - } else if (settings.scrollDefault && typeof settings.scrollDefault != 'function') { - var val = settings.scrollDefault; - settings.scrollDefault = function() { - return settings.roundingFunction(_time2int(val), settings); - } - } else if (settings.minTime) { - settings.scrollDefault = function() { - return settings.roundingFunction(settings.minTime, settings); - } - } - - if ($.type(settings.timeFormat) === "string" && settings.timeFormat.match(/[gh]/)) { - settings._twelveHourTime = true; - } - - if (settings.showOnFocus === false && settings.showOn.indexOf('focus') != -1) { - settings.showOn.splice(settings.showOn.indexOf('focus'), 1); - } - - if (settings.disableTimeRanges.length > 0) { - // convert string times to integers - for (var i in settings.disableTimeRanges) { - settings.disableTimeRanges[i] = [ - _time2int(settings.disableTimeRanges[i][0]), - _time2int(settings.disableTimeRanges[i][1]) - ]; - } - - // sort by starting time - settings.disableTimeRanges = settings.disableTimeRanges.sort(function(a, b){ - return a[0] - b[0]; - }); - - // merge any overlapping ranges - for (var i = settings.disableTimeRanges.length-1; i > 0; i--) { - if (settings.disableTimeRanges[i][0] <= settings.disableTimeRanges[i-1][1]) { - settings.disableTimeRanges[i-1] = [ - Math.min(settings.disableTimeRanges[i][0], settings.disableTimeRanges[i-1][0]), - Math.max(settings.disableTimeRanges[i][1], settings.disableTimeRanges[i-1][1]) - ]; - settings.disableTimeRanges.splice(i, 1); - } - } - } - - return settings; - } - - function _render(self) - { - var settings = self.data('timepicker-settings'); - var list = self.data('timepicker-list'); - - if (list && list.length) { - list.remove(); - self.data('timepicker-list', false); - } - - if (settings.useSelect) { - list = $(' - - - - - - - - diff --git a/web_widget_timepicker/views/web_widget_timepicker_assets.xml b/web_widget_timepicker/views/web_widget_timepicker_assets.xml index a57c169d..a6cf7dd3 100644 --- a/web_widget_timepicker/views/web_widget_timepicker_assets.xml +++ b/web_widget_timepicker/views/web_widget_timepicker_assets.xml @@ -1,18 +1,12 @@ - - - -