JQuery - Add class on click verifying ID - javascript

I'm trying to add a class to a specific element that contains a parent container with a unique ID.
I have several buttons contained in a div, and all of them are using the same classes. For some reason, I can't use only $(this), so I created a loop that adds a unique ID to the containers.
HTML
<div class='section'>
<div class='btn-container' id='btn-1'>
<button class='btn'></button>
</div>
<div class='btn-container' id='btn-2'>
<button class='btn'></button>
</div>
<div class='btn-container' id='btn-3'>
<button class='btn'></button>
</div>
</div>
JQuery
$("button").click(function (e) {
e.preventDefault();
var target = $(e.target).parents(".button-container").attr("id");
console.log(target);
$(target).find(".btn").addClass("active");
});
I'm targeting the ID and it works, the console.log gives me back the correct info. However, for some reason, I can't add the class.
Thank you in advance for any help! (:
Edited:
I'm trying to add the class active to the button that is contained in the ID.
Example:
$("#btn-1 .btn").addClass("active"); but with the ID dynamically populate based on the info from the click.

Keep things simple, this should work
$(document).ready(function() {
$("button").click(function (e) {
e.preventDefault();
$(e.target).addClass("active")
});
});
.active{
border: 1px red solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='section'>
<div class='btn-container' id='btn-1'>
<button class='btn'>Test</button>
</div>
<div class='btn-container' id='btn-2'>
<button class='btn'>Test</button>
</div>
<div class='btn-container' id='btn-3'>
<button class='btn'>Test</button>
</div>
</div>

Related

JavaScript code not working with multiple HTML elements

I've build myself a sign input on my website inside a modal popup. The problem is that I can have an unknown amount of modals generated in a foreach within PHP. Because of this my JavaScript code don't works anymore. Do you have any idea how I can improve my function to make it workable for a undefined amount of signature modals?
var signaturePad;
jQuery(document).ready(function () {
jQuery(document).on('opened', '#sign-modal', function () {
var signaturePadCanvas = document.querySelector('.signature-pad-canvas');
var parentWidth = jQuery(signaturePadCanvas).parent().outerWidth();
signaturePadCanvas.setAttribute("width", parentWidth);
signaturePad = new SignaturePad(signaturePadCanvas);
jQuery('#clear-signature').click(function () {
if (signaturePad) {
signaturePad.clear();
}
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/signature_pad#3.0.0-beta.3/dist/signature_pad.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/remodal#1.1.1/dist/remodal.min.js"></script>
<div id="sign-modal" class="remodal remodal remodal-is-initialized remodal-is-opened" data-remodal-id="sign-nda-modal-1234567889">
<button data-remodal-action="close" class="remodal-close"></button>
<h1>Hello</h1>
<p>I am a random text</p>
<div class="signature-pad-canvas-container">
<div class="signature-pad-canvas-wrapper">
<canvas class="signature-pad-canvas"></canvas>
</div>
<div class="clear-signature-wrapper">
<span id="clear-signature">Delete</span>
</div>
</div>
<br>
<div class="remodal-buttons">
<button data-remodal-action="cancel">Cancel</button>
<button onclick="sign('123abc', '456cdf')">Sign</button>
</div>
</div>
<div id="sign-modal" class="remodal remodal remodal-is-initialized remodal-is-opened" data-remodal-id="sign-nda-modal-9876543">
<button data-remodal-action="close" class="remodal-close"></button>
<h1>Hello</h1>
<p>I am a random text</p>
<div class="signature-pad-canvas-container">
<div class="signature-pad-canvas-wrapper">
<canvas class="signature-pad-canvas"></canvas>
</div>
<div class="clear-signature-wrapper">
<span id="clear-signature">Delete</span>
</div>
</div>
<br>
<div class="remodal-buttons">
<button data-remodal-action="cancel">Cancel</button>
<button onclick="sign('764647gc', 'iuhiz78')">Sign</button>
</div>
</div>
......
The reason why your modals have stopped working is because each modal you create is created with the same id.
This means that when you access the element with DOM, only the first element would be returned. Using a class is not the best idea as you lose the ability to target specific elements without looping.
The best solution in my opinion is to dynamically generate the id as you create your modals. This means you could have something like sign-modal-1, sign-modal-2 etc for each modal you create.
Then, in JQuery, you target elements with ID's that get opened, that begin with sign-modal, i.e. using the JQuery attribute selector.
JQuery Attribute Selector:
https://api.jquery.com/attribute-starts-with-selector/

jQuery element removal

I want to remove an element using jQuery.
HTML:
<div class="listContainer" id="listContainer">
<div class="listItem">
<div class="name">
Item Name
</div>
<div class="amount">
<input type="text" class="amountInput" />
</div>
<div class="delete">
<div class="deleteBtn">
X
</div>
</div>
</div>
</div>
There are several listItemss on the page and each of the listItem will be created dynamically using jQuery. I want to delete amountInput of specific listItem by clicking the deleteBtn, so I tried doing:
$("#listContainer").on("click", ".deleteBtn", function() {
$(this).closest(".amountInput").remove();
});
This doesn't work. But on the other hand if I try to delete a listItem as a whole, the code works:
$("#listContainer").on("click", ".deleteBtn", function() {
$(this).closest(".listItem").remove();
});
Why is this happening?
Thanks.
Because .closest propagates to the top of the HTML. So it searches for the first parent that matches your selector. That is why it cannot find .amountInput. Because it isn't a parent of your button.
To get .amountInput you have to:
$("#listContainer").on("click", ".deleteBtn", function() {
$(this).closest(".listItem").find('.amountInput').remove();
});
This will get the wrapping .listItem element and then search it for the .amountInput element.
Your selector is not correct, use find instead of closest could be helpful in this case, also $(this) in your sample is related to deleteBtn class not to listContainer.
$("#listContainer").on("click", ".deleteBtn", function() {
console.log($(this)) // this here is .deleteBtn not listContainer
$(this).closest(".listItem").find(".amountInput").remove();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="listContainer" id="listContainer">
<div class="listItem">
<div class="name">
Item Name
</div>
<div class="amount">
<input type="text" class="amountInput" />
</div>
<div class="delete">
<div class="deleteBtn">
X
</div>
</div>
</div>
</div>

Add class to previous element

I just want to add class for the button after another class but it's inside of another div. Take a look at this example.
<div class="wrap">
<button class="one">Click</button>
<button class="two">Click</button>
</div>
<div class="bottom"></div>
.add-me{
color:red;
}
In here, I want to add to class button one. But it needs to be applied when bottom class appears.(This is a validation message. So I can't style directly to button one.)
I tried with this way. But it only apply for wrapper div.
$('.bottom').prev('div').first().addClass('add-me');
Here is the fiddle: https://jsfiddle.net/eqhj0vm9/2/
You have to use $('.bottom').prev().find(':first-child').addClass('add-me'); to select the prev element's first child.
$(function() {
$(".activate").click(function(){
$('.bottom').show();
$('.bottom').prev().find(':first-child').addClass('add-me');
});
});
.add-me {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrap">
<button class="one">Click</button>
<button class="two">Click</button>
</div>
<div class="bottom" style="display:none"> BOTTOM CLASS </div>
<br />
<button class="activate">Activate bottom class</button>

Find ID of HTML element which called JavaScript function

I have a three button navigation panel, comprising of three divs and an anchor. On mouse over, myFunction() assigns a class to the three divs and anchor tag, for styling purposes.
<nav>
<div id="btn1" class="button" onMouseOver="myFunction();">
<div id="btn_bdr1">
<div id="btn_bdr2">
</div>
</div>
</div>
<div id="btn3" class="button" onMouseOver="myFunction();">
<div id="btn_bdr1">
<div id="btn_bdr2">
</div>
</div>
</div>
<div id="btn2" class="button" onMouseOver="myFunction();">
<div id="btn_bdr1">
<div id="btn_bdr2">
</div>
</div>
</div>
</nav>
What I need to do is find the ID of the div which called myFunction(), so I can make a change within the function to only the calling div, not all three.
Using JavaScript only, how can I go about doing this.
Thanks in advance.
There is two ways you can do is
1) Send an argument to the method with the div's name
Example
<div id="btn1" class="button" onMouseOver="myFunction('btn1')">
2) Send the element this
Example
<div id="btn1" class="button" onMouseOver="myFunction(this)">
In the javascript you can then do
myFunction(element) {
//element is now the element you clicked on
}
You can use the event object and look at the target (e.target). This is a reference to the element itself so to get the ID you would simply access the element's id property. (e.target.id)
document.querySelectorAll('.a').forEach(function(ele, ind) {
ele.addEventListener("mouseover", function(e) {
console.log(e.target, e.target.id);
})
});
.a {
height: 40px;
width: 40px;
border: solid black 3px;
margin-top: 5px;
}
<div class="a" id="one"></div>
<div class="a" id="two"></div>
<div class="a" id="three"></div>
You can call this.event.target from myFunction() to determine which element generated the event.
For example:
myFunction() {
console.log("I was called by: ", this.event.target);
}

Hiding/Showing divs on click

I have created a script that when a button is clicked it displays all of the content beneath it and hides the other buttons content. The only problem I'm having is that I want to refactor the script so it only works if you hit the button, instead of the entire div the button sits in as it's causing some confusion. What would be the best way about this?
<div class="signup-button">
<button type="button" class="btn btn-default">Subscribe</button>
<div class="signup-form" style="display:none;">
Content
</div>
</div>
<div class="signup-button">
<button type="button" class="btn btn-default">Subscribe</button>
<div class="signup-form" style="display:none;">
Content
</div>
</div>
<div class="signup-button">
<button type="button" class="btn btn-default">Subscribe</button>
<div class="signup-form" style="display:none;">
Content
</div>
</div>
<div class="signup-button">
<button type="button" class="btn btn-default">Subscribe</button>
<div class="signup-form" style="display:none;">
Content
</div>
</div>
jQuery:
(function($) {
$(".signup-button").on('click', function() {
$(".signup-button").not(this).find(".signup-form").hide();
$(this).find(".signup-form").toggle("slow");
});
})(jQuery);
JSFiddle: https://jsfiddle.net/v6bmphct/3/
One option would be to attach the event listener directly to the descendant button element. In doing so, the click event isn't triggered when clicking on the other content. You would also have to change instances of $(this) to $(this).parent() or $(this).closest('.signup-button').
Updated Example
$(".signup-button .btn").on('click', function(e) {
$(this).parent().find(".signup-form").toggle("slow");
$(".signup-button").not($(this).parent()).find(".signup-form").hide();
});
Alternatively, since event.target is a reference to the clicked element, you could also just check to see if event.target is the button element by using the .is() method:
Updated Example
$(".signup-button").on('click', function(e) {
if ($(e.target).is('.btn')) {
$(this).find(".signup-form").toggle("slow");
$(".signup-button").not(this).find(".signup-form").hide();
}
});
Check this out:
(function($) {
$(".signup-button").find('button').on('click', function() {
$(this).siblings(".signup-form").toggle("slow");
$(".signup-button").not(this.closest(".signup-button")).find(".signup-form").hide();
});
})(jQuery);

Categories