Get parent form class when you click on an element jQuery - javascript

Let's start with the HTML:
<form class="send_units">
<div class="buttons">
<div id="button_attack" class="button">
<div class="caption at">Attack!</div>
</div>
<div id="button_support" class="button">
<div class="caption sp">Support!</div>
</div>
</div>
</form>
This is an example of the code on a website. I've made a script for that website. To run that script, a player can use Tampermonkey. It just adds some code to the webpage. Note: We cannot change the HTML!
So, I've to get the classname of the form (send_units in this example), when you click on the Attack! button.
To figure out on which element the user clicks, we use Javascript:
window.onclick = function(e){
var clickedClass = e.target.className;
var clickedID = e.target.id;
if(clickedClass == 'caption at'){
// Check if parent form has class send_units
}
}
So, when the user clicks on the button with class = 'caption at', we have to check if the form class is send_units.
I've tried this to get the class:
jQuery(e).find('form').parent().prop('class')
but it returns "undefined". (Logic says to me: Get the parent of the clicked element, with element "form" and get the className of that element).
Can anyone explains to me what I'm doing wrong here?
Thanks!

Use .parents( selector ) to traverse multiple levels up the DOM to the element you need and .hasClass( class ) to test for presence of a class.
window.onclick = function(e){
var clickedClass = e.target.className;
var clickedID = e.target.id;
if(clickedClass == 'caption at'){
var is_send_units = $( e.target ).parents( 'form' ).hasClass( 'send_units' );
console.log( is_send_units );
if( is_send_units ){
// do stuff
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="send_units">
<div class="buttons">
<div id="button_attack" class="button">
<div class="caption at">Attack!</div>
</div>
<div id="button_support" class="button">
<div class="caption sp">Support!</div>
</div>
</div>
</form>

Try this out since you know the div levels already.
$(e.target).parent().parent().parent().attr("send_units")

Related

Button Onclick only working on first element

When clicking button on elements, overlay box only works with first one, not the rest
I tried already to add 2 classes but not working as I read that that might be the issue, but I am not able to make it work properly.
<div class="container">
<input type="button" value="Contactar ahora" id="Overly" class="overly"
/>
</div>
<div id="ogrooModel" class="modalbox ogroobox" >
<div class="dialog">
<button title="Close" onClick="overlay()" class="closebutton" id="close">close</button>
<div style="min-height: 150px;">
</div>
</div>
</div>
<script>
//only javascript
document.getElementById("Overly").addEventListener("click", function(){
var e =document.getElementsByClassName("modalbox");
e[0].style.display = 'block';
}) ;
document.getElementById("close").addEventListener("click", function(){
var e =document.getElementsByClassName("modalbox");
e[0].style.display= 'none';
});
</script>
What exactly to change in that code so the rest of elements display the box after clicking on button?
You don't need onClick="overlay()" for your close button, as you are already binding it with a click event listener in your script.

jQuery ID Return is undefined although HTML ID is defined

I'm trying to retrieve the ID of one element, store it as a variable and then use that ID value to interact with other elements in that section with the same ID.
<div class="mainContent">
<div class="articleContent">
<h1>header1</h1>
<p class="articlePara" id="one">para1</p>
</div>
<div class="articleFooter" id="one" onclick="readMore()">
</div>
</div>
<div class="mainContent">
<div class="articleContent">
<h1>header2</h1>
<p class="articlePara" id="two">para2</p>
</div>
<div class="articleFooter" id="two" onclick="readMore()">
</div>
</div>
And then the JS/jQuery
function readMore() {
var subID = event.target.id;
var newTarget = document.getElementById(subID).getElementsByClassName("articlePara");
alert(newTarget.id);
}
At this point I'm only trying to display the ID of the selected element but it is returning undefined and in most cases people seem to notice that jQuery is getting confused because of the differences between DOM variables and jQuery ones.
jsfiddle: https://jsfiddle.net/dr0f2nu3/
To be completely clear, I want to be able to click on one element, retrieve the ID and then select an element in the family of that clicked element using that ID value.
just remove the getElementsByClassName("articlePara"); in end of the newTarget .already you are call the element with id alert the element of the id is same with target.id
function readMore() {
var subID = event.target.id;
var newTarget = $('[id='+subID+'][class="articlePara"]')
console.log(newTarget.attr('id'));
console.log(newTarget.length);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mainContent">
<div class="articleContent">
<h1>header</h1>
<p class="articlePara" id="one"></p>
</div>
<div class="articleFooter" id="one" onclick="readMore()">click
</div>
</div>
As you have read before, you should keep your id's unique, and you should avoid using onclick in html, but you could do it like this.
With querySelector you get the element and then with parentElement you can retrieve the parent of that element.
function readMore(el) {
var articleFooterId = el.id;
var articlePara = document.querySelector(".articleContent #"+articleFooterId);
var articleContent = articlePara.parentElement;
console.log('articleFooter', articleFooterId);
console.log('articlePara', articlePara);
console.log('articleContent', articleContent);
}
In your html you can return the 'this' object back to the function by doing readMore(this).
<div class="mainContent">
<div class="articleContent">
<h1>header1</h1>
<p class="articlePara" id="one">para1</p>
</div>
<div class="articleFooter" id="one" onclick="readMore(this)">footertext</div>
</div>
<div class="mainContent">
<div class="articleContent">
<h1>header2</h1>
<p class="articlePara" id="two">para2</p>
</div>
<div class="articleFooter" id="two" onclick="readMore(this)">footertext</div>
</div>
jsfiddle
if you're using Jquery:
$(function () {
$('div.articleFooter').click(function () {
var para = $(this).prev().find('p.articlePara').text();
alert('T:' + para);
});
})
$('.articleFooter').click(function() {
var b=subId; //can be any
var a="p[id="+b+"]"+"[class='articlePara']";
$(a).something;
});
You have forgotten to pass in event as parameter in your onclick= call in html.
In your javascript, you need to include event in the parenthesis as well.
window.readMore = function(event) {...}
if you write document.getElementById(subID).getElementsByClassName("articlePara"); That's saying you want to get your clicked element's CHILD elements that have class equal to articlePara . There is none. So you get undefined.
If you want to find all element with a ID one and a class articlePara, it can be done easily with jQuery:
newtarget = $("#one.articlePara");
You can insert a line: debugger; in your onclick handler function to trigger the browser's debugging tool and inspect the values of variables. Then you will know whether you are getting what you want.

Is it bad practice to hold information in the id of an HTML element?

Let's say I have a template and I want to loop and create div's. I want to listen to clicks on the buttons contained in each of these divs:
<div class="repeatedDiv">
<button class="reply-button">
</div>
$('.reply-button').on('click',function(e)...)
I want to make the reply button function specific to the div that it was selected on. Would it be bad to have something like:
<div class="repeatedDiv">
<button class="reply-button" id="reply-{{this.id}}">
</div>
Don't make it more complicated than it really is
$(document).on('click', '.reply-button', function(e){
var divClicked = $(e.target).closest('.repeatedDiv');
// do something with clicked div
// var divClicked is the div elmt that contains the button that was clicked
// doing it this way you might not even need an id at all
console.log(divClicked.attr('id'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div1" class="repeatedDiv">
<button class="reply-button">div1</button>
</div>
<div id="div2" class="repeatedDiv">
<button class="reply-button">div2</button>
</div>
<div id="div3" class="repeatedDiv">
<button class="reply-button">div3</button>
</div>
And if you do need an id when creating a new div create it dynamically with e.g.
var newID = "id-" + Date.now();
console.log(newID);

Get parent of the parent of div

I have searched and tried many things to do this such as closest() and parents() and parent() and find() But i couldnt make it to work at all .
I have this html
<div class='message_holder area2 user45 chatid32'>
<a class='avatar' title='jhon'>
<img height='28px' width = '28px' src="link to image" />
</a>
<div class='flag_holder'>
<div class='edited png32'></div>
<div class=' png32'></div>
</div>
<div class='message user_chat'> hghgghgh</div>
<div class='like_holder'>
<div class='chattime'>02-12 22:16</div>
<div class='likepng'></div>
<div class='likescore'>5</div>
<div class='unlikescore'>0</div>
<div class='unlikepng'></div>
<div class="like">
<div class="editpng"></div>
<div class="deletepng"></div>
</div>
</div>
</div>
So what i want is when i click on on div class deletepng i want to remove the two divs unlikepng and likepng .
this js
$(document).on ("click", ".deletepng", function () {
$this = $(this);
//alert( $this.closest(".like").html()); I could just make this to work
// alert( $this.parents(".like_holder").html()); wont work
// alert( $this.closest(".like_holder").html()); wont work
// alert( $this.parent().parent().html()); wont work
// alert( $this.closest(".like_holder").find(".like_holder").html()); wont work
});
I just wonder why they dont work those my trying . Where it can be my mistake ?
EDIT:
i dont know if this have a role or not , i have what i tried inside Dialog box like that
$(document).on ("click", ".deletepng", function () {
$this = $(this);
$('<div>' + c_delete + '</div>').dialog({
resizable: false,
buttons: {
"Yes": function() {
chat_text_h.html('<div class="removed"> Removed</div>'); // do something here
$(this).dialog("close");
//alert( $this.closest(".like").html()); I could just make this to work
// alert( $this.parents(".like_holder").html()); wont work
// alert( $this.closest(".like_holder").html()); wont work
// alert( $this.parent().parent().html()); wont work
// alert( $this.closest(".like_holder").find(".like_holder").html()); wont work
}
}
});
});
use closest then use the second argument as the context.
$(document).on("click", ".deletepng", function() {
var $holder = $(this).closest('.like_holder');
$('.likepng, .unlikepng', $holder).remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='message_holder area2 user45 chatid32'>
<a class='avatar' title='jhon'>
<img height='28px' width='28px' src="link to image" />
</a>
<div class='flag_holder'>
<div class='edited png32'></div>
<div class=' png32'></div>
</div>
<div class='message user_chat'>hghgghgh</div>
<div class='like_holder'>
<div class='chattime'>02-12 22:16</div>
<div class='likepng'>like</div>
<div class='likescore'>5</div>
<div class='unlikescore'>0</div>
<div class='unlikepng'>unlike</div>
<div class="like">
<div class="editpng"></div>
<div class="deletepng">delete</div>
</div>
</div>
</div>
EDIT
Since your update, you need to set a global variable to remember $this or the container/holder. try this:-
var $holder;
$(document).on("click", ".deletepng", function() {
$holder = $(this).closest('.like_holder');
$('<div>' + c_delete + '</div>').dialog({
resizable: false,
buttons: {
"Yes": function() {
chat_text_h.html('<div class="removed"> Removed</div>');
$(this).dialog("close");
$('.likepng, .unlikepng', $holder).remove();
}
}
});
});
$this.closest(".like").html(); => this will return HTML of parent div, where delete button is. Not removing the element
$this.parents(".like_holder").html() => this will return html of div.message_holder. Not removing the element.
$this.closest(".like_holder").html() => this will return html of div.like_holder
$this.parent().parent().html(); close enogh, but still far => html of div.like_holder
$this.closest(".like_holder").find(".like_holder").html(); return null => no child element with class like_holder in div.like_holder.
Kind of example
$(document).on ("click", ".deletepng", function () {
var $parent = $(this).parent().parent();
$parent.find('.likepng').remove();
$parent.find('.unlikepng').remove();
});
.deletepng{
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='message_holder area2 user45 chatid32'>
<a class='avatar' title='jhon'>
<img height='28px' width = '28px' src="http://www.gettyimages.pt/gi-resources/images/Homepage/Hero/PT/PT_hero_42_153645159.jpg" />
</a>
<div class='flag_holder'>
<div class='edited png32'></div>
<div class=' png32'></div>
</div>
<div class='message user_chat'> hghgghgh</div>
<div class='like_holder'>
<div class='chattime'>02-12 22:16</div>
<div class='likepng'> like me</div>
<div class='likescore'>5</div>
<div class='unlikescore'>0</div>
<div class='unlikepng'> unlike me</div>
<div class="like">
<div class="editpng"></div>
<div class="deletepng">delete button</div>
</div>
</div>
</div>
UPDATE
If you want to make it from dialog box, or other things - you can't use this variable. This is not making any sense. You should provide unique id to your message_box and then use it, like
$(id_of_message_box).find('.likepng, .unlikepng').remove()
or as I can see from your code:
var $parent = $this.parent().parent();
$parent.find('.likepng, .unlikepng').remove();
It means you should use $this in your function instead of $(this)
You can access the parents parent of your $(this) like:
var likeholder;
likeholder = $(this).parent().parent();
However this is generally ill advised. You'll have a jquery object though.
Let me know how you get on
In order to select the parent of a parent of an element you try this:
$(document).on ("click", ".deletepng", function () {
alert( $($(this).parent()).parent().html());
});
Since you can only execute the parent() method on Jquery Objects.
Here's an example unrelated to your code. JSFiddle.
Try this, you need sibling of parent;
alert( $this.closest(".like").parent().find(".unlikescore").html());
alert ($this.closest('.like').siblings('.unlikepng').html()) ;
working js fiddle

Find sibling with Javascript and Hammer.js

I have made a simple system which detects double taps. I want to show a heart icon when someone double taps on an image, just like on Instagram.
This is what my code looks right now:
var elements = document.getElementsByClassName('snap_img');
[].slice.call(elements).forEach(function(element) {
var hammertime = new Hammer(element),
img_src = element.getAttribute('src');
hammertime.on('doubletap', function(event) {
alert(img_src); // this is to test if doubletap works
// Some javascript to show the heart icon
});
});
This is what the HTML looks like:
<div class="snap_item">
<div class="snap_item_following_info">
<img class="snap_item_following_img" src="res/stat/img/user/profile/small/1.fw.png" alt="#JohnDoe" />
<a class="snap_item_following_name" href="#">#JohnDoe</a>
<div class="snap_too">
</div>
</div>
<img class="snap_img" src="res/stat/img/user/snap/43/2.fw.png" alt="#ErolSimsir" />
<div class="like_heart"></div>
<div class="snap_info">
<div class="snap_text">
LA is the shit...
<a class="snap_text_hashtah" href="#">#LA_city_trip</a>
</div>
<div class="snap_sub_info">
<span class="snap_time">56 minutes ago</span>
<div class="like inactive_like">
<div class="like_icon"></div>
<div class="like_no_active">5477</div>
</div>
</div>
</div>
</div>
So when the element 'snap_img' is double tapped, I need to get the element 'like_heart' which is one line below the snap_img element. How do I get that sibling element and fade it in with JQuery?
Like this
[].slice.call(elements).forEach(function(element) {
var hammertime = new Hammer(element),
img_src = element.getAttribute('src');
hammertime.on('doubletap', function(event) {
alert(img_src); // this is to test if doubletap works
$(element).next().text('♥').hide().fadeIn();
});
});
P.S. I've added that heart text, since the sibling was empty.
On the event handler, i would do $(element).parent().find('.like_heart').fadeIn(); So the code is not dependant on the element ordering.
(To clarify to selector: take the parent element which is the div.snap_item and find an element with class like-heart inside it)

Categories