<a> element not working properly when hiding parent? - javascript

I made this script, and despite one oddity, it works fine. It's hiding/showing the parent of div element with a class containing specific content. The problem when I press my <a> elements, that act as buttons, they "filter" the divs, but it leaves the first comment <a>? If I change the element do a <div> instead no problem, but with an <a> element it behaves weirdly? Is this just a bug or?
here is a JSFiddle: https://jsfiddle.net/g1puxhs7/2/
HTML:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</script>
<a class='viewBtn'>Published<a>
<a class='viewBtn'>Completed<a>
<a class='viewBtn'>Created<a>
<div class="orders" id="orders">
<div class="row">
<div class="status">
Completed
</div>
<a>Comment</a>
</div>
<div class="row">
<div class="status">
Completed
</div>
<a>Comment</a>
</div>
<div class="row">
<div class="status">
Completed
</div>
<a>Comment</a>
</div>
</div>
<style>
.row {
width: 200px;
margin: 10px;
background: #ccc;
padding: 4px;
}
</style>
SCRIPT:
//--Filter by Status--//
$('.viewBtn').click(function() {
var txt = $(this).text();
$('.status:contains("' + txt + '")').parent().toggle();
$(this).toggleClass('down');
});

The problem is with your links:
<a class='viewBtn'>Published<a>
<a class='viewBtn'>Completed<a>
<a class='viewBtn'>Created<a>
You have 6 opening a tags, instead of 3 opening and 3 closing tags.
This is why the browser adds closing a tags in your script in a bunch of places, one of them in your first div—and then your whole DOM tree looks different than what you want.

Your markup needed to be cleaned up. Here is your markup cleaned up. Also, i find it best to add href for you anchor tags, and then you can comment them out with #, or you can add javascript:void(0). If you use the # approach, in your JS, you can add e.preventDefault();
HTML Cleaned:
<div>
<a class='viewBtn' href="#">Published</a>
<a class='viewBtn' href="#">Completed</a>
<a class='viewBtn' href="#">Created</a>
</div>
<div class="orders" id="orders">
<div class="row">
<div class="status">
Completed
</div>
<a class="stuff" onclick="Comment">Comment</a>
</div>
<div class="row">
<div class="status">
Completed
</div>
<a class="stuff">Comment</a>
</div>
<div class="row">
<div class="status">
Completed
</div>
<a class="stuff">Comment</a>
</div>
</div>
JS with preventDefault():
$('.viewBtn').click(function(e) {
e.preventDefault();
var txt = $(this).text();
$('.status:contains("' + txt + '")').parent().toggle();
$(this).toggleClass('down');
});

Related

How can i click and just own class can be shown on Javascript

