0

I am new to JavaScript and rails. I am building a site in ruby on rails and I am trying to use JavaScript in a view. I need to hide and show some elements of a table I have some script task down and it is only working for the first row of the table. is there a better way of doing this thank you for any help. i need each button to show or hide the corresponding element in the table

application.html

    <!DOCTYPE html>
<script>
function changeColor(newColor) {

    document.getElementById("para1").style.display = "none"
    document.getElementById("para2").style.display = "none"
    document.getElementById("para3").style.display = "none"
    document.getElementById("para4").style.display = "block"
    document.getElementById("para5").style.display = "none"
  }


  function show(newColor) {

    document.getElementById("para1").style.display = "block"
    document.getElementById("para2").style.display = "block"
    document.getElementById("para3").style.display = "block"
    document.getElementById("para4").style.display = "none"
    document.getElementById("para5").style.display = "block"

  }
  </script>
<html>
<head>
  <title>VincentricData</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= stylesheet_link_tag    "defaults", media: "all", "data-turbolinks-track" => true %>
  <%= csrf_meta_tags %>
</head>

<body>

<%= yield %>

</body>
</html>

index.html

<h1>Listing vehicles</h1>



    <table>
      <thead>
        <tr>
          <th>Year</th>
          <th>Make</th>
          <th>Model</th>
          <th>Msrp</th>
          <th>Rating</th>
          <th>Total operating costs</th>
          <th colspan="3"></th>
        </tr>
      </thead>

      <tbody>
        <% @vehicles.each do |vehicle| %>
          <tr>
            <td><%= vehicle.year %></td>
            <td><%= vehicle.make %></td>
            <td><%= vehicle.model %></td>
            <td><div id="para1" ><%= vehicle.msrp %></div></td>
            <td><div id="para2" ><%= vehicle.rating %></div></td>
            <td><div id="para3" ><%= vehicle.total_operating_costs %></div></td>
            <td><div id="para4" ><button onclick="show('#00FFFF');">Show</button></div></td>
            <td><div id="para5" ><button onclick="changeColor('#00FFFF');">hide</button></div></td>
            <td><%= link_to 'Edit', edit_vehicle_path(vehicle) %></td>
            <td><%= link_to 'Destroy', vehicle, method: :delete, data: { confirm: 'Are you sure?' } %></td>
          </tr>
        <% end %>
      </tbody>
    </table>

    <br>

    <%= link_to 'New Vehicle', new_vehicle_path %>

1 Answer 1

1

First, if your rows are in a loop, you cannot give hardcoded ID to your elements as there will be several HTML elements with the same ID, which is definitely very bad. Give your elements a class, that can be duplicated as many times as you want.

Second, you could (and probably should if possible) use jQuery for this kind of things. It is really, really much more intuitive and easier than pure javascript.

<script src='/somewhere/jquery.min.js'></script>
<script>
    (function ($) {
        // Here you are sure that jQuery is included in your HTML page
        $(function () {
            // Now the DOM is fully loaded, you can use some javascript without problem

            // Listen a click on each ".para4" element : (class='para4')
            $('.para4').on('click', function (event) {
                // Get the parent <tr> element
                var $tr = $(this).closest('tr');
                // On this parent <tr>, display all .para elements
                $tr.find('.para').show();
                /*
                This is equivalent to :
                $tr.find('.para').css('display', 'block');
                */
                // Then hide the .para4 one only.
                $tr.find('.para4').hide();
                /*
                This is equivalent to :
                $tr.find('.para4').css('display', 'none');
                */
            });
            // Listen a click on each ".para5" element : (class='para5')
            $('.para5').on('click', function (event) {
                // Get the parent <tr> element
                var $tr = $(this).closest('tr');
                // On this parent <tr>, hide all .para elements
                $tr.find('.para').hide();
                /*
                This is equivalent to :
                $tr.find('.para').css('display', 'none');
                */
                // Then display the .para4 one only.
                $tr.find('.para4').show();
                /*
                This is equivalent to :
                $tr.find('.para4').css('display', 'block');
                */
            });
        });
    })(window.jQuery);
</script>

Fiddle : http://jsfiddle.net/9uRps/

Without jQuery, you have to use loops and event listeners :

// Find all your .para4 elements
var para4Array = document.getElementsByClassName('para4');
var para4Length = para4Array.length;
// For each of them, listen for a click event
while (para4Length--) {
    para4Array[para4Length].addEventListener('click', function (event) {
        // Find the parent's <tr>
        var tr = this.parentNode.parentNode;
        // Display all .para children of this <tr>
        tr.querySelectorAll('.para').style.display = 'block';
        // Then hide the .para4 one
        tr.querySelectorAll('.para4').style.display = 'none';
    });
}

// Find all your .para5 elements
var para5Array = document.getElementsByClassName('para5');
var para5Length = para5Array.length;
// For each of them, listen for a click event
while (para5Length--) {
    para5Array[para5Length].addEventListener('click', function (event) {
        // Find the parent's <tr>
        var tr = this.parentNode.parentNode;
        // Hide all .para children of this <tr>
        tr.querySelectorAll('.para').style.display = 'none';
        // Then display the .para4 one
        tr.querySelectorAll('.para4').style.display = 'block';
    });
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.