jquery if $this has not ClassName do action - javascript

I see many answers but none of them seem to be working.
All my buttons have the "Trev" class. I want to check if the clicked class, also contains the "Namdons" class, and if so, do some code. However if not, do some code.
Some code that half works is:
$(".Trev").click
(
function(e)
{
if($(this).hasClass("Namdons"))
{
console.log("Namdons");
}
else
{
console.log("Asdf");
}
e.preventDefault();
}
);
However the "else" condition is not executing.
I've tried:
$(".Trev").click
(
function(e)
{
if($(this).hasClass("Namdons"))
{
console.log("Namdons");
}
if(!$(this).hasClass("Namdons")) //added apostrophe
{
console.log("Asdf");
}
e.preventDefault();
}
);
as per these pages:
How to check if an element does NOT have a specific class?
How do I use hasClass to detect if a class is NOT the class I want?
The "not" command does not apply as I'm only wanting to procure a single element and not select a bunch of them. Explained more on those pages.
HTML:
<div class="Trev Width50" onclick="Button('buttonname')"></div>
and
<button onclick="Namdons()" class="Namdons Trev TextAlignCenter">ButtonTitle</button>
also tried changing the Width50 div to a button:
<button class="Trev Width50" onclick="Button('buttonname')"></button>
There also doesn't seem to be an "elseif" in javascript is that correct?
Thanks.

Since you tag javascript i put example in vanilla js. I leave it for you to translate it to jQuery. I also put notes inside:
const trev = document.querySelectorAll('button.trev'); // get button with .trev style
for (var i=0; i < trev.length; i++) { // itterate them
trev[i].addEventListener('click', function() { // add click event
if (this.classList.contains('Namdons')) {alert('This is .Namdons');} // if it has .Namdons alert it
else {alert('This is NOT .Namdons');} // it not alert that
});
}
<button class="Trev TextAlignCenter">ButtonTitle</button>
<button class="Namdons Trev TextAlignCenter">ButtonTitle</button>
<button class="Trev TextAlignCenter">ButtonTitle</button>
<button class="Namdons Trev TextAlignCenter">ButtonTitle</button>
<button class="Trev TextAlignCenter">ButtonTitle</button>
Read more about classList on MDN

Related

Click and toggle between two classes on an array (no JQuery)

I need to make a site where I can add something to a shoppingcart. I do not need to store any data, so just changing a class to 'addedInCart' is enough. This is what I have so far, but it's not working yet. I know all the classnames I got are coming back in an array. I just dont know how to change them if the button is clicked. I tried a lot with the addEventListener and the toggle, but I just started coding, not everything is clear for me yet. I am not alloud to use Jquery, only HTML and Javascript.
This is what I have in Javascript:
var buyMe = document.getElementsByClassName("materials-icon");
function shoppingcart() {
for(let i = 0; i < buyMe.length; i++){
buyMe[i].classList.toggle("addedInCart");
buyMe[i].addEventListener("click", toggleClass, false)
}
}
This is what my button looks like:
<button class="material-icons" onclick="shoppingcart()"></button>
Thank you for your time!
Use event delegation to be able to use one handler. Use a data-attribute to verify the button as being a button for adding to cart. Something like:
document.addEventListener("click", handle);
function handle(evt) {
const origin = evt.target;
if (origin.dataset.cartToggle) {
// ^ if element has attribute data-cart-toggle...
origin.classList.toggle("addedInCart");
// ^ ... toggle the class
}
};
.addedInCart {
color: red;
}
.addedInCart:after {
content: " (in cart, click to remove)";
}
<button class="material-icons" data-cart-toggle="1">buy</button>
<button class="material-icons" data-cart-toggle="1">buy</button>
<button class="material-icons" data-cart-toggle="1">buy</button>

How to assign a javascript function by classname

