Using checkboxes to render selected items to <div> - javascript

I have a populated table of JSON data with a checkbox next to each---I want it so that when a checkbox is selected it pushes that selected item into an array (in this case the div myFave.hs-gc-header).
When I console.log(arr) it just shows a bunch of empty arrays (I believe one for each of the list items). Not sure why this is--if anyone could shed light on this that would be great.
I think the problem lies with the populateArr() block, but I can't say for sure.
JS:
loadTableData() {
let tableRes = redactedName.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).map(function(obj) {
return {
// "FileName": obj.FileLeafRef,
// "Path": obj.EncodedAbsUrl,
"Titles": obj.File.Name
}
});
let allTitles = tableRes;
for (var i = 0; i < allTitles.length; i++) {
let tr = $("<tr/>");
$(tr).append("<td> </td>");
$(tr).append("<td>" + allTitles[i].Titles + "</td>");
$(tr).append("<input type='checkbox'/>").addClass("checkbox").val("val");
/* ---------- */
function populateArr() {
let arr = [];
$(".checkbox input[type='checkbox']:checked").each(function() {
arr.push($(this).val());
});
return arr;
}
$("#myFave.hs-gc-header").click(function() {
populateArr();
})
};
HTML snippet
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1, shrink-to-fit=no">
<meta name="description" content="description here">
<meta name="keywords" content="keywords,here">
<!------------------------------->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.6.2/core.min.js"></script>
<script
type="text/javascript"
src="dist/js/jquery_wrapper.min.js"></script>
</head>
<body>
<script src="./bundle.js"></script>
<div class="km-div-container">
<div class="col-md-2"> <!-- Left -->
<div class="form-group">
<input
type="search"
class="form-control"
id="searchbar"
placeholder="Search All Documents...">
</div>
<div id="myFave.hs-gc-header">
<p>My Favorites:</p>
</div>
</div>
</div> <!-- km -->
</body>
</html>

I don't think this will work, I had a similar problem while using vanilla JavaScript.
When you append to the dom like below, you won't be able to add event listeners to the html tags.
$(tr).append("<input type='checkbox'/>").addClass("checkbox").val("val");
You should do this in your for loop when you filter for the .checkbox with attribute check it should work.
// convert code to jquery
let checkbox = document.createElement('checkbox');
check.setAttribute('type', 'checkbox');
checkbox.className = 'checkbox';
tr.appendChild(checkbox);

Related

Problem with targeting created button with addEventListener

I'm learning vanilla JS and trying to make "To-do list" project.
So, idea is simple adding values from form into the list. After that I add edit/remove buttons for every li in list and put the addEventListener to that buttons.
For some reason, event listener is targeted on button from form. When I click on button to add new item in list, there is click listener that I want on edit button.
I try different ways to target the right button with parentNodes or childNodes, i find the pretty same code as mine but that don't work for me.
function newItem() {
let input = document.getElementById("input").value;
if (input != "") {
let li = document.createElement("li");
li.appendChild(document.createTextNode(input));
let editButton = document.createElement("button");
editButton.appendChild(document.createTextNode("Edit"));
li.appendChild(editButton);
editButton.addEventListener("click", console.log('a'));
let ul = document.getElementById("list");
ul.appendChild(li);
document.getElementById("input").value = "";
}
function editItem() {
alert('e');
}
}
<!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>To Do!</title>
</head>
<body>
<h1>To do list</h1>
<div>
<input id = "input" type = "text" placeholder="What do you want to do?" value="">
<button id = "enter" onclick = "newItem()">Ok</button>
</div>
<p id="proba"></p>
<div>
<ul id = "list">
</ul>
</div>
<script type="text/javascript" src="todo.js"></script>
</body>
</html>
You need to pass a function in addEventListener, not just code.
editButton.addEventListener("click", ()=>{console.log('a')});
Or pass it to editItem
editButton.addEventListener("click", editItem);
addEventListener takes in a string and a callback function, by passing in console.log('a'), JavaScript is passing in the return value of the console.log, which is undefined. You instead need to wrap it in a function like this: editButton.addEventListener('click', () => { console.log('a'); }).
You will need to pass a function to your addEventListener method like this: editButton.addEventListener("click", editItem).
Remember that you don't have to add the parameter on the parenthesis of your function.
You can also invoke an anonymous function like this and then add your function to the right block:
editButton.addEventListener("click", () => editItem()).
function newItem() {
let input = document.getElementById("input").value;
if (input != "") {
let li = document.createElement("li");
li.appendChild(document.createTextNode(input));
let editButton = document.createElement("button");
editButton.appendChild(document.createTextNode("Edit"));
li.appendChild(editButton);
editButton.addEventListener("click", () => editItem());
let ul = document.getElementById("list");
ul.appendChild(li);
document.getElementById("input").value = "";
}
function editItem() {
alert('e');
}
}
<!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>To Do!</title>
</head>
<body>
<h1>To do list</h1>
<div>
<input id = "input" type = "text" placeholder="What do you want to do?" value="">
<button id = "enter" onclick = "newItem()">Ok</button>
</div>
<p id="proba"></p>
<div>
<ul id = "list">
</ul>
</div>
<script type="text/javascript" src="todo.js"></script>
</body>
</html>

