Change the value of a text in html with javascript - javascript

I have an icon with a text that says "Open" in green color , what I want is a function that if receives "true" keep the text in Open, but if it receives "false" it changes to Closed and the text with the icon is red
<i class="fa fa-shopping-cart" style="color:green;"></i>
<span style="color:green;">Open</span>
function open_close () {
var resp=false;
}

document.addEventListeners('DOMContentLoaded', () => {
const button = document.querySelector('span');
function toggleButtonText(status){
button.innerHTML = status ? 'Open' : 'Closed';
}
});

Related

I am having problems trying to toggle an icon in javascript

I am trying to toggle my edit button to the class of hidden and my trash button to the class of show. but I am not able to target the elements I always am getting the error of NULL would anyone be able to help I am stuck.
I have tried many ways but I cant get the edit button to toggle to display none and my trash button to toggle to display flex thanks guys for any help
HTML
```
TO-DO LIST
Today's To Do
<div class="todo-list"></div>
<button id="clear-btn" class="clear-btn" type="button"
name="button">
Clear all completed
</button>
</div>
</body>
</html>
```
const clear = document.querySelector(".clear-btn");
const list = document.querySelector(".todo-list");
const input = document.getElementById("add-input");
const form = document.getElementById("todoform");
let todos = [];
const LINE_THROUGH = "lineThrough";
form.addEventListener("submit", (e) => {
e.preventDefault();
saveTodo();
});
function saveTodo() {
const todoValue = input.value;
todos.push({
value: todoValue,
completed: false,
});
input.value = "";
renderTodos();
}
function renderTodos() {
list.innerHTML = "";
todos.forEach((todo, index) => {
list.innerHTML += `
<div class="todo" id=${index}>
<i class="fa ${
todo.checked ? "solid fa-check" : "regular fa-square"
}" data-action="check"
></i>
<p class=${todo.checked ? LINE_THROUGH : ""} data-
action="check">${todo.value}</p>
<span class= "edit">
<i class='fas fa-ellipsis-v edit-task ' data-action="edit">
</i>
</span>
<i class="fa-solid fa-trash-can trash-btnn hidden " data-
action="delete">
</i>
</div>
`;
});
}
list.addEventListener("click", (event) => {
const { target } = event;
const parentElement = target.parentNode;
if (parentElement.className !== "todo") return;
const todo = parentElement;
const todoId = Number(todo.id);
const { action } = target.dataset;
action === "check" && checkTodo(todoId);
// action === 'edit' && checkTodo(todoId);
// action === 'delete' && checkTodo(todoId);
});
function checkTodo(todoId) {
todos = todos.map((todo, index) => ({
...todo,
checked: index === todoId ? !todo.checked : todo.checked,
}));
renderTodos();
}
const threeVBtn = document.querySelector(".edit-task");
const trashBtn = document.querySelector(".trash-btnn");
threeVBtn.addEventListener("click", (e) => {
trashBtn.classList.toggle("show");
threeVBtn.classList.toggle("hidden");
});
.hidden {
display: none;
}
.trash-btnn {
cursor: pointer;
color: rgb(204, 16, 47);
}
.show {
display: flex;
}
It is because on your first render there is no todo initially and the element specified by querySelector for threeVBtn returns undefined. One simple way is to check if the element is added to document before attaching event listener, like this:
if (threeVBtn) {
threeVBtn.addEventListener("click", (e) => {
trashBtn.classList.toggle("show");
threeVBtn.classList.toggle("hidden");
});
//perform any action for once threeVBtn is added to Document
}
The problem is when you run any of the DOM selection methods (querySelector, getElementByClassName, etc), it only grabs what's currently in the DOM (ie. currently rendered html). When you add or remove items from the DOM, you must re-select elements to get the current items. It's kind of a pain, but there is a solution.
There is a concept called "event delegation" which is a technique that solves this problem. Delegation works by picking a parent element of the dynamic list - it can be any parent element so long as the element stays in the DOM while your list is dynamically changing. Many people just use the <body> since it's always guaranteed to be there. Whenever something inside the parent element is clicked, the event does this cool thing called "bubbling" - which is beyond the scope of this answer. You can read all about DOM events, bubbling, and delegation on MDN.
You can attach your click handlers to the <body> element and check the event.target for the different types of things you want, best shown by example:
document.body.addEventListener('click', (ev) => {
const el = event.target;
if (el.classList.contains("edit-task")) {
// edit button was clicked
ev.preventDefault();
return;
}
if (el.classList.contains("trash-btnn")) {
// trash button was clicked
ev.preventDefault();
return;
}
});

Changing inner content of a button

I’m new to Js.. and I’m trying to change the inner Text of a button to toggle on click between On and Off using addEventListener method.
const btn = document.getElementsByClassName("btn")[0];
const btn2 = document.createTextNode("Off");
btn.addEventListener.toggle("click", modifiedText() {
// enter code here
});
ModifiedText() {
// enter code here
}
<button class=“btn”>On</button>
Just addEventListener on button and get or set the text inside button using textContent property.
const button = document.querySelector(".btn");
button.addEventListener("click", function clickHandler( e ) {
const btnText = e.target.textContent;
if( btnText.toLowerCase() === "on") e.target.textContent = "Off";
else e.target.textContent = "On"
})
<button class="btn">On</button>

Toggle only one show more / show less button on site with multiple buttons of the same id

