slash_admin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +95 -0
  3. data/app/assets/config/relax_admin_manifest.js +2 -0
  4. data/app/assets/images/slash_admin/en.png +0 -0
  5. data/app/assets/images/slash_admin/favicon.png +0 -0
  6. data/app/assets/images/slash_admin/fr.png +0 -0
  7. data/app/assets/javascripts/slash_admin/application.js +344 -0
  8. data/app/assets/javascripts/slash_admin/custom.js +0 -0
  9. data/app/assets/stylesheets/slash_admin/alert.scss +29 -0
  10. data/app/assets/stylesheets/slash_admin/application.scss +1469 -0
  11. data/app/assets/stylesheets/slash_admin/colors.scss +17 -0
  12. data/app/assets/stylesheets/slash_admin/custom.scss +0 -0
  13. data/app/controllers/slash_admin/application_controller.rb +17 -0
  14. data/app/controllers/slash_admin/base_controller.rb +45 -0
  15. data/app/controllers/slash_admin/batch_actions_controller.rb +17 -0
  16. data/app/controllers/slash_admin/dashboard_controller.rb +11 -0
  17. data/app/controllers/slash_admin/models_controller.rb +325 -0
  18. data/app/controllers/slash_admin/security/sessions_controller.rb +29 -0
  19. data/app/controllers/slash_admin/selectize_controller.rb +49 -0
  20. data/app/helpers/slash_admin/application_helper.rb +212 -0
  21. data/app/helpers/slash_admin/menu_helper.rb +14 -0
  22. data/app/helpers/slash_admin/widgets_helper.rb +7 -0
  23. data/app/jobs/slash_admin/application_job.rb +4 -0
  24. data/app/mailers/slash_admin/application_mailer.rb +6 -0
  25. data/app/models/slash_admin/admin.rb +46 -0
  26. data/app/models/slash_admin/admin_ability.rb +11 -0
  27. data/app/models/slash_admin/application_record.rb +5 -0
  28. data/app/views/layouts/slash_admin/admin_user.html.erb +16 -0
  29. data/app/views/layouts/slash_admin/application.html.erb +40 -0
  30. data/app/views/slash_admin/base/_data_belongs_to.html.erb +37 -0
  31. data/app/views/slash_admin/base/_data_list.html.erb +276 -0
  32. data/app/views/slash_admin/base/_data_nestable.html.erb +33 -0
  33. data/app/views/slash_admin/base/_data_new.html.erb +16 -0
  34. data/app/views/slash_admin/base/_data_show.html.erb +72 -0
  35. data/app/views/slash_admin/base/_filters.html.erb +60 -0
  36. data/app/views/slash_admin/base/_translatable_fields.html.erb +23 -0
  37. data/app/views/slash_admin/base/edit.html.erb +26 -0
  38. data/app/views/slash_admin/base/index.html.erb +47 -0
  39. data/app/views/slash_admin/base/index.xls.erb +27 -0
  40. data/app/views/slash_admin/base/nestable.html.erb +28 -0
  41. data/app/views/slash_admin/base/new.html.erb +26 -0
  42. data/app/views/slash_admin/base/show.html.erb +22 -0
  43. data/app/views/slash_admin/custom_fields/_color.html.erb +2 -0
  44. data/app/views/slash_admin/custom_fields/_email.html.erb +2 -0
  45. data/app/views/slash_admin/custom_fields/_google_map.html.erb +72 -0
  46. data/app/views/slash_admin/custom_fields/_nested_belongs_to.html.erb +55 -0
  47. data/app/views/slash_admin/custom_fields/_password.html.erb +2 -0
  48. data/app/views/slash_admin/custom_fields/_select.html.erb +2 -0
  49. data/app/views/slash_admin/custom_fields/_tags.html.erb +2 -0
  50. data/app/views/slash_admin/custom_fields/_wysiwyg.html.erb +2 -0
  51. data/app/views/slash_admin/dashboard/home.html.erb +5 -0
  52. data/app/views/slash_admin/dashboard/widgets/_statistic_chart.html.erb +0 -0
  53. data/app/views/slash_admin/dashboard/widgets/_statistic_progress_tile.html.erb +29 -0
  54. data/app/views/slash_admin/fields/_belongs_to.html.erb +9 -0
  55. data/app/views/slash_admin/fields/_boolean.html.erb +2 -0
  56. data/app/views/slash_admin/fields/_carrierwave.html.erb +15 -0
  57. data/app/views/slash_admin/fields/_date.html.erb +2 -0
  58. data/app/views/slash_admin/fields/_decimal.html.erb +2 -0
  59. data/app/views/slash_admin/fields/_form_group.html.erb +12 -0
  60. data/app/views/slash_admin/fields/_has_many.html.erb +12 -0
  61. data/app/views/slash_admin/fields/_has_many_row.html.erb +18 -0
  62. data/app/views/slash_admin/fields/_has_one.html.erb +24 -0
  63. data/app/views/slash_admin/fields/_integer.html.erb +2 -0
  64. data/app/views/slash_admin/fields/_json.html.erb +14 -0
  65. data/app/views/slash_admin/fields/_nested_has_many.html.erb +14 -0
  66. data/app/views/slash_admin/fields/_number.html.erb +2 -0
  67. data/app/views/slash_admin/fields/_string.html.erb +2 -0
  68. data/app/views/slash_admin/fields/_text.html.erb +2 -0
  69. data/app/views/slash_admin/security/sessions/new.html.erb +30 -0
  70. data/app/views/slash_admin/shared/_batch_actions.html.erb +21 -0
  71. data/app/views/slash_admin/shared/_better_paginate.html.erb +30 -0
  72. data/app/views/slash_admin/shared/_breadcrumb.html.erb +30 -0
  73. data/app/views/slash_admin/shared/_debug.html.erb +24 -0
  74. data/app/views/slash_admin/shared/_errors_data_new.html.erb +12 -0
  75. data/app/views/slash_admin/shared/_header.html.erb +38 -0
  76. data/app/views/slash_admin/shared/_menu.html.erb +57 -0
  77. data/app/views/slash_admin/shared/_new_form_buttons.html.erb +9 -0
  78. data/app/views/slash_admin/shared/_sub_header.html.erb +11 -0
  79. data/config/initializers/validators.rb +13 -0
  80. data/config/locales/slash_admin.en.yml +67 -0
  81. data/config/locales/slash_admin.fr.yml +72 -0
  82. data/config/routes.rb +16 -0
  83. data/db/migrate/20170512104248_create_slash_admin_admins.rb +19 -0
  84. data/lib/batch_translation.rb +19 -0
  85. data/lib/generators/slash_admin/controllers/controllers_generator.rb +16 -0
  86. data/lib/generators/slash_admin/controllers/templates/controllers.erb +9 -0
  87. data/lib/generators/slash_admin/install/install_generator.rb +13 -0
  88. data/lib/generators/slash_admin/install/templates/install.erb +14 -0
  89. data/lib/generators/slash_admin/override_admin/override_admin_generator.rb +13 -0
  90. data/lib/generators/slash_admin/override_admin/templates/admin.erb +46 -0
  91. data/lib/generators/slash_admin/override_session/override_session_generator.rb +13 -0
  92. data/lib/generators/slash_admin/override_session/templates/session.erb +27 -0
  93. data/lib/generators/slash_admin/permissions/permissions_generator.rb +13 -0
  94. data/lib/generators/slash_admin/permissions/templates/permissions.erb +11 -0
  95. data/lib/slash_admin.rb +29 -0
  96. data/lib/slash_admin/engine.rb +8 -0
  97. data/lib/slash_admin/version.rb +3 -0
  98. data/lib/tasks/slash_admin_tasks.rake +4 -0
  99. data/vendor/assets/javascripts/bootstrap-material-datetimepicker.js +1295 -0
  100. data/vendor/assets/javascripts/codemirror/codemirror.js +9657 -0
  101. data/vendor/assets/javascripts/codemirror/lint/json-lint.js +37 -0
  102. data/vendor/assets/javascripts/codemirror/lint/jsonlint.js +432 -0
  103. data/vendor/assets/javascripts/codemirror/lint/lint.js +252 -0
  104. data/vendor/assets/javascripts/codemirror/mode/javascript.js +865 -0
  105. data/vendor/assets/javascripts/jquery.nestable.js +910 -0
  106. data/vendor/assets/javascripts/jquery.tagsinput-revisited.min.js +5 -0
  107. data/vendor/assets/javascripts/toastr.js +6 -0
  108. data/vendor/assets/stylesheets/animate.css +1579 -0
  109. data/vendor/assets/stylesheets/bootstrap-material-datetimepicker.css +82 -0
  110. data/vendor/assets/stylesheets/codemirror/codemirror.css +346 -0
  111. data/vendor/assets/stylesheets/codemirror/lint/lint.css +73 -0
  112. data/vendor/assets/stylesheets/codemirror/theme/relax-seti.css +41 -0
  113. data/vendor/assets/stylesheets/jquery.nestable.css +121 -0
  114. data/vendor/assets/stylesheets/jquery.tagsinput-revisited.min.css +1 -0
  115. data/vendor/assets/stylesheets/sweetalert.css +935 -0
  116. data/vendor/assets/stylesheets/toastr.css +1 -0
  117. metadata +509 -0
@@ -0,0 +1,72 @@
1
+ fr:
2
+ slash_admin:
3
+ controller:
4
+ create:
5
+ success: "%{model_name} créé(e)."
6
+ error: "Erreur lors de la création d'un(e) %{model_name}"
7
+ update:
8
+ success: "%{model_name} mis(e) à jour."
9
+ error: "Erreur lors de la mise à jour d'un(e) %{model_name}"
10
+ delete:
11
+ success: "%{model_name} supprimé(e)."
12
+ nestable:
13
+ error: Impossible de trier '%{model_name}'
14
+ success: Opération réussi.
15
+ view:
16
+ administration: Administration
17
+ home: Accueil
18
+ welcome: Vous permet d'administrer votre application
19
+ login: 'SE CONNECTER'
20
+ create: "Création d'un(e) %{model_name}"
21
+ create_success: "%{model_name} créé(e) avec succès"
22
+ add: "Ajouter un(e) %{model_name}"
23
+ cancel: Annuler
24
+ save: Enregistrer
25
+ delete: Supprimer
26
+ new: Nouveau
27
+ edit: "Édition: %{model_name}"
28
+ show: "Affichage: %{model_name}"
29
+ see: Voir
30
+ tools: Outils
31
+ order: Trier
32
+ erase: Effacer
33
+ ordering: "Trier les %{model_name}"
34
+ export_xls: Export XLS
35
+ export_csv: Export CSV
36
+ save_and_return_html: Enregistrer & Retourner à la liste
37
+ save_and_add_html: Enregistrer & Ajouter un nouveau
38
+ actions: Actions
39
+ batch_actions: Actions groupées
40
+ total_of: Total de
41
+ of: sur
42
+ result_found: résultats trouvé(s)
43
+ show_by: Voir par
44
+ be_careful: Vous ne serez pas capable de revenir en arrière.
45
+ selected_elements: élément(s) sélectionné(s)
46
+ page: Page
47
+ yes: Oui
48
+ no: Non
49
+ filter: Filtrer
50
+ reset: Réinitialiser
51
+ select_model: "Sélectionner un(e) %{model_name}"
52
+ list: "Liste des %{model_name}"
53
+ return_to_list: Retour à la liste
54
+ no_image: Aucune Image
55
+ close: Fermer
56
+ associations: Associations
57
+ no_associations: Pas d'associations
58
+ translations: Traductions
59
+ add_tag: Ajouter un tag
60
+ confirm: Êtes-vous sûr ?
61
+ no_back: Vous ne serez pas capable de revenir en arrière
62
+ yes_delete: Oui, supprimer
63
+ enable_javascript_html: '
64
+ Pour accéder à toutes les fonctionnalités de ce site, vous devez activer JavaScript.
65
+ Voici les <a href="http://www.enable-javascript.com/fr/" target="_blank">
66
+ instructions pour activer JavaScript dans votre navigateur Web</a>.'
67
+ administration_login: Administration - Login
68
+ json_not_valid: Le JSON n'est pas valide
69
+ username: Nom d'utilisateur
70
+ password: Mot de passe
71
+ sessions:
72
+ login_required: Vous devez êtres connecté pour accéder à cette page.
@@ -0,0 +1,16 @@
1
+ SlashAdmin::Engine.routes.draw do
2
+ scope :admin do
3
+ get '/' => 'dashboard#home', as: 'dashboard'
4
+ get 'login' => 'security/sessions#new'
5
+ post 'login', to: 'security/sessions#create'
6
+ get 'logout' => 'security/sessions#destroy'
7
+ get 'dashboard/toggle' => 'dashboard#toggle', as: 'toggle_dashboard'
8
+
9
+ get 'search' => 'selectize#search', as: 'remote_selectize'
10
+
11
+ # Batch actions
12
+
13
+ # DELETE
14
+ post 'batch_actions/delete/:model_class', to: 'batch_actions#delete', as: 'batch_delete'
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ class CreateSlashAdminAdmins < ActiveRecord::Migration[5.0]
3
+ def change
4
+ create_table :slash_admin_admins do |t|
5
+ ## Database authenticatable
6
+ t.string :username, null: false, default: ''
7
+ t.string :email, null: false, default: ''
8
+ t.string :password_digest, null: false, default: ''
9
+ t.string :avatar
10
+ t.string :roles
11
+
12
+ ## Recoverable
13
+ t.string :reset_password_token
14
+ t.datetime :reset_password_sent_at
15
+
16
+ t.timestamps null: false
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # Do not forget to set accepts_nested_attributes_for :translations in the translated model.
2
+
3
+ module ActionView
4
+ module Helpers
5
+ class FormBuilder
6
+ def globalize_fields_for(locale, *args, &proc)
7
+ raise ArgumentError, 'Missing block' unless block_given?
8
+ options = args.extract_options!
9
+ @index = @index ? @index + 1 : 1
10
+ object_name = "#{@object_name}[translations_attributes][#{@index}]"
11
+ form_object = @object || @object_name.to_s.camelize.constantize.new
12
+ object = form_object.translations.select{ |t| t.locale.to_s == locale.to_s }.first
13
+ @template.concat @template.hidden_field_tag("#{object_name}[id]", object ? object.id : '')
14
+ @template.concat @template.hidden_field_tag("#{object_name}[locale]", locale)
15
+ @template.fields_for(object_name, object, options, &proc)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ module SlashAdmin
3
+ module Generators
4
+ class ControllersGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+ argument :model, required: true,
7
+ desc: 'The model concerned'
8
+
9
+ def create_controller
10
+ @model_name = model.camelize
11
+ template 'controllers.erb',
12
+ "app/controllers/slash_admin/models/#{model}_controller.rb"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ module SlashAdmin
2
+ module Models
3
+ class <%= @model_name %>Controller < SlashAdmin::ModelsController
4
+ def list_params
5
+ []
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ module SlashAdmin
3
+ module Generators
4
+ class InstallGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def install
8
+ template 'install.erb',
9
+ 'app/helpers/slash_admin/menu_helper.rb'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ module SlashAdmin
3
+ module MenuHelper
4
+ def menu_entries
5
+ [
6
+ {
7
+ title: 'Dashboard',
8
+ path: slash_admin.dashboard_path,
9
+ icon: 'icon-home',
10
+ },
11
+ ]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ module SlashAdmin
3
+ module Generators
4
+ class OverrideAdminGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def override_admin
8
+ template 'admin.erb',
9
+ 'app/models/slash_admin/admin.rb'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+ module SlashAdmin
3
+ class Admin < ApplicationRecord
4
+ include CanCan::Ability
5
+
6
+ has_secure_password
7
+
8
+ attr_accessor :login
9
+
10
+ EMAIL_REGEX = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i
11
+ USERNAME_REGEX = /^[a-zA-Z0-9_\.]*$/
12
+ validates :username, presence: true, uniqueness: true, length: {in: 3..20}
13
+ validates :email, presence: true, uniqueness: true
14
+ validates_length_of :password, in: 6..20, on: :create
15
+ validates_format_of :email, with: EMAIL_REGEX, multiline: true
16
+ validates_format_of :username, with: USERNAME_REGEX, multiline: true
17
+
18
+ before_create :handle_default_role
19
+
20
+ serialize :roles, JSON
21
+
22
+ def has_role?(role)
23
+ if roles.blank?
24
+ false
25
+ else
26
+ roles.include?(role)
27
+ end
28
+ end
29
+
30
+ def handle_default_role
31
+ self.roles = 'superadmin' unless roles.present?
32
+ end
33
+
34
+ def login=(login)
35
+ @login = login
36
+ end
37
+
38
+ def login
39
+ @login || self.username || self.email
40
+ end
41
+
42
+ def identicon
43
+ RubyIdenticon.create_base64(email, grid_size: 5, border_size: 150, square_size: 50, background_color: 0xf0f0f0ff)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ module SlashAdmin
3
+ module Generators
4
+ class OverrideSessionGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def override_session
8
+ template 'session.erb',
9
+ 'app/controllers/slash_admin/security/sessions_controller.rb'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+ module SlashAdmin
3
+ class Security::SessionsController < ActionController::Base
4
+ layout 'slash_admin/admin_user'
5
+
6
+ def new
7
+ end
8
+
9
+ def create
10
+ admin = Admin.where('username = :value OR lower(email) = lower(:value)', value: params[:admin][:login]).first
11
+ if admin&.authenticate(params[:admin][:password])
12
+ session[:admin_id] = admin.id
13
+ flash[:notice] = 'Vous êtes à présent connecté.'
14
+ redirect_to slash_admin.dashboard_path
15
+ else
16
+ @error_messages = 'Merci de vérifier vos identifiants'
17
+ render :new and return
18
+ end
19
+ end
20
+
21
+ def destroy
22
+ session[:admin_id] = nil
23
+ flash[:notice] = 'Déconnecté avec succès.'
24
+ redirect_to slash_admin.login_url
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ module SlashAdmin
3
+ module Generators
4
+ class PermissionsGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def create_permissions
8
+ template 'permissions.erb',
9
+ 'app/models/slash_admin/admin_ability.rb'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ module SlashAdmin
3
+ class AdminAbility
4
+ include CanCan::Ability
5
+
6
+ def initialize(user)
7
+ @user = user
8
+ can :manage, :all
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ require 'slash_admin/engine'
3
+ require 'cancancan'
4
+ require 'kaminari'
5
+ require 'groupdate'
6
+ require 'ruby_identicon'
7
+ require 'bcrypt'
8
+ require 'chartkick'
9
+ require 'chart-js-rails'
10
+ require 'highcharts-rails'
11
+ require 'selectize-rails'
12
+ require 'font-awesome-rails'
13
+ require 'js-routes'
14
+ require 'i18n-js'
15
+ require 'bootstrap'
16
+ require 'cocoon'
17
+ require 'datetime_picker_rails'
18
+ require 'jquery-rails'
19
+ require 'bootstrap-datepicker-rails'
20
+ require 'jquery-minicolors-rails'
21
+ require 'momentjs-rails'
22
+ require 'sass-rails'
23
+ require 'tether-rails'
24
+ require 'sweetalert-rails'
25
+ require 'http_accept_language'
26
+ require 'batch_translation'
27
+
28
+ module SlashAdmin
29
+ end
@@ -0,0 +1,8 @@
1
+ module SlashAdmin
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace SlashAdmin
4
+ config.to_prepare do
5
+ Rails.application.config.assets.precompile += %w( slash_admin/* )
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ module SlashAdmin
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :slash_admin do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,1295 @@
1
+ (function ($, moment)
2
+ {
3
+ var pluginName = "bootstrapMaterialDatePicker";
4
+ var pluginDataName = "plugin_" + pluginName;
5
+
6
+ moment.locale('en');
7
+
8
+ function Plugin(element, options)
9
+ {
10
+ this.currentView = 0;
11
+
12
+ this.minDate;
13
+ this.maxDate;
14
+
15
+ this._attachedEvents = [];
16
+
17
+ this.element = element;
18
+ this.$element = $(element);
19
+
20
+
21
+ this.params = {date: true, time: true, format: 'YYYY-MM-DD', minDate: null, maxDate: null, currentDate: null, lang: 'en', weekStart: 0, disabledDays: [], shortTime: false, clearButton: false, nowButton: false, cancelText: 'Cancel', okText: 'OK', clearText: 'Clear', nowText: 'Now', switchOnClick: false, triggerEvent: 'focus', monthPicker: false, year:true};
22
+ this.params = $.fn.extend(this.params, options);
23
+
24
+ this.name = "dtp_" + this.setName();
25
+ this.$element.attr("data-dtp", this.name);
26
+
27
+ moment.locale(this.params.lang);
28
+
29
+ this.init();
30
+ }
31
+
32
+ $.fn[pluginName] = function (options, p)
33
+ {
34
+ this.each(function ()
35
+ {
36
+ if (!$.data(this, pluginDataName))
37
+ {
38
+ $.data(this, pluginDataName, new Plugin(this, options));
39
+ } else
40
+ {
41
+ if (typeof ($.data(this, pluginDataName)[options]) === 'function')
42
+ {
43
+ $.data(this, pluginDataName)[options](p);
44
+ }
45
+ if (options === 'destroy')
46
+ {
47
+ delete $.data(this, pluginDataName);
48
+ }
49
+ }
50
+ });
51
+ return this;
52
+ };
53
+
54
+ Plugin.prototype =
55
+ {
56
+ init: function ()
57
+ {
58
+ this.initDays();
59
+ this.initDates();
60
+
61
+ this.initTemplate();
62
+
63
+ this.initButtons();
64
+
65
+ this._attachEvent($(window), 'resize', this._centerBox.bind(this));
66
+ this._attachEvent(this.$dtpElement.find('.dtp-content'), 'click', this._onElementClick.bind(this));
67
+ this._attachEvent(this.$dtpElement, 'click', this._onBackgroundClick.bind(this));
68
+ this._attachEvent(this.$dtpElement.find('.dtp-close > a'), 'click', this._onCloseClick.bind(this));
69
+ this._attachEvent(this.$element, this.params.triggerEvent, this._fireCalendar.bind(this));
70
+ },
71
+ initDays: function ()
72
+ {
73
+ this.days = [];
74
+ for (var i = this.params.weekStart; this.days.length < 7; i++)
75
+ {
76
+ if (i > 6)
77
+ {
78
+ i = 0;
79
+ }
80
+ this.days.push(i.toString());
81
+ }
82
+ },
83
+ initDates: function ()
84
+ {
85
+ if (this.$element.val().length > 0)
86
+ {
87
+ if (typeof (this.params.format) !== 'undefined' && this.params.format !== null)
88
+ {
89
+ this.currentDate = moment(this.$element.val(), this.params.format).locale(this.params.lang);
90
+ } else
91
+ {
92
+ this.currentDate = moment(this.$element.val()).locale(this.params.lang);
93
+ }
94
+ } else
95
+ {
96
+ if (typeof (this.$element.attr('value')) !== 'undefined' && this.$element.attr('value') !== null && this.$element.attr('value') !== "")
97
+ {
98
+ if (typeof (this.$element.attr('value')) === 'string')
99
+ {
100
+ if (typeof (this.params.format) !== 'undefined' && this.params.format !== null)
101
+ {
102
+ this.currentDate = moment(this.$element.attr('value'), this.params.format).locale(this.params.lang);
103
+ } else
104
+ {
105
+ this.currentDate = moment(this.$element.attr('value')).locale(this.params.lang);
106
+ }
107
+ }
108
+ } else
109
+ {
110
+ if (typeof (this.params.currentDate) !== 'undefined' && this.params.currentDate !== null)
111
+ {
112
+ if (typeof (this.params.currentDate) === 'string')
113
+ {
114
+ if (typeof (this.params.format) !== 'undefined' && this.params.format !== null)
115
+ {
116
+ this.currentDate = moment(this.params.currentDate, this.params.format).locale(this.params.lang);
117
+ } else
118
+ {
119
+ this.currentDate = moment(this.params.currentDate).locale(this.params.lang);
120
+ }
121
+ } else
122
+ {
123
+ if (typeof (this.params.currentDate.isValid) === 'undefined' || typeof (this.params.currentDate.isValid) !== 'function')
124
+ {
125
+ var x = this.params.currentDate.getTime();
126
+ this.currentDate = moment(x, "x").locale(this.params.lang);
127
+ } else
128
+ {
129
+ this.currentDate = this.params.currentDate;
130
+ }
131
+ }
132
+ this.$element.val(this.currentDate.format(this.params.format));
133
+ } else
134
+ this.currentDate = moment();
135
+ }
136
+ }
137
+
138
+ if (typeof (this.params.minDate) !== 'undefined' && this.params.minDate !== null)
139
+ {
140
+ if (typeof (this.params.minDate) === 'string')
141
+ {
142
+ if (typeof (this.params.format) !== 'undefined' && this.params.format !== null)
143
+ {
144
+ this.minDate = moment(this.params.minDate, this.params.format).locale(this.params.lang);
145
+ } else
146
+ {
147
+ this.minDate = moment(this.params.minDate).locale(this.params.lang);
148
+ }
149
+ } else
150
+ {
151
+ if (typeof (this.params.minDate.isValid) === 'undefined' || typeof (this.params.minDate.isValid) !== 'function')
152
+ {
153
+ var x = this.params.minDate.getTime();
154
+ this.minDate = moment(x, "x").locale(this.params.lang);
155
+ } else
156
+ {
157
+ this.minDate = this.params.minDate;
158
+ }
159
+ }
160
+ } else if (this.params.minDate === null)
161
+ {
162
+ this.minDate = null;
163
+ }
164
+
165
+ if (typeof (this.params.maxDate) !== 'undefined' && this.params.maxDate !== null)
166
+ {
167
+ if (typeof (this.params.maxDate) === 'string')
168
+ {
169
+ if (typeof (this.params.format) !== 'undefined' && this.params.format !== null)
170
+ {
171
+ this.maxDate = moment(this.params.maxDate, this.params.format).locale(this.params.lang);
172
+ } else
173
+ {
174
+ this.maxDate = moment(this.params.maxDate).locale(this.params.lang);
175
+ }
176
+ } else
177
+ {
178
+ if (typeof (this.params.maxDate.isValid) === 'undefined' || typeof (this.params.maxDate.isValid) !== 'function')
179
+ {
180
+ var x = this.params.maxDate.getTime();
181
+ this.maxDate = moment(x, "x").locale(this.params.lang);
182
+ } else
183
+ {
184
+ this.maxDate = this.params.maxDate;
185
+ }
186
+ }
187
+ } else if (this.params.maxDate === null)
188
+ {
189
+ this.maxDate = null;
190
+ }
191
+
192
+ if (!this.isAfterMinDate(this.currentDate))
193
+ {
194
+ this.currentDate = moment(this.minDate);
195
+ }
196
+ if (!this.isBeforeMaxDate(this.currentDate))
197
+ {
198
+ this.currentDate = moment(this.maxDate);
199
+ }
200
+ },
201
+ initTemplate: function ()
202
+ {
203
+ var yearPicker = "";
204
+ var y =this.currentDate.year();
205
+ for (var i = y-3; i < y + 4; i++) {
206
+ yearPicker += '<div class="year-picker-item" data-year="' + i + '">' + i + '</div>';
207
+ }
208
+ this.midYear=y;
209
+ var yearHtml =
210
+ '<div class="dtp-picker-year hidden" >' +
211
+ '<div><a href="javascript:void(0);" class="btn btn-default dtp-select-year-range before" style="margin: 0;"><i class="material-icons">keyboard_arrow_up</i></a></div>' +
212
+ yearPicker +
213
+ '<div><a href="javascript:void(0);" class="btn btn-default dtp-select-year-range after" style="margin: 0;"><i class="material-icons">keyboard_arrow_down</i></a></div>' +
214
+ '</div>';
215
+
216
+ this.template = '<div class="dtp hidden" id="' + this.name + '">' +
217
+ '<div class="dtp-content">' +
218
+ '<div class="dtp-date-view">' +
219
+ '<header class="dtp-header">' +
220
+ '<div class="dtp-actual-day">Lundi</div>' +
221
+ '<div class="dtp-close"><a href="javascript:void(0);"><i class="material-icons">clear</i></a></div>' +
222
+ '</header>' +
223
+ '<div class="dtp-date hidden">' +
224
+ '<div>' +
225
+ '<div class="left center p10">' +
226
+ '<a href="javascript:void(0);" class="dtp-select-month-before"><i class="material-icons">chevron_left</i></a>' +
227
+ '</div>' +
228
+ '<div class="dtp-actual-month p80">MAR</div>' +
229
+ '<div class="right center p10">' +
230
+ '<a href="javascript:void(0);" class="dtp-select-month-after"><i class="material-icons">chevron_right</i></a>' +
231
+ '</div>' +
232
+ '<div class="clearfix"></div>' +
233
+ '</div>' +
234
+ '<div class="dtp-actual-num">13</div>' +
235
+ '<div>' +
236
+ '<div class="left center p10">' +
237
+ '<a href="javascript:void(0);" class="dtp-select-year-before"><i class="material-icons">chevron_left</i></a>' +
238
+ '</div>' +
239
+ '<div class="dtp-actual-year p80'+(this.params.year?"":" disabled")+'">2014</div>' +
240
+ '<div class="right center p10">' +
241
+ '<a href="javascript:void(0);" class="dtp-select-year-after"><i class="material-icons">chevron_right</i></a>' +
242
+ '</div>' +
243
+ '<div class="clearfix"></div>' +
244
+ '</div>' +
245
+ '</div>' +
246
+ '<div class="dtp-time hidden">' +
247
+ '<div class="dtp-actual-maxtime">23:55</div>' +
248
+ '</div>' +
249
+ '<div class="dtp-picker">' +
250
+ '<div class="dtp-picker-calendar"></div>' +
251
+ '<div class="dtp-picker-datetime hidden">' +
252
+ '<div class="dtp-actual-meridien">' +
253
+ '<div class="left p20">' +
254
+ '<a class="dtp-meridien-am" href="javascript:void(0);">AM</a>' +
255
+ '</div>' +
256
+ '<div class="dtp-actual-time p60"></div>' +
257
+ '<div class="right p20">' +
258
+ '<a class="dtp-meridien-pm" href="javascript:void(0);">PM</a>' +
259
+ '</div>' +
260
+ '<div class="clearfix"></div>' +
261
+ '</div>' +
262
+ '<div id="dtp-svg-clock">' +
263
+ '</div>' +
264
+ '</div>' +
265
+ yearHtml+
266
+ '</div>' +
267
+ '</div>' +
268
+ '<div class="dtp-buttons">' +
269
+ '<button class="dtp-btn-now btn btn-flat hidden">' + this.params.nowText + '</button>' +
270
+ '<button class="dtp-btn-clear btn btn-flat hidden">' + this.params.clearText + '</button>' +
271
+ '<button class="dtp-btn-cancel btn btn-flat">' + this.params.cancelText + '</button>' +
272
+ '<button class="dtp-btn-ok btn btn-flat">' + this.params.okText + '</button>' +
273
+ '<div class="clearfix"></div>' +
274
+ '</div>' +
275
+ '</div>' +
276
+ '</div>';
277
+
278
+ if ($('body').find("#" + this.name).length <= 0)
279
+ {
280
+ $('body').append(this.template);
281
+
282
+ if (this)
283
+ this.dtpElement = $('body').find("#" + this.name);
284
+ this.$dtpElement = $(this.dtpElement);
285
+ }
286
+ },
287
+ initButtons: function ()
288
+ {
289
+ this._attachEvent(this.$dtpElement.find('.dtp-btn-cancel'), 'click', this._onCancelClick.bind(this));
290
+ this._attachEvent(this.$dtpElement.find('.dtp-btn-ok'), 'click', this._onOKClick.bind(this));
291
+ this._attachEvent(this.$dtpElement.find('a.dtp-select-month-before'), 'click', this._onMonthBeforeClick.bind(this));
292
+ this._attachEvent(this.$dtpElement.find('a.dtp-select-month-after'), 'click', this._onMonthAfterClick.bind(this));
293
+ this._attachEvent(this.$dtpElement.find('a.dtp-select-year-before'), 'click', this._onYearBeforeClick.bind(this));
294
+ this._attachEvent(this.$dtpElement.find('a.dtp-select-year-after'), 'click', this._onYearAfterClick.bind(this));
295
+ this._attachEvent(this.$dtpElement.find('.dtp-actual-year'), 'click', this._onActualYearClick.bind(this));
296
+ this._attachEvent(this.$dtpElement.find('a.dtp-select-year-range.before'), 'click', this._onYearRangeBeforeClick.bind(this));
297
+ this._attachEvent(this.$dtpElement.find('a.dtp-select-year-range.after'), 'click', this._onYearRangeAfterClick.bind(this));
298
+ this._attachEvent(this.$dtpElement.find('div.year-picker-item'), 'click', this._onYearItemClick.bind(this));
299
+
300
+ if (this.params.clearButton === true)
301
+ {
302
+ this._attachEvent(this.$dtpElement.find('.dtp-btn-clear'), 'click', this._onClearClick.bind(this));
303
+ this.$dtpElement.find('.dtp-btn-clear').removeClass('hidden');
304
+ }
305
+
306
+ if (this.params.nowButton === true)
307
+ {
308
+ this._attachEvent(this.$dtpElement.find('.dtp-btn-now'), 'click', this._onNowClick.bind(this));
309
+ this.$dtpElement.find('.dtp-btn-now').removeClass('hidden');
310
+ }
311
+
312
+ if ((this.params.nowButton === true) && (this.params.clearButton === true))
313
+ {
314
+ this.$dtpElement.find('.dtp-btn-clear, .dtp-btn-now, .dtp-btn-cancel, .dtp-btn-ok').addClass('btn-xs');
315
+ } else if ((this.params.nowButton === true) || (this.params.clearButton === true))
316
+ {
317
+ this.$dtpElement.find('.dtp-btn-clear, .dtp-btn-now, .dtp-btn-cancel, .dtp-btn-ok').addClass('btn-sm');
318
+ }
319
+ },
320
+ initMeridienButtons: function ()
321
+ {
322
+ this.$dtpElement.find('a.dtp-meridien-am').off('click').on('click', this._onSelectAM.bind(this));
323
+ this.$dtpElement.find('a.dtp-meridien-pm').off('click').on('click', this._onSelectPM.bind(this));
324
+ },
325
+ initDate: function (d)
326
+ {
327
+ this.currentView = 0;
328
+
329
+ if (this.params.monthPicker === false)
330
+ {
331
+ this.$dtpElement.find('.dtp-picker-calendar').removeClass('hidden');
332
+ }
333
+ this.$dtpElement.find('.dtp-picker-datetime').addClass('hidden');
334
+ this.$dtpElement.find('.dtp-picker-year').addClass('hidden');
335
+
336
+ var _date = ((typeof (this.currentDate) !== 'undefined' && this.currentDate !== null) ? this.currentDate : null);
337
+ var _calendar = this.generateCalendar(this.currentDate);
338
+
339
+ if (typeof (_calendar.week) !== 'undefined' && typeof (_calendar.days) !== 'undefined')
340
+ {
341
+ var _template = this.constructHTMLCalendar(_date, _calendar);
342
+
343
+ this.$dtpElement.find('a.dtp-select-day').off('click');
344
+ this.$dtpElement.find('.dtp-picker-calendar').html(_template);
345
+
346
+ this.$dtpElement.find('a.dtp-select-day').on('click', this._onSelectDate.bind(this));
347
+
348
+ this.toggleButtons(_date);
349
+ }
350
+
351
+ this._centerBox();
352
+ this.showDate(_date);
353
+ },
354
+ initHours: function ()
355
+ {
356
+ this.currentView = 1;
357
+
358
+ this.showTime(this.currentDate);
359
+ this.initMeridienButtons();
360
+
361
+ if (this.currentDate.hour() < 12)
362
+ {
363
+ this.$dtpElement.find('a.dtp-meridien-am').click();
364
+ } else
365
+ {
366
+ this.$dtpElement.find('a.dtp-meridien-pm').click();
367
+ }
368
+
369
+ var hFormat = ((this.params.shortTime) ? 'h' : 'H');
370
+
371
+ this.$dtpElement.find('.dtp-picker-datetime').removeClass('hidden');
372
+ this.$dtpElement.find('.dtp-picker-calendar').addClass('hidden');
373
+ this.$dtpElement.find('.dtp-picker-year').addClass('hidden');
374
+
375
+ var svgClockElement = this.createSVGClock(true);
376
+
377
+ for (var i = 0; i < 12; i++)
378
+ {
379
+ var x = -(162 * (Math.sin(-Math.PI * 2 * (i / 12))));
380
+ var y = -(162 * (Math.cos(-Math.PI * 2 * (i / 12))));
381
+
382
+ var fill = ((this.currentDate.format(hFormat) == i) ? "#8BC34A" : 'transparent');
383
+ var color = ((this.currentDate.format(hFormat) == i) ? "#fff" : '#000');
384
+
385
+ var svgHourCircle = this.createSVGElement("circle", {'id': 'h-' + i, 'class': 'dtp-select-hour', 'style': 'cursor:pointer', r: '30', cx: x, cy: y, fill: fill, 'data-hour': i});
386
+
387
+ var svgHourText = this.createSVGElement("text", {'id': 'th-' + i, 'class': 'dtp-select-hour-text', 'text-anchor': 'middle', 'style': 'cursor:pointer', 'font-weight': 'bold', 'font-size': '20', x: x, y: y + 7, fill: color, 'data-hour': i});
388
+ svgHourText.textContent = ((i === 0) ? ((this.params.shortTime) ? 12 : i) : i);
389
+
390
+ if (!this.toggleTime(i, true))
391
+ {
392
+ svgHourCircle.className += " disabled";
393
+ svgHourText.className += " disabled";
394
+ svgHourText.setAttribute('fill', '#bdbdbd');
395
+ } else
396
+ {
397
+ svgHourCircle.addEventListener('click', this._onSelectHour.bind(this));
398
+ svgHourText.addEventListener('click', this._onSelectHour.bind(this));
399
+ }
400
+
401
+ svgClockElement.appendChild(svgHourCircle)
402
+ svgClockElement.appendChild(svgHourText)
403
+ }
404
+
405
+ if (!this.params.shortTime)
406
+ {
407
+ for (var i = 0; i < 12; i++)
408
+ {
409
+ var x = -(110 * (Math.sin(-Math.PI * 2 * (i / 12))));
410
+ var y = -(110 * (Math.cos(-Math.PI * 2 * (i / 12))));
411
+
412
+ var fill = ((this.currentDate.format(hFormat) == (i + 12)) ? "#8BC34A" : 'transparent');
413
+ var color = ((this.currentDate.format(hFormat) == (i + 12)) ? "#fff" : '#000');
414
+
415
+ var svgHourCircle = this.createSVGElement("circle", {'id': 'h-' + (i + 12), 'class': 'dtp-select-hour', 'style': 'cursor:pointer', r: '30', cx: x, cy: y, fill: fill, 'data-hour': (i + 12)});
416
+
417
+ var svgHourText = this.createSVGElement("text", {'id': 'th-' + (i + 12), 'class': 'dtp-select-hour-text', 'text-anchor': 'middle', 'style': 'cursor:pointer', 'font-weight': 'bold', 'font-size': '22', x: x, y: y + 7, fill: color, 'data-hour': (i + 12)});
418
+ svgHourText.textContent = i + 12;
419
+
420
+ if (!this.toggleTime(i + 12, true))
421
+ {
422
+ svgHourCircle.className += " disabled";
423
+ svgHourText.className += " disabled";
424
+ svgHourText.setAttribute('fill', '#bdbdbd');
425
+ } else
426
+ {
427
+ svgHourCircle.addEventListener('click', this._onSelectHour.bind(this));
428
+ svgHourText.addEventListener('click', this._onSelectHour.bind(this));
429
+ }
430
+
431
+ svgClockElement.appendChild(svgHourCircle)
432
+ svgClockElement.appendChild(svgHourText)
433
+ }
434
+
435
+ this.$dtpElement.find('a.dtp-meridien-am').addClass('hidden');
436
+ this.$dtpElement.find('a.dtp-meridien-pm').addClass('hidden');
437
+ }
438
+
439
+ this._centerBox();
440
+ },
441
+ initMinutes: function ()
442
+ {
443
+ this.currentView = 2;
444
+
445
+ this.showTime(this.currentDate);
446
+
447
+ this.initMeridienButtons();
448
+
449
+ if (this.currentDate.hour() < 12)
450
+ {
451
+ this.$dtpElement.find('a.dtp-meridien-am').click();
452
+ } else
453
+ {
454
+ this.$dtpElement.find('a.dtp-meridien-pm').click();
455
+ }
456
+
457
+ this.$dtpElement.find('.dtp-picker-year').addClass('hidden');
458
+ this.$dtpElement.find('.dtp-picker-calendar').addClass('hidden');
459
+ this.$dtpElement.find('.dtp-picker-datetime').removeClass('hidden');
460
+
461
+ var svgClockElement = this.createSVGClock(false);
462
+
463
+ for (var i = 0; i < 60; i++)
464
+ {
465
+ var s = ((i % 5 === 0) ? 162 : 158);
466
+ var r = ((i % 5 === 0) ? 30 : 20);
467
+
468
+ var x = -(s * (Math.sin(-Math.PI * 2 * (i / 60))));
469
+ var y = -(s * (Math.cos(-Math.PI * 2 * (i / 60))));
470
+
471
+ var color = ((this.currentDate.format("m") == i) ? "#8BC34A" : 'transparent');
472
+
473
+ var svgMinuteCircle = this.createSVGElement("circle", {'id': 'm-' + i, 'class': 'dtp-select-minute', 'style': 'cursor:pointer', r: r, cx: x, cy: y, fill: color, 'data-minute': i});
474
+
475
+ if (!this.toggleTime(i, false))
476
+ {
477
+ svgMinuteCircle.className += " disabled";
478
+ } else
479
+ {
480
+ svgMinuteCircle.addEventListener('click', this._onSelectMinute.bind(this));
481
+ }
482
+
483
+ svgClockElement.appendChild(svgMinuteCircle)
484
+ }
485
+
486
+ for (var i = 0; i < 60; i++)
487
+ {
488
+ if ((i % 5) === 0)
489
+ {
490
+ var x = -(162 * (Math.sin(-Math.PI * 2 * (i / 60))));
491
+ var y = -(162 * (Math.cos(-Math.PI * 2 * (i / 60))));
492
+
493
+ var color = ((this.currentDate.format("m") == i) ? "#fff" : '#000');
494
+
495
+ var svgMinuteText = this.createSVGElement("text", {'id': 'tm-' + i, 'class': 'dtp-select-minute-text', 'text-anchor': 'middle', 'style': 'cursor:pointer', 'font-weight': 'bold', 'font-size': '20', x: x, y: y + 7, fill: color, 'data-minute': i});
496
+ svgMinuteText.textContent = i;
497
+
498
+ if (!this.toggleTime(i, false))
499
+ {
500
+ svgMinuteText.className += " disabled";
501
+ svgMinuteText.setAttribute('fill', '#bdbdbd');
502
+ } else
503
+ {
504
+ svgMinuteText.addEventListener('click', this._onSelectMinute.bind(this));
505
+ }
506
+
507
+ svgClockElement.appendChild(svgMinuteText)
508
+ }
509
+ }
510
+
511
+ this._centerBox();
512
+ },
513
+ animateHands: function ()
514
+ {
515
+ var H = this.currentDate.hour();
516
+ var M = this.currentDate.minute();
517
+
518
+ var hh = this.$dtpElement.find('.hour-hand');
519
+ hh[0].setAttribute('transform', "rotate(" + 360 * H / 12 + ")");
520
+
521
+ var mh = this.$dtpElement.find('.minute-hand');
522
+ mh[0].setAttribute('transform', "rotate(" + 360 * M / 60 + ")");
523
+ },
524
+ createSVGClock: function (isHour)
525
+ {
526
+ var hl = ((this.params.shortTime) ? -120 : -90);
527
+
528
+ var svgElement = this.createSVGElement("svg", {class: 'svg-clock', viewBox: '0,0,400,400'});
529
+ var svgGElement = this.createSVGElement("g", {transform: 'translate(200,200) '});
530
+ var svgClockFace = this.createSVGElement("circle", {r: '192', fill: '#eee', stroke: '#bdbdbd', 'stroke-width': 2});
531
+ var svgClockCenter = this.createSVGElement("circle", {r: '15', fill: '#757575'});
532
+
533
+ svgGElement.appendChild(svgClockFace)
534
+
535
+ if (isHour)
536
+ {
537
+ var svgMinuteHand = this.createSVGElement("line", {class: 'minute-hand', x1: 0, y1: 0, x2: 0, y2: -150, stroke: '#bdbdbd', 'stroke-width': 2});
538
+ var svgHourHand = this.createSVGElement("line", {class: 'hour-hand', x1: 0, y1: 0, x2: 0, y2: hl, stroke: '#8BC34A', 'stroke-width': 8});
539
+
540
+ svgGElement.appendChild(svgMinuteHand);
541
+ svgGElement.appendChild(svgHourHand);
542
+ } else
543
+ {
544
+ var svgMinuteHand = this.createSVGElement("line", {class: 'minute-hand', x1: 0, y1: 0, x2: 0, y2: -150, stroke: '#8BC34A', 'stroke-width': 2});
545
+ var svgHourHand = this.createSVGElement("line", {class: 'hour-hand', x1: 0, y1: 0, x2: 0, y2: hl, stroke: '#bdbdbd', 'stroke-width': 8});
546
+
547
+ svgGElement.appendChild(svgHourHand);
548
+ svgGElement.appendChild(svgMinuteHand);
549
+ }
550
+
551
+ svgGElement.appendChild(svgClockCenter)
552
+
553
+ svgElement.appendChild(svgGElement)
554
+
555
+ this.$dtpElement.find("#dtp-svg-clock").empty();
556
+ this.$dtpElement.find("#dtp-svg-clock")[0].appendChild(svgElement);
557
+
558
+ this.animateHands();
559
+
560
+ return svgGElement;
561
+ },
562
+ createSVGElement: function (tag, attrs)
563
+ {
564
+ var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
565
+ for (var k in attrs)
566
+ {
567
+ el.setAttribute(k, attrs[k]);
568
+ }
569
+ return el;
570
+ },
571
+ isAfterMinDate: function (date, checkHour, checkMinute)
572
+ {
573
+ var _return = true;
574
+
575
+ if (typeof (this.minDate) !== 'undefined' && this.minDate !== null)
576
+ {
577
+ var _minDate = moment(this.minDate);
578
+ var _date = moment(date);
579
+
580
+ if (!checkHour && !checkMinute)
581
+ {
582
+ _minDate.hour(0);
583
+ _minDate.minute(0);
584
+
585
+ _date.hour(0);
586
+ _date.minute(0);
587
+ }
588
+
589
+ _minDate.second(0);
590
+ _date.second(0);
591
+ _minDate.millisecond(0);
592
+ _date.millisecond(0);
593
+
594
+ if (!checkMinute)
595
+ {
596
+ _date.minute(0);
597
+ _minDate.minute(0);
598
+
599
+ _return = (parseInt(_date.format("X")) >= parseInt(_minDate.format("X")));
600
+ } else
601
+ {
602
+ _return = (parseInt(_date.format("X")) >= parseInt(_minDate.format("X")));
603
+ }
604
+ }
605
+
606
+ return _return;
607
+ },
608
+ isBeforeMaxDate: function (date, checkTime, checkMinute)
609
+ {
610
+ var _return = true;
611
+
612
+ if (typeof (this.maxDate) !== 'undefined' && this.maxDate !== null)
613
+ {
614
+ var _maxDate = moment(this.maxDate);
615
+ var _date = moment(date);
616
+
617
+ if (!checkTime && !checkMinute)
618
+ {
619
+ _maxDate.hour(0);
620
+ _maxDate.minute(0);
621
+
622
+ _date.hour(0);
623
+ _date.minute(0);
624
+ }
625
+
626
+ _maxDate.second(0);
627
+ _date.second(0);
628
+ _maxDate.millisecond(0);
629
+ _date.millisecond(0);
630
+
631
+ if (!checkMinute)
632
+ {
633
+ _date.minute(0);
634
+ _maxDate.minute(0);
635
+
636
+ _return = (parseInt(_date.format("X")) <= parseInt(_maxDate.format("X")));
637
+ } else
638
+ {
639
+ _return = (parseInt(_date.format("X")) <= parseInt(_maxDate.format("X")));
640
+ }
641
+ }
642
+
643
+ return _return;
644
+ },
645
+ rotateElement: function (el, deg)
646
+ {
647
+ $(el).css
648
+ ({
649
+ WebkitTransform: 'rotate(' + deg + 'deg)',
650
+ '-moz-transform': 'rotate(' + deg + 'deg)'
651
+ });
652
+ },
653
+ showDate: function (date)
654
+ {
655
+ if (date)
656
+ {
657
+ this.$dtpElement.find('.dtp-actual-day').html(date.locale(this.params.lang).format('dddd'));
658
+ this.$dtpElement.find('.dtp-actual-month').html(date.locale(this.params.lang).format('MMM').toUpperCase());
659
+ this.$dtpElement.find('.dtp-actual-num').html(date.locale(this.params.lang).format('DD'));
660
+ this.$dtpElement.find('.dtp-actual-year').html(date.locale(this.params.lang).format('YYYY'));
661
+ }
662
+ },
663
+ showTime: function (date)
664
+ {
665
+ if (date)
666
+ {
667
+ var minutes = date.minute();
668
+ var content = ((this.params.shortTime) ? date.format('hh') : date.format('HH')) + ':' + ((minutes.toString().length == 2) ? minutes : '0' + minutes) + ((this.params.shortTime) ? ' ' + date.format('A') : '');
669
+
670
+ if (this.params.date)
671
+ this.$dtpElement.find('.dtp-actual-time').html(content);
672
+ else
673
+ {
674
+ if (this.params.shortTime)
675
+ this.$dtpElement.find('.dtp-actual-day').html(date.format('A'));
676
+ else
677
+ this.$dtpElement.find('.dtp-actual-day').html('&nbsp;');
678
+
679
+ this.$dtpElement.find('.dtp-actual-maxtime').html(content);
680
+ }
681
+ }
682
+ },
683
+ selectDate: function (date)
684
+ {
685
+ if (date)
686
+ {
687
+ this.currentDate.date(date);
688
+
689
+ this.showDate(this.currentDate);
690
+ this.$element.trigger('dateSelected', this.currentDate);
691
+ }
692
+ },
693
+ generateCalendar: function (date)
694
+ {
695
+ var _calendar = {};
696
+
697
+ if (date !== null)
698
+ {
699
+ var startOfMonth = moment(date).locale(this.params.lang).startOf('month');
700
+ var endOfMonth = moment(date).locale(this.params.lang).endOf('month');
701
+
702
+ var iNumDay = startOfMonth.format('d');
703
+
704
+ _calendar.week = this.days;
705
+ _calendar.days = [];
706
+
707
+ for (var i = startOfMonth.date(); i <= endOfMonth.date(); i++)
708
+ {
709
+ if (i === startOfMonth.date())
710
+ {
711
+ var iWeek = _calendar.week.indexOf(iNumDay.toString());
712
+ if (iWeek > 0)
713
+ {
714
+ for (var x = 0; x < iWeek; x++)
715
+ {
716
+ _calendar.days.push(0);
717
+ }
718
+ }
719
+ }
720
+ _calendar.days.push(moment(startOfMonth).locale(this.params.lang).date(i));
721
+ }
722
+ }
723
+
724
+ return _calendar;
725
+ },
726
+ constructHTMLCalendar: function (date, calendar)
727
+ {
728
+ var _template = "";
729
+
730
+ _template += '<div class="dtp-picker-month">' + date.locale(this.params.lang).format('MMMM YYYY') + '</div>';
731
+ _template += '<table class="table dtp-picker-days"><thead>';
732
+ for (var i = 0; i < calendar.week.length; i++)
733
+ {
734
+ _template += '<th>' + moment(parseInt(calendar.week[i]), "d").locale(this.params.lang).format("dd").substring(0, 1) + '</th>';
735
+ }
736
+
737
+ _template += '</thead>';
738
+ _template += '<tbody><tr>';
739
+
740
+ for (var i = 0; i < calendar.days.length; i++)
741
+ {
742
+ if (i % 7 == 0)
743
+ _template += '</tr><tr>';
744
+ _template += '<td data-date="' + moment(calendar.days[i]).locale(this.params.lang).format("D") + '">';
745
+ if (calendar.days[i] != 0)
746
+ {
747
+ if (this.isBeforeMaxDate(moment(calendar.days[i]), false, false) === false
748
+ || this.isAfterMinDate(moment(calendar.days[i]), false, false) === false
749
+ || this.params.disabledDays.indexOf(calendar.days[i].isoWeekday()) !== -1)
750
+ {
751
+ _template += '<span class="dtp-select-day">' + moment(calendar.days[i]).locale(this.params.lang).format("DD") + '</span>';
752
+ } else
753
+ {
754
+ if (moment(calendar.days[i]).locale(this.params.lang).format("DD") === moment(this.currentDate).locale(this.params.lang).format("DD"))
755
+ {
756
+ _template += '<a href="javascript:void(0);" class="dtp-select-day selected">' + moment(calendar.days[i]).locale(this.params.lang).format("DD") + '</a>';
757
+ } else
758
+ {
759
+ _template += '<a href="javascript:void(0);" class="dtp-select-day">' + moment(calendar.days[i]).locale(this.params.lang).format("DD") + '</a>';
760
+ }
761
+ }
762
+
763
+ _template += '</td>';
764
+ }
765
+ }
766
+ _template += '</tr></tbody></table>';
767
+
768
+ return _template;
769
+ },
770
+ setName: function ()
771
+ {
772
+ var text = "";
773
+ var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
774
+
775
+ for (var i = 0; i < 5; i++)
776
+ {
777
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
778
+ }
779
+
780
+ return text;
781
+ },
782
+ isPM: function ()
783
+ {
784
+ return this.$dtpElement.find('a.dtp-meridien-pm').hasClass('selected');
785
+ },
786
+ setElementValue: function ()
787
+ {
788
+ this.$element.trigger('beforeChange', this.currentDate);
789
+ if (typeof ($.material) !== 'undefined')
790
+ {
791
+ this.$element.removeClass('empty');
792
+ }
793
+ this.$element.val(moment(this.currentDate).locale(this.params.lang).format(this.params.format));
794
+ this.$element.trigger('change', this.currentDate);
795
+ },
796
+ toggleButtons: function (date)
797
+ {
798
+ if (date && date.isValid())
799
+ {
800
+ var startOfMonth = moment(date).locale(this.params.lang).startOf('month');
801
+ var endOfMonth = moment(date).locale(this.params.lang).endOf('month');
802
+
803
+ if (!this.isAfterMinDate(startOfMonth, false, false))
804
+ {
805
+ this.$dtpElement.find('a.dtp-select-month-before').addClass('invisible');
806
+ } else
807
+ {
808
+ this.$dtpElement.find('a.dtp-select-month-before').removeClass('invisible');
809
+ }
810
+
811
+ if (!this.isBeforeMaxDate(endOfMonth, false, false))
812
+ {
813
+ this.$dtpElement.find('a.dtp-select-month-after').addClass('invisible');
814
+ } else
815
+ {
816
+ this.$dtpElement.find('a.dtp-select-month-after').removeClass('invisible');
817
+ }
818
+
819
+ var startOfYear = moment(date).locale(this.params.lang).startOf('year');
820
+ var endOfYear = moment(date).locale(this.params.lang).endOf('year');
821
+
822
+ if (!this.isAfterMinDate(startOfYear, false, false))
823
+ {
824
+ this.$dtpElement.find('a.dtp-select-year-before').addClass('invisible');
825
+ } else
826
+ {
827
+ this.$dtpElement.find('a.dtp-select-year-before').removeClass('invisible');
828
+ }
829
+
830
+ if (!this.isBeforeMaxDate(endOfYear, false, false))
831
+ {
832
+ this.$dtpElement.find('a.dtp-select-year-after').addClass('invisible');
833
+ } else
834
+ {
835
+ this.$dtpElement.find('a.dtp-select-year-after').removeClass('invisible');
836
+ }
837
+ }
838
+ },
839
+ toggleTime: function (value, isHours)
840
+ {
841
+ var result = false;
842
+
843
+ if (isHours)
844
+ {
845
+ var _date = moment(this.currentDate);
846
+ _date.hour(this.convertHours(value)).minute(0).second(0);
847
+
848
+ result = !(this.isAfterMinDate(_date, true, false) === false || this.isBeforeMaxDate(_date, true, false) === false);
849
+ } else
850
+ {
851
+ var _date = moment(this.currentDate);
852
+ _date.minute(value).second(0);
853
+
854
+ result = !(this.isAfterMinDate(_date, true, true) === false || this.isBeforeMaxDate(_date, true, true) === false);
855
+ }
856
+
857
+ return result;
858
+ },
859
+ _attachEvent: function (el, ev, fn)
860
+ {
861
+ el.on(ev, null, null, fn);
862
+ this._attachedEvents.push([el, ev, fn]);
863
+ },
864
+ _detachEvents: function ()
865
+ {
866
+ for (var i = this._attachedEvents.length - 1; i >= 0; i--)
867
+ {
868
+ this._attachedEvents[i][0].off(this._attachedEvents[i][1], this._attachedEvents[i][2]);
869
+ this._attachedEvents.splice(i, 1);
870
+ }
871
+ },
872
+ _fireCalendar: function ()
873
+ {
874
+ this.currentView = 0;
875
+ this.$element.blur();
876
+
877
+ this.initDates();
878
+
879
+ this.show();
880
+
881
+ if (this.params.date)
882
+ {
883
+ this.$dtpElement.find('.dtp-date').removeClass('hidden');
884
+ this.initDate();
885
+ } else
886
+ {
887
+ if (this.params.time)
888
+ {
889
+ this.$dtpElement.find('.dtp-time').removeClass('hidden');
890
+ this.initHours();
891
+ }
892
+ }
893
+ },
894
+ _onBackgroundClick: function (e)
895
+ {
896
+ e.stopPropagation();
897
+ this.hide();
898
+ },
899
+ _onElementClick: function (e)
900
+ {
901
+ e.stopPropagation();
902
+ },
903
+ _onKeydown: function (e)
904
+ {
905
+ if (e.which === 27)
906
+ {
907
+ this.hide();
908
+ }
909
+ },
910
+ _onCloseClick: function ()
911
+ {
912
+ this.hide();
913
+ },
914
+ _onClearClick: function ()
915
+ {
916
+ this.currentDate = null;
917
+ this.$element.trigger('beforeChange', this.currentDate);
918
+ this.hide();
919
+ if (typeof ($.material) !== 'undefined')
920
+ {
921
+ this.$element.addClass('empty');
922
+ }
923
+ this.$element.val('');
924
+ this.$element.trigger('change', this.currentDate);
925
+ },
926
+ _onNowClick: function ()
927
+ {
928
+ this.currentDate = moment();
929
+
930
+ if (this.params.date === true)
931
+ {
932
+ this.showDate(this.currentDate);
933
+
934
+ if (this.currentView === 0)
935
+ {
936
+ this.initDate();
937
+ }
938
+ }
939
+
940
+ if (this.params.time === true)
941
+ {
942
+ this.showTime(this.currentDate);
943
+
944
+ switch (this.currentView)
945
+ {
946
+ case 1 :
947
+ this.initHours();
948
+ break;
949
+ case 2 :
950
+ this.initMinutes();
951
+ break;
952
+ }
953
+
954
+ this.animateHands();
955
+ }
956
+ },
957
+ _onOKClick: function ()
958
+ {
959
+ switch (this.currentView)
960
+ {
961
+ case 0:
962
+ if (this.params.time === true)
963
+ {
964
+ this.initHours();
965
+ } else
966
+ {
967
+ this.setElementValue();
968
+ this.hide();
969
+ }
970
+ break;
971
+ case 1:
972
+ this.initMinutes();
973
+ break;
974
+ case 2:
975
+ this.setElementValue();
976
+ this.hide();
977
+ break;
978
+ }
979
+ },
980
+ _onCancelClick: function ()
981
+ {
982
+ if (this.params.time)
983
+ {
984
+ switch (this.currentView)
985
+ {
986
+ case 0:
987
+ this.hide();
988
+ break;
989
+ case 1:
990
+ if (this.params.date)
991
+ {
992
+ this.initDate();
993
+ } else
994
+ {
995
+ this.hide();
996
+ }
997
+ break;
998
+ case 2:
999
+ this.initHours();
1000
+ break;
1001
+ }
1002
+ } else
1003
+ {
1004
+ this.hide();
1005
+ }
1006
+ },
1007
+ _onMonthBeforeClick: function ()
1008
+ {
1009
+ this.currentDate.subtract(1, 'months');
1010
+ this.initDate(this.currentDate);
1011
+ this._closeYearPicker();
1012
+ },
1013
+ _onMonthAfterClick: function ()
1014
+ {
1015
+ this.currentDate.add(1, 'months');
1016
+ this.initDate(this.currentDate);
1017
+ this._closeYearPicker();
1018
+ },
1019
+ _onYearBeforeClick: function ()
1020
+ {
1021
+ this.currentDate.subtract(1, 'years');
1022
+ this.initDate(this.currentDate);
1023
+ this._closeYearPicker();
1024
+ },
1025
+ _onYearAfterClick: function ()
1026
+ {
1027
+ this.currentDate.add(1, 'years');
1028
+ this.initDate(this.currentDate);
1029
+ this._closeYearPicker();
1030
+ },
1031
+ refreshYearItems:function () {
1032
+ var curYear=this.currentDate.year(),midYear=this.midYear;
1033
+ var minYear=1850;
1034
+ if (typeof (this.minDate) !== 'undefined' && this.minDate !== null){
1035
+ minYear=moment(this.minDate).year();
1036
+ }
1037
+
1038
+ var maxYear=2200;
1039
+ if (typeof (this.maxDate) !== 'undefined' && this.maxDate !== null){
1040
+ maxYear=moment(this.maxDate).year();
1041
+ }
1042
+
1043
+ this.$dtpElement.find(".dtp-picker-year .invisible").removeClass("invisible");
1044
+ this.$dtpElement.find(".year-picker-item").each(function (i, el) {
1045
+ var newYear = midYear - 3 + i;
1046
+ $(el).attr("data-year", newYear).text(newYear).data("year", newYear);
1047
+ if (curYear == newYear) {
1048
+ $(el).addClass("active");
1049
+ } else {
1050
+ $(el).removeClass("active");
1051
+ }
1052
+ if(newYear<minYear || newYear>maxYear){
1053
+ $(el).addClass("invisible")
1054
+ }
1055
+ });
1056
+ if(minYear>=midYear-3){
1057
+ this.$dtpElement.find(".dtp-select-year-range.before").addClass('invisible');
1058
+ }
1059
+ if(maxYear<=midYear+3){
1060
+ this.$dtpElement.find(".dtp-select-year-range.after").addClass('invisible');
1061
+ }
1062
+
1063
+ this.$dtpElement.find(".dtp-select-year-range").data("mid", midYear);
1064
+ },
1065
+ _onActualYearClick:function(){
1066
+ if(this.params.year){
1067
+ if(this.$dtpElement.find('.dtp-picker-year.hidden').length>0) {
1068
+ this.$dtpElement.find('.dtp-picker-datetime').addClass("hidden");
1069
+ this.$dtpElement.find('.dtp-picker-calendar').addClass("hidden");
1070
+ this.$dtpElement.find('.dtp-picker-year').removeClass("hidden");
1071
+ this.midYear = this.currentDate.year();
1072
+ this.refreshYearItems();
1073
+ }else{
1074
+ this._closeYearPicker();
1075
+ }
1076
+ }
1077
+ },
1078
+ _onYearRangeBeforeClick:function(){
1079
+ this.midYear-=7;
1080
+ this.refreshYearItems();
1081
+ },
1082
+ _onYearRangeAfterClick:function(){
1083
+ this.midYear+=7;
1084
+ this.refreshYearItems();
1085
+ },
1086
+ _onYearItemClick:function (e) {
1087
+ var newYear = $(e.currentTarget).data('year');
1088
+ var oldYear = this.currentDate.year();
1089
+ var diff = newYear - oldYear;
1090
+ this.currentDate.add(diff, 'years');
1091
+ this.initDate(this.currentDate);
1092
+
1093
+ this._closeYearPicker();
1094
+ this.$element.trigger("yearSelected",this.currentDate);
1095
+ },
1096
+ _closeYearPicker:function(){
1097
+ this.$dtpElement.find('.dtp-picker-calendar').removeClass("hidden");
1098
+ this.$dtpElement.find('.dtp-picker-year').addClass("hidden");
1099
+ },
1100
+ enableYearPicker:function () {
1101
+ this.params.year=true;
1102
+ this.$dtpElement.find(".dtp-actual-year").reomveClass("disabled");
1103
+ },
1104
+ disableYearPicker:function () {
1105
+ this.params.year=false;
1106
+ this.$dtpElement.find(".dtp-actual-year").addClass("disabled");
1107
+ this._closeYearPicker();
1108
+ },
1109
+ _onSelectDate: function (e)
1110
+ {
1111
+ this.$dtpElement.find('a.dtp-select-day').removeClass('selected');
1112
+ $(e.currentTarget).addClass('selected');
1113
+
1114
+ this.selectDate($(e.currentTarget).parent().data("date"));
1115
+
1116
+ if (this.params.switchOnClick === true && this.params.time === true)
1117
+ setTimeout(this.initHours.bind(this), 200);
1118
+
1119
+ if(this.params.switchOnClick === true && this.params.time === false) {
1120
+ setTimeout(this._onOKClick.bind(this), 200);
1121
+ }
1122
+
1123
+ },
1124
+ _onSelectHour: function (e)
1125
+ {
1126
+ if (!$(e.target).hasClass('disabled'))
1127
+ {
1128
+ var value = $(e.target).data('hour');
1129
+ var parent = $(e.target).parent();
1130
+
1131
+ var h = parent.find('.dtp-select-hour');
1132
+ for (var i = 0; i < h.length; i++)
1133
+ {
1134
+ $(h[i]).attr('fill', 'transparent');
1135
+ }
1136
+ var th = parent.find('.dtp-select-hour-text');
1137
+ for (var i = 0; i < th.length; i++)
1138
+ {
1139
+ $(th[i]).attr('fill', '#000');
1140
+ }
1141
+
1142
+ $(parent.find('#h-' + value)).attr('fill', '#8BC34A');
1143
+ $(parent.find('#th-' + value)).attr('fill', '#fff');
1144
+
1145
+ this.currentDate.hour(parseInt(value));
1146
+
1147
+ if (this.params.shortTime === true && this.isPM())
1148
+ {
1149
+ this.currentDate.add(12, 'hours');
1150
+ }
1151
+
1152
+ this.showTime(this.currentDate);
1153
+
1154
+ this.animateHands();
1155
+
1156
+ if (this.params.switchOnClick === true)
1157
+ setTimeout(this.initMinutes.bind(this), 200);
1158
+ }
1159
+ },
1160
+ _onSelectMinute: function (e)
1161
+ {
1162
+ if (!$(e.target).hasClass('disabled'))
1163
+ {
1164
+ var value = $(e.target).data('minute');
1165
+ var parent = $(e.target).parent();
1166
+
1167
+ var m = parent.find('.dtp-select-minute');
1168
+ for (var i = 0; i < m.length; i++)
1169
+ {
1170
+ $(m[i]).attr('fill', 'transparent');
1171
+ }
1172
+ var tm = parent.find('.dtp-select-minute-text');
1173
+ for (var i = 0; i < tm.length; i++)
1174
+ {
1175
+ $(tm[i]).attr('fill', '#000');
1176
+ }
1177
+
1178
+ $(parent.find('#m-' + value)).attr('fill', '#8BC34A');
1179
+ $(parent.find('#tm-' + value)).attr('fill', '#fff');
1180
+
1181
+ this.currentDate.minute(parseInt(value));
1182
+ this.showTime(this.currentDate);
1183
+
1184
+ this.animateHands();
1185
+
1186
+ if (this.params.switchOnClick === true)
1187
+ setTimeout(function ()
1188
+ {
1189
+ this.setElementValue();
1190
+ this.hide();
1191
+ }.bind(this), 200);
1192
+ }
1193
+ },
1194
+ _onSelectAM: function (e)
1195
+ {
1196
+ $('.dtp-actual-meridien').find('a').removeClass('selected');
1197
+ $(e.currentTarget).addClass('selected');
1198
+
1199
+ if (this.currentDate.hour() >= 12)
1200
+ {
1201
+ if (this.currentDate.subtract(12, 'hours'))
1202
+ this.showTime(this.currentDate);
1203
+ }
1204
+ this.toggleTime((this.currentView === 1));
1205
+ },
1206
+ _onSelectPM: function (e)
1207
+ {
1208
+ $('.dtp-actual-meridien').find('a').removeClass('selected');
1209
+ $(e.currentTarget).addClass('selected');
1210
+
1211
+ if (this.currentDate.hour() < 12)
1212
+ {
1213
+ if (this.currentDate.add(12, 'hours'))
1214
+ this.showTime(this.currentDate);
1215
+ }
1216
+ this.toggleTime((this.currentView === 1));
1217
+ },
1218
+ _hideCalendar: function() {
1219
+ this.$dtpElement.find('.dtp-picker-calendar').addClass('hidden');
1220
+ },
1221
+ convertHours: function (h)
1222
+ {
1223
+ var _return = h;
1224
+
1225
+ if (this.params.shortTime === true)
1226
+ {
1227
+ if ((h < 12) && this.isPM())
1228
+ {
1229
+ _return += 12;
1230
+ }
1231
+ }
1232
+
1233
+ return _return;
1234
+ },
1235
+ setDate: function (date)
1236
+ {
1237
+ this.params.currentDate = date;
1238
+ this.initDates();
1239
+ },
1240
+ setMinDate: function (date)
1241
+ {
1242
+ this.params.minDate = date;
1243
+ this.initDates();
1244
+ },
1245
+ setMaxDate: function (date)
1246
+ {
1247
+ this.params.maxDate = date;
1248
+ this.initDates();
1249
+ },
1250
+ destroy: function ()
1251
+ {
1252
+ this._detachEvents();
1253
+ this.$dtpElement.remove();
1254
+ },
1255
+ show: function ()
1256
+ {
1257
+ this.$dtpElement.removeClass('hidden');
1258
+ this._attachEvent($(window), 'keydown', this._onKeydown.bind(this));
1259
+ this._centerBox();
1260
+ this.$element.trigger('open');
1261
+ if (this.params.monthPicker === true)
1262
+ {
1263
+ this._hideCalendar();
1264
+ }
1265
+ },
1266
+ hide: function ()
1267
+ {
1268
+ $(window).off('keydown', null, null, this._onKeydown.bind(this));
1269
+ this.$dtpElement.addClass('hidden');
1270
+ this.$element.trigger('close');
1271
+ },
1272
+ _centerBox: function ()
1273
+ {
1274
+ var h = (this.$dtpElement.height() - this.$dtpElement.find('.dtp-content').height()) / 2;
1275
+ this.$dtpElement.find('.dtp-content').css('marginLeft', -(this.$dtpElement.find('.dtp-content').width() / 2) + 'px');
1276
+ this.$dtpElement.find('.dtp-content').css('top', h + 'px');
1277
+ },
1278
+ enableDays: function ()
1279
+ {
1280
+ var enableDays = this.params.enableDays;
1281
+ if (enableDays) {
1282
+ $(".dtp-picker-days tbody tr td").each(function () {
1283
+ if (!(($.inArray($(this).index(), enableDays)) >= 0)) {
1284
+ $(this).find('a').css({
1285
+ "background": "#e3e3e3",
1286
+ "cursor": "no-drop",
1287
+ "opacity": "0.5"
1288
+ }).off("click");
1289
+ }
1290
+ });
1291
+ }
1292
+ }
1293
+
1294
+ };
1295
+ })(jQuery, moment);