Rails4 + jQuery datepicker

Witam,
Nie bardzo rozumiem, o co chodzi, zatem pytam mądrzejszych.

Uczę się RoR i w ramch wprawek różne rzeczy instaluję i tak oto mam:

lista zainstalowanych gemów:
(> gem list)
actionmailer (4.1.4, 4.1.2, 4.1.1)
actionpack (4.1.4, 4.1.2, 4.1.1)
actionview (4.1.4, 4.1.2, 4.1.1)
activemodel (4.1.4, 4.1.2, 4.1.1)
activerecord (4.1.4, 4.1.2, 4.1.1)
activerecord-fb-adapter (0.8.8)
activesupport (4.1.4, 4.1.2, 4.1.1)
arel (5.0.1.20140414130214)
bcrypt (3.1.7)
better_errors (1.1.0)
bigdecimal (1.2.5, 1.2.4)
binding_of_caller (0.7.2)
builder (3.2.2)
bundler (1.6.3, 1.6.2)
bundler-unload (1.0.2)
coderay (1.1.0)
coffee-rails (4.0.1)
coffee-script (2.2.0)
coffee-script-source (1.7.0)
commonjs (0.2.7)
debug_inspector (0.0.2)
devise (3.2.4)
erubis (2.7.0)
execjs (2.2.1, 2.2.0, 2.1.0)
executable-hooks (1.3.2, 1.3.1)
faraday (0.9.0)
fb (0.7.2)
font-awesome-rails (4.1.0.0)
foreigner (1.6.1)
foundation-icons-sass-rails (3.0.0)
foundation-rails (5.3.0.1)
gem-wrappers (1.2.5, 1.2.4)
haml (4.0.5)
hashie (3.1.0, 2.1.2)
high_voltage (2.2.0)
hike (2.1.3, 1.2.3)
i18n (0.6.11, 0.6.9)
io-console (0.4.2)
jbuilder (2.1.2, 2.1.1, 2.1.0, 2.0.7)
jquery-rails (3.1.1, 3.1.0)
jquery-ui-rails (5.0.0, 4.2.1)
json (1.8.1)
jwt (1.0.0)
kaminari (0.16.1)
less (2.6.0, 2.5.1)
libv8 (3.16.14.3)
mail (2.6.1, 2.5.4)
mime-types (2.3, 1.25.1)
mini_portile (0.6.0)
minitest (5.4.0, 5.3.5, 5.3.4, 4.7.5)
multi_json (1.10.1)
multi_xml (0.5.5)
multipart-post (2.0.0)
mysql2 (0.3.16)
n (0.1.0)
nested_form (0.3.2)
nokogiri (1.6.2.1)
oauth2 (0.9.4)
omniauth (1.2.1)
omniauth-facebook (1.6.0)
omniauth-oauth2 (1.1.2)
orm_adapter (0.5.0)
polyglot (0.3.5)
psych (2.0.5)
quiet_assets (1.0.3)
rack (1.5.2)
rack-pjax (0.7.0)
rack-test (0.6.2)
rails (4.1.4, 4.1.2, 4.1.1)
rails_admin (0.6.2)
rails_apps_composer (3.0.9, 3.0.3)
rails_apps_pages (0.5.10, 0.5.9, 0.5.8)
rails_layout (1.0.20)
railties (4.1.4, 4.1.2, 4.1.1)
rake (10.3.2, 10.1.0)
rdoc (4.1.1, 4.1.0)
ref (1.0.5)
remotipart (1.2.1)
rubygems-bundler (1.4.4, 1.4.3)
rvm (1.11.3.9)
safe_yaml (1.0.3)
sass (3.3.9, 3.2.19)
sass-rails (4.0.3)
schema_to_scaffold (0.5.1, 0.5.0)
sdoc (0.4.0)
simple-form-datepicker (0.1.3)
simple_form (3.0.2)
spring (1.1.3)
sprockets (2.12.1, 2.11.0)
sprockets-rails (2.1.3)
sqlite3 (1.3.9)
test-unit (2.5.5, 2.1.2.0)
therubyracer (0.12.1)
thor (0.19.1)
thread_safe (0.3.4)
tilt (2.0.1, 1.4.1)
treetop (1.5.3, 1.4.15)
turbolinks (2.2.2)
tzinfo (1.2.1, 1.2.0)
uglifier (2.5.1, 2.5.0)
warden (1.2.3)
wice_grid (3.4.4)

W Gemfile mam:
gem ‘rails’, ‘4.1.2’
gem ‘sqlite3’
gem ‘sass-rails’, ‘~> 4.0.3’
gem ‘uglifier’, ‘>= 1.3.0’
gem ‘coffee-rails’, ‘~> 4.0.0’
gem ‘jquery-rails’
gem ‘turbolinks’
gem ‘jbuilder’, ‘~> 2.0’
gem ‘sdoc’, ‘~> 0.4.0’,          group: :doc
gem ‘spring’,        group: :development
gem ‘foundation-rails’
group :development do
  gem ‘rails_layout’
end
gem ‘simple_form’
gem ‘jquery-ui-rails’, ‘~> 4.2.1’
gem ‘simple-form-datepicker’
gem ‘wice_grid’,’~> 3.4.3’

