Targeting a div with the right selector - javascript

My HTML:
<tr class="main">
<td class="dropdown">
<a href="#">
<div class="dropdown-image"></div>
</a>
</td>
<td class="from">from</td>
<td class="subject">subject</td>
<td class="received">received</td>
<td class="status">Quarantined</td>
<td class="action">
<a href="#">
<div class="dropdown-menu"></div>
</a>
</td>
</tr>
I am trying to target the .dropdown-menu to change it's background image once the .dropdown-image has been clicked.
My JavaScript:
$(function) {
$('.dropdown-image').click(function() {
var clicks = $(this).data('clicks');
var td = $(this).parent().parent();
var tr = $(this).parent().parent().parent();
if (clicks) {
td.closest('.action').child().child().css("background-image", "url(images/new-arrow.png)");
} else {
td.closest('.action').child().child().css("background-image", "url(images/new-arrow-blue.png)");
}
$(this).data("clicks", !clicks);
});
});
However, this doesn't work. How can I target the .dropdown-menu correctly?

You seem to be trying to use the .closest() method to find the sibling '.action' element, but that's not what .closest() does. As explained in the doco, it looks for a matching ancestor element. So you can get the tr element that the clicked div belongs to like this:
var tr = $(this).closest("tr");
And then you can find the dropdown-menu div that belongs in that tr using .find() method - which is like the opposite of .closest() in that it looks for a descendant:
tr.find(".dropdown-menu")
In other words, to find the related .dropdown-menu, navigate up to the tr with .closest() and then back down to the related div with .find().
$(function() {
$('.dropdown-image').click(function() {
var $this = $(this),
clicks = $this.data('clicks'),
$relatedDiv = $this.closest("tr").find(".dropdown-menu");
if (clicks) {
$relatedDiv.css("background-image", "url(images/new-arrow.png)");
} else {
$relatedDiv.css("background-image", "url(images/new-arrow-blue.png)");
}
$this.data("clicks", !clicks);
});
});
Note that I only call $(this) once, putting the result in a variable. This is more efficient.
Also, as has been pointed out in comments, you have two syntax errors:
the first line should be $(function() { (you have incorrect parentheses)
the third-last line is missing a " before the comma.

JS
$(function () {
$('.dropdown-image').click(function () {
var $relatedDiv = $(this).parents('tr.main').find('.dropdown-menu');
$relatedDiv.toggleClass('bg-image-new-arrow-blue');
$relatedDiv.toggleClass('bg-image-new-arrow');
});
});
css
.bg-image-new-arrow{
color: red;
font-size: 12px;
background: url(images/new-arrow.png) no-repeat;
}
.bg-image-new-arrow-blue{
color: blue;
font-size: 23px;
background: url(images/new-arrow-blue.png) no-repeat;
}
html
<table>
<tr class="main">
<td class="dropdown">
<a href="#">
<div class="dropdown-image">asasdasdd</div>
</a>
</td>
<td class="from">from</td>
<td class="subject">subject</td>
<td class="received">received</td>
<td class="status">Quarantined</td>
<td class="action">
<a href="#">
<div class="dropdown-menu bg-image-new-arrow-blue">DropDown menu</div>
</a>
</td>
</tr>
</table>
The related is code-pen is in this link

Related

add OnClick event on a div

I'm trying to add an event of a button that is in a div.
HTML :
<template id="modele-panier" type="text/AhuntsicModele">
<div class="dialog-item">
<table>
<tr>
<td>
<img src={cheminImage} alt="">
</td>
<td>
<h2>Article : {libelleProduit}</h2>
<p>Qte : {qteProduit} prix : {prixProduit}$</p>
</td>
<div class="supp">
<td>
Supprimer
</td>
</div>
</tr>
</table>
</div>
</template>
Controler.js
document.addEventListener('click', function (e) {
if (e.target && e.target.matches('button')) {
controleur.ajouterPanier(e.target.id);
} else if (e.target && e.target.matches('#main')) {
controleur.loadCatalogue();
} else if (e.target && e.target.matches('#getBMW')) {
controleur.loadBMW();
} else if (e.target && e.target.matches('#getAudi')) {
controleur.loadAudi();
} else if (e.target && e.target.matches('#getMercedes')) {
controleur.loadMercedes();
} else if (e.target && e.target.matches('#icone_compte')) {
controleur.creationCompte();
} // THIS EVENT RIGHT HERE :
else if (event.target.matches('supp')) {
alert(e.target.id)
controleur.supprimerItem();
}
});
Im not able to add the event to the div class supp all the other are working fine since im not using a div class for the other ones.
Thanks
you could use this
const div = document.getElementsByClassName("supp");
else if (div[0]!=undefined) {
alert(e.target.id)
controleur.supprimerItem();
}
hope it helps
If I understand correctly, you'd like your controller logic to detect and process click events on the element with the supp class.
To achieve that with minimal changes to your code, you could do the following via the classList interface:
document.addEventListener('click', function(e) {
/* Existing code removed for bervity */
/* Use classList.contains method to check if target element has supp class */
if (event.target.classList.contains('supp')) {
alert(e.target.id)
controleur.supprimerItem();
}
});
<table>
<tr>
<td><img src="https://via.placeholder.com/150" alt=""></td>
<td>
<h2>Article : {libelleProduit}</h2>
<p>Qte : {qteProduit} prix : {prixProduit}$</p>
</td>
<div class="supp">
<td>Supprimer </td>
</div>
</tr>
</table>
I'm assuming that the click handler is targeting elements that are dynamically added to the DOM (which is why you're running the if/else if check inside of the click handler?) - another approach to this logic that might give you a bit more flexibility would be to query the DOM via a CSS-like selector and the querySelector() method:
document.addEventListener('click', function(e) {
/* Existing code removed for bervity */
/* Query document during click for first .supp relative to table */
const suppDiv = document.querySelector("table .supp")
if(suppDiv) {
alert('clicked .supp')
}
});
<table>
<tr>
<td><img src="https://via.placeholder.com/150" alt=""></td>
<td>
<h2>Article : {libelleProduit}</h2>
<p>Qte : {qteProduit} prix : {prixProduit}$</p>
</td>
<div class="supp">
<td>Supprimer </td>
</div>
</tr>
</table>
Hope that helps!
You are trying to use a function parameter event, which isn't called in your function. You named the parameter e in your function.
Also, .matches() checks if an element would normally be targeted based on a selector string. Which is what you would normally use to target elements with document.querySelector(). So supp should be changed to .supp.
So your code should work when you change it to:
} else if (e.target.matches('.supp')) {
controleur.supprimerItem();
}
Or even:
} else if (e.target && e.target.matches('.supp')) {
controleur.supprimerItem();
}
Like the rest of your if-statements.
Here is a snippet to show that this code should work as intended:
document.addEventListener("click", function (e) {
if (e.target && e.target.matches(".supp")) {
alert("It works");
}
});
.supp {
width: 100px;
height: 100px;
background-color: blue;
color: white;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
<div class="supp">Click me</div>

Javascript - Show/change image on hover

I have a table on one side and an area for an image on the right.
When a row within the table is hovered over, I want a different image to display.
There will end up being 20 rows of data, with 20 respective images.
I have javascript:
document.getElementById("showlot1").mouseover = function() {
document.getElementById("lot1").style.visibility = "visible"; }
document.getElementById("showlot2").mouseover = function() {
document.getElementById("lot2").style.visibility = "visible"; }
CSS:
#lot1, #lot2 { visibility: hidden; }
HTML Table:
<table style="width: 100%;" cellpadding="2">
<tbody>
<tr class="hover">
<td style="text-align: center;">
<a id="showlot1">1</a>
</td>
<td style="text-align: center;">
<a id="showlot1">3.4ha (8.4 acres)</a>
</td>
<td style="text-align: center;">
<a id="showlot1"></a>$99,000</a>
</td>
</tr>
<tr class="hover">
<td style="text-align: center;">
<a id="showlot2">2</a>
</td>
<td style="text-align: center;">
<a id="showlot2">3.5ha (8.6 acres)</a>
</td>
<td style="text-align: center;">
<a id="showlot2">$99,000</a>
</td>
</tr>
</tbody>
</table>
HTML Image Placer:
<img id="lot1" src="/wp-content/uploads/sites/291/2015/02/QA-CONTOUR-LOT1.jpg" />
<img id="lot2" src="/wp-content/uploads/sites/291/2015/02/QA-CONTOUR-LOT2.jpg" />
One simple way would be to do it with css.
HTML
<img id="myimg" src="first_image"/>
CSS
#myimg:hover {
content: url('second_image');
}
See running JSFiddle example here
I found using classes to denote functional elements easier; a bunch of elements with ids (which is illegal by the way, as id's should be unique in the document) I changed to putting a class .showImage on your tr's and targeting them with event listeners.
I used CSS to set images to display:none; by default. This is more ideal than visibility:hidden because they disappear completely and won't take up space.
Instead of using anonymous functions, I split the desired result into two mouseover and mouseout handlers that toggle the display property. You'll see they also take a parameter index, which I used to determine which #lot to target:
function showImageOnMouseover(i) {<change display property to block>}
and
function hideImageOnMouseout(i) {<change display property to none>}
Where i is a variable used to find the right image using your convention #lot<i>
// get elements by class name
var elementSelection = document.getElementsByClassName('showImage');
// attach event listener to each element
for( var i=0; i<elementSelection.length; i++ ) {
elementSelection[i].addEventListener( 'mouseover', showImageOnMouseover(i+1) );
// pass i+1 to index since i starts out as 0. You could just as easily change the for loop to var i=1, or alter your #lot naming convention to start at 0.
elementSelection[i].addEventListener( 'mouseout', hideImageOnMouseout(i+1) );
}
// handle mouseover
function showImageOnMouseover( index ) {
return function(e) {
var imgId = 'lot' + index.toString();
console.log(imgId);
document.getElementById( imgId ).style = ( 'display: block' );
}
}
// handle mouseout
function hideImageOnMouseout( index ) {
return function(e) {
var imgId = 'lot' + index.toString();
document.getElementById( imgId ).style = ( 'display: none' );
}
}
#lot1 {
display: none;
}
#lot2 {
display: none;
}
<table cellpadding="2" style="width: 100%;">
<tbody>
<tr class="hover showImage">
<td style="text-align: center;">
<a>1</a>
</td>
<td style="text-align: center;">
<a>3.4ha (8.4 acres)</a>
</td>
<td style="text-align: center;">
<a></a>$99,000
</td>
</tr>
<tr class="hover showImage">
<td style="text-align: center;">
<a>2</a>
</td>
<td style="text-align: center;">
<a>3.5ha (8.6 acres)</a>
</td>
<td style="text-align: center;">
<a>$99,000</a>
</td>
</tr>
</tbody>
</table>
<img id="lot1" src="http://www.kaybojesen.com/wp-content/uploads/2013/07/505-Dessertske-ni-tre.png" />
<img id="lot2" src="https://www.house.com.au/images/hires/HAG-CU249610.jpg" />

