简体   繁体   中英

How to put javascript code for rails view to assets/javascript folder?

I have added code to my investment_time_machine.html.erb file. The code is:

<body id="body">
  <div id="view">
    <ul id="page"></ul>
  </div>
  <script>
    var space = -600;
    var pageSize = 5;
    var angle = 0;
    var data = [];
    var investment_count = <%= @investment_updates.count %>
    var MAX_SIZE = investment_count;
    data.push(new Item(0, 0, 0));
    var current_index = 1;
    var max_index = 0;
    var page = document.getElementById('page');

    function add(n, investment_update){
      if(! data[n]){
        data.push(new Item(data[max_index].translate_y+space, data[max_index].translate_z+space, data[max_index].rotate_z+3));
      }
      var item = document.createElement('li');
      item.id = n;
      item.style.zIndex = (10-n);
      item.onclick = function() {jumpTo(n)};
      item.innerHTML = investment_update
      page.appendChild(item);
      max_index++;
    }

    function Item(translate_y, translate_z, rotate_z){
      this.translate_y = translate_y;
      this.translate_z = translate_z;
      this.rotate_z = rotate_z;
    }

    // displays total investment updates
    <% @investment_updates.each_with_index do |investment_update, index| %>
      data.push(new Item(<%= index + 1 %>*space, <%= index + 1 %>*space, (<%= index + 1 %>-1)*angle));
      add(<%= index + 1 %>, "<%= render 'single_investment_update', investment_update: investment_update %>");
    <% end %>

    // animate total investment updates
    <% @investment_updates.each_with_index do |investment_update, index| %>
      animate(<%= index + 1 %>, 0, 1);
    <% end %>

    function shortCut(event){
      if(event.wheelDelta > 0){
        next();
      }
      else if(event.wheelDelta < 0){
        prev();
      }
    }

    if ("onmousewheel" in document) {
      document.onmousewheel = shortCut;
    } else {
      document.addEventListener('DOMMouseScroll', shortCutFF, false);
    }

    function jumpTo(n){
      for(var i=current_index; i<n; i++){
        next();
      }
    }

    function animate(n, y, opacity) {
      if(n<=MAX_SIZE) {
        var new_y = data[n].translate_y + y;
        var new_z = data[n].translate_z + y;
        var new_rz = data[n].rotate_z + angle*y/space;
        var elementN = document.getElementById(n);
        elementN.onclick = function() {jumpTo(n)};
        elementN.style.webkitTransform = 'translateX('+ (-0.3*new_y) + 'px) translateY('+ new_y + 'px) translateZ(' + new_z + 'px) rotateZ(' + new_rz + 'deg)';
        elementN.style.transform = 'translateX('+ (-0.3*new_y) + 'px) translateY('+ new_y + 'px) translateZ(' + new_z + 'px) rotateZ(' + new_rz + 'deg)';
        elementN.style.opacity = opacity;

        data[n].translate_y = new_y;
        data[n].translate_z = new_z;
        data[n].rotate_z = new_rz;
      }
    }

    function prev() {
      if(current_index >1) {
        document.getElementById(current_index-1).style.opacity = 1;
        current_index --;
        for(var n=1; n<current_index; n++){
          animate(n, space, 0);
        }
        for(var n=current_index; n<current_index+pageSize; n++){
          animate(n, space, 1);
        }
        for(var n=current_index+pageSize; n<=max_index; n++){
          animate(n, space, 0);
        }
      }
    }

    function next() {
      if(current_index < data.length && current_index < MAX_SIZE) {
        document.getElementById(current_index).style.opacity = 0;
        current_index ++;
        if(current_index+pageSize-1>max_index && max_index<MAX_SIZE){
          add(current_index + pageSize -1);
        }
        for(var n=1; n<current_index; n++){
          animate(n, -1*space, 0);
        }
        for(var n=current_index; n<current_index+pageSize; n++){
          animate(n, -1*space, 1);
        }
        for(var n=current_index+pageSize; n<=max_index; n++){   
          animate(n, -1*space, 0);
        }
      }
    }
  </script>
</body>

Now, I have to put this code in my assets/javascripts folder. Also, I have called @investment_updates from controller and don't know how to add this in assets folder. Also, I added 'jquery-rails' gem and in my application.js file, I added

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

I tried different things but didn't work and this is my first time working with javascript in rails. Please help me in solving this issue.

Well, the way I see it, you're having problems mostly with mixing erb and js. I can help you with a easy way to deal with this.

Step 1: Instead of mixing ruby code and js code, you can render the ruby/rails variables (ie @investment_updates ) in a hidden input field in your html.erb view file. So, what's gonna happen is that the server will render your html.erb file first and it will already contain your variables "stored" in hidden input fields. Notice the JS code still hasn't started yet.

Step 2: Now you need to assure that you have a separate file with the js code. Let's say investment.js . Put it in the same folder as the application.js file and require your js file in the application.js:

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

Step 3: Make sure you have in your layout file (probably a html.erb in a file inside views/layouts) the tag <%= javascript_include_tag "application" %> which is the code loading the application.js file in assets. That's the assets pipeline part of the question.

Step 4: Now to make it work. Once you assure this JS file is being loaded (try an alert or console in the beginning of the file), you can refactor your js code to manipulate the values already in the view file instead of dealing with ruby/rails variables. For instance:

//in investment.js var index = $("#index").val(); //using the value already written in the view animate(index, 0, 1); ...

Another approach, if you really want to mix ruby code with JS, would be to go about steps 2 and 3, but with the file named as investment.js.erb which can interpret ruby as well as JS. But instead of calling <%= javascript_include_tag "application" %> from the layout view, you can call <%= javascript_include_tag "investment" %> from the view you described in your question (it could be in the end of the file). Approach 1 is more advised though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM