OnClick change button text and URL - javascript

I have this HTML code that works as expected. When the user clicks on "Start" button, the button text should change to stop (along with href to stop_api)
How do I accomplish this? Pushing the stop button should change the text back to Start if stop_api response was "success". The code mentioned above is an example. I just need a button to hit the api. This is simple GUI for new users.
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<div class="container">
<h2>start activity</h2>
<button type="button" class="btn btn-danger">Start</button>
</div>

What you are describing is a form being submitted, so it doesn't make a lot of sense to link to another page.
const submitButton = document.querySelector('form button')
const form = document.querySelector('form')
const start = 'Start'
const stop = 'Stop'
const startApiEndpoint = 'https://link_to_start_api'
const stopApiEndpoint = 'https://link_to_stop_api'
// Listen for form submit
form.addEventListener('submit', e => {
e.preventDefault()
if (submitButton.textContent.includes(start)) {
api(startApiEndpoint)
submitButton.textContent = stop
} else {
api(stopApiEndpoint)
submitButton.textContent = start
}
})
// Hit api endpoint and do something with the response
function api(endpoint) {
console.log(`Fetching ${endpoint}`)
fetch(endpoint)
.then(response => response.json())
.then(data => {
console.log(data)
// Check for success and update button text
})
.catch((error) => {
console.error(error);
});
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" />
<form class="container">
<h2>start activity</h2>
<button class="btn btn-danger">Start</button>
</form>
It's probably a better idea to wait for a successful response from each api call before changing the behaviour/UI of the form.

This should do the trick, I recommend using a different id though
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<div class="container">
<h2>start activity</h2>
<button id="start" type="button" class="btn btn-danger">Start</button>
</div>
<script>
var button = document.getElementById("start")
button.onclick = function(){
button.innerHTML = 'Stop'
}
</script>

I would recommend creating a second button next to the existing one with an display of none. When the user presses the button, switch the display:none off and enable display:none on your current start button

Related

How do I make my copy to clipboard buttons work in a fetched JSON table?

first post and code newbie here. Be kind :-)
So I've got this fetched and into JSON converted data from an example API where certain colors with their HEX codes are displayed. I tried to include buttons after every HEX code, so that whenever u like a color, you can easily copy the HEX via button click. However i can not make the functionality of the buttons work. Any tips, hints, whatsoever?
Appreciated!
fetch("https://api.sampleapis.com/csscolornames/colors")
.then(response => response.json())
.then(json => {
let li = `<tr><th>Name</th><th>Hex</th></tr>`;
let copyButton = `<button onclick="goCopy"><i class="fa-regular fa-copy"></i></button>`
json.forEach(color => {
li += `<tr>
<td>${color.name}</td>
<td class="test">${color.hex} ${copyButton}</td>
</tr>`;
});
function goCopy() {
// Get the text field
var copyText = document.getElementsByClassName("test");
// Select the text field
copyText.select();
copyText.setSelectionRange(0, 99999); // For mobile devices
// Copy the text inside the text field
navigator.clipboard.writeText(copyText.value);
// Alert the copied text
alert("Copied the text: " + copyText.value);
}
document.addEventListener("click", () => {
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>c</title>
<link rel="shortcut icon" href="./IMG/favicon-96x96.ico" type="image/x-icon">
<!-- CSS Stylesheet -->
<link rel="stylesheet" href="./CSS/style.css">
</head>
<body>
<div class="container">
<h1 class="header">c</h1>
<!-- Suchleiste -->
<form action="" class="searchbar">
<input type="text" name="" id="searchInput" onkeyup="tableSearch()" placeholder=" Suchen" style="font-family:Arial, FontAwesome" />
</form>
<!-- Tabelle für Daten-->
<table id="colorTable"></table>
</div>
<script src="./index.js"></script>
</body>
I tried giving the second row of a class, but I am not really sure how to make each button work it's own HEX code.

how to pass event in innerhtml by onclick

I am making a project about add to cart. I want to pass event by onclick from innerhtml.
Here is my html code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Add to cart</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
</head>
<body>
<div id="cards-container" class="row align-items-center my-3 p-3"></div>
<script src="./script.js"></script>
</body>
</html>
Here is my js code
fetch('https://jsonplaceholder.typicode.com/users')
.then(res=>res.json())
.then(data=>show(data))
function show(data){
const cardsContainer = document.getElementById('cards-container');
cardsContainer.innerHTML='';
data.map(element => {
const cardDiv = document.createElement('div')
cardDiv.className= "col-md-4"
cardDiv.innerHTML=`
<div class='card p-5 m-1'>
<h3>${element.name}</h3>
<h5>${element.email}</h3>
<button class="btn btn-primary" id='card-button' onclick='setLocalStorage(e)'>Add to Card</button>
</div>
`
cardsContainer.appendChild(cardDiv);
});
}
function setLocalStorage(e){
console.log("clicked",e)
}
I got this error in console https://d.pr/i/JCjI77
I've run into this issue a few times before as well.
First, I would suggest using jquery anyway. When writing plain html, I almost always use jquery. It makes interaction with the DOM much easier. So here is an example in jquery of the onClick event for an element with id="card-button". A normal click event won't work from jquery here. You have to set it on the document and then further set a selector:
fetch('https://jsonplaceholder.typicode.com/users')
.then(res=>res.json())
.then(data=>show(data))
function show(data){
const cardsContainer = $('#cards-container');
cardsContainer.html("");
data.map(element => {
cardsContainer.append(`
<div class='card p-5 m-1 col-md-4'>
<h3>${element.name}</h3>
<h5>${element.email}</h3>
<button class="btn btn-primary" id='card-button'>Add to Card</button>
</div>
`
});
}
$(document).on("click", "#card-button", function(e) {
setLocalStorage(e)
// or you can just place the contents of setLocalStorage directly
// into here!
})
function setLocalStorage(e){
console.log("clicked",e)
}
you can remove onClick from the button element here. Make sure you remember to import jquery. Ideally the minified version.
BUT YOU HAVE ANOTHER MORE IMPORTANT ISSUE
you're creating multiple add card buttons with the same id (card-button). you need to set card-button as a class. This way it can be applied multiple elements. I would suggest adding an ID to the button or cardDiv that is associated with userID, Index or any other unique identifier. This way you can recognize which user or card button is actually being pressed, and take action accordingly. Here is the updated jQuery with class instead of ID
fetch('https://jsonplaceholder.typicode.com/users')
.then(res=>res.json())
.then(data=>show(data))
function show(data){
const cardsContainer = $('#cards-container');
cardsContainer.html("");
data.map(element => {
cardsContainer.append(`
<div class='card p-5 m-1 col-md-4'>
<h3>${element.name}</h3>
<h5>${element.email}</h3>
<button class="btn btn-primary" class="card-button" id='some-unique-id'>Add to Card</button>
</div>
`
});
}
$(document).on("click", ".card-button", function(e) {
setLocalStorage(e)
// or you can just place the contents of setLocalStorage directly into here!
// Here you can grab the jquery object with $(this), or use the
// ID with e.target.id with the e.target.id, etc...
clickedButton = $(this);
clickedButtonID = e.target.id;
})
function setLocalStorage(e){
console.log("clicked",e)
}
I don't use plain HTML without jQuery often, so I can't answer for sure if you want to take that route. It seems as if this previous thread answers that question, definitely better than I could.
unable to use getElementById on HTML element not yet appended to document
Best of luck!!

addEventlistener for buttons does not work properly with more than one button

I want to create a script where I can upload files via event listener drop.
Everytime a file is dropped, a new table row has to be created with a save/edit button. These buttons need event listeners for click, but the problem is that the event listener works only on the last button added to the table.
I have made a simplified example of my problem. The function clickEventSaveButton() contains an .addEventlistener, with an anonymous function. For now it just executes a console log, but only for the button in the last table row. Everytime a new button is created, the old one stops working.
JS:
'use strict';
const dragArea = document.getElementById('dragArea');
const fileTable = document.getElementById('fileTable');
const fileTableBody = fileTable.querySelector('tbody');
let id = 0;
dragArea.addEventListener('dragover', (e) => {
e.preventDefault();
e.stopPropagation();
});
dragArea.addEventListener('drop', (e) => {
e.preventDefault();
e.stopPropagation();
// Add table row
fileTableBody.innerHTML += createFileTableRow(id, 'placeholder');
clickEventSaveButton(id);
id++;
});
function clickEventSaveButton(id) {
let saveButton = document.querySelector('.file-save a[data-id="'+id+'"]');
console.log(saveButton);
console.log(id);
saveButton.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
console.log('Save Button (ID:'+id+') pressed!');
});
}
function createFileTableRow(id, name) {
return `
<tr data-id="${id}">
<td class="file-name">${name}</td>
<td class="file-save">
<a data-id="${id}" class="button is-info is-small">Save</a>
</td>
</tr>
`;
};
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'self';">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Test</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma#0.9.1/css/bulma.min.css">
<script defer src="test.js"></script>
</head>
<body>
<div class="columns"><div class="column is-half is-offset-one-quarter">
<h1>Work in progress</h1>
<div id="dragArea" class="box has-background-info-light has-text-centered py-6">
Drag .xlsx files here!
</div>
<hr>
<h3 id="fileTableTitle">No files loaded...</h3>
<table id="fileTable" class="table table is-fullwidth is-hoverable">
<thead><tr><th>File</th><th>Save File</th></tr></thead>
<tbody></tbody>
</table>
<hr>
</div></div>
</body>
</html>
So, thanks to Patrick Evans I was able to solve the issue that bugged me for some hours.
Instead of innerHTML I have to use insertAdjacentHTML.
Solution:
fileTableBody.insertAdjacentHTML('beforeend', createFileTableRow(id, 'placeholder'));

Unable to add content using insertAdjacentHTML after i have successfully removed it

this is my code:
"use strict";
const searchBox = document.querySelector("#myText");
const searchBtn = document.querySelector(".btn-search");
const searchContainer = document.querySelector(".search-container");
let mainText = document.querySelector(".main-text");
const quit = document.querySelector("#btn-close");
let showMain;
const newMain = "";
let printMain = function(text) {
showMain = `
<article class="country">
<h1>Country you Searched</h1>
<p>Hello</p>
<p>${text}</p>
</article>`;
console.log(`Our show main is : ${showMain}`);
mainText.insertAdjacentHTML("beforeend", showMain);
};
searchBox.addEventListener("click", function() {
if (searchBox.value === "Type in") {
searchBox.value = "";
}
});
searchBtn.addEventListener("click", function() {
if (searchBox.value && searchBox.value !== "Type in") {
console.log(searchBox.value);
printMain(searchBox.value);
searchBox.value = "";
} else {
alert("please type in country name!");
}
});
quit.addEventListener("click", function() {
//mainText.remove(showMain);
const myDiv = document.getElementById("myId");
const parent = myDiv.parentNode;
parent.removeChild(myDiv);
console.log(showMain);
});
<!DOCTYPE html>
<html lang="en">
<header>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<script defer src="script.js"></script>
<title>Simple Work</title>
<button id="btn-close">go back</button>
</header>
<body>
<main class="container">
<div class="main-text" id="myId"></div>
<p class="search-container">
<label>Type In : </label>
<input type="text" id="myText" value="Type in" />
</p>
<button class="btn-search">input</button>
</main>
</body>
</html>
So, I was trying to make code that add the text using insertAdjacentHTML
and next when I click "go back" button, it will erase the html that I had added using insertAdjacentHTML.
I have success up to this point. After this when I try to add new HTML using insertAdjacentHTML, it doesn't work. What I must do to fix this?
(as my English is second language, explanation might not be clear, I am just making web site that I could add text(must use insertAdjacentHTML) and erase that by using "go back" button and after I erase all of them, it could add new text again by using "input" button)
When you remove the node, you are removing the element that mainText points to, therefore, you code cannot place content into a node that is no longer there. So it throws an error stating so.
You should probably only remove the element with classname of country:
document.querySelector('.country').remove();

How do I update the input value using an onchange event and get the value in vanilla Javascript?

I am doing an assignment where I make a simple API call using fetch to retrieve an image a of dog by breed. The one issue I can't resolve is that the input value never changes when I try to retrieve an image of a different breed. the default value, which is 'hound', reappears after I press submit. I know I need to attach an onchange event to my input but I am not sure how to write it or how to get the value after the onchange event is triggered. Any help would be greatly appreciated. I originally wrote this with jQuery but decided to rewrite it in vanilla Javascript so that's why there is no jQuery.
I put a '<---' on the line I am struggling with.
P.S I know my code isn't very good, I am new to this.
Javascript
function getJson(breed) {
fetch("https://dog.ceo/api/breed/" + breed + "/images/random")
.then((response) => response.json())
.then((responseJson) => displayResults(responseJson));
}
function displayResults(responseJson) {
const dogImage = responseJson.message;
let breedImage = "";
let container = document.createElement("div");
console.log(dogImage);
breedImage += `<img src="${dogImage}">`;
container.innerHTML = breedImage;
document.querySelector(".results-img").innerHTML = "";
document.querySelector(".results-img").appendChild(container);
}
function submitButton() {
let breedName = document.querySelector("#numberValue").value;
breedName.addEventListener().onchange.value; <---
document.getElementById("dog-input").addEventListener("submit", (e) => {
e.preventDefault();
getJson(breedName);
});
}
submitButton();
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dog Api</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<form>
<input id="numberValue" type="text" value="hound" />
<button type="submit" class="submit-button">Submit</button>
</form>
<section class="results">
<h2>Look at these Dogs!</h2>
<div class="results-img"></div>
</section>
</div>
<script src="main.js"></script>
</body>
</html>
You don't need an onchange event handler. Currently you're storing the value of the input in breedName when you call submitButton. That means that breedName will never change because it is merely a reference to the value at that moment.
Instead create a reference to the element and read the value property in the submit event handler. That will get the value how it is at the time you submit.
function getJson(breedName) {
console.log(breedName);
}
function submitButton() {
const form = document.querySelector('#dog-form');
const input = document.querySelector('#numberValue');
form.addEventListener('submit', event => {
event.preventDefault();
const breedName = input.value;
getJson(breedName);
});
}
submitButton()
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dog Api</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<form id="dog-form">
<input id="numberValue" type="text" value="hound" />
<button type="submit" class="submit-button">Submit</button>
</form>
<section class="results">
<h2>Look at these Dogs!</h2>
<div class="results-img"></div>
</section>
</div>
<script src="main.js"></script>
</body>
</html>

Categories