Selection of elements using nth-child selectors - javascript

$(".sidebar>i:nth-child(3)").on("click", showMenu);
<div class="sidebar">
<i class="fa fa-volume-up"></i>
<div class="colorPalette">
<button class="submit">Submit</button>
<p>Color Pallette:</p><br />
<div class="colors_1">
<span id="color1"></span>
<span id="color2"></span>
<span id="color3"></span>
</div>
<div class="colors_2">
<span id="color4"></span>
<span id="color5"></span>
<span id="color6"></span>
</div>
</div>
<i class="fa fa-arrow-circle-o-left" title="Back to Menu"></i>
</div>
I need to select the 2nd (Back to Menu) button. So why nth-child(3) works but not nth-child(2)?

Since :nth-child(n) selects all children inside a parent element, regardless of what they are. So, in your case:
.sidebar>i:nth-child(3)
// This is the 3rd child, i tag
.sidebar>i:nth-child(2)
// This is the 2nd child, div tag
console.log($('.sidebar>i:nth-child(1)')[0])
console.log($('.sidebar>:nth-child(2)')[0])
console.log($('.sidebar>i:nth-child(2)')[0])
console.log($('.sidebar>i:nth-child(3)')[0])
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sidebar">
<i class="fa fa-volume-up"></i>
<div class="colorPalette">Test</div>
<i class="fa fa-arrow" title="Back to Menu"></i>
</div>
What you need is actually :nth-of-type() selector.
console.log($('.sidebar>i:nth-of-type(1)')[0])
console.log($('.sidebar>i:nth-of-type(2)')[0])
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sidebar">
<i class="fa fa-volume-up"></i>
<div class="colorPalette">
Test
</div>
<i class="fa fa-arrow" title="Back to Menu"></i>
</div>

From JQuery's docs:
The :nth-child(n) pseudo-class is easily confused with :eq(n), even though the two can result in dramatically different matched elements. With :nth-child(n), all children are counted, regardless of what they are, and the specified element is selected only if it matches the selector attached to the pseudo-class. With :eq(n) only the selector attached to the pseudo-class is counted, not limited to children of any other element, and the (n+1)th one (n is 0-based) is selected.

Related

JavaScript click on the link/button

Hi guys how would you click this link/Button I cant get any method to work, i have tried:
$('btn btn-large btn-info btn-embossed').children('a').click();
$('visit-trigger').trigger('click');
document.querySelector("visit-trigger").click();
I have tried all the names and class I could find not only the : visit-trigger class.
Website if you want to try your self
<div class="expandable ng-scope" ng-include="entryMethodView(entry_method)">
<form class="entry_details compact-box form-compact ng-pristine ng-valid ng-scope" name="entryDetailsForm">
<div class="form-compact__content center">
<div class="form-compact__part">
<p>Click here to ensure you are subscribed:</p>
</div>
<div class="form-compact__part">
<p class="visit-trigger">
<a class="btn btn-large btn-info btn-embossed" ng-href="https://youtube.com/user/videochumstube?sub_confirmation=1" rel="noopener" target="_blank" href="https://youtube.com/user/videochumstube?sub_confirmation=1">
<i class="fa fa-youtube"></i>
Subscribe here
</a>
</p>
</div>
</div>
visit-trigger is a class so use class selector
$('.visit-trigger').trigger('click');
//-^-------here
or
$('.btn-embossed').click(); // to fire the click event of `a`
Anyways most important part is use proper selectors. . for class, # for ids and so on.

Hide divs on click - multiple boxes

