How to leave one active button in the JavaScript? - javascript

I am beginner.
I have four buttons and I want to leave one active button every time with expression operator (if). One button must have active every time .
I tried to do it something like that. I am open to your ideas, if you can do without (if) .Help me!
var count = 4;
var flag = true;
function select(currentColor, changeColor){
if(count > 1 && flag === true){
var currentElement = angular.element(document.getElementsByClassName(currentColor));
currentElement.toggleClass(changeColor);
count--;
console.log(count);
console.log('From minus: ' + count);
}else{
flag = false;
}
if(count < 4 && flag === false) {
var currentElement = angular.element(document.getElementsByClassName(currentColor));
currentElement.toggleClass(changeColor);
count++;
console.log(count);
console.log('From plus: ' + count);
}else{
flag = true;
}
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<style>
.changeColor{
color: red !important;
}
.first{
color: #07888A;
}
.second{
color: #07888A;
}
.third{
color: #07888A;
}
.fourth{
color: #07888A;
}
h1{
display: inline;
margin-right: 20px;
}
</style>
</head>
<body>
<h1 class="first" onClick="select('first', 'changeColor')">First</h1>
<h1 class="second" onClick="select('second', 'changeColor')">Second</h1>
<h1 class="third" onClick="select('third', 'changeColor')">Third</h1>
<h1 class="fourth" onClick="select('fourth', 'changeColor')">Fourth</h1>
</body>
</html>

Add this bit:
function select(currentColor, changeColor) {
// Get the list of the `.changeColor` elements.
changed = document.querySelectorAll(".changeColor");
// Loop through all the elements with `changeColor` class.
for (i = 0; i < changed.length; i++)
// Remove the changeColor class from their class list.
changed[i].classList.remove("changeColor");
// Rest comes your code.
if(count > 1 && flag === true){

are you trying to get one button disabled when any three buttons are enabled ? if so, perhaps this could help. I highly suggest not to use the h1 tags for this purpose, and use something like a button or div, and removing the onclick attributes from your elements and incorporate them in your main js file similar to the js snippet found below.
(function() {
//an empty array to track the number of elements currently colored
var numberOfElesColored = [],
eles = document.querySelectorAll('h1'),
//the number of active elements allowed at once
numberOfActiveElementsAllowed = eles.length - 1;
//loop though all the elements and attach click event
[].forEach.call(eles, function(ele, i) {
ele.addEventListener('click', function(event) {
var currentEle = event.target;
//is there at least two other elements avaliable still ?
if (!(numberOfElesColored.length === numberOfActiveElementsAllowed)) {
//yes
//is the current clicked element not active already ?
if (!currentEle.classList.contains('changeColor')) {
//yes
//add 1 to tracking array
numberOfElesColored.push(1);
//activate element
return currentEle.classList.add('changeColor');
} else {
//no
//remove 1 from tracking array
numberOfElesColored.pop();
//deactivate elements
return currentEle.classList.remove('changeColor');
}
//are all the elements active already ?
} else if (numberOfElesColored.length === numberOfActiveElementsAllowed) {
//yes
//is the current element an active one ?
if (currentEle.classList.contains('changeColor')) {
//yes
//remove 1 from tracking array
numberOfElesColored.pop();
//deactivate element
return currentEle.classList.remove('changeColor');
}
}
});
});
})();

Related

Prepend only once on scroll

Prepend an element on scroll only once if class exist. Remove if class does not exist.
For example scroll down -> class is added + prepend. Scroll back up -> class is removed so is prepend and so on.
$(window).scroll(function() {
if($("#container").hasClass("active")){
$("#container-wrapper").addClass("active-exists");
$("#container-wrapper").prepend("<p>Test</p>");
}
else {
$("#container-wrapper").removeClass("active-exists");
$("#container-wrapper").remove("<p>Test</p>");
}
});
Current behavior keeps adding infinite <p>Test</p> non stop, just spams it while scrolling up and down.
You can check this with a flag "appended"
window.appended = false; // set as global variable
$(window).scroll(function() {
if($("#container").hasClass("active")){
$("#container-wrapper").addClass("active-exists");
if (!window.appended){ // check with global variable
$("#container-wrapper").prepend("<p>Test</p>");
appended = true;
}
}
else {
$("#container-wrapper").removeClass("active-exists");
$("#container-wrapper").remove("<p>Test</p>");
}
}
Instead of checking whether the element has a specific class, check whether the y-axis scroll position is 0. You'll also need to store whether you've appended the element in a variable, so as not to keep on appending on scroll.
let elem = $('<p>Test</p>')
var hasAdded = false;
$(window).scroll(function() {
const scrollY = window.scrollY;
if (scrollY == 0) {
$('#container-wrapper').removeClass('active-exists')
elem.remove()
hasAdded = false;
} else {
if (!hasAdded) {
$('#container-wrapper').addClass('active-exists').prepend(elem)
hasAdded = true
}
}
});
html,
body {
height: 300%;
}
#container-wrapper{
position:fixed;
height:50px;
}
.active-exists{
background-color:yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container-wrapper">
<div id="container">
</div>
</div>

How do I attach placeholder to the button through JS' DOM?

I am trying to figure out how to attach button 'Delete' to the each list element making so in advance that I will be able to make more buttons for additional list elements later.But when I create buttons,they appear without the text,just tiny rectangle box near the text.I wanted to fix through command 'document.getElementByClassName[list_number + "_button"].placeholder = "Delete",but I got an error even earlier trying to attach classnames to the buttons:
Uncaught TypeError: Cannot read property 'classList' of undefined
at addButton (script.js:74)
at script.js:82
But what's strange is that this error shows only at the [1] list object,not the the [0].For some reason with [0] object everything goes OK,although I didn't succeed in attaching name to it.I thought that the problem laid in list numeration,because the first button is actually "Send',but when I changed the value of var list_number = 0 from 0 to 1,it only got worse and gave an error right away.
How do I attach text in the buttons so they will look normal?
Note:the commands related to the buttons are at the end,everything earlier are command to add new elements to the list trhough input and make the elements line-through
CODE
var button = document.getElementById("button");
var modify_list = document.getElementById("userinput");
var ul = document.querySelector("ul");
var li = document.querySelectorAll("li");
var all_buttons = document.querySelectorAll("button");
var i = 0; //Attach classes to the li
while (li.length > i) {
li[i].classList.add(i);
li[i].classList.add('done');
li[i].classList.add('cursor');
i++
}
//Toggle the line-through function(later we will cal the function that will toggle once more when clicked on element of the list.
var n = 0
while (li.length > n) {
li[n].classList.toggle("done");
n++
}
//Command to add new elements to the list and make line-thorugh when clicked.
function inputLength() {
return modify_list.value.length;
}
function addToTheList() {
var li = document.createElement("li");
li.appendChild(document.createTextNode(modify_list.value));
ul.appendChild(li);
modify_list.value = '';
}
function addAfterClick() {
if (inputLength() === 0) {
alert("Please,don\'t enter the empty list");
} else {
addToTheList();
}
}
function addAfterEnter(key) {
if (key.keyCode === 13 && inputLength() > 0) {
addToTheList();
}
}
button.addEventListener("click", addAfterClick);
modify_list.addEventListener("keypress", addAfterEnter);
function toggle(number) {
li[number].classList.toggle("done");
}
ul.addEventListener("click", whenClicked);
function whenClicked(event) {
var li_number = event.target.className[0];
//In JS it doesn't matter in some occasions if it's a string or number,I suppouse.
// var li_number = Number(li_number_string);
// console.log(li_number);
toggle(li_number);
}
// Create buttons and their functions
function addButton(list_number) {
var button = document.createElement("button");
li[list_number].appendChild(button); //append button near the respective li objects
all_buttons[list_number].classList.add(list_number + "_button") //create class for the button
console.log(all_buttons[list_number].classList);
// document.getElementByClassName[list_number + "_button"].placeholder = "Delete"
}
var list_number = 0 // because under number 0 we have "Send" button
while (li.length > list_number) {
addButton(list_number);
list_number++;
}
// console.log(list_number);
.done {
color: red;
text-decoration: line-through;
}
.cursor {
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<title>DOM</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<h1>What plans do I have till the end of the summer?</h1>
<p>They are:</p>
<input type="text" name="add activities" id="userinput" placeholder="add activities">
<button id="button">Send</button>
<ul>
<li>Learn German</li>
<li>Learn Japanese</li>
<li>Learn Java Script</li>
<li>Physical activities</li>
</ul>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
The text you want to be displayed on a programatically generated HTMLButtonElement can be set using it's .innerText property. The .placeholder property serves a different purpose.
Let's take a closer look at your addButton function:
function addButton(list_number){
var button = document.createElement("button");
li[list_number].appendChild(button); //append button near the respective li objects
all_buttons[list_number].classList.add(list_number + "_button") //create class for the button
console.log(all_buttons[list_number].classList);
// document.getElementByClassName[list_number + "_button"].placeholder = "Delete"
}
The first two lines are okay. Trouble starts here:
all_buttons[list_number].classList.add(list_number + "_button");
all_buttons is a HTML collection of buttons you initialized before you started adding dynamically generated button elements to the DOM thus it just contains the buttons set up via HTML. That means this array is outdated and would need to be updated every time you add or remove buttons.
Furthermore you don't need to use that array at all if you want to manipulate properties of your freshly generated button - you can directly access it using the variable button. I'd also recommend giving those buttons an unique id, so you can reference them later on and give it a click event listener for example. Also since there is already a global variable named button you should give the variable inside the function a different name e.g. localButton.
Here's an example:
var button = document.getElementById("button");
var modify_list = document.getElementById("userinput");
var ul = document.querySelector("ul");
var li = document.querySelectorAll("li");
var all_buttons = document.querySelectorAll("button");
var i = 0; //Attach classes to the li
while (li.length > i) {
li[i].classList.add(i);
li[i].classList.add('done');
li[i].classList.add('cursor');
i++
}
//Toggle the line-through function(later we will cal the function that will toggle once more when clicked on element of the list.
var n = 0;
while (li.length > n) {
li[n].classList.toggle("done");
n++;
}
//Command to add new elements to the list and make line-thorugh when clicked.
function inputLength() {
return modify_list.value.length;
}
function addToTheList() {
var li = document.createElement("li");
li.appendChild(document.createTextNode(modify_list.value));
ul.appendChild(li);
modify_list.value = '';
}
function addAfterClick() {
if (inputLength() === 0) {
alert("Please,don\'t enter the empty list");
} else {
addToTheList();
}
}
function addAfterEnter(key) {
if (key.keyCode === 13 && inputLength() > 0) {
addToTheList();
}
}
button.addEventListener("click", addAfterClick);
modify_list.addEventListener("keypress", addAfterEnter);
function toggle(number) {
li[number].classList.toggle("done");
}
ul.addEventListener("click", whenClicked);
function whenClicked(event) {
var li_number = event.target.className[0];
//In JS it doesn't matter in some occasions if it's a string or number,I suppouse.
// var li_number = Number(li_number_string);
// console.log(li_number);
toggle(li_number);
}
// Create buttons and their functions
function addButton(list_number) {
var localButton = document.createElement("button");
localButton.innerText = "Delete";
localButton.id = "myButton" + list_number;
li[list_number].appendChild(localButton);
}
var list_number = 0 // because under number 0 we have "Send" button
while (li.length > list_number) {
addButton(list_number);
list_number++;
}
.done {
color: red;
text-decoration: line-through;
}
.cursor {
cursor: pointer;
}
<h1>What plans do I have till the end of the summer?</h1>
<p>They are:</p>
<input type="text" name="add activities" id="userinput" placeholder="add activities">
<button id="button">Send</button>
<ul>
<li>Learn German</li>
<li>Learn Japanese</li>
<li>Learn Java Script</li>
<li>Physical activities</li>
</ul>

Toggle between 3 functions on mouse click

I am adding an addEventListener to a picture on my website.
The goal is that every time the user clicks this picture (album-cover-art) a function will be called (function (event)), which will toggle between 3 functions
document.getElementsByClassName("album-cover-art")[0].addEventListener("click", function (event){
});
these are the 3 functions i want to toggle between:
setCurrentAlbum(albumPicasso);
setCurrentAlbum(albumMarconi);
setCurrentAlbum(albumGreenDay);
how can include these 3 function calls in the eventListener that when the picture is clicked it will toggle between them??
document.getElementsByClassName("album-cover-art")[0].addEventListener("click", function (event){
//toggle between the 3 functions below:
setCurrentAlbum(albumPicasso);
setCurrentAlbum(albumMarconi);
setCurrentAlbum(albumGreenDay);
});
NOTE:
This is a challenge where can i only use JavaScript NOT JQuery
It must toggle between them forever, not a loop which will have an end
you can create an array containg all choise then , using an index , select choise and increment this last every click , if index equals to the arrays length then return to the first index (0) ,
var index= 1;
var albums = [albumPicasso,albumMarconi,albumGreenDay];
document.getElementsByClassName("album-cover-art")[0].addEventListener("click", function(event) {
if(index == albums.length) index = 0;
setCurrentAlbum(albums[index]);
index++;
});
See beelow snippet as an explaining sample :
var albumPicasso = "https://dummyimage.com/300x300/500/f0f",
albumMarconi = "https://dummyimage.com/300x300/550/ff0",
albumGreenDay = "https://dummyimage.com/300x300/555/0ff";
var index= 0;
var albums = [albumPicasso,albumMarconi,albumGreenDay];
document.getElementsByClassName("album-cover-art")[0].addEventListener("click", function(event) {
if(index == albums.length) index = 0;
setCurrentAlbum(albums[index]);
index++;
});
function setCurrentAlbum(album){
document.getElementsByClassName("album-cover-art")[0].style.backgroundImage = "url('"+album+"')";
}
.album-cover-art {
background-image : url('https://dummyimage.com/300x300/500/0ff');
width:300px;
height:300px;
}
<div class="album-cover-art">
</div>
For all downvoters: just because you don't like the pattern it doesn't mean the solution is wrong. Type your own, better answer and let the asker pick the one he prefer. Also, if you're downvoting supply the reason (as a comment) for learning purposes, for me and the asker. thanks.
Here is the snippet you may find usefull:
albumClickCounter = 0;
document.getElementsByClassName("album-cover-art")[0].addEventListener("click", function (event){
if(window.albumClickCounter % 3 === 0) setCurrentAlbum(albumPicasso);
if(window.albumClickCounter % 3 === 1) setCurrentAlbum(albumMarconi);
if(window.albumClickCounter % 3 === 2) setCurrentAlbum(albumGreenDay);
window.albumClickCounter++;
});
var setCurrentAlbum = function(album) { alert(album); }
var albumPicasso = 1;
var albumMarconi = 2;
var albumGreenDay = 3;
.album-cover-art {
width: 200px;
height: 200px;
background: green;
}
<div class="album-cover-art"></div>
For demonstration purposes albums are numbers, but the logic can be whatever you like. Adjust to suit your needs.
use as below
var previouParam="";
document.getElementsByClassName("album-cover-art")
[0].addEventListener("click", function (event){
if(previouParam==""){
setCurrentAlbum("albumPicasso");
}else if(previouParam=="albumPicasso"){
setCurrentAlbum("albumMarconi");
}else{
previouParam="";
setCurrentAlbum("albumGreenDay");
}
});

Need To Convert Text To UpperCase and Lowercase When Clicked

I know nothing about JavaScript, and I'm sure this is an easy thing to do, but I've been bashing my brain for the past three hours trying to figure it out.
What I want is to have some text, say Test.com, that when clicked will transform all the letters to uppercase (TEST.COM). If the user clicks again, the text will go to all lowercase(text.com). On the third click the text goes back to the original form (Test.com).
Is this possible?
var count = 1;
$('.text').click(function() {
$(this).toggleClass('uppercase', count === 2);
$(this).toggleClass('lowercase', count === 3);
if (count === 3) {
count = 0
}
count++;
});
.uppercase {
text-transform: uppercase;
}
.lowercase {
text-transform: lowercase;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="text">CamelCase 1 </span>
Here's the long-winded vanilla JS version:
// grab the element containing the text
var div = document.querySelector('#test');
// grab the text
var text = div.innerHTML;
// save a copy of the text
var originalText = div.innerHTML;
// set `toggle` to O for original
// L = lowercase, U = uppercase
var toggle = 'O';
// add an click listener to the element containing the text
div.addEventListener('click', function () {
// toggle between the states updating the text
// of the element with each new click
switch (toggle) {
case 'O':
div.innerHTML = text.toUpperCase();
toggle = 'U';
break;
case 'U':
div.innerHTML = text.toLowerCase();
toggle = 'L';
break;
case 'L':
div.innerHTML = originalText;
toggle = 'O';
break;
}
}, false)
DEMO
And if you wanted to get this working for multiple instances of text on the page, something like this would work. Ideally you'd want to use event propagation for this, but since the layout of your page might change in the future it's probably not worth the risk:
;(function () {
// grab all the elements
var divs = document.querySelectorAll('.test');
// status is used to keep track of where in the cycle each text item is
var status = {};
for (var i = 0, l = divs.length; i < l; i++) {
var div = divs[i];
var key = div.innerHTML.toLowerCase();
// update the status object with the initial text values
status[key] = {
status: 'O',
originalText: div.innerHTML
};
// add the listener like last time
// except this time we monitor the status object for
// for each text instance
div.addEventListener('click', function () {
var text = this.innerHTML.toLowerCase();
var key = status[text].originalText.toLowerCase();
var toggle = status[key].status;
var originalText = status[key].originalText;
switch (toggle) {
case 'O':
this.innerHTML = originalText.toUpperCase();
status[key].status = 'U';
break;
case 'U':
this.innerHTML = originalText.toLowerCase();
status[key].status = 'L';
break;
case 'L':
this.innerHTML = status[key].originalText;
status[key].status = 'O';
break;
}
}, false);
}
}());
DEMO
Define 2 CSS classes.
.ucase {text-transform:uppercase;}
.lcase {text-transform:lowercase;}
Use a combination of jQuery .hasClass() .removeClass() and .addClass() to switch the cases.
Remove all classes from the text to return to original state.
jQuery(document).ready(function() {
jQuery(".textitem").click(function() {
$t = jQuery(this);
if($t.hasClass("ucase")) {
$t.removeClass("ucase").addClass("lcase");
} else if($t.hasClass("lcase")) {
$t.removeClass("lcase");
} else {
$t.addClass("ucase");
}
});
});
Fiddle: https://jsfiddle.net/ptj1ke8y/
Perhaps not the most elegant solution, but you can count the clicks (modulus 3), and adjust the text according to the number and cycle through your 3 cases.
var i = 0;
var cl = $('#text').text();
$('#text').click(function() {
var str = $(this).text();
if (i % 3 == 0) {
$('#text').html(str.toUpperCase());
}
if (i % 3 == 1) {
$('#text').html(str.toLowerCase());
}
if (i % 3 == 2) {
$('#text').html(cl);
}
i++
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="text">Text</div>
You can use .toUpperCase() and .toLowerCase() JavaScript methods to change the case of any text.
Since you're using jQuery then you can use the .text() jQuery method to get and set the text content of any DOM node.
You need to store somewhere the original value of your text so that you can get it after the third click, and the jQuery .data() method would be good for this because that way you can easily have few elements on one page that behaves this way.
You can write something like this to make all elements with class "test" behave in a way that you have described:
$('.test').click(function () {
var $this = $(this),
data = $this.data('clicker');
if (!data || !data.text) {
data = {
text: [
$this.text(),
$this.text().toUpperCase(),
$this.text().toLowerCase()
],
step: 0
};
}
data.step = (data.step + 1) % 3;
$this.text(data.text[data.step]);
$this.data('clicker', data);
});
See: DEMO for an example of how it works with 3 elements simultaneously.
First use click() to event handler to the "click" and then use .hasClass(), removeClass() and addClass() to do and use css text-transform
HTML file
<div id="trigger">click me to transform</div>
CSS File
.uppercase { text-transform: uppercase; }
.lowercase { text-transform:lowercase; }
Javascript file
$( document ).ready(function() {
$( "#trigger" ).click(function() {
if($( "#trigger" ).hasClass( "uppercase" )) {
$(this).removeClass('uppercase').addClass('lowercase');
}
else {
$(this).removeClass('lowercase').addClass('uppercase');
}
});
});
Try to play the Sandbox
I think this is what you want (button caption changes to tell what is it going to do and changes the text):
<form name="form1" method="post">
<input name="instring" id="instring" type="text" value="this is the text string" size="30">
<input type="button" id="button" name="Convert" value="Make Uppercase >>" onClick="makeUppercase();">
<input name="outstring" type="text" id="outstring" value="" size="30">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
function makeUppercase(){
if( $('#button').val()=="Make Uppercase >>"){
$('#button').attr("value","Make Lowercase >>");
$('#outstring').attr('value', $('#instring').attr('value').toUpperCase());
} else if($('#button').val()=="Make Lowercase >>") {
$('#button').attr("value","Make Original >>");
$('#outstring').attr('value', $('#instring').attr('value').toLowerCase());
} else{
$('#button').attr("value","Make Uppercase >>");
$('#outstring').attr('value', $('#instring').attr('value'));
}
}
</script>

Adding className to body on mouseevent occuring multiple times?

I am adding an additional className to the body tag, however the className is being added multiple times... some help on how to avoid this would be very welcome!
Thanks
<html>
<head>
<style type="text/css">
.defaultText {
font-size:100%;
}
.myNewClass {
font-size:150%;
color:red;
}
</style>
<script type="text/javascript">
<!--
var state;
window.onload=function() {
obj=document.getElementsByTagName('body')[0];
state=(state==null)?' defaultText':state;
obj.className+=state;
document.getElementById('addClass').onclick=function() {
obj.className+=(obj.className==' myNewClass')?' defaultText':' myNewClass';
state=obj.className;
}
}
-->
</script>
</head>
<body class="thisClassMustStay">
<div>My text here</div><br />
toggle class</div>
</body>
</html>
> var state;
>
> window.onload=function() {
>
> obj = document.getElementsByTagName('body')[0];
> state = (state == null)? ' defaultText' : state;
The first time the code is run, state us undefined so it would be better to either set it to null when declaring it or change the above to:
state = state? ' defaultText' : state;
Given that the first time it is run the expression will evaluate to true, then state will be set to ' defaultText'. Note that there is a space at the start of the string. In some browsers, this space will be removed and in others it will be kept, so much better to remove it.
> obj.className += state;
At this point, 'defaultText' will be added to the list of classes on the body element. Again there may be issues with leading spaces that are best dealt with by robust hasClass, addClass and removeClass functions (they aren't particularly difficult to write).
>
> document.getElementById('addClass').onclick = function() {
> obj.className += (obj.className == ' myNewClass')? ' defaultText' :
> ' myNewClass';
With functions suggested above, this could be:
if (hasClassname(obj, 'myNewClass')) {
addClassname(obj, 'defaultText') ;
} else {
addClassname(obj, 'myNewClass') ;
}
.
state = obj.className;
}
}
If you need help with has/add/removeClassname functions, just ask.
I use this function (for sites where I don't have jQuery).
function addClass(element, className)
{
// Split the classes
var classes = element.className.split(' ');
// Remove class if it exists (to force the added class to be added at the end).
index = classes.indexOf(className);
if (index > -1)
{
classes.splice(index, 1);
}
// Add class.
classes.push(className);
element.className = classes.join(' ');
}
Another solution would be to keep a global to remember if you have added the class, or write a function to check it:
function hasClass(element, className)
{
var classes = element.className.split(' ');
index = classes.indexOf(className);
return index > -1;
}

Categories

Resources