Reputation: 453
I'm using Ruby on Rails and I'm trying to hide/show an individual div
from a collection of dynamically generated items by using the dynamically generated id
which I then insert in a data attribute
. This is what I've come up with so far, I think I'm on the right track but can't figure out what I'm missing. Without the if statement
it works but shows the hidden div of every item instead of that specific one, and with the if statement, nothing happens.
Link and hidden div
<span class="options" data-ovly=<%= activity.targetable.id %>>
<i class="fa fa-ellipsis-h"></i>
</span>
<div class="ed_ovly none" data-ovly=<%= activity.targetable.id %>>
<span class="shu_e">
<%= link_to "Edit", edit_medium_path(activity.targetable), :title => "Edit", :alt => "Edit", class: '' %>
</span>
<span class="shu_d">
<%= render :partial => "activities/delete", :locals => {:activity => activity} %>
</span>
</div>
jquery
$('.options').click(function(){
var $ovly = $(this).attr("data-ovly");
if ($('.ed_ovly').data("ovly") === $ovly) {
$('.ed_ovly').toggleClass("none");
}
});
Upvotes: 0
Views: 246
Reputation: 10497
Use id
attributes instead of data-ovly
in your div
tags and avoid the if
statement in your script:
html
<span class="options" data-ovly=<%= activity.targetable.id %>>
<i class="fa fa-ellipsis-h"></i>
</span>
<div class="ed_ovly none" id="<%= activity.targetable.id %>">
<span class="shu_e">
<%= link_to "Edit", edit_medium_path(activity.targetable), :title => "Edit", :alt => "Edit", class: '' %>
</span>
<span class="shu_d">
<%= render :partial => "activities/delete", :locals => {:activity => activity} %>
</span>
</div>
script
$('.options').click(function() {
var $ovly = $(this).data("ovly");
$('#' + $ovly).toggleClass("none");
});
Check this snippet:
$(document).ready(function() {
$('.options').click(function() {
var $ovly = $(this).data("ovly");
$('#' + $ovly).toggleClass("none");
});
});
.none {
display: none;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="options" data-ovly="1">
ovly#1 <i class="fa fa-ellipsis-h"></i>
</span>
<br><br>
<span class="options" data-ovly="2">
ovly#2 <i class="fa fa-ellipsis-h"></i>
</span>
<div class="ed_ovly none" id="1">
<span class="shu_e">
<a title="Edit ovly # 1" alt="Edit" href="#">Edit</a>
</span>
<span class="shu_d">
"Your rendered partial for ovly # 1"
</span>
</div>
<div class="ed_ovly none" id="2">
<span class="shu_e">
<a title="Edit ovly # 2" alt="Edit" href="#">Edit</a>
</span>
<span class="shu_d">
"Your rendered partial for ovly # 2"
</span>
</div>
The first problem is in your if
statement: You are using ===
to compare your values, but, since you are getting those values with different methods (attr
and data
), you are getting different data types.
Look closely at your code (i added a couple of comments):
$('.options').click(function(){
var $ovly = $(this).attr("data-ovly"); // Returns a string: "1"
if ($('.ed_ovly').data("ovly") === $ovly) // Returns a number: 1
{
$('.ed_ovly').toggleClass("none");
}
});
So your if
returns false
every time (since you are comparing string
with number
). To fix this, just use the same method1 to get data in both lines, like this:
$('.options').click(function(){
var $ovly = $(this).data("ovly"); // Returns a number: 1
if ($('.ed_ovly').data("ovly") === $ovly) // Returns a number: 1
{
$('.ed_ovly').toggleClass("none");
}
});
Now that you are getting same data types, your if
statement will work as expected. But you are not out of the woods yet, there is another issue with your code, look how you are identifying each unique <div>
:
if ($('.ed_ovly').data("ovly") === $ovly)
{
$('.ed_ovly').toggleClass("none");
}
You are using $('.ed_ovly')
, that is, you are using the class, and all div
s have that class, so with
$('.ed_ovly').data("ovly")
you will always get the value of the first div
with class ed_ovly
; and in
$('.ed_ovly').toggleClass("none")
you apply toggleClasss("none")
to all div
s with ed_ovly
class (and, as a result, you will hide/show all div
s every time).
So, you want to target only one div
at a time, and the best way to do it is assigning an id
to each div
(also dynamically), something like this:
<div class="ed_ovly none" data-ovly="<%= activity.targetable.id %>" id="<%= activity.targetable.id %">
<!-- Your div code... -->
</div>
And on your script, refer only to the div
you want to show/hide using its id
, and that can be done by changing $('.ed_ovly')
to $('#' + $ovly)
. Now your script should look like this:
if ($('#' + $ovly).data("ovly") === $ovly) {
$('#' + $ovly).toggleClass("none");
}
Your script now should be working fine, but something is off: with the changes we made, now the if
is not necessary at all! Since we now get a unique id
for each div, its safe to delete it:
$('.options').click(function() {
var $ovly = $(this).data("ovly");
$('#' + $ovly).toggleClass("none");
});
And, while we are at it, lets get rid also of that unnecessary data
tag in your div
(i assume you don't need it for anything else):
<div class="ed_ovly none" id="<%= activity.targetable.id %">
<!-- Your div code... -->
</div>
Note
1 You could still get away using both methods by comparing them with ==
, but i prefer sticking with ===
. Check this question for more information.
Upvotes: 1