I have a bit long info submission form. I have an option that someone click "add another", there is a notification box display with text like "Success!" like that with close button. Please check this image.
Therefore I have three "add another" buttons and three success alerts. When someone click close, that alert message needs to be disappear.
The problem
I used javascript for that success box. It does these things.
Click "Add another" button, appears success box. Click close button on
success box, box disappears.
Here is my code.
document.querySelector(".add-box").addEventListener("click", function() {
document.querySelector(".add-box-wrap").style.display = "inline-block";
});
document.querySelector(".add-box1").addEventListener("click", function() {
document.querySelector(".add-box-wrap1").style.display = "inline-block";
});
document.querySelector(".add-box2").addEventListener("click", function() {
document.querySelector(".add-box-wrap2").style.display = "inline-block";
});
$(".claim-btn-close").click(function() {
$(".add-box-wrap").hide();
});
$(".claim-btn-close1").click(function() {
$(".add-box-wrap1").hide();
});
$(".claim-btn-close2").click(function() {
$(".add-box-wrap2").hide();
});
<!-- This goes end of html page -->
function hide(target) {
document.getElementsByClassName(target).style.display = 'none';
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!--Success form-->
<div class="add-box-wrap">
<div class="claim-btn-close" onclick="hide('.claim-btn-close')">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<!--Add another button -->
<div class="col-lg-10 col-md-10 col-sm-12 no-padding">
<a class="add-box">Add another<i class="fa fa-plus"></i></a>
</div>
See.. there is a major problem with code repeating. (I didn't repeat html codes, just post here one example) I would like to know the best practice to achieve things like this.
For displaying the notification box without repeating the code, one of the way is you could make use of data attributes. Change the data attribute for all the buttons and let the class .add-box be the same. like so:
<div class="add-box-wrap1" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<div class="add-box-wrap2" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<!--Add another button -->
<div class="col-lg-10 col-md-10 col-sm-12 no-padding">
<a class="add-box" data-target="1">Add another<i class="fa fa-plus"></i></a>
</div>
<!--Add another button -->
<div class="col-lg-10 col-md-10 col-sm-12 no-padding">
<a class="add-box" data-target="2">Add another<i class="fa fa-plus"></i></a>
</div>
And change your Jquery to just one function.
$(".add-box").click(function() {
$(".add-box-wrap" + $(this).data('target')).show(); //.add-box-wrap1 or .add-box-wrap2
});
Explanation of the above line: It just means we are getting the value of the "clicked" button's data-target value(which is 1 or 2) AND appending that value to the "add-box-wrap"(which will be add-box-wrap1 or add-box-wrap2) to search for that element to display it using .show().
Using show() or .css jquery functions is upto you. But I suggest not to mix both vanilla JS and JQuery codes(like in your question).
Closing
You can simply use closest or parent, like so:
$(".claim-btn-close").click(function(){
$(this).parent().hide();
});
$(".add-box").click(function() {
$(".add-box-wrap" + $(this).data('target')).show();
});
$(".claim-btn-close").click(function(){
$(this).parent().hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="add-box-wrap1" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<div class="add-box-wrap2" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<!--Add another button -->
<div class="col-lg-10 col-md-10 col-sm-12 no-padding">
<a class="add-box" data-target="1">Add another<i class="fa fa-plus"></i></a>
</div>
<!--Add another button -->
<div class="col-lg-10 col-md-10 col-sm-12 no-padding">
<a class="add-box" data-target="2">Add another<i class="fa fa-plus"></i></a>
</div>
Update on another question(3 column):
Using bootstrap, you can wrap the add-box-wrap divs within a .row and give each of it a class like col-*-4(class="col-xs-4 col-md-4 col-lg-4") assuming you have 3 success buttons(12/3 = 4). So the first part of your html would become
<div class="row">
<div class="add-box-wrap1 col-md-4 col-lg-4" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<div class="add-box-wrap2 col-md-4 col-lg-4" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<div class="add-box-wrap3 col-md-4 col-lg-4" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
</div>
You can use DOM relationship to target the desired element. Bind event handlers using a common class then use .closest() to traverse up desired element.
$(".claim-btn-close").click(function(){
$(this).closest(".add-box-wrap").hide();
});
If element are dynamically generate use Event Delegation approach.
$(staticParentElemet).on('click',".claim-btn-close",function(){
$(this).closest(".add-box-wrap").hide();
});

angular-ui-tree two events instead of one

I'm sure it is pretty simple question, but I can't find answer. I use pretty common pattern for creating tree. I need to know if user click parent node or child node. Everything works fine if I click parent node. But if I click child node, the callback function calls two times - first from child node, second from parent node. Could somebody explain me why? Thank you.
<div id="groups-tree" class="col-sm-4">
<script type="text/ng-template" id="nodes_renderer.html">
<div ui-tree-handle class="tree-node tree-node-content">
<a class="btn btn-success btn-xs" ng-if="node.nodes && node.nodes.length > 0"
ng-click="selected(node)" data-nodrag>
<span class="glyphicon"
ng-class="{
'glyphicon-chevron-right': collapsed,
'glyphicon-chevron-down': !collapsed
}"></span>
</a>
{{node.title}}
</div>
<ol ui-tree-nodes="" ng-model="node.nodes" ng-class="{hidden: collapsed}">
<li ng-repeat="node in node.nodes" ui-tree-node ng-include="'nodes_renderer.html'"
ng-click="selected(node)"*# data-nodrag>
</li>
</ol>
</script>
<div class="row">
<div class="col-sm-6">
<div ui-tree id="tree-root">
<ol ui-tree-nodes ng-model="data" data-nodrag>
<li ng-repeat="node in data" ui-tree-node ng-include="'nodes_renderer.html'"
ng-click="selected(node)"></li>
</ol>
</div>
</div>
</div>
</div>
I found solution here. The angular-ui-tree is sequence of enclosed elements. So I should stop propagate the event from child element to parent element.

Hiding and showing fields via Javascript based on the type of the category the results item has

I have a dynamic list of properties on a search results page, the problem I am having on each individual search result is that if it is a certain property type i.e. Land it does not need the bedrooms and bathrooms fields within that search result to show, but if it is a Villa, the fields would show.
I would need to show and hide fields on the page load in JS like my example above on each individual search result as if I do a general JS function for Land hiding the div classes for bedrooms and bathrooms, there could also be a Villa on the page needing those fields.
If anyone could help with some JS to help me solve this issue above, it would be much appreciated!
Heres some of the Html Results below, you will see there are multiple property types, so different fields should be show/hidden
<div class="property-listing">
<ul>
<li class="col-md-12">
<div class="col-md-4">
<a href="/propertydetails.aspx?SalePropertyID=615237" class="property-featured-image"><div class="overlay" style="line-height:167px"><i class="fa fa-search"></i></div>
<img src="http://example.com/ImageProcessor.aspx?watermarkImageFileName=&Text=NEW LISTING&imageURL=487/Sales/615237/615237_7969.jpg" alt="Villa in Javea">
<span class="images-count">
<i class="fa fa-link"></i>
MidasS
</span>
</a>
</div>
<div class="col-md-8">
<div class="property-info">
<div class="price"><span>115.000</span><strong>€</strong></div>
<div class="title">
<a href="/propertydetails.aspx?SalePropertyID=615237" title="Villa in Javea">
Villa in Javea
</a>
</div>
<span class="location"><i class="fa fa-map-marker"></i> Alicante, SPAIN</span>
<p>A beautiful and rustic style 'home' offering spectacular views over the coast, the mountains and the Mediterranean Sea.</p>
</div>
<div class="property-amenities clearfix">
<span id="spbeds"><strong>2</strong>Bedrooms</span>
<span id="spbaths"><strong>1</strong>Bathrooms</span>
<span id="sppool"><strong>Yes</strong>Pool</span>
</div>
</div>
</li>
<li class="col-md-12">
<div class="col-md-4">
<a href="/propertydetails.aspx?SalePropertyID=638700" class="property-featured-image"><div class="overlay" style="line-height:167px"><i class="fa fa-search"></i></div>
<img src="http://example.com/ImageProcessor.aspx?watermarkImageFileName=&Text=REDUCED&imageURL=487/Sales/638700/638700_1145.jpg" alt="Apartment in Famagusta">
<span class="images-count">
<i class="fa fa-link"></i>
PRO1011
</span>
</a>
</div>
<div class="col-md-8">
<div class="property-info">
<div class="price"><span>155.000</span><strong>€</strong></div>
<div class="title">
<a href="/propertydetails.aspx?SalePropertyID=638700" title="Apartment in Famagusta">
Apartment in Famagusta
</a>
</div>
<span class="location"><i class="fa fa-map-marker"></i> Famagusta, CYPRUS</span>
<p>hnglkrehnblarjl;kbkhmtr;mnb;rstlmnstrn</p>
</div>
<div class="property-amenities clearfix">
<span id="spbeds"><strong>0</strong>Bedrooms</span>
<span id="spbaths"><strong>0</strong>Bathrooms</span>
<span id="sppool"><strong>No</strong>Pool</span>
</div>
</div>
</li>
<li class="col-md-12">
<div class="col-md-4">
<a href="/propertydetails.aspx?SalePropertyID=636364" class="property-featured-image"><div class="overlay" style="line-height:188px"><i class="fa fa-search"></i></div>
<img src="http://example.com/487/Sales/636364/636364_5562.jpg" alt="Country House in Not Specified">
<span class="images-count">
<i class="fa fa-link"></i>
cyc130
</span>
</a>
</div>
<div class="col-md-8">
<div class="property-info">
<div class="price"><span>175.000</span><strong>€</strong></div>
<div class="title">
<a href="/propertydetails.aspx?SalePropertyID=636364" title="Country House in Not Specified">
Country House in Not Specified
</a>
</div>
<span class="location"><i class="fa fa-map-marker"></i> Andalucia, SPAIN</span>
<p>;.lkijuhygtfrdeswaq</p>
</div>
<div class="property-amenities clearfix">
<span id="spbeds"><strong>3</strong>Bedrooms</span>
<span id="spbaths"><strong>1</strong>Bathrooms</span>
<span id="sppool"><strong>Yes</strong>Pool</span>
</div>
</div>
</li>
<br> <br>
<div class="pagination">
<span class="disabled"><i class="fa fa-chevron-left"></i></span>
1
2
3
4
<i class="fa fa-chevron-right"></i>
</div>
</ul>
</div>
I'm just gonna go ahead and make up my own HTML structure to demonstrate the simple if/else statement you would make with jQuery.
function hideFields() {
$(".result").each( function() {
if ( $(this).hasClass("land") ) {
$(this).children(".bedroom").hide();
$(this).children(".bathroom").hide();
}
else if ( $(this).hasClass("villa") ) {
$(this).children(".land-area").hide();
}
});
}
hideFields();
span {
display:block;
border:1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<div class="result villa"><b>Villa</b><br>
<span class="bedroom">Bedroom</span>
<span class="bathroom">Bathroom</span>
<span class="location">Location</span>
<span class="land-area">Land-area</span>
</div>
<br>
<div class="result land"><b>Land</b><br>
<span class="bedroom">Bedroom</span>
<span class="bathroom">Bathroom</span>
<span class="location">Location</span>
<span class="land-area">Land-area</span>
</div>
Your HTML seems confusing for multiple reasons, which you can easily fix to use this method:
1) sppools, spbaths, spbeds should indeed be classes rather than IDs. This is due to IDs being unique identifiers - they should hence not appear more than once on each page, whereas classes identify a "type" (class) of item, which may appear multiple times. Multiple instances of the same ID will mess with your CSS and JS.
2) There is no clear definition within each result of what type of result this is (or I can't seem to find it, at least?).
Words like "villa" or "house" indeed appear in the title-tag, but having to search within these is an inefficient way of performing the action.
Instead, make your code show the type of content as a class on each li-item or the initial div-item.

How to select only one li element using javascript?

This should be an easy fix but I just can't wrap my head around javascript selectors just yet. I have a list of h3 li elements that each contain content that is shown on click. I want a toggle arrow to change from up to down on click. But with the JS code below this happens for all li elements including the one for which the collapsed content is not showing. How can I fix this?
$(document).ready(function () {
$('#toggle-view li').click(function () {
var text = $(this).children('div.panel');
if (text.is(':hidden')) {
text.slideDown('200');
$("h3 .fa-caret-up").removeClass("fa-caret-up").addClass("fa-caret-down");
} else {
text.slideUp('200');
$("h3 .fa-caret-down").removeClass("fa-caret-down").addClass("fa-caret-up");
}
});
});
Here is the html in case you need it:
<ul class="services-ul facebook-ul" id="toggle-view">
<li>
<h3><i class="fa fa-check"></i>Header 1<i class="fa fa-caret-up"></i></h3>
<span>+</span>
<div class="panel">
<p>dummy text...</p>
</div>
</li>
<li>
<h3><i class="fa fa-check"></i>Header 2<i class="fa fa-caret-up"></i></h3>
<span>+</span>
<div class="panel">
<p>dummy text...</p>
</div>
</li>
<li>
<h3><i class="fa fa-check"></i>Header 3<i class="fa fa-caret-up"></i></h3>
<span>+</span>
<div class="panel">
<p>dummy text...</p>
</div>
</li>
<li>
<h3><i class="fa fa-check"></i>Header 4<i class="fa fa-caret-up"></i></h3>
<span>+</span>
<div class="panel">
<p>dummy text...</p>
</div>
</li>
</ul>
You need to specify the elements relative to this (which within your click event is the li element which has been clicked on).
Simply wrap this in a jQuery selector ($(this)), then use jQuery's find() method to find the elements contained within it:
$(this).find('.fa-caret-up').removeClass('.fa-caret-up').addClass('.fa-caret-down');
And:
$(this).find('.fa-caret-down').removeClass('fa-caret-down').addClass('fa-caret-up');

Categories

Resources