Comparing table tr values before and after and get two objects or arrays with difference

I have a table structure like this,
<table id="dltable" class="dTable">
<tbody>
<tr class="dRow " data-userid="s-1-5-21-34154-1668">
<td class="dCell" style="width:40px;">
<img src="1.png" class="avatar" />
</td>
<td class="dCell" style="vertical-align: top; padding-top:8px;"><span class="personItem">person 1</span>
</td>
<td class="dCell" style="width:30px;">
<div class="dir-list_tick on hide" onclick="toggleSelection(this);" style="display: block;"></div>
</td>
</tr>
<tr class="dRow " data-userid="s-1-5-21-3415-3433">
<td class="dCell" style="width:40px;">
<img src="2.png" class="avatar" />
</td>
<td class="dCell" style="vertical-align: top; padding-top:8px;"><span class="personItem">person 2</span>
</td>
<td class="dCell" style="width:30px;">
<div class="dir-list_tick on hide" onclick="toggleSelection(this);" style="display: block;"></div>
</td>
</tr>
</tbody>
</table>
Now on edit click button, user may toggleSelection,
function toggleSelection(e) {
var obj = $(e);
if (obj.hasClass('on')) {
obj.removeClass("on").addClass("off");
} else {
obj.addClass("on").removeClass("off");
}
}
and CSS
.dir-list_tick.on {
background-image: url(/_layouts/15/images/arrow.png);
background-position: 50%;
width:22px;
height:22px;
}
.dir-list_tick.off {
background-image: url(/_layouts/15/images/arrow_inactive.png);
background-position: 50%;
width:22px;
height:22px;
}
Now what I want is that, when user clicks on Edit button, I capture all users with there ids and statuses (atleast for now) e.g.
var user = { id: userid, status: 1 if image is arrow or class is on and -1 for not}
And then when user clicks on another button Save I want to get all user whoes status (may have more properties in future) has changed from on to off or off to on.
Only way i can think of is to iterate through table again and again to compare them, any easier way of doing it please ?
Edit
Based on comments I think i am on right track but i am stuck here,
var beforeEditUsers = [];
$('#dltable > tbody > tr').each(function () {
beforeEditUsers.push({
id : $(this).attr('data-userid'),
status : // how can i cast div with class dir-list_tick on class as one here and otherwise 0 ?
});
});
Found it
var beforeEditUsers = [];
$('#dltable > tbody > tr').each(function () {
beforeEditUsers.push({
id : $(this).attr('data-userid'),
status : $(this).children('.dir-list_tick').hasClass('on')
});
});