When I click the "show more" button, more gallery images show and "show more" is changed to "show less". However, because I'm working with ExpressionEngine (CMS) templates and entries, the id is the same for every "show more" button on the page, causing other buttons to change its innerText value when they haven't actually been clicked. I need my code to reflect only one button being clicked.
Since I'm working in a CMS template, I'd like to only use HTML and JavaScript.
Here is my code:
{if image:total>6}
<button class="btn btn-primary mx-auto" id="showMoreButton" type="button" data-toggle="collapse" data-target="#collapse-{embed:park_url}-{park_facilities_relate:url_title}" aria-expanded="false" aria-controls="collapseExample" onclick="showLess()">SHOW MORE</button>
{/if}
<script>
var status = "less";
function showLess() {
if (status == "less") {
document.getElementById("showMoreButton").innerText = "SHOW LESS";
status = "more";
} else if (status == "more") {
document.getElementById("showMoreButton").innerText = "SHOW MORE";
status = "less"
}
}
</script>
Results of what happens actually differ depending on where the script tag is placed (if I put the script tag below the button code vs if the script code is above the button code). Here is an image of what's happening:
To change the Button text you can use the event instead of getElementById().
To do so add this to your function call on button.
onclick=”showLess(this)”
This way you can get all the attributes of just the button you actually clicked. In the script it could look like:
function showLess(event) {
if (event.innerText == "SHOW MORE") {
event.innerText = "SHOW LESS";
} else if (event.innerText == "SHOW LESS") {
event.innerText = "SHOW MORE";
}
}
Don’t know anything about the actually showing of the gallery so can’t help with that but this way atleast the button works.
so what you could do is use the .id within your function.
var status = "less";
function showLess() {
if (status == "less") {
document.getElementById("showMoreButton").id = "showLessButton";
document.getElementById("showMoreButton").innerText = "SHOW LESS";
status = "more";
} else if (status == "more") {
document.getElementById("showLessButton").id = "showMoreButton";
document.getElementById("showMoreButton").innerText = "SHOW MORE";
status = "less"
}
}
I think I have the logic the right way around but its worth thinking about. all its going to do is change the ID of the element, so it stays a a unique id and therefor you can control it better in one state rather than trying to make it to something when its one way than the other

jQuery button toggle text doesn't work onlick

I've created button to show content below. I need change text inside this button when this content is visible. So:
My HTML code
<button class="c-cta c-cta--show-hide">
<div class="e-cta-text">Pokaż więcej</div>
<span class="e-cta__icon--regular e-cta__icon--after">
<i class="fas fa-chevron-circle-down"></i>
</span>
</button>
and my jQuery
$(function() {
var button = $("button.c-cta--show-hide");
var buttonText = $(".e-cta-text");
button.click(function() {
$(this).next(".l-center--hidden-content").toggleClass("l-center--show-content");
$(this).children("span.e-cta__icon--before").children("i").toggleClass("e-cta__icon--before--rotate");
$(this).children("span.e-cta__icon--after").children("i").toggleClass("e-cta__icon--after--rotate");
});
// function to change the text
button.click(function() {
if (buttonText.innerHTML === "Pokaż mniej") {
buttonText.innerHTML = "Pokaż więcej"
} else {
buttonText.innerHTML = "Pokaż mniej"
}
})
});
How to makes it right?
Since your code mostly uses jQuery here's your text-change function completely in jQuery working:
jsFiddle demo: https://jsfiddle.net/wfj6L38v/
$(function() {
var button = $("button");
var buttonText = $(".e-cta-text");
button.click(function() {
if (buttonText.text() == 'Less') {
buttonText.html("More");
} else {
buttonText.html("Less");
}
});
});

Update document field value depending ils value on single button click

Foreach of my "categories" collection document's (5), i'm displaying a button. And i would like when I click on my button it change the value of my document "active" field to "yes" or "no" depending of the old value.
This is what I tried :
db.collection("categories").orderBy("id", "asc").onSnapshot(snapshot =>
{
let changes = snapshot.docChanges();
changes.forEach(change =>
{
if (change.type == "added" || change.type == "removed")
{
renderNavItems(change.doc);
renderTab(change.doc);
renderButtons(change.doc);
}
else if(change.type == "modified")
{
buttonFc(change.doc);
}
})
});
RenderButtons() Function : (Only one time)
var buttons;
var button;
var buttonDiv;
function renderButtons(doc)
{
button = document.createElement("button");
buttonDiv = document.createElement("div");
buttonDiv.setAttribute("class","btnDiv"+doc.data().id);
if (doc.data().active == "yes")
{
button.setAttribute("class", "btn btn-success btn-sm btnView");
button.textContent= "Slide activée";
}
else if (doc.data().active == "no")
{
button.setAttribute("class", "btn btn-danger btn-sm btnView");
button.textContent= "Slide desactivée";
}
buttonDiv.appendChild(button);
var tab = document.querySelector("#"+doc.data().name);
tab.appendChild(buttonDiv);
buttonFc(doc);
}
buttonFc() function : (Each time, the value of my field change)
function buttonFc(doc)
{
DocRef = db.collection("categories").doc(doc.id);
if (doc.data().active == "yes")
{
button.addEventListener('click', () =>
{
console.log("YES TO NO");
DocRef.update({
"active": "no"
})
});
}
else if (doc.data().active == "no")
{
button.addEventListener('click', () =>
{
console.log("NO TO YES");
DocRef.update({
"active": "yes"
})
});
}
But, when I click on a button, my functions loops and each time loop is bigger.
When I click 5 time :
The buttonFc() function adds a new eventlistener for each time it is called, so you end up with multiple eventlisteners on the same button. This explains why the loop gets 'bigger' each time.
Make sure you add eventlisteners only once.

Categories

Resources