JavaScript: Get parent element values on click event - javascript

I'm completely new to JavaScript and struggling to get this working. I'm trying to display contact details in an alert box when a button is clicked.
The information is displayed in nested DIVs outlined below:
<div class="info-and-actions">
<div class="info">
<div class="name-container">
<h4 class="name">Trader 1</h4>
</div>
<div class="details-container">
<p class="tele">###############</p>
<p class="email">hello#url.com</p>
</div>
<div class="actions">
<button class="displayContactDetails">Display contact details</button>
</div>
</div>
</div>
<div class="info-and-actions">
<div class="info">
<div class="name-container">
<h4 class="name">Trader 2</h4>
</div>
<div class="details-container">
<p class="tele">###############</p>
<p class="email">hello#url.com</p>
</div>
<div class="actions">
<button class="displayContactDetails">Display contact details</button>
</div>
I am using this JavaScript with an event listener on the displayContactDetails button to display the contact details in the alert box.
function displayContactDetails() {
var contactName = document.querySelector("a.name-link.profile-link").textContent;
var contactTele = document.querySelector("p.tele").textContent;
alert("Contact " + contactName + " on " + contactTele);
}
This currently displays the first trader's contact details when any displayContactDetails button is clicked.
What I want to do is select the relevant contact information from the parent elements of the button (.name-container and .details-container) - so when the second button is clicked, Trader 2's details are displayed.
How do I traverse the DOM to achieve this?

Your event will have the necessary info to locate the corresponding telephone element.
function displayContactDetails(e) {
var contactName = e. currentTarget // this is the element that has the click listener
.parentNode // this would be .actions div
.parentNode // this would be .info div
.querySelector('.name a') // the link with the name
.innerHTML; // the inner contents of the link, in this case the name
// repeat but change querySelector to grab the telephone
alert("Contact " + contactName + " on " + contactTele);
}
or easier with jquery
$('.displayContactDetails').on('click', function(e){
var name = $(this)
.closest('.info') // goes up in the tree until .info
.find('.name').html(); // then back to .name and get content
alert(name);
});
With jquery it is not only easier, but it is also more resilient to changes in the html structure. Jquery will go up the DOM tree until it finds the .info div. With plain js you have to hardcode the number of times to jump to the parent element, or make a loop for it.
You can also try the other answers suggested but you also have to maintain the additional id's and markup required for it to work.

i hope passing a unique info on the function call
function displayContactDetails(id){
var contactName = document.getElementById("name-link-"+id).textContent;
alert("Contact " + contactName );
}
<div class="info-and-actions">
<div class="info">
<div class="name-container">
<h4 class="name">Trader 1</h4>
</div>
<div class="details-container">
<p class="tele">###############</p>
<p class="email">hello#url.com</p>
</div>
<div class="actions">
<button class="displayContactDetails" onclick="displayContactDetails('one')">Display contact details</button>
</div>
</div>
</div>
<div class="info-and-actions">
<div class="info">
<div class="name-container">
<h4 class="name">Trader 2</h4>
</div>
<div class="details-container">
<p class="tele">###############</p>
<p class="email">hello#url.com</p>
</div>
<div class="actions">
<button class="displayContactDetails" onclick="displayContactDetails('two')">Display contact details</button>
</div>

Related

how to target the element above my show more button