“application.css.scss”

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= content_for?(:title) ? yield(:title) : "Test1" %></title>
    <meta name="description" content="<%= content_for?(:description) ? yield(:description) : "Test1" %>">
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
    <%# Modernizr is required for Zurb Foundation %>
    <%= javascript_include_tag 'vendor/modernizr' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= csrf_meta_tags %>
  </head>
  <body>
    <header>
      <%= render 'layouts/navigation' %>
    </header>
    <main role="main" class="large-12 columns">
       <%= render 'layouts/messages' %>
       <%= yield %>       
    </main>
  </body>
</html>

Utworzyłem model zawierający pole typ data i w podformularzu “_form.html.erb” mam takie coś:

<%= simple_form_for(@Osoba) do |f| %>
  <%= f.error_notification %>
    <fieldset>
      <legend>Osoba</legend>

      <div class="form-inputs">

        <div class="row">
.....
          <div class="small-4 columns">
            <%= f.input :data_ur,
                  :as => :datepicker  %>
          </div>
......
        </div>

      </div>

    </fieldset>

    <div class="form-actions">
      <%= f.submit 'Zapisz', class: "button small radius success" %>
    </div>
  <% end %>

I gdy ten formularz jest wywoływany zarówno dla akcji “new”: jak i “edit”
<%= render ‘form’ %>
to po otwarciu formularza nie działa mi ten datepicker. Normalnie, po kliknięcie w pole formularza nie pokazuje się “kalendarzyk”. Wystarczy jednak, że nacisnę klawisz F5 w przeglądarce i teraz kliknę w pole formularza, to jest ok i wyskakuje datepicker.

Czy może ktoś podpowiedzieć, gdzie szukać przyczyny tego zjawiska?
Turbolink? WTF?

(Firefox 30, Ubuntu 12.04)

Obstawiam, że kalendarzyk jest inicjalizowany podczas $(document).ready. Korzystając z turbolinks musisz też inicjować pluginy podczas ‘page-load’:

$(document).on('page:load', function() { ... })

Turbolinks ajaxowo podmienia strony, wiec ‘ready’ na documencie jest wywoływane tylko podczas pierwszego ładowania strony, później załadowanie kolejnych podstron sygnalizowane jest przez ‘page:load’.

Tego typu rzeczy najlepiej jednak jest inicjalizować podczas kliknięcia, coś w stylu:

$(document).on('click.date-picker', '.date-picker', function() {
   ....
})

Wtedy nie ważne czy strona była załadowana normalnie czy przez turbolinks, podpinasz się pod event tylko raz.

PS. Możesz też spróbować wyłączyć Turbolinks i sprawdzić czy problem dalej występuje.

1 Like

Obstawiał bym właśnie turbolink’a
Polecam ten gem na takie problemy: jquery.turbolink

1 Like

Jesteście wielcy!

Dodanie: gem 'jquery-turbolinks’ do Gemfile rozwiązało problemy!

Dzięki!! :slight_smile:

Ja też w tej sprawie. Mianowicie datepicker (https://github.com/Nerian/bootstrap-datepicker-rails) nie chce odpalić.

Fragment layout.html.haml

%head
  %meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
  %meta{:name => "viewport", :content => "width=device-width, initial-scale=1"}
  %title Data Synchronizator Monitoring Server
  = stylesheet_link_tag    'application', media: 'all'
  = javascript_include_tag 'application'
  = csrf_meta_tags

application.js

//= require jquery
//= require jquery_ujs
//= require bootstrap-sprockets
//= require bootstrap-datepicker
//= require_tree .

application.scss

@import "bootstrap-sprockets";
@import "bootstrap";
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
 * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any styles
 * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
 * file per style scope.
 *
 *= require_tree .
 *= require_self
 *= require devise_bootstrap_views
 *= require bootstrap-datepicker
 */

synchronization_reports.js.coffee

$('#synchronization_report_synch_completed_time').datepicker
  autoclose: true
  clearBtn: true
  format: 'yyyy-mm-dd'

W config.initializers/assets dodałem

Rails.application.config.assets.precompile += %w( synchronization_reports.js )

Plik jest ładowany, niestety skrypt nie uruchamia się (a jak zrobię to samo z konsoli to działa). W czym może leżeć problem. Nie używam turbolinków bo mnie denerwują.

U mnie problemem został rozwiązany po dodaniu tego gem ‘jquery-turbolinks’ .

Tak jak napisałem nie korzystam z turbolinków więc dodanie jquery-turbolinks nic mi nie da.

Hmm… a czymś go odpalasz? Dodaj słuchacza albo odpal go za pomocą funkcji anonimowej, np:

$->
  $('#synchronization_report_synch_completed_time').datepicker
    autoclose: true
    clearBtn: true
    format: 'yyyy-mm-dd'

I daj znać czy działa.

Niepotrzebny $ na początku.

W efekcie wygenerowany kod JS’a wygląda tak

(function() {
  (function() {
    return $('#synchronization_report_synch_completed_time').datepicker({
      autoclose: true,
      clearBtn: true,
      format: 'yyyy-mm-dd'
    });
  });

}).call(this);

I nie dzieje się nic.

No to idąc dalej słuchacz gotowości dokumentu

Też nie zadziałało, ale znalazłem rozwiązanie

$ ->
  $('#synchronization_report_synch_completed_time').datepicker
    autoclose: true
    clearBtn: true
    format: 'yyyy-mm-dd'

Spacja po pierwszym znaku $ musi być. Ehh Coffee nigdy nie będzie moją mocną stroną :slight_smile: