javascriptjqueryruby-on-railsajaxbootstrap-sass

Different jQuery/JS errors in rails app with bootsrap


I have a filter that filters my form. When I open it my datepicker does not work even if the same code works on another page of the app. I do not get the error on the other pages.

Uncaught TypeError: $(...).datepicker is not a function

On every page I get

DEPRECATED: This filename doesn't follow the convention, use bootstrap-datepicker.en-CA.js instead.
$.fn.datepicker.deprecated @ core.self-c808be6e04274a80c551034d8f8a677b7c3995aec044ea4e6edf9cbbc19ff750.js?body=1:2012
(anonymous) @ bootstrap-datepicker-en-CA.self-fb416403a677f41efad9cfc05939c9fe3eeb04627845d85da10d9eee99ba96b2.js?body=1:21
(anonymous) @ bootstrap-datepicker-en-CA.self-fb416403a677f41efad9cfc05939c9fe3eeb04627845d85da10d9eee99ba96b2.js?body=1:23
core.self-c808be6e04274a80c551034d8f8a677b7c3995aec044ea4e6edf9cbbc19ff750.js?body=1:2012 DEPRECATED: The language code "kh" is deprecated and will be removed in 2.0. For Khmer support use "km" instead.
$.fn.datepicker.deprecated @ core.self-c808be6e04274a80c551034d8f8a677b7c3995aec044ea4e6edf9cbbc19ff750.js?body=1:2012
(anonymous) @ bootstrap-datepicker.kh.self-6562a5a87f529e9a3121f8b49f20a6f7d3651340738f7d747a2418d721d01eae.js?body=1:21
(anonymous) @ bootstrap-datepicker.kh.self-6562a5a87f529e9a3121f8b49f20a6f7d3651340738f7d747a2418d721d01eae.js?body=1:22
core.self-c808be6e04274a80c551034d8f8a677b7c3995aec044ea4e6edf9cbbc19ff750.js?body=1:2012 DEPRECATED: The language code "kr" is deprecated and will be removed in 2.0. For korean support use "ko" instead.
$.fn.datepicker.deprecated @ core.self-c808be6e04274a80c551034d8f8a677b7c3995aec044ea4e6edf9cbbc19ff750.js?body=1:2012
(anonymous) @ bootstrap-datepicker.kr.self-ca28b775db5a32ebbee6667b0bc40e26e078ce363db5c55c9a904155d3b9fdb5.js?body=1:19
(anonymous) @ bootstrap-datepicker.kr.self-ca28b775db5a32ebbee6667b0bc40e26e078ce363db5c55c9a904155d3b9fdb5.js?body=1:20
core.self-c808be6e04274a80c551034d8f8a677b7c3995aec044ea4e6edf9cbbc19ff750.js?body=1:2012 DEPRECATED: This language code "rs-latin" is deprecated (invalid serbian language code) and will be removed in 2.0. For Serbian latin support use "sr-latin" instead.
$.fn.datepicker.deprecated @ core.self-c808be6e04274a80c551034d8f8a677b7c3995aec044ea4e6edf9cbbc19ff750.js?body=1:2012
(anonymous) @ bootstrap-datepicker.rs-latin.self-a3302a16cb7cc00b6d455f26ed8a73f8890da7280ee9507c2cd9fe9f36ec6352.js?body=1:20
(anonymous) @ bootstrap-datepicker.rs-latin.self-a3302a16cb7cc00b6d455f26ed8a73f8890da7280ee9507c2cd9fe9f36ec6352.js?body=1:21
core.self-c808be6e04274a80c551034d8f8a677b7c3995aec044ea4e6edf9cbbc19ff750.js?body=1:2012 DEPRECATED: This language code "rs" is deprecated (invalid serbian language code) and will be removed in 2.0. For Serbian support use "sr" instead.

Uncaught TypeError: $(...).popover is not a function
at HTMLDocument.<anonymous> (bootstrap.self-fdc98dee79ee88255e10cac6caa91338165cb76cf0d263744d8d90011fc2ef8f.js?body=1:3)
at fire (jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1:3233)
at Object.fireWith [as resolveWith] (jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1:3363)
at Function.ready (jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1:3583)
at HTMLDocument.completed (jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1:3618)

and I googled that this comes from importing jQuery twice. But my

application.js

//= require jquery
//= require rails-ujs
//= require activestorage
//= require bootstrap
//= require bootstrap-datepicker
//= require bootstrap/dropdown
//= require turbolinks
//= require_tree .

imports it just once and even the order should be ok.

html.erb

    <script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>

    <%= csrf_meta_tags %>

    <% provide(:title, "Mitarbeiter hinzufügen") %>
    <div class="row">
      <div class="col-md-6 col-md-offset-3">
        <div>
  <%= form_for :anything, url: add_worker_tm_trainings_path do |f| %>
    <%= f.label :schicht %>
    <%= f.collection_select :shift, Shift.all, :id, :name, include_blank: :true %>
    <div class="lineshow">
    <%= f.label :linie %>
    <%= f.collection_select :line, Line.all, :id, :name, include_blank: :true %>
    <%= f.submit "submit", :class => 'submit_button' %>
    <% end %>
    </div>
  <div class="realform">
    <%= form_with model: Trainingsmembership, url: add_worker_tm_trainings_path do |f| %>
  <div style="overflow: auto; height: 350px">
    <table>
      <tr>
        <th style="width: 25px"></th>
        <th style="width: 200px"><%= sort_link "name" %></th>
        <th style="width: 125px"><%= sort_link "position" %></th>
        <th style="width: 75px"><%= sort_link "Schicht" %></th>
        <th style="width: 100px"><%= sort_link "linie" %></th>
      </tr>
      <% @workers.each do |worker| %>
        <tr>
          <td><%= check_box_tag "worker_ids[worker_ids][]", worker.id %></td>
          <td><%= worker.name %></td>
          <td><%= Position.find(worker.position_id).name %></td>
          <td><%= Shift.find(worker.shift_id).name %></td>
          <td><% worker.line_ids.each do |line| %>
              <%= Line.find(line).name %>
            <% end %></td>
        </tr>
      <% end %>
    </table>
  </div>
    <div style="overflow: auto; height: 350px">
      <table>
        <tr>
          <th style="width: 25px"></th>
          <th style="width: 200px"><%= sort_link "Training" %></th>
          <th style="width: 100px"><%= sort_link "linie" %></th>
        </tr>
        <% @trainingall.each do |training| %>
          <tr>
            <td><%= check_box_tag "training_ids[training_ids][]", training.id %></td>
            <td><%= training.name %></td>
            <td><%= Line.find(training.where_lines).name %></td>
          </tr>
        <% end %>
      </table>
    </div>
  <br><br>
    <%= f.label "Gültigkeit" %>
    <%= f.text_field :duration%>
    <%= f.label "Prüfungstermin" %>
    <%= f.text_field :date%>
    <%= f.label "Bemerkung" %>
    <%= f.text_field :comment%>
    <%= f.label "PDF-Protokoll" %>
    <%= f.text_field :attachement%>
    <%= f.submit "Submit" %>
  <!-- %= f.input :training_id, collection: @trainings, label_method: :name, value_method: :id, label: 'Training:', include_blank: false %>
  %= f.input :duration, label: 'Gültigkeit:' %>
  %= f.input :date, :as => :string, :input_html => { data: {behaviour: "datepicker"}}, label: 'Prüfungstermin:' %>

  %= f.input :comment, as: :text, label: 'Bemerkung:' %>
  %= f.input :attachement, as: :file, label: 'PDF-Protokoll:' %>
  %= f.submit "Training bearbeiten", class: "btn btn-primary" %-->
    <!--#%= f.input :worker_id, collection: Worker.all, label_method: :name, value_method: :id, label: 'Mitarbeiter', include_blank: false, input_html: { multiple: false } %>-->
<% end %>
  </div>
  <script type="text/javascript">
      $(document).ready(function(){
          $('.lineshow').hide();
          $('.realform').hide();
          $('#anything_shift').change(function () {
              if($('#anything_shift option:selected').text != ""){
                  $('.lineshow').show();
              }
          });
          $('#anything_line').change(function () {
              if($('#anything_line option:selected').text != ""){
                  $('.realform').show();
              }
          });
          $("submit").click(function (e) {
              e.preventDefault();
              $.ajax({
                  type: "POST",
                  url: "/trainings/add_worker_tm",
                  data: {
                      id: $(this).val(),
                      access_token: $("access_token").val()
                  },
                  success: function (result) {
                      $('.realform').show();
                  }
              })
          })
      });
  </script>
<script type="text/javascript">
    $('#micropost_picture').bind('change', function() {
        var size_in_megabytes = this.files[0].size/1024/1024;
        if (size_in_megabytes > 5) {
            alert('Maximum file size is 5MB. Please choose a smaller file.');
        }
    });
</script>
<script type="text/javascript">
    $('[data-behaviour~=datepicker]').datepicker({
        "format": "dd.mm.yyyy",
        "weekStart": 1,
        "autoclose": true
    });
</script>
</div>
      </div>
    </div>

The ajax call is not working as well but I had not invested much time in it yet. I do not like the first line there but without my jQuery seems not working, but why? I think I included jQuery in my application.js...

controller.erb

def add_worker_tm
    if !params.has_key?(:anything)
      puts "emoty"
    @worker = Worker.new
    @workers = Worker.order("#{sort_column} #{sort_direction}")
    @workerall = Worker.all
    @trainings = Training.all
    @trainingall = Training.all
    else
      @shift = params[:anything].require(:shift)
      @line = params[:anything].require(:line)
      @worker = Worker.new
      @workersshifts = Worker.all.where("shift_id= ?", @shift)
      puts @workersshifts
      @workers = []
      @workersshifts.each do |w|
        puts w.line_ids
          if w.line_ids.include? @line
            @workers << w
        end
      end
      @workerall = Worker.all
      @trainings = Training.all.where(where_lines: @line)
      @trainingall = Training.all.where(where_lines: @line)
    end
    end

  def add_worker_tm
if !params.has_key?(:anything)
  puts "empty"
@worker = Worker.new
@workers = Worker.order("#{sort_column} #{sort_direction}")
@workerall = Worker.all
@trainings = Training.all
@trainingall = Training.all
else
  @shift = params[:anything].require(:shift)
  @line = params[:anything].require(:line)
  @worker = Worker.new
  @workersshifts = Worker.where(shift_id: @shift)
  @workers = []
  @workersshifts.each do |w|
      if !w.line_ids.include?(@line)
        @workers << w
    end
  end
  @workerall = Worker.all
  @trainings = Training.all.where(where_lines: @line)
  @trainingall = Training.all.where(where_lines: @line)
end
end

My controller is fine I think, I fixed my filter bug and it displays what I want.

Now my questions:

  1. How can I fix the bootstrap js/jQuery errors?

  2. How can I make the datepicker working again?

  3. What do I need to change, that my AJAX call works correctly and displays my filtered tables without any refresh?

I am very confused and should add that I am very new to rails, jQuery and js.


Solution

  • After many hours try and error, I found some solutions.

    I found out that turbolinks are evil and do not trigger all my events. After I found out, I deleted <script src="http://code.jquery.com/jquery-1.12.0.min.js"></script> and changed my script to

    <script type="text/javascript">
          document.addEventListener("turbolinks:load", function () {
              $('.lineshow').hide();
              $('.realform').hide();
    

    Now it is working.

    My datepicker seems like not working cause of my previous jQuery-Script so I made it to a simple_form_for and the picker is there again. I put the whole form in a partial.

        <div>
      <%= form_for :anything, :html=>{:id=>"filter", :multipart => true,:remote=>true}, url: add_worker_tm_trainings_path do |f| %>
        <%= f.label :schicht %>
        <%= f.collection_select :shift, Shift.all, :id, :name, include_blank: :true %>
        <div class="lineshow">
          <%= f.label :linie %>
          <%= f.collection_select :line, Line.all, :id, :name, include_blank: :true %>
          <%= hidden_field_tag :authenticity_token, form_authenticity_token %>
          <%= f.submit "filter", {:class => "bttn-and-txt", :id => "filter", :name => "filter", :value => "filter"} %>
      <% end %>
      </div>
      <div class="realform">
        <%= simple_form_for(Trainingsmembership.new, url: add_worker_tm_trainings_path) do |f| %>
          <div style="overflow: auto; height: 350px">
            <table>
              <tr>
                <th style="width: 25px"></th>
                <th style="width: 200px"><%= sort_link "name" %></th>
                <th style="width: 125px"><%= sort_link "position" %></th>
                <th style="width: 75px"><%= sort_link "Schicht" %></th>
                <th style="width: 100px"><%= sort_link "linie" %></th>
              </tr>
              <% @workers.each do |worker| %>
                <tr>
                  <td><%= check_box_tag "worker_ids[worker_ids][]", worker.id %></td>
                  <td><%= worker.name %></td>
                  <td><%= Position.find(worker.position_id).name %></td>
                  <td><%= Shift.find(worker.shift_id).name %></td>
                  <td>
                    <% worker.line_ids.each do |line| %>
                      <%= Line.find(line).name %>
                    <% end %></td>
                </tr>
              <% end %>
            </table>
          </div>
          <div style="overflow: auto; height: 350px">
            <table>
              <tr>
                <th style="width: 25px"></th>
                <th style="width: 200px"><%= sort_link "Training" %></th>
                <th style="width: 100px"><%= sort_link "linie" %></th>
              </tr>
              <% @trainingall.each do |training| %>
                <tr>
                  <td><%= check_box_tag "training_ids[training_ids][]", training.id %></td>
                  <td><%= training.name %></td>
                  <td><%= Line.find(training.where_lines).name %></td>
                </tr>
              <% end %>
            </table>
          </div>
          <br><br>
          <%= f.input :duration, label: 'Gültigkeit:' %>
          <%= f.input :date, :as => :string, :input_html => { data: {behaviour: "datepicker"}}, label: 'Prüfungstermin:' %>
          <%= f.input :comment, as: :text, label: 'Bemerkung:' %>
          <%= f.input :attachement, as: :file, label: 'PDF-Protokoll:' %>
          <%= hidden_field_tag :authenticity_token, form_authenticity_token %>
          <%= f.submit "Mitarbeiter hinzufügen", {:class => "btn btn-primary", :name => "submit", :value => "submit"} %>
        <% end %>
      </div>
      <script type="text/javascript">
          $('[data-behaviour~=datepicker]').datepicker({
              "format": "dd.mm.yyyy",
              "weekStart": 1,
              "autoclose": true
          });
      </script>
      <script type="text/javascript">
          function GetCookie(name) {
              var arg=name+"=";
              var alen=arg.length;
              var clen=document.cookie.length;
              var i=0;
    
              while (i<clen) {
                  var j=i+alen;
                  if (document.cookie.substring(i,j)==arg)
                      return "here";
                  i=document.cookie.indexOf(" ",i)+1;
                  if (i==0)
                      break;
              }
    
              return null;
          };
          document.addEventListener("turbolinks:load", function () {
              $('.lineshow').hide();
              //$('.realform').hide();
    
                  var visit=GetCookie("COOKIE1");
    
                  if (visit==null){
                      $('.realform').hide();
                  }
                  var expire=new Date();
                  expire=new Date(expire.getTime()+(5*60*1000));
                  document.cookie="COOKIE1=here; expires="+expire;
    
              $('#anything_shift').change(function () {
                  if ($('#anything_shift option:selected').text != "") {
                      $('.lineshow').show();
                  }
              });
              $('#anything_line').change(function () {
                  if ($('#anything_line option:selected').text != "") {
                      $("#filter").click();
                  }
              });
    
          });
      </script>
      <script type="text/javascript">
          $('#micropost_picture').bind('change', function () {
              var size_in_megabytes = this.files[0].size / 1024 / 1024;
              if (size_in_megabytes > 5) {
                  alert('Maximum file size is 5MB. Please choose a smaller file.');
              }
          });
      </script>
    </div>
    

    With these javascripts and form.js.erb $("#filter").html("<%= j(render 'tform').html_safe %>") and in my controller I needed to add this before the end of the methods

    respond_to do |format|
          format.js { render 'trainings/add_worker_tm'}
          format.html
        end
    

    everything looks like working. The cookies are a dirty solution to make it possible that a different request to the filter will be shown immediately.