Cannot get element inside distant parent div using jQuery - javascript

In a dom which has many of the blocks like the one below, I'd like to get name of pid element (i.d 123) when link is clicked:
<div class="a-post">
<a class="pid" name="123"></a>
<div class="row">
<p>Some text</p>
</div>
<br>
<div class="row">
<div class="col-xs-12">
<p>Othe text </p>
</div>
<br>
<div class="row">
<div class="col-xs-1">
<img class="link" src="link.svg">
</div>
</div>
</div>
</div>
Here is my jQuery:
$(document).ready(function () {
$(".link").click(function () {
let pid = $(this).parent(".a-post").find(".pid").attr('name');
console.log('pid is:', pid);
}
});
But I get pid is: undefined
How can I fix this?

You have to use .closest() and not .parent(), because .parent() only goes 1 step up. .closest() will continue until it reach the top or finds the element.
$(document).ready(function() {
$(".link").click(function() {
let pid = $(this).closest(".a-post").find(".pid").attr('name');
console.log('pid is:', pid);
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="a-post">
<a class="pid" name="123"></a>
<div class="row">
<p>Some text</p>
</div>
<br>
<div class="row">
<div class="col-xs-12">
<p>Othe text </p>
</div>
<br>
<div class="row">
<div class="col-xs-1">
<img class="link" src="link.svg">
</div>
</div>
</div>
</div>

Related

How to run a function when one button is clicked without changing other id values

I have 2 columns with same ID, each have 1 button. How to run a function when one button is clicked without changing other ID values?
Here is my code:
<div class="row">
<!--- column 1 ------>
<div class="column nature">
<div class="content">
<img src="images/pic.jpg" alt="Jane" style="width:100%">
<div class="container">
<p class="title" style="text-align:center;">SCA5-01</p>
<div style="text-align:center;">
<div id="hrg" style="font-size:5vw;font-weight:bold;">2000</div>
<div id="per">/500</div>
</div>
<div style="width:100%;margin:0px 5%;display:block;">
<div style="font-size:2vw;">
<br>Spect :
<br>- New
<br>- Fresh
</div>
</div>
<p>
<div style="width:100%;margin:0px auto;text-align:center;">
<input id="jmlh" type="number" value="500" style="width:50%;">
<button onclick="price();">chek</button>
</div>
</p>
<p>
<button class="button">Order</button>
</p>
</div>
</div>
</div>
<!--- column 1 ------>
<div class="column nature">
<div class="content">
<img src="images/pic.jpg" alt="Jane" style="width:100%">
<div class="container">
<p class="title" style="text-align:center;">SCA5-01</p>
<div style="text-align:center;">
<div id="hrg" style="font-size:5vw;font-weight:bold;">2000</div>
<div id="per">/500</div>
</div>
<div style="width:100%;margin:0px 5%;display:block;">
<div style="font-size:2vw;">
<br>Spect :
<br>- New
<br>- Fresh
</div>
</div>
<p>
<div style="width:100%;margin:0px auto;text-align:center;">
<input id="jmlh" type="number" value="500" style="width:50%;">
<button onclick="price();">chek</button>
</div>
</p>
<p>
<button class="button">Order</button>
</p>
</div>
</div>
</div>
</div>
Here is my function:
<script>
function price(){
var qty = document.getElementById("jmlh").value;
var prc = Math.ceil((1000000 / qty)/100)*100;
document.getElementById("hrg").innerHTML = prc;
document.getElementById("per").innerHTML = "/" + qty;
}
</script>
The problem here is that function only runs on 'column 1' & doesn't work on 'column 2'.
Where exactly am I going wrong?
id should be unique in the same document. Use classes or other attributes instead of id.
If you want centralized function to handle clicks, submit the clicked element itself to that function, so it would know which column was clicked:
<div class="column nature">
<div class="content">
<img src="images/pic.jpg" alt="Jane" style="width:100%">
<div class="container">
<p class="title" style="text-align:center;">SCA5-01</p>
<div style="text-align:center;">
<div class="hrg" style="font-size:5vw;font-weight:bold;">2000</div>
<div class="per">/500</div>
</div>
<div style="width:100%;margin:0px 5%;display:block;">
<div style="font-size:2vw;">
<br>Spect :
<br>- New
<br>- Fresh
</div>
</div>
<p>
<div style="width:100%;margin:0px auto;text-align:center;">
<input class="jmlh" type="number" value="500" style="width:50%;">
<button onclick="price(this);">chek</button>
</div>
</p>
<p>
<button class="button">Order</button>
</p>
</div>
</div>
</div>
function price(el){
const elContainer = el.closest(".container");// find parent
var qty = elContainer.querySelector(".jmlh").value;
var prc = Math.ceil((1000000 / qty)/100)*100;
elContainer.querySelector(".hrg").innerHTML = prc;
elContainer.querySelector(".per").innerHTML = "/" + qty;
}
Note, that all id were replaced by class attribute and in javascript instead of searching entire document with document.getElementById() it's now only searching children inside the .container element.

Reset Image Gallery Count When Loading New Article Content

I have a lots of articles that have 1, 2, 3 or 4 pictures. On mobile I created a carousel. All images all on the same line and I have a count that is 0. And when I press on the right button(for example) that count it will be -100 and all images will have a left: -100 and so on. The problem is that, let's say, I press on the button from one article that count will be -100. but after I go to another article and if I press again the count is not -100 and is -200. How can I reset that count when I change the article. The code is something like:
var c = 0;
$('.plus').on('click', function(){
c += 100
$(this).siblings('.num').text(c)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="article">
<div class="minus">Minu</div>
<div class="plus">Plus
</div><div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu2</div>
<div class="plus">Plus2
</div><div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu3</div>
<div class="plus">Plus3
</div><div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu4</div>
<div class="plus">Plus4
</div><div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu5</div>
<div class="plus">Plus5
</div><div class="num">0</div>
</div>
Here's what I cooked up for you.
$('.plus').on('click', function(){
c = Number($(this).siblings('.num').text()) + 100;
$(this).siblings('.num').text(c)
});
$('.minus').on('click', function(){
c = Number($(this).siblings('.num').text()) - 100;
$(this).siblings('.num').text(c)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="article">
<div class="minus">Minu</div>
<div class="plus">Plus</div>
<div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu2</div>
<div class="plus">Plus2</div>
<div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu3</div>
<div class="plus">Plus3</div>
<div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu4</div>
<div class="plus">Plus4</div>
<div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu5</div>
<div class="plus">Plus5</div>
<div class="num">0</div>
</div>
The Plus button will add to the total displayed for the current article and Minus will subtract from it. Every article has it's own c value that can't be changed by a button from a different article.
I hope that's what you are looking for.
Add an on('click', function() {...}) handler to your "change the article" button. If this button is just another article's text, then give them all a common class and a common class onclick handler.
HTML...
<span class="article">Article 1</span>
<span class="article">Article 2</span>
<span class="article">Article 3</span>
jQuery...
$('.article').on('click', function() {
c = 0;
});

Clone one span into another for each group of div

I have many sets of div and I'm trying to copy the content of a specific span into another one and repeat the same operation for all my divs.
Here is my html code:
<div class="item">
<div class="row">
<div class="col-md-12">
<span class="ContentGoesHere"></span>
</div>
</div>
<div class="DivWithContent">
<span class="ContentComesFromHere">This is my content 1</span>
</div>
</div>
<div class="item">
<div class="row">
<div class="col-md-12">
<span class="ContentGoesHere"></span>
</div>
</div>
<div class="DivWithContent">
<span class="ContentComesFromHere">This is my content 2</span>
</div>
</div>
<div class="item">
<div class="row">
<div class="col-md-12">
<span class="ContentGoesHere"></span>
</div>
</div>
<div class="DivWithContent">
<span class="ContentComesFromHere">This is my content 3</span>
</div>
</div>
And my jQuery code is:
$("div.item").each(function(i) {
$(this).find('span.ContentComesFromHere').clone(true, true).contents().appendTo('span.ContentGoesHere');
});
It almost works, right now what I get in my span.ContentGoesHere is: This is my content 1This is my content 2This is my content 3 - and it's the same content for all but the content needs to be specific to each div.item.
Thank you for your help.
Try The code below
$("div.item").each(function(i) {
$(this).find('span.ContentComesFromHere')
.clone(true,true).contents()
.appendTo($(this).find('span.ContentGoesHere'));
});
To See The demo in jsFiddle
Click here to see Demo In JsFiddle
Try the code bellow.
$("div.item").each(function(i) {
var content = $(this).find('span.ContentComesFromHere').html();
$(this).find('span.ContentGoesHere').html(content);
});
If you type your function like this:
$("div.item").each(function(i) {
let content = $(this).find('span.ContentComesFromHere');
let contentTarget = $(this).find('span.ContentGoesHere');
content.clone().appendTo(contentTarget);
});
Then the end result will looks like this:
This is my content 1
This is my content 1
This is my content 2
This is my content 2
This is my content 3
This is my content 3
See snippet for the working code.
$("div.item").each(function(i) {
let content = $(this).find('span.ContentComesFromHere');
let contentTarget = $(this).find('span.ContentGoesHere');
content.clone().appendTo(contentTarget);
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<div class="item">
<div class="row">
<div class="col-md-12">
<span class="ContentGoesHere"></span>
</div>
</div>
<div class="DivWithContent">
<span class="ContentComesFromHere">This is my content 1</span>
</div>
</div>
<div class="item">
<div class="row">
<div class="col-md-12">
<span class="ContentGoesHere"></span>
</div>
</div>
<div class="DivWithContent">
<span class="ContentComesFromHere">This is my content 2</span>
</div>
</div>
<div class="item">
<div class="row">
<div class="col-md-12">
<span class="ContentGoesHere"></span>
</div>
</div>
<div class="DivWithContent">
<span class="ContentComesFromHere">This is my content 3</span>
</div>
</div>
See it working
Your way
$("div.item").each(function(i) {
var targetElement = $(this).find('span.ContentGoesHere');
var sourceHtml = $(this).find('span.ContentComesFromHere').clone().contents()
sourceHtml.appendTo(targetElement);
});
Simpler way
$("div.item").each(function(i) {
var contents = $(this).find('span.ContentComesFromHere').html();
$(this).find('span.ContentGoesHere').html(contents);
});
In your case you need find the source and target both by $(this).find()
Just replace to .appendTo($(this).find('span.ContentGoesHere')); into your JS code and I hope it will be work.

jquery on click appear another element in html

for example I have this html code:
<div class="product">
<p>Name1<p>
</div>
<div class="product">
<p>Name2<p>
</div>
<div class="product">
<p>Name3<p>
</div>
<div class="product">
<p>Name4<p>
</div>
<div class="settings">
<p>SETTINGS<p>
</div>
I made settings class to display nothing in css, unless I click on one of 4 p elements in product class. After click the settings class appears at the bottom as it should be.
How should I make that if I click for example Name2 then settings class appears after Name2 and not at the bottom?
Use $(this) to target the element you clicked on, combined with insertAfter() to add the content to this element.
Run the code snippet below and click on any of the elements with the classname product to see how this works.
$(".product").click(function(){
$(".settings").insertAfter($(this));
});
$(".product").click(function(){
$(".settings").insertAfter($(this));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="product">
<p>Name1
<p>
</div>
<div class="product">
<p>Name2
<p>
</div>
<div class="product">
<p>Name3
<p>
</div>
<div class="product">
<p>Name4
<p>
</div>
<div class="settings">
<p>SETTINGS
<p>
</div>
You can use .insertAfter() :
$(function(){
$('.product p').click(function(){
$('.settings').insertAfter($(this).closest('.product '))
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="product">
<p>Name1<p>
</div>
<div class="product">
<p>Name2<p>
</div>
<div class="product">
<p>Name3<p>
</div>
<div class="product">
<p>Name4<p>
</div>
<div class="settings">
<p>SETTINGS<p>
</div>
You can do it like,
$(".product > p").click(function(){
var $parent = $(this).parent(".product");
$parent.siblings(".settings").insertAfter($parent);
});
by using .insertAfter()
DEMO

fadeOut() only fades out the first element

By default, I have several DIVs hidden and then I fade them in when the user clicks on a certain button. That works fine but when I try to close a .holder DIV using a span within said .holder DIV, only the first one works. When I click the others, nothing happens. I get no error or any sort of visual feedback whatsoever.
The markup:
<div class="holder" id="window_one">
<div class="title_bar">
<p>Window 1</p>
<div class="control_holder">
<span class="controls" id="close">X</span>
<span class="controls" id="minimize">_</span>
</div>
</div>
<div class="interface">
<p>Testing123</p>
</div>
</div>
<div class="calculator" id="window_two">
<div class="title_bar">
<p>Window 2</p>
<div class="control_holder">
<span class="controls" id="close">X</span>
<span class="controls" id="minimize">_</span>
</div>
</div>
<div class="interface">
<p>Testing123</p>
</div>
</div>
The jQuery:
$(document).ready(function() {
$('#close').click(function() {
$(this).parents('.holder').fadeOut(250);
});
});
What exactly am I doing wrong here? I'm using jQuery 1.10.2 if that makes any difference.
I'd demo the code on jsFiddle but is seems to be down atm.
You can not have the same id of two element on the page. If you want to do that give it as a class name like -
<div class="holder" id="window_one">
<div class="title_bar">
<p>Window 1</p>
<div class="control_holder">
<span class="controls close">X</span>
</div>
</div>
<div class="interface">
<p>Testing123</p>
</div>
</div>
<div class="calculator" id="window_two">
<div class="title_bar">
<p>Window 2</p>
<div class="control_holder">
<span class="controls close">X</span>
</div>
</div>
<div class="interface">
<p>Testing123</p>
</div>
</div>
and the Jquery like -
$(document).ready(function() {
$('.close').click(function() {
$(this).parents('.holder').fadeOut(250);
});
});
Hope this will help.
Here is how it should be:
<div class="holder" id="window_one">
<div class="title_bar">
<p>Window 1</p>
<div class="control_holder">
<span class="controls close">X</span>
</div>
</div>
<div class="interface">
<p>Testing123</p>
</div>
</div>
<div class="calculator" id="window_two">
<div class="title_bar">
<p>Window 2</p>
<div class="control_holder">
<span class="controls close">X</span>
</div>
</div>
<div class="interface">
<p>Testing123</p>
</div>
</div>
and the JavaScript:
$(document).ready(function() {
$('.close').click(function(e) {
$(this).parents('.holder').forEach(function(){
$(this).fadeOut(250);
});
e.preventDefault();
});
});

Categories

Resources