i want to target the element above my show more button, so when i click the button more text appears i don't want to target it by class name or id
here is my code
<div class="ccontainer" id="ccontainer">
<p id="context"> content </p>
<div class="img" id="cntimgcon" >
<img src="images\image2.jpg" id="cntimgp1">
</div>
<p id="context"> content </p>
</div>
<Button id="showmore" onclick=" this.parentElement.style.maxHeight = 'none'"> show more </button>
Don't refer to the IDs that can get cumbersome. Instead give your show more button a class to refer to. That will give you the ability to add many to the same page without needing to adjust/track the IDs.
This is a basic example that toggles a class on the content div that will show the full div. Obviously the details are up to your specific needs.
Using previousElementSibling allows you to refer to the previous element.
document.addEventListener("click",function(e){
let btn = e.target;
if(btn.className.indexOf("showmore") > -1){
btn.previousElementSibling.classList.toggle("active");
}
});
.ccontainer{
height:50px;
overflow:hidden;
border:1px solid #000;
margin:10px 0;
padding:10px;
}
.ccontainer.active{
height:auto;
}
<div class="ccontainer">
<p id="context"> content </p>
<div class="img" id="cntimgcon" >
<img src="images\image2.jpg" id="cntimgp1">
</div>
<p id="context"> content </p>
</div>
<Button class="showmore"> show more </button>
<div class="ccontainer">
<p id="context"> content3 </p>
<div class="img" id="cntimgcon" >
<img src="images\image2.jpg" id="cntimgp1">
</div>
<p id="context"> content4 </p>
</div>
<Button class="showmore"> show more </button>
When using jQuery you can use:
$(this).prev(); // $(this) is equal to the button
// or very specific
$(this).prev(".container");
Using vanilla JS you could use something like
onclick="this.previousSibling"
not sure if vanilla js has a way of selecting a previous node by identifier.
Any whitespace or comment block is also considered a previousSibling, so be careful with that.
html
<div>
<div class="ccontainer" id="ccontainer">
<p id="context"> content </p>
<div class="img" id="cntimgcon" >
<img src="images\image2.jpg" id="cntimgp1">
</div>
<p id="context"> content </p>
</div>
<Button id="showmore" onclick="hideParent(this)"> show more </button>
</div>
js
function hideParent(elm){
console.log(elm.previousElementSibling.innerHTML )
}
see https://jsfiddle.net/rkqnmv0w/
If your using only vanila JS you can access the previous element with the previousElementSibling property.
Example:
var showMoreButton = document.getElementById('showmore');
var previousElement = showMoreButton.previousElementSibling;

Javascript keeps modal hidden

I'm having 2 small issues with some JS below involving a modal and cloning/appending an image:
A button click opens the modal, the modal contains a search bar which populates the content with images. When an image is clicked, it's cloned and appended into another div (outside of modal on the main page) and the modal is closed.
After this is done one time, the button click no longer opens the modal again. How can I alter so that the appending of the images closes the modal but it can be re-opened?
Also, once the image is appended to a new div, if I click it it disappears. Is there a way to only append the image source without the class tag so that clicking on it in the new div won't make it disappear?
function appendSomeItems(url, id, name, style) {
return '<div><div class="md-card md-card-hover"> <div class="gallery_grid_item md-card-content getImage"> <img class ="uk-align-center imageClick" src="https://media.testsite' + url + '" alt=""></a> <div class="gallery_grid_image_caption"> <span class="gallery_image_title uk-text-truncate">' + name + '</span> <span>' + style + '</span> </div></div></div></div>';
}
$(document).on('click', '.imageClick', function handleImage() {
console.log('good');
var img = $(this).closest(".getImage").children("img").clone(true);
$("#holdImage").html('');
$("#holdImage").append(img);
$('#image-modal').hide();
});
<!--image placeholder->
<div id="holdImage" style="margin-top: 15px;">
</div>
<!--open modal-->
<div style="text-align: center;">
Choose an existing image
</div>
<!--Modal-->
<div id="image-modal" class="uk-modal">
<div class="uk-modal-dialog" style="width:80%;">
<a class="uk-modal-close uk-close"></a>
{!! Form::open(array('id' => 'search_form')) !!}
<div class="uk-grid">
<div class="uk-width-1-1">
<div class="md-card">
<div class="md-card-content">
<div class="input-group">
<input type="text" class="md-input" placeholder="Search" name="srch-term" id="srch-term">
<p class="text-center">Search for images by Name </p>
</div>
</div>
</div>
</div>
</div>
{!! Form::close() !!}
<br/>
<div id="imageResult" class="gallery_grid uk-grid-width-medium-1-5 uk-grid-width-large-1-6" data-uk-grid="{gutter: 16}">
</div>
<button style="display: none;" id="hidden_button"></button>
</div>
</div>
Main problem seems to be that you are hiding the entire modal using Jquery's hide() message (which will set display:none; on the element) rather than calling the modal's hide() message. This has also been mentioned on the Git repository as can be seen here.
Solution would be to call the proper hide method like so:
var modal = UIkit.modal("#image-modal");
modal.hide();
instead of
$('#image-modal').hide();
Regarding the other question: remove the class that has the click handler attached before adding it to the #holdImage placeholder:
var img = $(this).closest(".getImage").children("img").clone(true);
img.removeClass("FillInClassNameHere");
$("#holdImage").html('');
$("#holdImage").append(img);
As I don't have the class name for it, you will need to change FillInClassNameHere with the proper class name in your code.

