@ -0,0 +1,53 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
||||
|
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
================= |
||||
|
Field Time Picker |
||||
|
================= |
||||
|
|
||||
|
Time picker for fields, using Wickedpicker. |
||||
|
|
||||
|
Installation & Configuration |
||||
|
============================ |
||||
|
|
||||
|
After installing the module, you can use character fields for reading time input with the help of a time picker. |
||||
|
When you define the fields in xml, use 'widget="timepicker"' for those fields which you need to use as time fields. |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
License |
||||
|
------- |
||||
|
General Public License, Version 3 (AGPL v3). |
||||
|
(https://www.gnu.org/licenses/agpl-3.0-standalone.html) |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
Developer: (V14) Mruthul Raj, Contact: odoo@cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
Contact odoo@cybrosys.com |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Mruthul Raj <mruthul@cybrosys.info> |
||||
|
|
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
* Website : https://cybrosys.com |
||||
|
|
||||
|
Maintainer |
||||
|
========== |
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://cybrosys.com |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
For support and more information, please visit `Our Website <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,21 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Mruthul Raj (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
@ -0,0 +1,45 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Mruthul Raj (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
{ |
||||
|
'name': 'Field Time Picker', |
||||
|
'version': '14.0.1.0.0', |
||||
|
'category': 'Extra Tools', |
||||
|
'summary': 'We can use the TimePicker widget in Odoo', |
||||
|
'description': 'We Can Add Time Picker Widget That Can Be Used With ' |
||||
|
'Character Type Fields In Odoo', |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': 'https://www.cybrosys.com/', |
||||
|
'depends': ['base'], |
||||
|
'data': [ |
||||
|
'views/web_templates.xml', |
||||
|
], |
||||
|
'qweb': [ |
||||
|
"static/src/xml/timepicker.xml", |
||||
|
], |
||||
|
'images': ['static/description/banner.jpg'], |
||||
|
'license': 'AGPL-3', |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
'application': False, |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
## Module <field_timepicker> |
||||
|
|
||||
|
#### 31.08.2023 |
||||
|
#### Version 14.0.1.0.0 |
||||
|
#### ADD |
||||
|
|
||||
|
- Initial Commit for Field Time Picker |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 8.7 KiB |
@ -0,0 +1,550 @@ |
|||||
|
<div class="container" style="padding: 1rem !important; margin-bottom: 1rem !important;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-12 col-md-12 col-lg-12 d-flex justify-content-between" |
||||
|
style="border-bottom: 1px solid #d5d5d5;"> |
||||
|
<div class="my-3"> |
||||
|
<img src="./assets/icons/logo.png" style="width: auto !important; height: 40px !important;"> |
||||
|
</div> |
||||
|
<div class="my-3 d-flex align-items-center"> |
||||
|
<div |
||||
|
style="background-color: #7C7BAD !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;"> |
||||
|
<i class="fa fa-check mr-1"></i>Community |
||||
|
</div> |
||||
|
<div |
||||
|
style="background-color: #875A7B !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;"> |
||||
|
<i class="fa fa-check mr-1"></i>Enterprise |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="container" style="padding: 0rem 1.5rem 4rem !important"> |
||||
|
<div class="row" style="height: 900px !important;"> |
||||
|
<div class="col-sm-12 col-md-12 col-lg-12" |
||||
|
style="padding: 4rem 1rem !important; background-color: #714B67 !important; height: 600px !important; border-radius: 20px !important;"> |
||||
|
<h1 |
||||
|
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #FFFFFF !important; font-size: 3.5rem !important; text-align: center !important;"> |
||||
|
Field Time Picker</h1> |
||||
|
<p |
||||
|
style="font-family: 'Montserrat', sans-serif !important; font-weight: 300 !important; color: #FFFFFF !important; font-size: 1.4rem !important; text-align: center !important;"> |
||||
|
Add Time Picker Widget That Can Be Used With Character Type Fields In Odoo |
||||
|
</p> |
||||
|
<img src="./assets/screenshots/hero1.png" class="img-responsive" width="100%" height="auto" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="row"> |
||||
|
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin-bottom: 2rem !important"> |
||||
|
<h2 |
||||
|
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;"> |
||||
|
<i class="fa fa-compass mr-2"></i>Explore this module |
||||
|
</h2> |
||||
|
</div> |
||||
|
<div class="col-md-6"> |
||||
|
<a href="#overview" style="text-decoration: none !important;"> |
||||
|
<div class="row" |
||||
|
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;"> |
||||
|
<div class="col-8"> |
||||
|
<h3 |
||||
|
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;"> |
||||
|
Overview</h3> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;"> |
||||
|
Learn more about this module</p> |
||||
|
</div> |
||||
|
<div class="col-4 text-right d-flex justify-content-end align-items-center"> |
||||
|
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i> |
||||
|
</div> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-md-6"> |
||||
|
<a href="#features" style="text-decoration: none !important;"> |
||||
|
<div class="row" |
||||
|
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;"> |
||||
|
<div class="col-8"> |
||||
|
<h3 |
||||
|
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;"> |
||||
|
Features</h3> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;"> |
||||
|
View features of this module</p> |
||||
|
</div> |
||||
|
<div class="col-4 text-right d-flex justify-content-end align-items-center"> |
||||
|
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i> |
||||
|
</div> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-md-6"> |
||||
|
<a href="#screenshots" style="text-decoration: none !important;"> |
||||
|
<div class="row" |
||||
|
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;"> |
||||
|
<div class="col-8"> |
||||
|
<h3 |
||||
|
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;"> |
||||
|
Screenshots</h3> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;"> |
||||
|
See key screenshots of this module</p> |
||||
|
</div> |
||||
|
<div class="col-4 text-right d-flex justify-content-end align-items-center"> |
||||
|
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i> |
||||
|
</div> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="row" id="overview"> |
||||
|
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important"> |
||||
|
<h2 |
||||
|
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;"> |
||||
|
<i class="fa fa-pie-chart mr-2"></i>Overview |
||||
|
</h2> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-mg-12 pl-3"> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important; line-height: 30px !important;"> |
||||
|
The module allows the user to add time picker widget that can be used with character type fields in |
||||
|
Odoo |
||||
|
using the jQuery plugin 'Wickedpicker'. |
||||
|
</p> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="row" id="features"> |
||||
|
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important"> |
||||
|
<h2 |
||||
|
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;"> |
||||
|
<i class="fa fa-star mr-2"></i>Features |
||||
|
</h2> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-md-6 pl-3 d-flex"> |
||||
|
<div> |
||||
|
<img src="assets/icons/check.png"> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4 |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
We can use timepicker widget in Char field</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-md-6 pl-3 d-flex"> |
||||
|
<div> |
||||
|
<img src="assets/icons/check.png"> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4 |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
The timepicker widget is in a 24-hour format</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<div class="row" id="screenshots"> |
||||
|
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important"> |
||||
|
<h2 |
||||
|
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;"> |
||||
|
<i class="fa fa-image mr-2"></i>Screenshots |
||||
|
</h2> |
||||
|
</div> |
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Field Time Picker</h4> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> |
||||
|
Once the widget is linked with the field, you will see a picker for time selection. Note that the |
||||
|
picker will be in 24 hours format. |
||||
|
</p> |
||||
|
<img src="assets/screenshots/time_picker.png" class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- SUGGESTED PRODUCTS --> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center" |
||||
|
style="text-align: center; padding: 2.5rem 1rem !important;"> |
||||
|
<h2 style="color: #212529 !important;">Suggested Products</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" /> |
||||
|
|
||||
|
<div id="demo1" class="row carousel slide" data-ride="carousel"> |
||||
|
<!-- The slideshow --> |
||||
|
<div class="carousel-inner"> |
||||
|
<div class="carousel-item active" style="min-height:0px"> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/employee_orientation/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./assets/modules/1.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/employee_documents_expiry/" |
||||
|
target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./assets/modules/2.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/automatic_payroll/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./assets/modules/3.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="carousel-item" style="min-height:0px"> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/product_return_pos/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./assets/modules/4.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/point_of_sale_logo" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./assets/modules/5.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/invoice_format_editor/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./assets/modules/6.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- Left and right controls --> |
||||
|
<a class="carousel-control-prev" href="#demo1" data-slide="prev" |
||||
|
style="left:-25px;width: 35px;color: #000;"> <span class="carousel-control-prev-icon"><i |
||||
|
class="fa fa-chevron-left" style="font-size:24px"></i></span> </a> <a |
||||
|
class="carousel-control-next" href="#demo1" data-slide="next" |
||||
|
style="right:-25px;width: 35px;color: #000;"> |
||||
|
<span class="carousel-control-next-icon"><i class="fa fa-chevron-right" |
||||
|
style="font-size:24px"></i></span> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- END OF SUGGESTED PRODUCTS --> |
||||
|
|
||||
|
<!-- OUR SERVICES --> |
||||
|
<section class="container" style="margin-top: 6rem !important;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center"> |
||||
|
<h2 style="color: #212529 !important;">Our Services</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" /> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/cogs.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Customization</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/wrench.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Implementation</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/lifebuoy.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Support</h6> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/user.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Hire |
||||
|
Odoo |
||||
|
Developer</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/puzzle.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Integration</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/update.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Migration</h6> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/consultation.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Consultancy</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/training.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Implementation</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/license.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Licensing Consultancy</h6> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<!-- END OF END OF OUR SERVICES --> |
||||
|
|
||||
|
<!-- OUR INDUSTRIES --> |
||||
|
<section class="container" style="margin-top: 6rem !important;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center"> |
||||
|
<h2 style="color: #212529 !important;">Our Industries</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" /> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/trading-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Trading |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Easily procure |
||||
|
and |
||||
|
sell your products</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/pos-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
POS |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Easy |
||||
|
configuration |
||||
|
and convivial experience</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/education-black.png" class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Education |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
A platform for |
||||
|
educational management</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/manufacturing-black.png" class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Manufacturing |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Plan, track and |
||||
|
schedule your operations</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/ecom-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
E-commerce & Website |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Mobile |
||||
|
friendly, |
||||
|
awe-inspiring product pages</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/service-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Service Management |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Keep track of |
||||
|
services and invoice</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/restaurant-black.png" class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Restaurant |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Run your bar or |
||||
|
restaurant methodically</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/hotel-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Hotel Management |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
An |
||||
|
all-inclusive |
||||
|
hotel management application</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<!-- END OF END OF OUR INDUSTRIES --> |
||||
|
|
||||
|
<!-- FOOTER --> |
||||
|
<!-- Footer Section --> |
||||
|
<section class="container" style="margin: 5rem auto 2rem;"> |
||||
|
<div class="row" style="max-width:1540px;"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center"> |
||||
|
<h2 style="color: #212529 !important;">Need Help?</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- Contact Cards --> |
||||
|
<div class="row d-flex justify-content-center align-items-center" |
||||
|
style="max-width:1540px; margin: 0 auto 2rem auto;"> |
||||
|
|
||||
|
<div class="col-lg-12" style="padding: 0rem 3rem 2rem; border-radius: 10px; margin-right: 3rem; "> |
||||
|
|
||||
|
<div class="row mt-4"> |
||||
|
<div class="col-lg-6"> |
||||
|
<a href="mailto:odoo@cybrosys.com" target="_blank" class="btn btn-block mb-2 deep_hover" |
||||
|
style="text-decoration: none; background-color: #4d4d4d; color: #FFF; border-radius: 4px;"><i |
||||
|
class="fa fa-envelope mr-2"></i>odoo@cybrosys.com</a> |
||||
|
</div> |
||||
|
<div class="col-lg-6"> |
||||
|
<a href="https://api.whatsapp.com/send?phone=918606827707" target="_blank" |
||||
|
class="btn btn-block mb-2 deep_hover" |
||||
|
style="text-decoration: none; background-color: #25D366; color: #FFF; border-radius: 4px;"><i |
||||
|
class="fa fa-whatsapp mr-2"></i>WhatsApp</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
<!-- End of Contact Cards --> |
||||
|
</section> |
||||
|
<!-- Footer --> |
||||
|
<section class="oe_container" style="padding: 2rem 3rem 1rem;"> |
||||
|
<div class="row" style="max-width:1540px; margin: 0 auto; margin-right: 3rem; "> |
||||
|
<!-- Logo --> |
||||
|
<div class="col-lg-12 d-flex justify-content-center align-items-center" style="margin-top: 3rem;"> |
||||
|
<img src="https://www.cybrosys.com/images/logo.png" width="200px" height="auto" /> |
||||
|
</div> |
||||
|
<!-- End of Logo --> |
||||
|
<div class="col-lg-12"> |
||||
|
<hr |
||||
|
style="margin-top: 3rem;background: linear-gradient(90deg, rgba(2,0,36,0) 0%, rgba(229,229,229,1) 33%, rgba(229,229,229,1) 58%, rgba(0,212,255,0) 100%); height: 2px; border-style: none;"> |
||||
|
<!-- End of Footer Section --> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<!-- END OF FOOTER --> |
||||
|
|
||||
|
</div> |
@ -0,0 +1,83 @@ |
|||||
|
odoo.define('field_timepicker.timepicker', function(require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
var basic_fields = require('web.basic_fields'); |
||||
|
var field_registry = require('web.field_registry'); |
||||
|
var global_show_time = null; |
||||
|
var FieldChar = require('web.basic_fields').FieldChar; |
||||
|
var Dialog = require('web.Dialog'); |
||||
|
|
||||
|
/** |
||||
|
* Custom field for time selection. |
||||
|
*/ |
||||
|
var FieldTimePicker = FieldChar.extend({ |
||||
|
template: 'FieldTimePicker', |
||||
|
widget_class: 'oe_form_field_time', |
||||
|
|
||||
|
/** |
||||
|
* Renders the field in read-only mode. |
||||
|
*/ |
||||
|
_renderReadonly: function() { |
||||
|
var show_value = this._formatValue(this.value); |
||||
|
this.$el.text(show_value); |
||||
|
global_show_time = show_value; |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Gets the current value of the field. |
||||
|
* |
||||
|
* @returns {string} The field value. |
||||
|
*/ |
||||
|
_getValue: function() { |
||||
|
var $input = this.$el.find('input'); |
||||
|
return $input.val(); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Renders the field in edit mode. |
||||
|
*/ |
||||
|
_renderEdit: function() { |
||||
|
this._super.apply(this, arguments); |
||||
|
var show_value = this._formatValue(this.value); |
||||
|
this.$el.find('input')[0].value=show_value; |
||||
|
var self = this; |
||||
|
this.$el.on('click', '.timepickerg', function() { |
||||
|
self._onClickTimePicker(); |
||||
|
}); |
||||
|
/** |
||||
|
* Call the click function. |
||||
|
*/ |
||||
|
setTimeout(function() { |
||||
|
self._onClickTimePicker(); |
||||
|
}, 50); |
||||
|
}, |
||||
|
_onClickTimePicker: function() { |
||||
|
/** |
||||
|
* Function to be executed when the "timepicker" class is clicked. |
||||
|
* It renders the field as an editable timepicker widget if the formatType is "char". |
||||
|
*/ |
||||
|
if (this.formatType === "char") { |
||||
|
var $input = this.$el.find('input'); |
||||
|
var options = { |
||||
|
twentyFour: true, |
||||
|
title: 'Timepicker', |
||||
|
showSeconds: true, |
||||
|
}; |
||||
|
if (global_show_time) { |
||||
|
options['now'] = global_show_time; |
||||
|
} |
||||
|
$input.wickedpicker(options); |
||||
|
} else { |
||||
|
Dialog.alert(this, "Timepicker widget only works with 'Char' field type"); |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
// Register the FieldTimePicker in the field registry
|
||||
|
field_registry.add('timepicker', FieldTimePicker); |
||||
|
|
||||
|
return { |
||||
|
FieldTimePicker: FieldTimePicker |
||||
|
}; |
||||
|
}); |
@ -0,0 +1,21 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!--Template for timepicker--> |
||||
|
<templates id="timepicker"> |
||||
|
<t t-name="FieldTimePicker"> |
||||
|
<span t-if="widget.mode !== 'readonly'"> |
||||
|
<div class="input-group timepicker-component"> |
||||
|
<input type="text" |
||||
|
t-att-id="widget.id_for_label" |
||||
|
t-att-tabindex="widget.attrs.tabindex" |
||||
|
t-att-autofocus="widget.attrs.autofocus" |
||||
|
t-att-placeholder="widget.attrs.placeholder" |
||||
|
t-att-maxlength="widget.field.size" |
||||
|
class="timepickerg form-control" |
||||
|
/> |
||||
|
<span class="input-group-addon" style="display:none;"> |
||||
|
</span> |
||||
|
</div> |
||||
|
</span> |
||||
|
<span t-if="widget.mode === 'readonly'"/> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,11 @@ |
|||||
|
.sass-cache |
||||
|
*.html |
||||
|
jquery-1.11.3.min.js |
||||
|
.idea |
||||
|
sass |
||||
|
jasmine |
||||
|
spec |
||||
|
node_modules |
||||
|
node_module/* |
||||
|
gulpfile.js |
||||
|
package.json |
@ -0,0 +1,21 @@ |
|||||
|
The MIT License |
||||
|
|
||||
|
Copyright (c) 2015-2016 Eric Gagnon http://ericjgagnon.github.io/wickedpicker/ |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
@ -0,0 +1,79 @@ |
|||||
|
# Wickedpicker |
||||
|
|
||||
|
## wickedpicker.js - A simple jQuery timepicker |
||||
|
|
||||
|
## Requirements |
||||
|
|
||||
|
* [jQuery](http://jquery.com/download/) (>= 1.9) |
||||
|
|
||||
|
## Installation |
||||
|
```shell |
||||
|
$ bower install wickedpicker |
||||
|
``` |
||||
|
|
||||
|
## Usage |
||||
|
|
||||
|
#### In your HTML |
||||
|
```html |
||||
|
<body> |
||||
|
.... |
||||
|
<input type="text" name="timepicker" class="timepicker"/> |
||||
|
.... |
||||
|
<script type="text/javascript" src="jquery-1.11.3.min.js"></script> |
||||
|
<script type="text/javascript" src="wickedpicker.js"></script> |
||||
|
</body> |
||||
|
``` |
||||
|
|
||||
|
#### In your JavaScript file |
||||
|
```javascript |
||||
|
$('.timepicker').wickedpicker(); |
||||
|
``` |
||||
|
|
||||
|
#### Options |
||||
|
```javascript |
||||
|
var options = { |
||||
|
now: "12:35", //hh:mm 24 hour format only, defaults to current time |
||||
|
twentyFour: false, //Display 24 hour format, defaults to false |
||||
|
upArrow: 'wickedpicker__controls__control-up', //The up arrow class selector to use, for custom CSS |
||||
|
downArrow: 'wickedpicker__controls__control-down', //The down arrow class selector to use, for custom CSS |
||||
|
close: 'wickedpicker__close', //The close class selector to use, for custom CSS |
||||
|
hoverState: 'hover-state', //The hover state class to use, for custom CSS |
||||
|
title: 'Timepicker', //The Wickedpicker's title, |
||||
|
showSeconds: false, //Whether or not to show seconds, |
||||
|
timeSeparator: ' : ', // The string to put in between hours and minutes (and seconds) |
||||
|
secondsInterval: 1, //Change interval for seconds, defaults to 1, |
||||
|
minutesInterval: 1, //Change interval for minutes, defaults to 1 |
||||
|
beforeShow: null, //A function to be called before the Wickedpicker is shown |
||||
|
afterShow: null, //A function to be called after the Wickedpicker is closed/hidden |
||||
|
show: null, //A function to be called when the Wickedpicker is shown |
||||
|
clearable: false, //Make the picker's input clearable (has clickable "x") |
||||
|
}; |
||||
|
$('.timepicker').wickedpicker(options); |
||||
|
``` |
||||
|
|
||||
|
#### Methods |
||||
|
|
||||
|
'time' get the current time inside of the input element that has a wickedpicker attached to it. |
||||
|
```javascript |
||||
|
$('.timepicker').wickedpicker('time'); |
||||
|
``` |
||||
|
|
||||
|
If multiple input fields have the same class and instantiate a wickedpicker then pass the index of the timepicker |
||||
|
you'd like to select |
||||
|
```javascript |
||||
|
$('.timepicker').wickedpicker('time', 0); |
||||
|
``` |
||||
|
|
||||
|
#### Functionality |
||||
|
The Wickedpicker opens when the bound input is clicked, or focused on (try tabbing), and it can be closed by either |
||||
|
clicking the X, by clicking outside of it, or by pressing esc. The arrows icons increase or decrease their |
||||
|
associated time values or toggle the meridiem. The values can also be changed using the up and down keys when |
||||
|
focused on. To move to the next value just press the left or right arrow key. |
||||
|
|
||||
|
For more checkout |
||||
|
[Wickedpicker gh-pages](http://ericjgagnon.github.io/wickedpicker/) |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
Copyright (c) 2015-2016 Eric Gagnon Licensed under the MIT license. |
||||
|
|
@ -0,0 +1,29 @@ |
|||||
|
{ |
||||
|
"name": "wickedpicker", |
||||
|
"version": "0.0.4", |
||||
|
"description": "A simple jQuery timepicker plugin.", |
||||
|
"main": [ |
||||
|
"./dist/wickedpicker.min.js", |
||||
|
"./dist/wickedpicker.min.css" |
||||
|
], |
||||
|
"authors": [ |
||||
|
"Eric Gagnon", |
||||
|
"Ruben Seyferth" |
||||
|
], |
||||
|
"moduleType": "globals", |
||||
|
"license": "MIT", |
||||
|
"keywords": [ |
||||
|
"jQuery", |
||||
|
"timepicker", |
||||
|
"wickedpicker" |
||||
|
], |
||||
|
"homepage": "http://ericjgagnon.github.io/wickedpicker/", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git://github.com/ericjgagnon/wickedpicker.git" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"jquery": ">= 1.9.0" |
||||
|
}, |
||||
|
"private": false |
||||
|
} |
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,624 @@ |
|||||
|
/** |
||||
|
* wickedpicker v0.4.1 - A simple jQuery timepicker. |
||||
|
* Copyright (c) 2015-2016 Eric Gagnon - http://github.com/wickedRidge/wickedpicker
|
||||
|
* License: MIT |
||||
|
*/ |
||||
|
|
||||
|
(function ($, window, document) { |
||||
|
|
||||
|
"use strict"; |
||||
|
|
||||
|
if (typeof String.prototype.endsWith != 'function') { |
||||
|
/* |
||||
|
* Checks if this string end ends with another string |
||||
|
* |
||||
|
* @param {string} the string to be checked |
||||
|
* |
||||
|
* @return {bool} |
||||
|
*/ |
||||
|
String.prototype.endsWith = function (string) { |
||||
|
return string.length > 0 && this.substring(this.length - string.length, this.length) === string; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* Returns if the user agent is mobile |
||||
|
* |
||||
|
* @return {bool} |
||||
|
*/ |
||||
|
var isMobile = function () { |
||||
|
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); |
||||
|
}; |
||||
|
|
||||
|
var today = new Date(); |
||||
|
|
||||
|
var pluginName = "wickedpicker", |
||||
|
defaults = { |
||||
|
now: today.getHours() + ':' + today.getMinutes(), |
||||
|
twentyFour: false, |
||||
|
upArrow: 'wickedpicker__controls__control-up', |
||||
|
downArrow: 'wickedpicker__controls__control-down', |
||||
|
close: 'wickedpicker__close', |
||||
|
hoverState: 'hover-state', |
||||
|
title: 'Timepicker', |
||||
|
showSeconds: false, |
||||
|
timeSeparator: ' : ', |
||||
|
secondsInterval: 1, |
||||
|
minutesInterval: 1, |
||||
|
beforeShow: null, |
||||
|
afterShow: null, |
||||
|
show: null, |
||||
|
clearable: false, |
||||
|
closeOnClickOutside: true, |
||||
|
onClickOutside: function() {}, |
||||
|
}; |
||||
|
|
||||
|
/* |
||||
|
* @param {object} The input object the timepicker is attached to. |
||||
|
* @param {object} The object containing options |
||||
|
*/ |
||||
|
function Wickedpicker(element, options) { |
||||
|
this.element = $(element); |
||||
|
this.options = $.extend({}, defaults, options); |
||||
|
|
||||
|
this.element.addClass('hasWickedpicker'); |
||||
|
this.element.attr('onkeypress', 'return false;'); |
||||
|
this.element.attr('aria-showingpicker', 'false'); |
||||
|
this.createPicker(); |
||||
|
this.timepicker = $('.wickedpicker'); |
||||
|
this.up = $('.' + this.options.upArrow.split(/\s+/).join('.')); |
||||
|
this.down = $('.' + this.options.downArrow.split(/\s+/).join('.')); |
||||
|
this.separator = $('.wickedpicker__controls__control--separator'); |
||||
|
this.hoursElem = $('.wickedpicker__controls__control--hours'); |
||||
|
this.minutesElem = $('.wickedpicker__controls__control--minutes'); |
||||
|
this.secondsElem = $('.wickedpicker__controls__control--seconds'); |
||||
|
this.meridiemElem = $('.wickedpicker__controls__control--meridiem'); |
||||
|
this.close = $('.' + this.options.close.split(/\s+/).join('.')); |
||||
|
|
||||
|
//Create a new Date object based on the default or passing in now value
|
||||
|
var time = this.timeArrayFromString(this.options.now); |
||||
|
this.options.now = new Date(today.getFullYear(), today.getMonth(), today.getDate(), time[0], time[1], time[2]); |
||||
|
this.selectedHour = this.parseHours(this.options.now.getHours()); |
||||
|
this.selectedMin = this.parseSecMin(this.options.now.getMinutes()); |
||||
|
this.selectedSec = this.parseSecMin(this.options.now.getSeconds()); |
||||
|
this.selectedMeridiem = this.parseMeridiem(this.options.now.getHours()); |
||||
|
this.setHoverState(); |
||||
|
this.attach(element); |
||||
|
this.setText(element); |
||||
|
} |
||||
|
|
||||
|
$.extend(Wickedpicker.prototype, { |
||||
|
|
||||
|
/* |
||||
|
* Show given input's timepicker |
||||
|
* |
||||
|
* @param {object} The input being clicked |
||||
|
*/ |
||||
|
showPicker: function (element) { |
||||
|
//If there is a beforeShow function, then call it with the input calling the timepicker and the
|
||||
|
// timepicker itself
|
||||
|
if (typeof this.options.beforeShow === 'function') { |
||||
|
this.options.beforeShow(element, this.timepicker); |
||||
|
} |
||||
|
var timepickerPos = $(element).offset(); |
||||
|
|
||||
|
$(element).attr({'aria-showingpicker': 'true', 'tabindex': -1}); |
||||
|
this.setText(element); |
||||
|
this.showHideMeridiemControl(); |
||||
|
if (this.getText(element) !== this.getTime()) { |
||||
|
|
||||
|
// Check meridiem
|
||||
|
var text = this.getText(element); |
||||
|
var re = /\s[ap]m$/i; |
||||
|
var meridiem = re.test(text) ? text.substr(-2, 2) : null; |
||||
|
var inputTime = text.replace(re, '').split(this.options.timeSeparator); |
||||
|
var newTime = {}; |
||||
|
newTime.hours = inputTime[0]; |
||||
|
newTime.minutes = inputTime[1]; |
||||
|
newTime.meridiem = meridiem; |
||||
|
if (this.options.showSeconds) { |
||||
|
newTime.seconds = inputTime[2]; |
||||
|
} |
||||
|
this.setTime(newTime); |
||||
|
} |
||||
|
this.timepicker.css({ |
||||
|
'z-index': this.element.css('z-index') + 1, |
||||
|
position: 'absolute', |
||||
|
left: timepickerPos.left, |
||||
|
top: timepickerPos.top + $(element)[0].offsetHeight |
||||
|
}).show(); |
||||
|
//If there is a show function, then call it with the input calling the timepicker and the
|
||||
|
// timepicker itself
|
||||
|
if (typeof this.options.show === 'function') { |
||||
|
this.options.show(element, this.timepicker); |
||||
|
} |
||||
|
|
||||
|
this.handleTimeAdjustments(element); |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Hides the timepicker that is currently shown if it is not part of the timepicker |
||||
|
* |
||||
|
* @param {Object} The DOM object being clicked on the page |
||||
|
* |
||||
|
* BeinnLora: added trigger function to call on closing/hiding timepicker. |
||||
|
*/ |
||||
|
hideTimepicker: function (element) { |
||||
|
this.timepicker.hide(); |
||||
|
if (typeof this.options.afterShow === 'function') { |
||||
|
this.options.afterShow(element, this.timepicker); |
||||
|
} |
||||
|
var pickerHidden = { |
||||
|
start: function () { |
||||
|
var setShowPickerFalse = $.Deferred(); |
||||
|
$('[aria-showingpicker="true"]').attr('aria-showingpicker', 'false'); |
||||
|
return setShowPickerFalse.promise(); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
function setTabIndex(index) { |
||||
|
setTimeout(function () { |
||||
|
$('[aria-showingpicker="false"]').attr('tabindex', index); |
||||
|
}, 400); |
||||
|
} |
||||
|
|
||||
|
pickerHidden.start().then(setTabIndex(0)); |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Create a new timepicker. A single timepicker per page |
||||
|
*/ |
||||
|
createPicker: function () { |
||||
|
if ($('.wickedpicker').length === 0) { |
||||
|
var picker = '<div class="wickedpicker"><p class="wickedpicker__title">' + this.options.title + '<span class="wickedpicker__close"></span></p><ul class="wickedpicker__controls"><li class="wickedpicker__controls__control"><span class="' + this.options.upArrow + '"></span><span class="wickedpicker__controls__control--hours" tabindex="-1">00</span><span class="' + this.options.downArrow + '"></span></li><li class="wickedpicker__controls__control--separator"><span class="wickedpicker__controls__control--separator-inner">:</span></li><li class="wickedpicker__controls__control"><span class="' + this.options.upArrow + '"></span><span class="wickedpicker__controls__control--minutes" tabindex="-1">00</span><span class="' + this.options.downArrow + '"></span></li>'; |
||||
|
if (this.options.showSeconds) { |
||||
|
picker += '<li class="wickedpicker__controls__control--separator"><span class="wickedpicker__controls__control--separator-inner">:</span></li><li class="wickedpicker__controls__control"><span class="' + this.options.upArrow + '"></span><span class="wickedpicker__controls__control--seconds" tabindex="-1">00</span><span class="' + this.options.downArrow + '"></span> </li>'; |
||||
|
} |
||||
|
picker += '<li class="wickedpicker__controls__control"><span class="' + this.options.upArrow + '"></span><span class="wickedpicker__controls__control--meridiem" tabindex="-1">AM</span><span class="' + this.options.downArrow + '"></span></li></ul></div>'; |
||||
|
$('body').append(picker); |
||||
|
this.attachKeyboardEvents(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Hides the meridiem control if this timepicker is a 24 hour clock |
||||
|
*/ |
||||
|
showHideMeridiemControl: function () { |
||||
|
if (this.options.twentyFour === false) { |
||||
|
$(this.meridiemElem).parent().show(); |
||||
|
} |
||||
|
else { |
||||
|
$(this.meridiemElem).parent().hide(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Hides the seconds control if this timepicker has showSeconds set to true |
||||
|
*/ |
||||
|
showHideSecondsControl: function () { |
||||
|
if (this.options.showSeconds) { |
||||
|
$(this.secondsElem).parent().show(); |
||||
|
} |
||||
|
else { |
||||
|
$(this.secondsElem).parent().hide(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Bind the click events to the input |
||||
|
* |
||||
|
* @param {object} The input element |
||||
|
*/ |
||||
|
attach: function (element) { |
||||
|
var self = this; |
||||
|
|
||||
|
if (this.options.clearable) { |
||||
|
self.makePickerInputClearable(element); |
||||
|
} |
||||
|
|
||||
|
$(element).attr('tabindex', 0); |
||||
|
$(element).on('click focus', function (event) { |
||||
|
//Prevent multiple firings
|
||||
|
if ($(self.timepicker).is(':hidden')) { |
||||
|
self.showPicker($(this)); |
||||
|
window.lastTimePickerControl = $(this); //Put the reference on this timepicker into global scope for unsing that in afterShow function
|
||||
|
$(self.hoursElem).focus(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
//Handle click events for closing Wickedpicker
|
||||
|
var clickHandler = function (event) { //TODO: Fix double firing
|
||||
|
//Only fire the hide event when you have to
|
||||
|
if ($(self.timepicker).is(':visible')) { |
||||
|
//Clicking the X
|
||||
|
if ($(event.target).is(self.close)) { |
||||
|
self.hideTimepicker(window.lastTimePickerControl); |
||||
|
} else if ($(event.target).closest(self.timepicker).length || $(event.target).closest($('.hasWickedpicker')).length) { //Clicking the Wickedpicker or one of it's inputs
|
||||
|
event.stopPropagation(); |
||||
|
} else { //Everything else
|
||||
|
if (typeof self.options.onClickOutside === 'function') { |
||||
|
self.options.onClickOutside(); |
||||
|
} |
||||
|
else { |
||||
|
console.warn("Type of onClickOutside must be a function"); |
||||
|
} |
||||
|
|
||||
|
if (!self.options.closeOnClickOutside) { |
||||
|
return; |
||||
|
} |
||||
|
self.hideTimepicker(window.lastTimePickerControl); |
||||
|
} |
||||
|
window.lastTimePickerControl = null; |
||||
|
} |
||||
|
}; |
||||
|
$(document).off('click', clickHandler).on('click', clickHandler); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Added keyboard functionality to improve usabil |
||||
|
*/ |
||||
|
attachKeyboardEvents: function () { |
||||
|
$(document).on('keydown', $.proxy(function (event) { |
||||
|
switch (event.keyCode) { |
||||
|
case 9: |
||||
|
if (event.target.className !== 'hasWickedpicker') { |
||||
|
$(this.close).trigger('click'); |
||||
|
} |
||||
|
break; |
||||
|
case 27: |
||||
|
$(this.close).trigger('click'); |
||||
|
break; |
||||
|
case 37: //Left arrow
|
||||
|
if (event.target.className !== this.hoursElem[0].className) { |
||||
|
$(event.target).parent().prevAll('li').not(this.separator.selector).first().children()[1].focus(); |
||||
|
} else { |
||||
|
$(event.target).parent().siblings(':last').children()[1].focus(); |
||||
|
} |
||||
|
break; |
||||
|
case 39: //Right arrow
|
||||
|
if (event.target.className !== this.meridiemElem[0].className) { |
||||
|
$(event.target).parent().nextAll('li').not(this.separator.selector).first().children()[1].focus(); |
||||
|
} else { |
||||
|
$(event.target).parent().siblings(':first').children()[1].focus(); |
||||
|
} |
||||
|
break; |
||||
|
case 38: //Up arrow
|
||||
|
$(':focus').prev().trigger('click'); |
||||
|
break; |
||||
|
case 40: //Down arrow
|
||||
|
$(':focus').next().trigger('click'); |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
}, this)); |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Set the time on the timepicker |
||||
|
* |
||||
|
* @param {object} The date being set |
||||
|
*/ |
||||
|
setTime: function (time) { |
||||
|
this.setHours(time.hours); |
||||
|
this.setMinutes(time.minutes); |
||||
|
this.setMeridiem(time.meridiem); |
||||
|
if (this.options.showSeconds) { |
||||
|
this.setSeconds(time.seconds); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Get the time from the timepicker |
||||
|
*/ |
||||
|
getTime: function () { |
||||
|
return [this.formatTime(this.getHours(), this.getMinutes(), this.getMeridiem(), this.getSeconds())]; |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Set the timpicker's hour(s) value |
||||
|
* |
||||
|
* @param {string} hours |
||||
|
*/ |
||||
|
setHours: function (hours) { |
||||
|
var hour = new Date(); |
||||
|
hour.setHours(hours); |
||||
|
var hoursText = this.parseHours(hour.getHours()); |
||||
|
this.hoursElem.text(hoursText); |
||||
|
this.selectedHour = hoursText; |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Get the hour(s) value from the timepicker |
||||
|
* |
||||
|
* @return {integer} |
||||
|
*/ |
||||
|
getHours: function () { |
||||
|
var hours = new Date(); |
||||
|
hours.setHours(this.hoursElem.text()); |
||||
|
return hours.getHours(); |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Returns the correct hour value based on the type of clock, 12 or 24 hour |
||||
|
* |
||||
|
* @param {integer} The hours value before parsing |
||||
|
* |
||||
|
* @return {string|integer} |
||||
|
*/ |
||||
|
parseHours: function (hours) { |
||||
|
return (this.options.twentyFour === false) ? ((hours + 11) % 12) + 1 : (hours < 10) ? '0' + hours : hours; |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Sets the timpicker's minutes value |
||||
|
* |
||||
|
* @param {string} minutes |
||||
|
*/ |
||||
|
setMinutes: function (minutes) { |
||||
|
var minute = new Date(); |
||||
|
minute.setMinutes(minutes); |
||||
|
var minutesText = minute.getMinutes(); |
||||
|
var min = this.parseSecMin(minutesText); |
||||
|
this.minutesElem.text(min); |
||||
|
this.selectedMin = min; |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Get the minutes value from the timepicker |
||||
|
* |
||||
|
* @return {integer} |
||||
|
*/ |
||||
|
getMinutes: function () { |
||||
|
var minutes = new Date(); |
||||
|
minutes.setMinutes(this.minutesElem.text()); |
||||
|
return minutes.getMinutes(); |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
/* |
||||
|
* Return a human-readable minutes/seconds value |
||||
|
* |
||||
|
* @param {string} value seconds or minutes |
||||
|
* |
||||
|
* @return {string|integer} |
||||
|
*/ |
||||
|
parseSecMin: function (value) { |
||||
|
return ((value < 10) ? '0' : '') + value; |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Set the timepicker's meridiem value, AM or PM |
||||
|
* |
||||
|
* @param {string} The new meridiem |
||||
|
*/ |
||||
|
setMeridiem: function (inputMeridiem) { |
||||
|
var newMeridiem = ''; |
||||
|
if (inputMeridiem === undefined) { |
||||
|
var meridiem = this.getMeridiem(); |
||||
|
newMeridiem = (meridiem === 'PM') ? 'AM' : 'PM'; |
||||
|
} else { |
||||
|
newMeridiem = inputMeridiem; |
||||
|
} |
||||
|
this.meridiemElem.text(newMeridiem); |
||||
|
this.selectedMeridiem = newMeridiem; |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Get the timepicker's meridiem value, AM or PM |
||||
|
* |
||||
|
* @return {string} |
||||
|
*/ |
||||
|
getMeridiem: function () { |
||||
|
return this.meridiemElem.text(); |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Set the timepicker's seconds value |
||||
|
* |
||||
|
* @param {string} seconds |
||||
|
*/ |
||||
|
setSeconds: function (seconds) { |
||||
|
var second = new Date(); |
||||
|
second.setSeconds(seconds); |
||||
|
var secondsText = second.getSeconds(); |
||||
|
var sec = this.parseSecMin(secondsText); |
||||
|
this.secondsElem.text(sec); |
||||
|
this.selectedSec = sec; |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Get the timepicker's seconds value |
||||
|
* |
||||
|
* return {string} |
||||
|
*/ |
||||
|
getSeconds: function () { |
||||
|
var seconds = new Date(); |
||||
|
seconds.setSeconds(this.secondsElem.text()); |
||||
|
return seconds.getSeconds(); |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Get the correct meridiem based on the hours given |
||||
|
* |
||||
|
* @param {string|integer} hours |
||||
|
* |
||||
|
* @return {string} |
||||
|
*/ |
||||
|
parseMeridiem: function (hours) { |
||||
|
return (hours > 11) ? 'PM' : 'AM'; |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Handles time incrementing and decrementing and passes |
||||
|
* the operator, '+' or '-', the input to be set after the change |
||||
|
* and the current arrow clicked, to decipher if hours, ninutes, or meridiem. |
||||
|
* |
||||
|
* @param {object} The input element |
||||
|
*/ |
||||
|
handleTimeAdjustments: function (element) { |
||||
|
var timeOut = 0; |
||||
|
//Click and click and hold timepicker incrementer and decrementer
|
||||
|
$(this.up).add(this.down).off('mousedown click touchstart').on('mousedown click', { |
||||
|
'Wickedpicker': this, |
||||
|
'input': element |
||||
|
}, function (event) { |
||||
|
if(event.which!=1) return false; |
||||
|
var operator = (this.className.indexOf('up') > -1) ? '+' : '-'; |
||||
|
var passedData = event.data; |
||||
|
if (event.type == 'mousedown') { |
||||
|
timeOut = setInterval($.proxy(function (args) { |
||||
|
args.Wickedpicker.changeValue(operator, args.input, this); |
||||
|
}, this, {'Wickedpicker': passedData.Wickedpicker, 'input': passedData.input}), 200); |
||||
|
} else { |
||||
|
passedData.Wickedpicker.changeValue(operator, passedData.input, this); |
||||
|
} |
||||
|
}).bind('mouseup touchend', function () { |
||||
|
clearInterval(timeOut); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Change the timepicker's time base on what is clicked |
||||
|
* |
||||
|
* @param {string} The + or - operator |
||||
|
* @param {object} The timepicker's associated input to be set post change |
||||
|
* @param {object} The DOM arrow object clicked, determines if it is hours, |
||||
|
* minutes, or meridiem base on the operator and its siblings |
||||
|
*/ |
||||
|
changeValue: function (operator, input, clicked) { |
||||
|
var target = (operator === '+') ? clicked.nextSibling : clicked.previousSibling; |
||||
|
var targetClass = $(target).attr('class'); |
||||
|
if (targetClass.endsWith('hours')) { |
||||
|
this.setHours(eval(this.getHours() + operator + 1)); |
||||
|
} else if (targetClass.endsWith('minutes')) { |
||||
|
this.setMinutes(eval(this.getMinutes() + operator + this.options.minutesInterval)); |
||||
|
} else if (targetClass.endsWith('seconds')) { |
||||
|
this.setSeconds(eval(this.getSeconds() + operator + this.options.secondsInterval)); |
||||
|
} else { |
||||
|
this.setMeridiem(); |
||||
|
} |
||||
|
this.setText(input); |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
/* |
||||
|
* Sets the give input's text to the current timepicker's time |
||||
|
* |
||||
|
* @param {object} The input element |
||||
|
*/ |
||||
|
setText: function (input) { |
||||
|
$(input).val(this.formatTime(this.selectedHour, this.selectedMin, this.selectedMeridiem, this.selectedSec)).change(); |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Get the given input's value |
||||
|
* |
||||
|
* @param {object} The input element |
||||
|
* |
||||
|
* @return {string} |
||||
|
*/ |
||||
|
getText: function (input) { |
||||
|
return $(input).val(); |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Returns the correct time format as a string |
||||
|
* |
||||
|
* @param {string} hour |
||||
|
* @param {string} minutes |
||||
|
* @param {string} meridiem |
||||
|
* |
||||
|
* @return {string} |
||||
|
*/ |
||||
|
formatTime: function (hour, min, meridiem, seconds) { |
||||
|
var formattedTime = hour + this.options.timeSeparator + min; |
||||
|
if (this.options.showSeconds) { |
||||
|
formattedTime += this.options.timeSeparator + seconds; |
||||
|
} |
||||
|
if (this.options.twentyFour === false) { |
||||
|
formattedTime += ' ' + meridiem; |
||||
|
} |
||||
|
return formattedTime; |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Apply the hover class to the arrows and close icon fonts |
||||
|
*/ |
||||
|
setHoverState: function () { |
||||
|
var self = this; |
||||
|
if (!isMobile()) { |
||||
|
$(this.up).add(this.down).add(this.close).hover(function () { |
||||
|
$(this).toggleClass(self.options.hoverState); |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Wrapping the given input field with the clearable container |
||||
|
* , add a span that will contain the x, and bind the clear |
||||
|
* input event to the span |
||||
|
* |
||||
|
* @param input |
||||
|
*/ |
||||
|
makePickerInputClearable: function(input) { |
||||
|
$(input).wrap('<div class="clearable-picker"></div>').after('<span data-clear-picker>×</span>'); |
||||
|
|
||||
|
//When the x is clicked, clear its sibling input field
|
||||
|
$('[data-clear-picker]').on('click', function(event) { |
||||
|
$(this).siblings('.hasWickedpicker').val(''); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Convert the options time string format |
||||
|
* to an array |
||||
|
* |
||||
|
* returns => [hours, minutes, seconds] |
||||
|
* |
||||
|
* @param stringTime |
||||
|
* @returns {*} |
||||
|
*/ |
||||
|
timeArrayFromString: function (stringTime) { |
||||
|
if (stringTime.length) { |
||||
|
var time = stringTime.split(':'); |
||||
|
time[2] = (time.length < 3) ? '00' : time[2]; |
||||
|
return time; |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
|
||||
|
//public functions
|
||||
|
/* |
||||
|
* Returns the requested input element's value |
||||
|
*/ |
||||
|
_time: function () { |
||||
|
var inputValue = $(this.element).val(); |
||||
|
return (inputValue === '') ? this.formatTime(this.selectedHour, this.selectedMin, this.selectedMeridiem, this.selectedSec) : inputValue; |
||||
|
}, |
||||
|
_hide: function() { |
||||
|
this.hideTimepicker(this.element); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
//optional index if multiple inputs share the same class
|
||||
|
$.fn[pluginName] = function (options, index) { |
||||
|
if (!$.isFunction(Wickedpicker.prototype['_' + options])) { |
||||
|
return this.each(function () { |
||||
|
if (!$.data(this, "plugin_" + pluginName)) { |
||||
|
$.data(this, "plugin_" + pluginName, new Wickedpicker(this, options)); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
else if ($(this).hasClass('hasWickedpicker')) { |
||||
|
if (index !== undefined) { |
||||
|
return $.data($(this)[index], 'plugin_' + pluginName)['_' + options](); |
||||
|
} |
||||
|
else { |
||||
|
return $.data($(this)[0], 'plugin_' + pluginName)['_' + options](); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
})(jQuery, window, document); |
@ -0,0 +1,90 @@ |
|||||
|
.wickedpicker { |
||||
|
-webkit-user-select: none; |
||||
|
-moz-user-select: none; |
||||
|
-ms-user-select: none; |
||||
|
user-select: none; |
||||
|
box-shadow: 0 0 0 1px rgba(14, 41, 57, 0.12), 0 2px 5px rgba(14, 41, 57, 0.44), inset 0 -1px 2px rgba(14, 41, 57, 0.15); |
||||
|
background: #fefefe; |
||||
|
margin: 0 auto; |
||||
|
border-radius: 0.1px; |
||||
|
width: 270px; |
||||
|
height: 130px; |
||||
|
font-size: 14px; |
||||
|
display: none; } |
||||
|
.wickedpicker__title { |
||||
|
background-image: -webkit-linear-gradient(top, #ffffff 0%, #f2f2f2 100%); |
||||
|
background-image: linear-gradient(to bottom, #ffffff 0%, #f2f2f2 100%); |
||||
|
position: relative; |
||||
|
background: #f2f2f2; |
||||
|
margin: 0 auto; |
||||
|
border-bottom: 1px solid #e5e5e5; |
||||
|
padding: 12px 11px 10px 15px; |
||||
|
color: #4C4C4C; |
||||
|
font-size: inherit; } |
||||
|
.wickedpicker__close { |
||||
|
-webkit-transform: translateY(-25%); |
||||
|
-moz-transform: translateY(-25%); |
||||
|
-ms-transform: translateY(-25%); |
||||
|
-o-transform: translateY(-25%); |
||||
|
transform: translateY(-25%); |
||||
|
position: absolute; |
||||
|
top: 25%; |
||||
|
right: 10px; |
||||
|
color: #34495e; |
||||
|
cursor: pointer; } |
||||
|
.wickedpicker__close:before { |
||||
|
content: '\00d7'; } |
||||
|
.wickedpicker__controls { |
||||
|
padding: 10px 0; |
||||
|
line-height: normal; |
||||
|
margin: 0; } |
||||
|
.wickedpicker__controls__control, .wickedpicker__controls__control--separator { |
||||
|
vertical-align: middle; |
||||
|
display: inline-block; |
||||
|
font-size: inherit; |
||||
|
margin: 0 auto; |
||||
|
width: 35px; |
||||
|
letter-spacing: 1.3px; } |
||||
|
.wickedpicker__controls__control-up, .wickedpicker__controls__control-down { |
||||
|
color: #34495e; |
||||
|
position: relative; |
||||
|
display: block; |
||||
|
margin: 3px auto; |
||||
|
font-size: 18px; |
||||
|
cursor: pointer; } |
||||
|
.wickedpicker__controls__control-up:before { |
||||
|
content: '\e800'; } |
||||
|
.wickedpicker__controls__control-down:after { |
||||
|
content: '\e801'; } |
||||
|
.wickedpicker__controls__control--separator { |
||||
|
width: 5px; } |
||||
|
|
||||
|
.text-center, .wickedpicker__title, .wickedpicker__controls, .wickedpicker__controls__control, .wickedpicker__controls__control--separator, .wickedpicker__controls__control-up, .wickedpicker__controls__control-down { |
||||
|
text-align: center; } |
||||
|
|
||||
|
.hover-state { |
||||
|
color: #3498db; } |
||||
|
|
||||
|
@font-face { |
||||
|
font-family: 'fontello'; |
||||
|
src: url("../fonts/fontello.eot?52602240"); |
||||
|
src: url("../fonts/fontello.eot?52602240#iefix") format("embedded-opentype"), url("../fonts/fontello.woff?52602240") format("woff"), url("../fonts/fontello.ttf?52602240") format("truetype"), url("../fonts/fontello.svg?52602240#fontello") format("svg"); |
||||
|
font-weight: normal; |
||||
|
font-style: normal; } |
||||
|
|
||||
|
.fontello:before, .wickedpicker__controls__control-up:before, .fontello-after:after, .wickedpicker__controls__control-down:after { |
||||
|
font-family: 'fontello'; |
||||
|
font-style: normal; |
||||
|
font-weight: normal; |
||||
|
speak: none; |
||||
|
display: inline-block; |
||||
|
text-decoration: inherit; |
||||
|
width: 1em; |
||||
|
margin-right: .2em; |
||||
|
text-align: center; |
||||
|
font-variant: normal; |
||||
|
text-transform: none; |
||||
|
line-height: 1em; |
||||
|
margin-left: .2em; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; } |
@ -0,0 +1,17 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<!-- This XML code is part of an Odoo module's manifest file and is used to enhance the web interface--> |
||||
|
<!-- of the Odoo application by adding custom assets for a time picker widget.--> |
||||
|
<template id="asset_backend" inherit_id="web.assets_backend"> |
||||
|
<xpath expr="." position="inside"> |
||||
|
<link href='/field_timepicker/static/wickedpicker/dist/wickedpicker.min.css' |
||||
|
rel='stylesheet'/> |
||||
|
<script type="text/javascript" |
||||
|
src='/field_timepicker/static/wickedpicker/dist/wickedpicker.min.js'/> |
||||
|
<script type="text/javascript" |
||||
|
src='/field_timepicker/static/wickedpicker/src/wickedpicker.js'/> |
||||
|
<script type="text/javascript" |
||||
|
src='/field_timepicker/static/src/js/time_widget.js'/> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
</odoo> |