How can I change the display a message depending on which number the user has selected?

I want when somebody input a number lower than 4.2, my app shows message as result, but i can't make it happen.
I already tried with return.
JS code
let resultEl = document.getElementById("results")
let numberEl = document.getElementById("number__select")
let message = "mAs: 0.5 y kV: 1.0"
function calculate() {
if (numberEl <= 4.2) {
resultEl.textContent = message;
} else {
resultEl.textContent = "error"
}
}
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">
<link rel="stylesheet" href="styleRx.css"/>
<script src="Rxappjs.js"></script>
<title>HVDN Rx app</title>
</head>
<body>
<div class="container">
<header>
<h1>Valoraciones de Rx</h1>
</header>
<div class="box">
<form action="">
<div class="values">
<label for="peso" id="peso__label">Peso</label>
<input class="text__input" type="number" step="0.1" id="number__select" placeholder="Peso"
min="0" required>
</div>
<button id="calcular" onclick="calculate()">Calcular</button>
</form>
<p id="results"></p>
</div>
</div>
</body>
</html>
You have the variable numberEl set to an html element and therefor it will never be less than or equal too 4.2. Try to get the value of that element instead:
let resultEl = document.getElementById("results")
let numberEl = document.getElementById("number__select")
let message = "mAs: 0.5 y kV: 1.0"
function calculate() {
if (numberEl.value <= 4.2) {
resultEl.textContent = message;
} else {
resultEl.textContent = "error"
}
}

todos list with a saved array and then retrieve it stuck?

i started an app todoslist , after creating first code simply of adding new todos in DOM
now my task is this :
addtodo :
// grab todo value
// pu tit in the array
// tell the draw method to redraw the todos
drawtodo :
grab the array
for each text add a todo entry in the documen
the array
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">
<link rel="stylesheet" type="text/css" href="style.css">
<title>TodoList</title>
</head>
<body>
<div class="todolist_box">
<h3> To Do List </h3>
<div class="input">
<input type="text" id ="inp" placeholder="Add new Task">
<button onclick="newTodo()" ><i> enter </i></button>
<button onclick="newTodo()" ><i> save </i></button>
<button onclick="drawtodo()" ><i> load </i></button>
</div>
<ul id="myUL">
</ul>
</div>
<script src="script.js" type="application/javascript"></script>
</body>
</html>
and this is my javascript code
function newElement() {
// this code doesn't work, but it gives you an idea
const li = document.createElement("li")
const newEntry = document.getElementById("inp").value
const u = document.createTextNode(newEntry)
li.appendChild(u)
document.getElementById("myUL").appendChild(li)
document.getElementById("inp").value = "Nothing"
// something like thi
let todos = []
function newTodo() {
let inpvalue = document.getElementById('inp').value
todos.push(inpvalue)
// trigger draw event
}
function drawtodo() {
for (var i = todos.length - 1; i >= 0; i--) {
let li = document.createElement('li')
let newlist = li.appendChild(document.createTextNode(todos[i]))
inpvalue.appendChild(newlist)
}
}
document.onload = function() {
// this will excute when the document loads
}
}
Try using Javascript event listener instead of onclick attribute in html.
HTML:
<button id="load" ><i> load </i></button> // Removed onclick attribute
JS:
document.getElementById("load").addEventListener("click", drawtodo, false);
same with enter and save buttons, when click triggers the newTodo function.

How can I get search functionality to work when typing in search queries in the input box?