I have multiple buttons (generated by php) for a shopping cart application:
<button class="addtocart" id="<?php echo $code; ?>">
<span id="addtocartbutton">Add to cart</span>
</button>
I want to update my cart using a function:
function AddtoCart() {
alert("Added!");
}
Later, I want to find the id ($code) created by the button which called it (not sure how to do that also, but maybe that's another question). And so I tried this:
document.getElementsByClassName("addtocart").addEventListener("click", AddtoCart());
But it doesn't work. It was working using an onclick, but I understand that the right way to do it by creating an EventListener. Also, I cannot use the on() function in jQuery, because I am forced to use jQuery Version 1.6 which does not have it.
I have looked at https://stackoverflow.com/a/25387857/989468 and I can't really assign it to the parent which is a p tag, because I obviously don't want the other elements in the p tag to be assigned this function.
While the answers given are correct, there is another way: Event Delegation
Attach the listener to a SINGLE thing, in this case the document body and then check to see what element was actually clicked on:
Warning: Typed on the fly: Untested
// Only needed *once* and items may be added or removed on the fly without
// having to add/remove event listeners.
document.body.addEventListener("click", addtoCart);
function addtoCart(event) {
var target = event.target;
while(target) {
if (target.classList.contains('addtocart')) {
break;
}
// Note: May want parentElement here instead.
target = target.parentNode;
}
if (!target) {
return;
}
var id = target.dataset.id;
alert(id + " added!");
}
You should attach click event to every element with class addtocart, since getElementsByClassName() return an array of all objects with given class name so you could use for to loop through everyone of them and associate it with function you want to trigger on click (in my example this function called my_function), check example bellow :
var class_names= document.getElementsByClassName("addtocart");
for (var i = 0; i < class_names.length; i++) {
class_names[i].addEventListener('click', my_function, false);
}
Hope this helps.
function my_function() {
alert(this.id);
};
var class_names= document.getElementsByClassName("addtocart");
for (var i = 0; i < class_names.length; i++) {
class_names[i].addEventListener('click', my_function, false);
}
<button class="addtocart" id="id_1">button 1</button>
<button class="addtocart" id="id_2">button 2</button>
<button class="addtocart" id="id_3">button 3</button>
<button class="addtocart" id="id_3">button 4</button>
I'll show some of the errors you had in your code, then I'll show you how can you improve it so that you can achieve what you want, and I also show that it works with buttons dynamically added later:
First and foremost, you need to pass the function reference (it's name) to the addEventListener! You have called the function, and passed whatever it returned. Instead of:
document.getElementsByClassName("addtocart").addEventListener("click", AddtoCart());
It should've been:
document.getElementsByClassName("addtocart").addEventListener("click", AddtoCart);
Second: document.getElementsByClassName("addtocart") returns a NodeList, you can't operate on it, you need to operate on it's elements: document.getElementsByClassName("addtocart")[0], [1],....
Third, I would suggest you to use the data-... html attribute:
<button class="addtocart" id="addtocart" data-foo="<? echo $code; ?>">
This way you can pass even more data. Now you can get the $code as:
document.getElementById('addtocart').dataset.foo
// el: the button element
function AddtoCart(el) {
// this is the id:
var id = el.id;
// and this is an example data attribute. You can have as many as you wish:
var foo = el.dataset.foo;
alert(id + " (" + foo + ") added!");
}
// Try add a div or something around the area where all the buttons
// will be placed. Even those that will be added dynamically.
// This optimizes it a lib, as every click inside that div will trigger
// onButtonClick()
document.getElementById("buttons").addEventListener("click", onButtonClick);
// this shows that even works when you dynamically add a button later
document.getElementById('add').onclick = addButton;
function addButton() {
var s = document.createElement("span");
s.text = "Add to cart";
var b = document.createElement("button");
b.innerHTML = 'Third <span class="addtocartbutton">Add to cart</span>';
b.className = "addtocart";
b.id="third";
b.dataset.foo="trio";
// note the new button has the same html structure, class
// and it's added under #buttons div!
document.getElementById("buttons").appendChild(b);
}
// this will gett triggered on every click on #buttons
function onButtonClick(event) {
var el = event.target;
if (el && el.parentNode && el.parentNode.classList.contains('addtocart')) {
// call your original handler and pass the button that has the
// id and the other datasets
AddtoCart(el.parentNode);
}
}
<div id="buttons">
<button class="addtocart" id="first" data-foo="uno">First <span class="addtocartbutton">Add to cart</span></button>
<button class="addtocart" id="second" data-foo="duo">Second <span class="addtocartbutton">Add to cart</span></button>
</div>
<button id="add">Add new button</button>
<html>
<head>
<script>
window.onload=function{
var btn = document.getElementsByName("addtocartbtn")[0];
btn.addEventListener("click", AddtoCart());
}
function AddtoCart() {
alert("Added!");
}
</script>
</head>
<body >
<button class="addtocart" name ="addtocartbtn" id="<?php echo $code; ?>" > <span id="addtocartbutton">Add to cart</span></button>
</body>
</html>
Actually class in Javascript is for multiple selection you should provide index like an array.
<button class="addtocart"> <span id="addtocartbutton">Add to cart</span></button>
<script type="text/javascript">
document.getElementsByClassName("addtocart")[0].addEventListener("click", AddtoCart);
function AddtoCart() {
alert("Added!");
}
</script>
Also your second parameter was wrong don't use parentheses.
Applying parentheses means it will call the function automatically when loaded, and will not call the function after that.

After click return to initial state

Hello I got a question regarding changing elements in the DOM. I got a situation that whenever I click on the button it will show a div. After 2 seconds the initial div is replaced by another div which also got a function call that removes the div again.
Now comes the tricky part. What I want is that whenever I hide the div again, the third click on the button will show the div again.
Let me explain a bit more. Imagine that I got the following situation:
First mouse click on button 1 (Result: shows red div)
Second mouse click on button 1 (Result: hide red div)
Third mouse click on button 1 (shows the div again)
The third bullet is the tricky one. How can I do that? Because when I click for the third time on button 1 it does not show anything anymore because I did not change it back to the original state
The code that I have so far JSFIDDLE
function Test(){
var target = window.event.target || window.event.srcElement;
console.log(target);
var content = arguments[0];
console.log(content);
$( "body" ).append( "<div class='red'>"+content+"</div>" );
setTimeout(function(){
$( ".press" ).replaceWith( "<button class='press' onclick='UnTest()'>button 1</button>" );
}, 2000);
}
function UnTest(){
$( ".red").remove();
}
Please note that due to implementation restrictions I can not check within my Function if the button is clicked (eq. $(".red").click())
There are a few ways you could accomplish this, but a quick solution might be just toggling the onclick attribute of the button (rather than replacing it entirely).
// In setTimeout
setTimeout(function(){
$('.press').attr('onclick', 'UnTest()');
}, 2000);
function UnTest(){
$( ".red").remove();
$('.press').attr('onclick', 'Test("one")');
}
https://jsfiddle.net/2mvqmtwq/1/
This will also allow you to add multiple .red divs (similar to the original fiddle) and then remove with a single click (which another answer does not take into account, instead treating it as a simple visibility toggle).
Edit: For multiple buttons/instances (per your comment), you'll need an identifier of sort. Your original code made it easy by declaring the target, which we can use. Let's say we have three buttons:
<button class="press" onclick="Test('one')">button 1</button>
<button class="press" onclick="Test('two')">button 2</button>
<button class="press" onclick="Test('three')">button 3</button>
Our updated JS doesn't change too much, other than referencing the string value we passed (which you declare as content):
setTimeout(function(){
$(target).attr('onclick', 'UnTest("' + content + '")');
}, 2000);
As well as referencing the target you've declared at the top (which allows us to keep each button instance unique).
Here's the updated fiddle with all the changes I made (additional parameters, scoped class names for the red boxes, etc):
https://jsfiddle.net/2mvqmtwq/9/
Use a variable to count the number of clicks, which is initially equal to 0. Then, each time you click the button, you increase the variable by 1 and check if the variable is odd or even. If it's odd, you add the div, if it's even you remove the div:
var clicked = 0;
function Test() {
clicked++;
var content = arguments[0];
if (clicked % 2 === 1) {
$("body").append("<div class='red'>" + content + "</div>");
} else {
$(".red").remove();
clicked = 0;
}
}
Fiddle: https://jsfiddle.net/2mvqmtwq/5/
Tip: you can reset the variable back to 0 when it's even.
Here's a dead simple fix. I think we can do this whole thing a lot more cleanly with some refactoring. But since you mention implementation restraints, I don't want to offer a solution that might break those restraints.
Simply add logic to your UnTest() function
function UnTest(){
$( ".red").remove();
$( ".press" ).replaceWith( "<button class='press' onclick='Test(\"hello\")'>button 1</button>" );
}
How about writing some clean code, avoiding inline event handlers?
What you could probably do is:
First click: add the div
Next click onwards: check if the div already exists. If yes, simply toggle it's display as opposed to removing it.
This is only a demo as to how this could be done. This one also works for multiple buttons/divs. As I said earlier, I have removed inline event handlers and added the div class and function params as data-attributes. Feel free to edit the code to suit your needs.
$(document).on("click", ".press", function() {
var $this = $(this);
var $div = $("div." + $this.data("class"));
if ($div.length) {
$div.toggle();
return;
}
$( "body" ).append( $("<div/>", {
'class': $this.data("class"),
'html': $this.data("param")
}) );
});
button{ margin:10px}
div {
width:200px;
height:50px;
}
.red {
background-color:red;
}
.blue {
background-color:blue;
}
.green {
background-color:green;
}
.orange {
background-color:orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="press" data-param="one" data-class="red">button 1</button>
<button class="press" data-param="two" data-class="blue">button 2</button>
<button class="press" data-param="three" data-class="green">button 3</button>
<button class="press" data-param="four" data-class="orange">button 4</button>

How to change class name of two IDs at same time using js?

I have two IDs in same name ! if any one clicked among them , i need to change the class name of the both IDs. i know we should use ID for single use. Because of my situation(I have two classes for button ) so i have moved to ID.
Her is my code if i click one id that name only changes another one is remains same
<button class="success" id="1" onClick="reply(this.id)"> Added </button>
<button class="success" id="1" onClick="reply(this.id)"> Added </button>
js function
function reply(clicked_id)
{
document.getElementById(clicked_id).setAttribute('class', 'failed');
var el = document.getElementById(clicked_id);
if (el.firstChild.data == "Added")
{
el.firstChild.data = "Add";
}
}
if i use instead of 'class' to id while renaming class which one will be renamed success class or 'class name 1' ?
You can't. Getelementbyid will only return one element. Probably the first one.
Pure JS Is Second Example
My JS Fiddle Example: http://jsfiddle.net/eunzs7rz/
This example will use the class attribute only to perform the switching that you need, its a extremely basic example as do not want to go beyond what is needed... Also i forgot to remove the id's in the JS Fiddle Example.. so just ignore them
THE CSS:
.success {
background-color:#00f;
}
.failed {
background-color:#f00;
}
THE HTML:
<button class="success"> Added </button>
<button class="success"> Added </button>
THE JAVSCRIPT:
$(function() {
$(".success").click(function(){
Reply(this);
});
});
function Reply(oElm) {
$(oElm).attr('class', 'failed');
}
EDIT - PURE JAVASCRIPT VERSION
Sorry, did not think to check the post tags if this was pure JS. But here you go anyway ;)
<style>
.success {
background-color:#00f;
}
.failed {
background-color:#f00;
}
</style>
<button class="success" onclick="Reply(this)"> Added </button>
<button class="success" onclick="Reply(this)"> Added </button>
<script>
function Reply(oElm) {
oElm.className = 'failed';
}
</script>
THE MAIN THING HERE
Once you have the element either by using 'this' or by using 'getElementBy', you can then simply use ".className" to adjust the class attribute of the selected element.
As already explained by others, id is for single use and is quicker than using class or type. So even if you have a group, if only one is ever used.. use an id.
Then you use the object/reference of 'this' from an event on an element, in this case the onclick... that will send that variable to the function / code called.
So using 'this' is a preferred option as it will always reference the element that it is used/called from.
pass elemenet, not it's Id
<button class="success" id="1" onClick="reply(this)"> Added </button>
<button class="success" id="1" onClick="reply(this)"> Added </button>
function reply(elem)
{
$(elem).setAttribute('class', 'failed');
if (elem.firstChild.data == "Added")
{
elem.firstChild.data = "Add";
}
}
the ID attribute must be unique or else it will get the last defined element with that ID.
See this for reference.
Use a class instead of an id. ids are supposed to be unique in a dom tree.
html:
<button class="success" onClick="reply()"> Added </button>
<button class="success" onClick="reply()"> Added </button>
js:
var ary_success = document.querySelectorAll(".success"); // once and forever. If the set of elements changes, move into function `reply`
function reply () {
var elem;
var s_myclasses;
for (var i=0; i < ary_success.length; i++) {
elem = ary_success[i];
s_myclasses = elem.getAttribute('class');
s_myclasses = s_myclasses.replace ( /(success|failed)/g, '' );
s_myclasses = s_myclasses + ' failed';
elem.setAttribute('class', s_myclasses );
if ( elem.firstChild.data.indexOf("Added") !== -1) {
elem.firstChild.data = "Add";
}
}
}
Live Demo here.
Notes
Make sure that you set ary_successin the onload handler or in an appropriately placed script section - at the timeof execution the buttons must be present in the dom ! If in doubt, move it to the start of reply' body.
If you employ jquery, the code simplifies (well...) to:
$(document).ready( function () {
$(".success").on ( 'click', function ( eve ) {
$(".success").removeClass("success").addClass("failed");
$(".success *:first-child:contains('Added')").text(" Add ");
});
});
Updates
Notes, Live Demo
Iterator method changed, every not supported on test platform

Javascript function changeImage: Issues using variables for getElementById or getElementsByName

I'm having some trouble getting my code to do what I want. I have multiple sections that I have set to toggle show/hide, and it functions correctly. However, I'm now trying to switch the images to where instead of always being static with "More," I'd like it to switch to "Less" when it's expanded.
It does work... but only for the first one. If I press the buttons on any of the others, it only changes just the first one. You can see the page here:
http://jfaq.us
I've tried several different solutions with variables, but I can't seem to get it to work.
Help? Thanks in advance!
function changeImage() {
if (document.getElementById("moreorless").src == "http://jfaq.us/more.png")
{
document.getElementById("moreorless").src = "http://jfaq.us/less.png";
}
else
{
document.getElementById("moreorless").src = "http://jfaq.us/more.png";
}
}
function toggleMe(a){
var e=document.getElementById(a);
if(!e)return true;
if(e.style.display=="none")
{
e.style.display="block"
}
else{
e.style.display="none"
}
return true;
}
<div>
Guestbook
<div>
<input type="image" src="http://jfaq.us/more.png" id="moreorless" onclick="changeImage();return toggleMe('para3')" >
</div>
<div id="para3" style="display:none">
This is normally hidden, but shows up upon expanding.
This is normally hidden, but shows up upon expanding.
</div>
About
<div>
<input type="image" src="http://jfaq.us/more.png" id="moreorless" onclick="changeImage();return toggleMe('para2')" >
</div>
<div id="para2" style="display:none">
This is normally hidden, but shows up upon expanding.
This is normally hidden, but shows up upon expanding.
</div>
</div>
The id attribute must be unique. That's why it's not working. Also, it's not a good idea to use inline event handlers like you are doing, you should register event handlers using addEventListener instead.
Without changing all your code, one thing you can do is pass a reference to the currently clicked element to the changeImage function.
function changeImage(el) {
var moreUrl = 'http://jfaq.us/more.png';
el.src = el.src === moreUrl? 'http://jfaq.us/less.png' : moreUrl;
}
Then change the inline handler for onclick="changeImage(this);"
You are using same Id for all inputs. This is causing the problem.
Give every element a unique Id.
If you want to perform grp operation use jquery class.
That's because you use the same id for the both images, and getElementById apparently takes the first one.
Here is the updated code:
html:
<input type="image" src="http://jfaq.us/more.png" id="moreorless" onclick="changeImage.call(this);return toggleMe('para3')" >
script:
// inside the event handler 'this' refers to the element clicked
function changeImage() {
if (this.src == "http://jfaq.us/more.png") {
this.src = "http://jfaq.us/less.png";
} else {
this.src = "http://jfaq.us/more.png";
}
}
check this
http://jsfiddle.net/Asb5A/3/
function changeImage(ele) {
if (ele.src == "http://jfaq.us/more.png")
{
ele.src = "http://jfaq.us/less.png";
}
else
{
ele.src = "http://jfaq.us/more.png";
}
}
<input type="image" src="http://jfaq.us/more.png" onclick="changeImage(this);return toggleMe('para3')" >

Categories

Resources