How can I assign an anchor tag to expand content

I have a list of things with links to click for more information which use anchor tags to move down the page. Since there is quite a bit of additional information I have it hidden in expandable/collapsable sections.
So far all I've managed to come up with is an expand collapse on the section itself. I know basically nothing about Javascript so what I have include is some stuff I pieced together from some other sites and research.
I would like for the 'click more' anchor tag link to expand the section automatically when clicked, but something that also collapses it similar to what I have now.
Here is the js I managed to pull together
<script type="text/javascript">
function toggle_visibility(tbid,lnkid) {
if (document.all) {
document.getElementById(tbid). style.display = document.getElementById(tbid).style.display == "block" ? "none" : "block";
}
else {
document.getElementById(tbid).style.display = document.getElementById(tbid).style.display == "table" ? "none" : "table";
}
document.getElementById(lnkid).value = document.getElementById(lnkid).value == "[-] Collapse" ? "[+] Expand" : "[-] Collapse";
}
</script>
<style type="text/css">
.hangingIndent {
text-indent: -24px;
padding-left: 24px;
}
#tbl1 {display:none;}
#lnk1 {
border:none;
background:none;
width:85px;
}
</style>
And here is an example of the body
<body style="background-color: #FFFFFF; margin: 20;">
<p style="font-family: Calibri, sans-serif; font-size: 12pt; padding:0px 20px;" class="hangingIndent">
<input type="checkbox">
<strong>Item one</strong><br />
<em>For more information about Item one click here!</em>
</p>
<br />
<table width="800px" border="0" align="center" cellpadding="4" cellspacing="0">
<tr height="1">
<td bgcolor="#333333" colspan="3"></td>
</tr>
<tr bgcolor="#EEEEEE" height="15">
<td>
<strong><a id="Item1">Item one</a></strong>
</td>
<td bgcolor="#EEEEEE" align="right">
<input id="lnk1" type="button" value="[+] Expand" onclick="toggle_visibility('tbl1','lnk1');">
</td>
</tr>
<tr>
<td colspan="3">
<table width="100%" border="0" cellpadding="4" cellspacing="0" id="tbl1">
<tr>
<td colspan="3">
<p style="font-family: Calibri, sans-serif; font-size: 12pt; padding:0px 20px;">Lots of extra information about Item one</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
<br />
</body>
Thanks for your help!
jquery may be your best route, and in particular the slideToggle or show and hide functions.
In addition, have a peek at jQuery ui accordion
A jquery accordion may be your best route
to hide elements:
document.getElementById(idOfElement).style.display="none"
to show them:
document.getElementById(idOfElement).style.display="block"
lets make a function
function toggleElementDisplay(elementID){
element = document.getElementById(elementID);
if(element.getPropertyValue("display") == "block"){
element.style.display="none";
} else {
element.style.display="block";
}
}
To use it do it like this
<body>
<div id="click" onClick="toggleElementDisplay('stuff');">Toggle</div>
<div id="stuff">Hello</div>
<script>
function toggleElementDisplay(elementID) {
var element = document.getElementById(elementID),
style = window.getComputedStyle(element),
display = style.getPropertyValue("display");
if (display == "block") {
element.style.display = "none";
} else {
element.style.display = "block";
}
}
</script>
</body>
Here is a demo to help