Get parent div recursively

I have this HTML
<div id="main-container">
<div style="style-here" data-status="active" data-state="loaded">
<div style="style-here">
<div style="style-here" {{click_event}}></div>
</div>
</div>
<div style="style-here" data-status="active" data-state="unloaded">
<div style="style-here">
<div style="style-here" {{click_event}}></div>
</div>
</div>
<div style="style-here" data-status="inactive" data-state="unloaded">
<div style="style-here">
<div style="style-here" {{click_event}}></div>
</div>
</div>
</div>
On click on one of the elements that has {{click_event}} I want to search recursively till I can find an element that has data-status or data-state, and in the worst case when I meet the id from top to stop de search.
The HTML is made generated from another JS file and I can't change the way is made it. Is there a way with closest or parent from jQuery to search after data attribute?
Thank you.
No need for recursion, you can use closest():
$clickedElement.click(function() {
var $parent = $(this).closest('[data-status], [data-state], #main-container');
});

Jquery slideToggle particular div

Respected ppl ...
This is my markup :
<div class="row-fluid">
<div class="span12 card card-even">
<div>
<h3>Case 1</h3>
Hide the subsection
</div>
<div class = "timeline">
<div class= "circle circle-green " data-toggle="tooltip" title="Task 2 ">
<span></span>
</div>
<div class="rect-fixed"></div>
</div>
<div class="subsection"><span>Panther a</span></div>
</div> <!-- end of card 1-->
</div>
<div class="row-fluid">
<div class="span12 card card-odd">
<div>
<h3>Case 1</h3>
Hide the subsection
</div>
<div class = "timeline">
<div class= "circle circle-green " data-toggle="tooltip" title="Task 2 ">
<span></span>
</div>
<div class="rect-fixed"></div>
</div>
<div class="subsection"><span>Panther b</span></div>
</div> <!-- end of card 2-->
</div>
I have an app which generates multiple alternating cards(row-fluids) which are even/odd with a button "hiderBUTTON" to hide the div with the class=subsection
But im unable to link the button of a particular row with its corresponding subsection ....
How do i use the this keyword correctly and target a button's subsection for a given row ...
Thanks very much ....
Regards
Like this?
$('.hiderBUTTON').click(function(e){
e.preventDefault();
$(this).closest('.card').find('.subsection').toggle();
});
Use .closest() to get to the its root parent of each subsection and button parent i.e .card and the use find to get the subsection and use toggle to switch it or just use .hide() to hide it.
Demo
With text toggling b/w show/hide
$('.hiderBUTTON').click(function (e) {
e.preventDefault();
var $this = $(this);
$this.closest('.card').find('.subsection').toggle();
$this.text(function(_, text){
return text == "Hide the subsection" ? "Show the subsection" : "Hide the subsection";
})
});
Demo

How to get an element inside nested divs by class name?

A webpage with HTML looks like this:
<div id="Parent-div" > </div>
<div class="first-child-div"> </div>
<div class=" second-child-div">
<div class="first-grand-child"> </div>
<div class="second-grand-child"> </div>
<div class="Third-grand-child">
<div class="Grand-grand child">
<button class="Confirm-button">Confirm!</button>
</div>
</div>
</div>
I've Tried This code using greasemonkey to remove
a button from the div with the class named "Grand-grand child"
This is what I did:
var targetDiv = document.querySelector("#<Parent-div>. Grand-grand.child");
targetDiv.innerHTML = "Hello world!";
The Button wasn't replaced by the Hello world! text, What did I do wrong?
document.querySelector('.Grand.grand.child');
Demo: http://jsfiddle.net/yGv3v/
You should change <div class=" Grand grand child"> to <div class="Grand-grand-child"> and then you can select it with $('.Grand-grand-child').
Edit
If you want to use pure JavaScript, then you can select the node element via
var grandChildChildNode = document.getElementsByClassName('Third')[0].children[0]
This should work in sufficiently modern browsers.

Categories