JS get value of buttons in a dynamic grid - javascript

Squares = Buttons with x = clicked, x = value
How do I create a textarea value onClick on a button that contains the value of each square AND empty values of anything that is not selected,
i.e.
<textarea>x,&bnsp;,&bnsp; ,&bnsp;\n,&bnsp;x,&bnsp; ,&bnsp;\n etc.</textarea>
Basically the text output needs to reflect the values of the squares in plain text, that’s why I need empty values to create that “visual”.
The rows and squares in each row are also subject to being dynamically generated when the page loads, based on a default or changed value.
Thank you!

It requires a bit of jQuery, but this does what you want.
var result = [];
var idnum;
for (var i = 1; i < 10; i++) {
result.push($("#" + i).html() + ",");
}
$(".result").html(result);
$(".button").click(function() {
idnum = $(this).attr("id");
$(this).html("x");
result[idnum - 1] = "x,";
$(".result").html(result);
});
.button {
width: 50px;
height: 50px;
vertical-align: top;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="button" id="1"> </button>
<button class="button" id="2"> </button>
<button class="button" id="3"> </button>
<br>
<button class="button" id="4"> </button>
<button class="button" id="5"> </button>
<button class="button" id="6"> </button>
<br>
<button class="button" id="7"> </button>
<button class="button" id="8"> </button>
<button class="button" id="9"> </button>
<br><br>
<textarea class="result">Result</textarea>

Related

How can I add elements in JS to certain divs

How do I put the created input into the other div in situation I presented below? If I introduce divs in js like this - '<div class="monday_input"><input type="button" class="remove_button" value="-" onclick="removeMon(this)" /></div>' removing the whole element is not working for some reason in this specific case. Answering the question. No I cannot create div in parent in html because input won't magically suit to created div . Please help me somehow, thank you!
HTML:
<div class="day">
<div class="day_info">
<p>Monday</p>
</div>
<div class="add">
<div class="button" onclick="add_monday()">
<i class="fas fa-plus" id="plus"></i>
</div>
</div>
<div style="clear:both"></div>
</div>
<div id="mon">
<div style="clear:both"></div>
</div>
JavaScript:
Function to adding:
function add_monday() {
if (monday_sub_count < 5) {
monday_sub_count++;
{
const mon = document.createElement('div');
mon.className = 'subcategory';
mon.innerHTML = '<textarea name="monday'+monday_id_count+'" placeholder="Type anything you want here" class="subcategory_text"></textarea><input type="button" class="remove_button" value="-" onclick="removeMon(this)" />';
monday_id_count++;
document.getElementById('mon').appendChild(mon);
}
}
}
Function to removing:
function removeMon(mon) {
document.getElementById('mon').removeChild(mon.parentNode);
monday_sub_count--;
monday_id_count--;
};
with your own HTML
function add_monday() {
var monday_sub_count = 0;
var a;
while (monday_sub_count < 5) {
a = '<div><textarea name="monday'+monday_id_count+'" placeholder="Type anything you want here" class="subcategory_text"></textarea><input type="button" class="remove_button" value="-" onclick="removeMon(this)" /></div>';
monday_sub_count++;
$('#mon').append(a);
}
}
Here is working, "proper" version of your code. I think your problem may come from over-complicating the removal process.
function add_monday()
{
let monday_count = 0;
// Use DocumentFragment for marginal optimizations
let fragment = new DocumentFragment();
while(monday_count < 5)
{
let monday = document.createElement('div');
monday.classList.add('subcategory');
let textarea = document.createElement('textarea');
textarea.classList.add('subcategory_text');
textarea.name = "monday_"+monday_count;
textarea.placeholder = "Type anything you want here";
let removeBtn = document.createElement('input');
removeBtn.type = "button";
removeBtn.classList.add('remove_button');
removeBtn.value = "-";
removeBtn.addEventListener('click', removeMon.bind(null, removeBtn));
monday.append(textarea, removeBtn);
fragment.appendChild(monday);
monday_count++;
}
document.getElementById('mon').appendChild(fragment);
}
function removeMon(button)
{
button.parentElement.remove();
}
I simplified your script a little and changed your name attributes: Instead of assigning individual names I simply gave all textareas the name monday[]. When posting this to a PHP page the values will be pushed into an array with the same name and in case you want to harvest the values with JavaScript, then this can be done easily too.
function add_monday(){
$("#mon").append('<div><textarea name="monday[]" placeholder="Type anything you want here"></textarea><input type="button" value="-"/></div>'.repeat(5))
}
$("#mon").on("click","input[type=button]",function(){$(this).parent(). remove()})
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<div class="day">
<div class="day_info">
<p>Monday</p>
</div>
<div class="add">
<div class="button" onclick="add_monday()">
<i class="fas fa-plus" id="plus">click here to add fields</i>
</div>
</div>
<div style="clear:both"></div>
</div>
<div id="mon">
<div style="clear:both"></div>
</div>
And here a non-jQuery version:
const ad=document.querySelector(".alldays");
ad.innerHTML=
"Mon,Tues,Wednes,Thurs,Fri,Satur,Sun".split(",").map(d=>`
<div class="day">
<div class="day_info"><p>${d}day</p></div>
<div class="add">
<div class="button">
<i class="fas fa-plus" id="plus">click here to add fields</i>
</div>
</div>
<div style="clear:both"></div>
</div>
<div id="${d.toLowerCase().substr(0,3)}">
<div style="clear:both"></div>
</div>`).join("");
function add2day(el,n){
const wd=el.closest(".day"),
d=wd.querySelector("p").textContent.toLowerCase(),
html=`<textarea name="${d.toLowerCase()}[]" placeholder="Type anything you want here"></textarea><input type="button" value="-"/>`;
while (n--) {
let div= document.createElement("div");
div.innerHTML=html;
wd.nextElementSibling.appendChild(div);
}
}
ad.addEventListener("click",function(ev){
const el=ev.target;
switch(el.tagName){
case "INPUT": // remove field
el.parentNode.remove(); break;
case "I": // add new fields
add2day(el,3); break;
}
})
<div class="alldays"></div>
I extended the second script to make it work for any day of the week.

get the different values from button with same class name

I want to get the values from clicking the button with same class name, but whenever I clicked the button it shows undefined.
var clr;
const btn = document.querySelectorAll('.color');
function myFunction() {
for (var i = 0; i < btn.length; i++) {
clr = btn[i].value;
console.log(clr);
}
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction()"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction()"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction()"> Purple </button>
</div>
const btn = document.querySelectorAll('.color'); gets the div not the buttons. Change that to const btn = document.querySelectorAll('.btn');:
var clr;
const btn = document.querySelectorAll('.btn');
function myFunction() {
for (var i = 0; i < btn.length; i++) {
clr = btn[i].value;
console.log(clr);
}
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction()"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction()"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction()"> Purple </button>
</div>
If you only want the value from the button being clicked, then change your code to
function myFunction(btn) {
console.log(btn.value);
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction(this)"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction(this)"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction(this)"> Purple </button>
</div>
do it in this way it will give you exact result
function myFunction(event) {
clr = event.target.value;
console.log(clr);
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction(event)"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction(event)"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction(event)"> Purple </button>
</div>
First: scripting where scripting should be (no inline handlers). So add an event listener to the document, and let it check if the target (the element clicked) has classname btn. In that case: iterate through the an Array of elements with className btn (Array.from(document.querySelectorAll(".btn"))) using Array.forEach to display the values of those elements.
document.addEventListener("click", myFunction);
function myFunction(evt) {
console.clear();
if (evt.target.classList.contains("btn")) {
// a button.btn was clicked, so
let report = `You clicked button with value ${evt.target.value}. Other .btn values:`;
let values = [];
Array.from(document.querySelectorAll(".btn"))
.forEach(val => val !== evt.target && values.push(val.value));
console.log(`${report} ${values.join(", ")}`);
}
}
<div class="color">
<button class="btn" value="#BADA55"> Yellow </button>
<button class="btn" value="#10A426"> Green </button>
<button class="btn" value="#8787DE"> Purple </button>
</div>

I'm trying to make each button increase the numbers in the input in his own div but doesn't work

I'm trying to make each button increase the numbers in the input in his own div but doesn't work.
var c = 0;
$(".up").click(function() {
var vote = document.getElementById('vote');
$(vote).find(".counter").val(c);
c++;
});
$(".down").click(function() {
var vote = document.getElementById('vote');
$(vote).find(".counter").val(c);
c = c - 1;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="votewrap">
<div id="vote">
<button class="up">up</button>
<input class="counter">
<button class="down">down</button>
</div>
<div id="vote">
<button class="up">up</button>
<input class="counter">
<button class="down">down</button>
</div>
</div>
To group multiple elements, use class property.
Your code seemed to had multiple errors, I've resolved them by using .siblings() and .closest() methods!
$(".up").click(function() {
var vote = $(this).closest('.vote'); // find the closest div
var c = $(this).siblings('.counter').val(); // get current value
$(vote).find(".counter").val(++c); // increment and set again
});
$(".down").click(function() {
var vote = $(this).closest('.vote'); // find the closest div
var c = $(this).siblings('.counter').val(); // get current value
$(vote).find(".counter").val(--c); // decrement and set again
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="votewrap">
<div class="vote"> <!-- use class instead of id -->
<button class="up" id='1'>up</button>
<input class="counter" value='0'> <!-- Set initial value to 0 -->
<button class="down">down</button>
</div>
<div class="vote"> <!-- use class instead of id -->
<button class="up" id='2'>up</button>
<input class="counter" value='0'> <!-- Set initial value to 0 -->
<button class="down">down</button>
</div>
</div>
An id should be unique per page, so you should only have one. The getElementById method is returning the first value of vote that it finds since it's only expecting one.
I've added a few modifications to your code to separate the two fields. I did it a bit of a long way just to help with understanding. I gave your elements each an id to make them all unique from one another. I also moved your calculations up in your click handlers so you don't get the weird add/subtract behavior.
var c1 = 0;
$("#up1").click(function() {
var vote1 = document.getElementById('vote1');
c1++;
$(vote1).find("#counter1").val(c1);
});
$("#down1").click(function() {
var vote1 = document.getElementById('vote1');
c1 = c1 - 1;
$(vote1).find("#counter1").val(c1);
});
var c2 = 0;
$("#up2").click(function() {
var vote2 = document.getElementById('vote2');
c2++;
$(vote2).find("#counter2").val(c2);
});
$("#down2").click(function() {
var vote2 = document.getElementById('vote2');
c2 = c2 - 1;
$(vote2).find("#counter2").val(c2);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="votewrap">
<div id="vote1">
<button id="up1">up</button>
<input id="counter1">
<button id="down1">down</button>
</div>
<div id="vote2">
<button id="up2">up</button>
<input id="counter2">
<button id="down2">down</button>
</div>
</div>

HTML Page search

I have a very long html file (20K+ lines) and I want to have a search that will find the search term and then scroll to the li class="page" data-name="XX". If more than one instance of the term is found we need a "next" result button.
Here is an excerpt from my HTML file I want to search:
<li class="page" data-name="11">
<div class="pageResizer" style="width:640px;height:960px;"> </div>
<div id="item690" class="pageItem" alt="Rectangle"> </div>
<div id="item728" class="pageItem" alt="Rectangle"> </div><button class="pageItem" alt="Home" id="item1426" data-id="1426" onclick="nav.to(5);"> </button><button class="pageItem" alt="prevBtn" id="item1423" data-id="1423" onclick="nav.back(this);"> </button><button class="pageItem" alt="nextBtn" id="item2550" data-id="2550" onclick="nav.next(this);"> </button><img src="assets/images/blank.gif" class="pageItem" alt="Rectangle" style="left:491px;top:11px;" data-src="assets/images/item_2757.png"/>
<div id="item2788" class="pageItem singleline" alt="Lafayette Chamber">
<p class="autoParaStyle1">Lafayette Chamber</p>
</div><button class="pageItem" alt="Share" id="item3136" data-id="3136"> </button>
<a href="javascript:nav.to(2);"><button class="pageItem" alt="Help" id="item2977" data-id="2977" onclick="nav.to(2);"> </button>
</a><img src="assets/images/blank.gif" class="pageItem" alt="Rectangle" style="left:1px;top:66px;" data-src="assets/images/item_4899.jpg"/><img src="assets/images/blank.gif" class="pageItem" alt="Rectangle" style="left:1px;top:707px;" data-src="assets/images/item_4901.jpg"/>
<div id="item4906" class="pageItem singleline" alt="lafayETTE ">
<p class="autoParaStyle13">lafayETTE<br />
</p>
</div>
<div id="item4937" class="pageItem singleline" alt="HISTORY">
<p class="autoParaStyle14">HISTORY</p>
</div>
<div id="item4982" class="pageItem" alt=" little more than a century ago, the first pioneers trickled into this region after a long journey across the Great P...">
<p class="Article-Body"> <span class="autoCharStyle5">little more than a century ago, the first pioneers trickled into this region after a long journey across the Great Plains. The gold rush attracted more and more adventurous fortune seekers who were closely followed by other settlers. The honeymoon of Lafayette and Mary E. Miller was spent crossing the plains and arriving in the Boulder region. In 1863, they started farming the Burlington (Longmont) area and soon moved south and settled in the present site of Lafayette. Lafayette Miller was an industrious man and besides farming, he operated the stage stop and ran several meat markets. His sudden death in 1878 left Mary Miller with six small children to raise. She did this and more…she raised a town!<br /></span> </p>
<p class="autoParaStyle8"><br /></p>
</div>
<div id="item27143" class="pageItem singleline" alt="A">
<p class="autoParaStyle15">A</p>
</div>
Here is the code I have so far:
<script>
function search() {
var name = document.getElementById("searchForm").elements["searchItem"].value;
var pattern = name.toLowerCase();
var targetId = "";
var divs = document.getElementsByClassName("page");
for (var i = 0; i < divs.length; i++) {
var para = divs[i].getElementsByTagName("p");
var index = para[0].innerText.toLowerCase().indexOf(pattern);
if (index != -1) {
targetId = divs[i].parentNode.id;
document.getElementById(targetId).scrollIntoView();
break;
}
}
}
</script>
<form id="searchForm" action="javascript:search();">
<div class="input-group">
<button id="go" type="button"
onclick="document.getElementById('searchForm').submit(); return false;">
Search</button>
<input type="text" id="searchItem" class="form-control" placeholder="Search" cols="50" rows="2">
</div>
</form>
Not sure what I need to do to my code to make this work and don't have a clue how to make a "next result" button.
I think this is what you are looking for:
HTML:
<body>
<form id="searchForm" action="javascript:search();" class="form">
<button id="nextButton" onclick="nextItem()" type="button" class="make-invisible">NEXT</button>
<div class="input-group">
<button id="go">Search</button>
<input type="text" id="searchItem" name="searchItem" class="form-control" placeholder="Search" cols="50" rows="2">
</div>
</form>
<ul>
<li class="page" data-name="foo">Has data-name = foo</li>
<li class="page" data-name="foo">Has data-name = foo</li>
...
</ul>
</body>
JavaScript:
var selectedItems;
var currentlySelectedItem;
var makeInvisibleClassName = "make-invisible";
var nextButton = document.querySelector("#nextButton");
function search() {
makeInvisible();
var searchPhrase = document.querySelector("#searchItem").value;
selectedItems = document.querySelectorAll(".page[data-name='" + searchPhrase + "']");
if (selectedItems.length === 0) {
return;
}
if (selectedItems.length > 1) {
makeVisible();
}
currentlySelectedItem = 0;
nextItem();
}
function nextItem() {
selectedItems[currentlySelectedItem].scrollIntoView();
currentlySelectedItem++;
if (currentlySelectedItem >= selectedItems.length) {
currentlySelectedItem = 0;
}
}
//////////
function makeInvisible() {
nextButton.classList.add(makeInvisibleClassName);
}
function makeVisible() {
nextButton.classList.remove(makeInvisibleClassName);
}
CSS:
.form {
position: fixed;
left: 0;
top: 0;
display: flex;
flex-direction: row;
justify-content: center;
width: 100%;
}
#nextButton {
margin-right: 10px;
}
.make-invisible {
display: none;
}
Here is the working Demo
Ok, let me explain what I did here.
When you have a form you don't actually need to this:
<button id="go" type="button" onclick="document.getElementById('searchForm').submit(); return false;">
Instead you can go very simple:
<button id="go">Search</button>
The default button type in a form is type="submit" which automatically triggers the event specified in the action attribute.
The next thing is the NEXT button. I hard-coded it and in order to show it and hide it, I will add or remove class make-invisible. Notice the button is invisible at the beginning. It also has a click event which will trigger nextItem()
<button id="nextButton" onclick="nextItem()" type="button" class="make-invisible">NEXT</button>
I also made 2 global variables: selectedItems, which will store the array of selected items and currentlySelectedItem that has the index of currently scrolled to item.
The search() function gets all elements that has the class name page and has attribute data-name with specified word. Then it checks if there is more then one result. If so, it makes the button visible.
The nextItem() function scrolls into selected element, and raises index by one. If the index value if bigger then there is matching elements, it will start a loop.

add clicked value to stored value query

This is for a quiz. The user has a question with a choice of three answers. The answers are buttons. Each button has a value. When the user clicks the button, it gives a value then moves onto the next question. And this process repeats through a series of 7 questions. During this process, I want it to add each of the values clicked and have an accumulated total at the end.
I'm not sure if I should create a loop for this? I also want to note that this is being done without refreshing the page using .show and .hide features to the different sections of the quiz.
Thanks for your help!
Here are the buttons:
<button class="blue" id="goat" value="5">ANSWER 1</button>
<button class="blue" id="bird" value="10">ANSWER 2</button>
<button class="blue" id="fish" value="15">ANSWER 3</button>
function charValue () {
$(this).val();
}
var storedValue = $(this).$("button").data(charValue);
var accumValue = storedValue + charValue;
$("button").on('click', charValue);
You could add a final button at the end, for example:
<button id="finalbutton">Get Results</button>
And then create the javascript like so:
var accumValue = 0;
$("button").on('click', function() {
if(!$(this).attr('value')) {
return;
}
accumValue += parseInt($(this).attr('value'));
});
$('#finalbutton').on('click', function() {
alert(accumValue);
});
Try this:
$("button").click(function() {
var curScore = parseInt($("span").text(), 10);
var newScore = parseInt($(this).val(), 10);
$("span").text(curScore + newScore);
$(this).parent().hide();
$(this).parent().next().show();
});
.Question{display: none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div class="Question" style="display: block;">
<h3>Question 1</h3>
<button class="blue" id="goat" value="5">ANSWER 1</button>
<button class="blue" id="bird" value="10">ANSWER 2</button>
<button class="blue" id="fish" value="15">ANSWER 3</button>
</div>
<div class="Question">
<h3>Question 2</h3>
<button class="blue" id="goat" value="5">ANSWER 1</button>
<button class="blue" id="bird" value="10">ANSWER 2</button>
<button class="blue" id="fish" value="15">ANSWER 3</button>
</div>
<div class="Question">
<h3>Question 3</h3>
<button class="blue" id="goat" value="5">ANSWER 1</button>
<button class="blue" id="bird" value="10">ANSWER 2</button>
<button class="blue" id="fish" value="15">ANSWER 3</button>
</div>
<p>The final score is <span>0</span>
</p>
You can use .val() to get value and sum them.
To hide the current question after choose an answer, and show next one, use code:
$(this).parent().hide();
$(this).parent().next().show();
you can use below code and show sum at the end, DEMO here
var sum= 0;
$("button").click(function() {
sum = sum + parseInt($(this).val());
//alert(sum);
});
You can put all your questions on the same page.
As the user completes the questions, hide the completed questions and show the next unanswered question.
every time one answers a question, add the selected answer to your submission form. When the user finished all the questions show the submit button, and let one submit his answers.

Categories

Resources