<div class="item text-center">
<div class="class1"> <p> Something </p> </div>
</div>
<div class="item text-center">
<div class="class1"> <p> Something </p> </div>
</div>
$(".class1").hide();
$(".item").click(function () {
$(".class1").show();
})
I want that when the user click div of item, its own class1 should be show();
But in my codes, when the user click item of div, all class1 shows.
How can i do that just own class can be shown?
To fix this you need to use DOM traversal to access the .class1 element(s) within the clicked .item. To do that you can use the this keyword within the event handler to access the element which raised the event. Try this:
$(".item").click(function() {
$(this).find(".class1").show();
})
.class1 { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item text-center">
Foo
<div class="class1">
<p> Something </p>
</div>
</div>
<div class="item text-center">
Bar
<div class="class1">
<p> Something </p>
</div>
</div>
Note in the example that I used CSS to hide the .class1 elements instead of JS. This is because JS runs after the DOM has loaded, so can result in elements being visible for a short time before they are hidden. CSS runs before this, so avoids that occurrence.
$(".class1").hide();
$(".item").click(function () {
$(this).find(".class1").show();
});
<!--The parent divs should not be empty, otherwise when later in the code you call the .hide () method on their respective child divs, there would be nothing left to click on-->
<div class="item text-center">
item1
<div class="class1">
<p> Something </p>
</div>
</div>
<div class="item text-center">
item2
<div class="class1">
<p> Something </p>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You can use the find () method, the find () method returns the descendant elements of the selected element. Like the code above

Enclose whole div in an <a>

I have a div which I want to surround with an <a href>. I have the jQuery to add the <a href> after the div but I struggle to set it before and close it after the div.
This is the jQuery code I have:
$('.box_service').each(function() {
var link = $(this).html();
$(this).contents().wrap('');
});
It results in this HTML:
<div class="row">
<div class="box_service">
<a href="example.com">
<div class="inner-row"></div>
</a>
</div>
</div>
However my goal is this structure:
<div class="row">
<a href="example.com">
<div class="box_service">
<div class="inner-row"></div>
</div>
</a>
</div>
I can't enter the div before because there are more boxes in this row so I would add the <a href> to everything in there
The issue is due to your call to contents() which means you're wrapping the elements inside .box_service, not that element itself. Remove that method call.
Also note that each() is redundant, you can do what you require in a single line:
$('.box_service').wrap('');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="box_service">
Box service #1
<div class="inner-row">Inner row #1</div>
</div>
</div>
<div class="row">
<div class="box_service">
Box service #2
<div class="inner-row">Inner row #2</div>
</div>
</div>
.content will wrap the contents of your div, you want to wrap the div with <a> so call wrap on the div not on contents.
$('.box_service').each(function() {
var link = $(this).html();
$(this).wrap('');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="box_service">
<div class="inner-row"></div>
</div>
</div>
$('.box_service').each(function() {
var link = $(this).html();
$(this).wrap('');
});
You just need to remove contents() in between $(this).wrap() because contents() mean that you are wrapping the children of $(this).
Remove .contents() in order to wrap around each element with the class box-service:
$('.box_service').each(function() {
$(this).wrap('');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="box_service">
<a href="example.com">
<div class="inner-row"></div>
</a>
</div>
</div>
$('.box_service').wrap('');

Get data from element without id or class

I am building a Chrome extension (and therefore can only use JavaScript) and I need to get the link that resides in the h2 with the heading2 class.
However, there are multiple h2 items with that class (not shown here), and I will not know what the link will point to, as it changes monthly.
In this example, the content of the header is "Think before you tweet". It will always be under another header that contains the words "Featured Topic."
What I am looking to get is the /think_before_you_tweet from the href= of that h2 item. It shows that I have already completed the topic underneath the h2, but that will not always be the case.
Here is the code for the website:
<div class="chosen_for_you_section">
<div class="internal_container">
<h2 class="section_header"><img src="/public/s360/img/360-spinner.png" class="s360LogoHeader">Featured Topic <i class="fa fa-info-circle"></i> <span class="infoTxt">Read about what to do</span></h2>
<article class="article_block masonry_item " data-article_id="431">
<div class="article_image">
<img src="/thumb/public/media/nh/images/twitter_tweet_think_before_send.png?q=&h=278" />
<i class="fa fa-check-square-o article_complete article_type_icon" title="Article"></i>
<div class="action_icons">
<span class="like "><a title="Favorite"><i class="fa fa-heart"></i></a></span>
</div>
</div>
<header>
<h2 class="heading2">Think Before You Tweet!</h2>
<div class="article_required_complete">Congratulations, you've completed this required topic.</div>
<div class="category_blocks">
<p>
Social Media
</p>
</div>
</header>
</article>
<div class="focus_items">
<div class="home_side">
<p>
<img alt="" src="" style="width: 430px; height: 422px;" /><!-- I hid the img src here because it reveals some personal information and is not important -->
</p>
<p></p>
</div>
</div>
</div>
</div>
I can use jQuery in my extension, but I do not have any back-end capabilities.
Use jQuery :contains selector:
$('h2.section_header:contains("Featured Topic") + article a')[0].href
Looks like you've gotta loop through the h2.section_header headers, see if the text matches whatever you want, and then grabs the link from the header following itself.
$('h2.section_header').each(function(index, element) {
var $element = $(element);
if ($element.text().match(/Featured Topic/i)) {
$('#result').html($element.next('article').find('h2.heading2 a').attr('href'));
}
});
#result {
border: 3px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>
<div class="chosen_for_you_section">
<div class="internal_container">
<h2 class="section_header"><img src="/public/s360/img/360-spinner.png" class="s360LogoHeader">Featured Topic <i class="fa fa-info-circle"></i> <span class="infoTxt">Read about what to do</span></h2>
<article class="article_block masonry_item " data-article_id="431">
<div class="article_image">
<img src="/thumb/public/media/nh/images/twitter_tweet_think_before_send.png?q=&h=278" />
<i class="fa fa-check-square-o article_complete article_type_icon" title="Article"></i>
<div class="action_icons">
<span class="like "><a title="Favorite"><i class="fa fa-heart"></i></a></span>
</div>
</div>
<header>
<h2 class="heading2">Think Before You Tweet!</h2>
<div class="article_required_complete">Congratulations, you've completed this required topic.</div>
<div class="category_blocks">
<p>
Social Media
</p>
</div>
</header>
</article>
<div class="focus_items">
<div class="home_side">
<p>
<img alt="" src="" style="width: 430px; height: 422px;" /><!-- I hid the img src here because it reveals some personal information and is not important -->
</p>
<p></p>
</div>
</div>
</div>
</div>
with jQuery's :contains selector use this:
jQuery('h2:contains("Featured Topic") ~ article h2.heading2 a').attr('href')
try at http://jsfiddle.net/ug01a0d2/
without jQuery try to bind to class "section_header" or use a cycle with the textContent check to iterate all "h2.section_header"
If there are multiple H2 class heading2 :
$('h2[class*="heading2"] a').each(function(){
var href = $(this).attr('href');
// Do what you want with this href
});
Use XPath! The syntax is pretty, uh, unfortunate, but it's very powerful:
var result = document.evaluate('//h2[#class="section_header"]/following-sibling::article//h2[#class="heading2"]/a', document, null, XPathResult.ANY_TYPE, null );
That should select that anchor node. I'm not sure if it's available to extensions, but Chrome defines a handy helper method called $x that eliminates all that boilerplate around the query.
More information: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript

OnClick event handler in DIVs (First OnClick affects all DIVs)

Basically I have three DIVs, and each DIV has an OnClick event handler inline. These OnClick events direct the user to whatever page the DIV is talking about specifically. This works, however, once all three DIVs have been coded with their onclick event, and separate URLs, the top most onclick event directs all three DIVs to the first URL. If I delete the code from the top most DIV, the second DIV directs to the second DIVs correct page, but the third DIV will direct to that page as well.
<div class="column_one" style="margin-top:25px;" onclick="location.href='/general-trades-contractor.php';">
<div class="column_one_image"></div>
<div class="white" class="row1"><h1> General Contractor </h1>
<p class="left"></p><br><a href="/general-trades-contractor.php"><span>more...</span>
<div class="column_two" style="margin-top:25px;" onclick="location.href='/specialty-contractor.php';">
<div class="column_two_image"></div>
<div class="white" class="row1"><h1 style="padding-left:20px;"> Specialty Contractor </h1>
<p class="right"></p><br><span style="padding-left:20px;">more...</span>
<div class="column_three" style="margin-top:25px;" onclick="location.href='/firestop-contractor.php';">
<div class="column_three_image"></div>
<div class="white" class="row1"><h1> Firestopping Contractor </h1>
<p class="left"></p><br><span>more...</span>
As well as the relevant CSS.
.column_one
{
display:block;
float:left;
background-color:rgba(236,236,236,0.83);
height:250px;
width:940px;
}
.column_two
{
display:block;
float:left;
background-color:rgba(236,236,236,0.83);
height:250px;
width:940px;
}
.column_three
{
display:block;
float:left;
background-color:rgba(236,236,236,0.83);
height:250px;
width:940px;
}
Your html is malformed, you are missing a closing </div> tag for each of your divs and a closing </a> tag for the second link.
if you run the html through a beautifier its easier to see:
<div class="column_one" style="margin-top:25px;" onclick="location.href='/general-trades-contractor.php';">
<a href="/general-trades-contractor.php">
<div class="column_one_image"></div>
</a>
<div class="white" class="row1">
<h1>General Contractor</h1>
<p class="left"></p>
<br>
<a href="/general-trades-contractor.php">
<span>more...</span>
</div>
<div class="column_two" style="margin-top:25px;" onclick="location.href='/specialty-contractor.php';">
<a href="/specialty-contractor.php">
<div class="column_two_image"></div>
</a>
<div class="white" class="row1">
<h1 style="padding-left:20px;">Specialty Contractor</h1>
<p class="right"></p>
<br>
<a href="/specialty-contractor.php">
<span style="padding-left:20px;">more...</span>
</a>
</div>
<div class="column_three" style="margin-top:25px;" onclick="location.href='/firestop-contractor.php';">
<a href="/firestop-contractor.php">
<div class="column_three_image"></div>
</a>
<div class="white" class="row1">
<h1>Firestopping Contractor</h1>
<p class="left"></p>
<br>
<a href="/firestop-contractor.php">
<span>more...</span>
</a>
</div>
You seem to be missing closing tags. Something like this:
<div class="column_one" style="margin-top:25px;" onclick="location.href='/general-trades-contractor.php';">
<div class="column_one_image"></div>
<div class="white" class="row1">
<h1> General Contractor </h1>
<p class="left"></p><br><span>more...</span>
</div>
</div>
Should work. You were missing the last </a></div></div> and because of this every subsequent div was the child of the div above, thus the first div included second two, and second was the parent of third. So when you click the div, you actually trigger it's parent click.
Of course, you need to repeat this three times, for each <div> add </a></div></div> to close the elements.

Toggle a repeated class in jQuery

I have this HTML code:
<div id="content">
<div class="profile_photo">
<img style="float:left;margin-right:7px;" src="http://gravatar.com/avatar/53566ac91a169b353a78b329bdd35c95?s=50&d=identicon" class="profile_img" alt="{username}"/>
</div>
<div class="container" id="status-#">
<div class="message">
<span class="username">{username} Debugr Rocks!
</div>
<div class="info">24-oct-2010, 14:05 GMT · Comment (5) · Flag · Via Twitter
</div>
<div class="comment_container">
<div class="profile_photo">
<img style="float:left;margin-right:7px;" src="http://gravatar.com/avatar/53566ac91a169b353a78b329bdd35c95?s=32&d=identicon" class="profile_img" alt="{username}"/>
</div>
<div class="comment_message">
<span class="username">{username}</span> Debugr Rocks! XD
</div>
<div class="comment_info">24-oct-2010</div>
</div>
</div>
<div class="profile_photo">
<img style="float:left;margin-right:7px;" src="http://gravatar.com/avatar/53566ac91a169b353a78b329bdd35c95?s=50&d=identicon" class="profile_img" alt="{username}"/>
</div>
That is repeated two or more times. What I want to do, is to when I click the "Comments (5)" link, the class "comment_container" appears, but only the one in the same "container" class.
It's this possible?
You can use .closest() to go up to the .container then .find() to look inside it, like this:
$(".toggle_comment").click(function() {
$(this).closest(".container").find(".comment_container").show();
});
You can try it here, if you're curious about finding other things relative to this here's a full list of the Tree Traversal functions.
As an aside, there's an error in your HTML that needs correcting, this:
<span class="username">{username} Debugr Rocks! </div>
Should be:
<span class="username">{username} Debugr Rocks! </span>

Categories