I am making a news style app that uses the newsapi. I want to ask how do I get search functionality to work, how do I get the HTML input box to display the results of what you type in. I have tried a few times to get it to work but can't. Any suggestions appreciated.
HTML
<!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">
<link rel="stylesheet" href="css/style.css">
<title>News App</title>
</head>
<body>
<header>
<h1 class="heading">News</h1>
<form class="searchform" autocomplete="off">
<input class="searchBox" name="search" type="text" >
<button type="submit">Submit</button>
</form>
<li class="newsList"></li>
<script src="js/main.js"></script>
</header>
</body>
JavaScript
const newsList = document.querySelector(".newsList")
const newsImage = document.querySelector(".newsList")
const form = document.querySelector("form.search")
newsImage.innerHTML = ''
newsList.innerHTML= ''
const url = 'https://newsapi.org/v2/everything?' +
'q=${search}&' +
'from=2021-06-02&' +
'sortBy=popularity&' +
'apiKey=****************';
let req = new Request(url);
fetch(req)
.then(function(response) {
return response.json()
}).then((data)=>{
console.log(data)
data.articles.map(article => {
let li = document.createElement('li')
let a = document.createElement('a')
let image = document.createElement('span')
image.innerHTML = `<img src="${article.urlToImage}" >`
a.setAttribute('href', article.url)
a.setAttribute('target','_blank' )
a.textContent = `${article.title}`
li.appendChild(a)
newsList.appendChild(li)
newsImage.appendChild(image)
});
})
function handleSubmit(e){
e.preventDefault()
console.log(e.target)
}
form.addEventListener('submit', handleSubmit)
Okay so I don't have an API key to the news API that you are using but I instead used a free Rick & Morty API to answer your question.
I had to make some alterations to your code in order to get it to work with my API but I added a bunch of comments in the code snippet to hopefully make it make a bit of sense why I made the changes and also how you can change it back to work with your news API. Good luck!
const characters = document.querySelector(".characters");
const searchInput = document.querySelector("#search");
characters.innerHTML = "";
// We also changed this here to include the actual act of fetching the data - you would instead do your news fetch here.
function handleClick(e) {
let url = "https://rickandmortyapi.com/api/character/";
// This here maps a HTMLCollection into a JavaScript array and then removes previous children if they exist,
// this is to clear the list items prior to a new search.
if (characters.children.length > 0)
Array.from(characters.children).forEach((child) => child.remove());
// If we provide a search input include it in the URL - note the only search we can do here is for pages so the input is now a number.
// This is where you would instead change your news URL and append the "searchInput.value" into the "search section" like so:
//
// const url =
// "https://newsapi.org/v2/everything?" +
// `q=${searchInput.value}&` +
// "from=2021-06-02&" +
// "sortBy=popularity&" +
// "apiKey=****************";
//
// Note that in order to use a variable you need backticks as your quote delimeter. See like `${variable}` instead of '' or "".
if (searchInput.value)
url =
"https://rickandmortyapi.com/api/character/" +
`?page=${searchInput.value}`;
let req = new Request(url);
fetch(req)
.then(function (response) {
return response.json();
})
.then((data) => {
console.log(data);
// I removed your image mapping here because I had no image from this free Rick and Morty API but I hope you get the idea.
data.results.map((character) => {
let li = document.createElement("li");
let a = document.createElement("a");
a.setAttribute(
"href",
"https://rickandmortyapi.com/api/character" + `/${character.id}`
);
a.setAttribute("target", "_blank");
a.textContent = `${character.name}`;
li.appendChild(a);
characters.appendChild(li);
});
});
}
<!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" />
<!-- I removed this because I had no css file -->
<!-- <link rel="stylesheet" href="css/style.css" /> -->
<title>Test App</title>
</head>
<body>
<header>
<h1 class="heading">Test</h1>
<form class="searchform" autocomplete="off">
<!-- <input id="search" class="searchBox" name="search" type="text" /> -->
<!-- Because my search in the free API could only handle numbers I changed the type here -->
<!-- You will want to change that back to the above commented out text field -->
<input id="search" class="searchBox" name="search" type="number" />
<!-- Instead of using prevent default I changed the action here to be the onclick of the button -->
<!-- That fires off our "handleClick()" method that lives in our main.js file -->
<button type="button" onclick="handleClick()">Submit</button>
</form>
<div class="characters"></div>
<script src="main.js"></script>
</header>
</body>
</html>

Add dynamic tags in js

Hope you are doing well.
I have an input and when I enter a number and press on button it should create *x p tags. When I update the value of input and press on button it should display new *x p tags but it does not remove the previous value and adds new one. Here is my code.
Thank you!
create.addEventListener("click" , () => {
let inp = inp1.value
for(let i = 0; i < inp ; i++){
let newELement = document.createElement("p")
newELement.innerHTML = i+1
document.body.append(newELement)
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" name="" id="inp1">
<br>
<button id="create">Create</button>
</body>
<script src="script.js"></script>
</html>
For this particular scenario , you can use a common class for all the creating elements
By doing this , we can get all the existing elements of that particular class and remove it in a single step.
create.addEventListener("click" , () => {
document.querySelectorAll('.nums').forEach(e => e.remove());
let inp = inp1.value
for(let i = 0; i < inp ; i++){
let newELement = document.createElement("p")
newELement.className += " " + "nums";
newELement.innerHTML = i+1
document.body.append(newELement)
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" name="" id="inp1">
<br>
<button id="create">Create</button>
</body>
<script src="script.js"></script>
</html>
As I see it, when a user clicks Create, you want to:
Remove the previous tags, if any exist
Create and add the new tags
You've gotten step 2 down already, but you just need to remove the tags before you render the new ones, to get your desired output.
The easiest way to do this would be to, instead of placing the tags directly in the body, place them in a separate div, specifically for tags. Then you just empty that div when Create is clicked.
So, in your HTML, you add a div specifically for the tags:
<body>
<input type="text" name="" id="inp1">
<br>
<button id="create">Create</button>
<div id="tags"></div>
</body>
<script src="script.js"></script>
...and, in your JS, you just place the tags in that div, instead of the body, whilst emptying it every time Create is clicked:
let tags = document.getElementById("tags")
create.addEventListener("click" , () => {
let inp = inp1.value
tags.innerHTML = "" // empty tags div first
for(let i = 0; i < inp ; i++){
let newELement = document.createElement("p")
newELement.innerHTML = i+1
tags.append(newELement) // add to tags div, not body
}
})
Run and edit this code online

Categories

Resources