javascript/php simple drop down menu logout

to save space, I would like to consolidate the username and logut buttons at the top of web template into one link. The username would be visible and when you hover over it as in stack overflow or click as in gmail or fb, you have option to logout or do other account related things. Ideally, would like to do this in css or javascript without jquery overhead.
Can anyone recommend simple javascript or other technique as I am very inexperienced in javascript. Don't need complicated full blown drop down menu. It should be something like below, but below is unpredictable...shows menu when page loads etc. Thx.
<html>
<head>
<script>
showMenu = function() {
var div = document.getElementById('box1');
div.style.display = 'block';
}
hideMenu = function() {
var div = document.getElementById('box1');
div.style.display = 'none';
}
</script>
</head>
<body>
<table>
<tr>
<td onmouseover="showMenu()" >username</td>
</tr>
</table>
<div id="box1" onmouseout="hideMenu()">
Logout<br>
</div>
</body>
</html>
UPDATE- this should fix the "jumping" problem:
<html>
<head>
<style type="text/css">
.username {
width: 100px;
border: 1px solid #ff0000;
padding: 3px;
text-align: center;
position: relative;
display: inline-block;
}
#box1 {
display: none;
text-align: center;
position: absolute;
background-color: #ccc;
}
</style>
<script>
showMenu = function() {
var div = document.getElementById('box1');
div.style.display = 'block';
}
hideMenu = function() {
var div = document.getElementById('box1');
div.style.display = 'none';
}
</script>
</head>
<body>
<table>
<tr>
<td colspan=3 align="left">
<img src=":">
</td>
<td colspan=6 valign="bottom" align="right">Menu1 Menu2 Menu3 Menu4 Menu5 Menu6 Menu7
<div class="username" onmouseover="showMenu();" onmouseout="hideMenu();">Username
<span id="box1">
Logout
</span>
</div>
</td>
</tr>
<tr>
<td colspan=9>
<hr color="red">
</td>
</tr>
</table>
</body>
</html>
The problem is that absolute positioning doesn't work the same inside of a span than as it does a div. So I had to change the "username" span to a div and use absolute position for the "box1" span. You could even change the "box1" span to a div as well so it occupies the whole width possible of the "username" div. Let me know how this one goes!
Here is the version where it jumps up. If you put position: absolute; in the style tag the menu extends one more cell to the right past the other columns...
.username {
}
#box1 {
display: none;
}
</style>
<script>
showMenu = function() {
var div = document.getElementById('box1');
div.style.display = 'block';
}
hideMenu = function() {
var div = document.getElementById('box1');
div.style.display = 'none';
}
</script>
</head>
<body>
<table><tr>
<td colspan=3 align="left"><img src=":"></td>
<td colspan=6 valign="bottom" align="right">Menu1 Menu2 Menu3 Menu4 Menu5
Menu6 Menu7 <span class="username" onmouseover="showMenu();"
onmouseout="hideMenu();">Username<span id="box1">
Logout
</span>
</span></b></td></tr>
<tr><td colspan=9><hr color = "red"></td></tr>
</table>
</body>
</html>

Categories

Resources