Javascript - Input text and output to multiple areas - javascript

I'm trying to input text in a field, and have it output to multiple fields.
Currently, it only outputs to the first field.
Here's the input:
<form class="form" onchange="myFunction()">
<div class="mb-4">
<p>The quick sly fox jumped over the <input id="object" class="inline borderless-input"></p>
</div>
</form>
JS controlling the output:
function myFunction()
{
//Object
var x = document.getElementById("object");
var div = document.getElementById("objectDisplay");
div.innerHTML = x.value;
}
Here's a codepen I'm working with: Codepen

ID's have to be unique. Use classes and a for loop to cycle through each one and change it. This cannot be done with document.getElementById. See https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById for some basic information about document.getElementById. document.getElementsByClassName returns an array filled with existing elements with a certain class. In this case, objectDisplay. If you want to read more about that then take a look here: https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName.
The new code should look like this:
function myFunction() {
//Object
var x = document.getElementById("object");
var div = document.getElementsByClassName("objectDisplay");
for (i = 0; i < div.length; i++) {
div[i].innerHTML = x.value;
}
}
.container {
padding: 10px;
}
.text-strong {
font-weight: bold;
}
.inline {
display: inline;
}
.borderless-input {
background-color: transparent;
border-style: solid;
border-width: 0px 0px 1px 0px;
padding: .5rem .75rem;
text-align: center;
}
<div class="container">
<div class="row">
<div class="col-lg-12">
<form class="form" onchange="myFunction()">
<div class="mb-4">
<p>The quick sly fox jumped over the <input id="object" class="inline borderless-input"></p>
</div>
</form>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-12">
<h3><strong>Output</strong></h3>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<p>The quick sly fox jumped over the <span class="objectDisplay inline"></span>.</p>
<p>The quick sly fox jumped over the <span class="objectDisplay inline"></span>.</p>
<p>The quick sly fox jumped over the <span class="objectDisplay inline"></span>.</p>
</div>
</div>
</div>
<!-- For Testing Only -->
<div class="container">
<div class="row">
<div class="col-lg-10 offset-lg-1 mx-auto">
<!-- Test Here -->
</div>
</div>
</div>

Identify your inputs with class instead of id
<p>The quick sly fox jumped over the <span id="objectDisplay" class="objectDisplay inline"></span>.</p>
use this
var divs = document.getElementsByClassName("objectDisplay");
for(var i = 0; i < divs.length; i++){
divs[i].innerHTML = x.value;
}
instead of
var div = document.getElementById("objectDisplay");
div.innerHTML = x.value;

I found a similar question see the link: jQuery id selector works only for the first element.
but briefly, you're using the same ID for more than one element, try using the class selector, example document.getElementsByClassName ('your-class') or document.querySelectorAll ('your-class'), remembering that in querySelectorAll for classes: '.your-class' and Id: '# my-id'.
function myFunction(){
//Object
var x = document.getElementById("object");
var div = document.querySelectorAll(".col-lg-12 span");
for(var i = 0; i < div.length;i = i + 1){
div[i].innerHTML = x.value;
}
}

IDs are unique so you should have only one ID per page. Try changing objectDisplay to a class and then selecting them all and looping through each as below
function myFunction(el)
{
//Object
var x = document.getElementById("object");
var divs = document.querySelectorAll(".objectDisplay");
var inputValue = el.value;
for(var i=0; i < divs.length; i++){
divs[i].innerHTML = inputValue;
}
}
<form class="form">
<div class="mb-4">
<p>The quick sly fox jumped over the <input id="object" class="inline borderless-input" onchange="myFunction(this)" value=""></p>
</div>
</form>
<div class="objectDisplay"></div>
<div class="objectDisplay"></div>

Related

Replace value from JS if found inside div based on if/else condition

I have an html code from an online product recommendation platform which allows me to add JS to html.
The HTML code below works fine, but i want to apply JS to it based on the logic that, if ${discountvalue} shows any value, then both ${discountvalue} and ${regularvalue} values are visible with cross line on regularvalue.
If ${regularvalue} does not have any value or is empty/null, then only ${regularvalue} will be visible.
HTML CODE:
<div class="slider-wrapper">
${#Recommendations} // This loads the the more then one values of product recommendation
${discountvalue}
${regularvalue}
<div class="slider-wrapper">
<div class="pricebox">
<p class="dynamic-price">${discountvalue}</p>
<p class="regular-price">
<span class="rec_price_num">${regularvalue}</span>
</p>
</div>
</div>
${/#Recommendations}
</div>
And this is the JS code:
var itemPrices = document.querySelectorAll('.slider-wrapper .pricebox');
for(var i=0; i<itemPrices.length; i++){
var discount_price = itemPrices[i].getElementsByClassName("dynamic-price")[0].innerHTML;
var price = getElementsByClassName("rec_price_num")[0].innerHTML;
if(discount_price){
var discount_price = itemPrices[i].getElementsByClassName("dynamic-price")[0].innerHTML;
var price = getElementsByClassName("rec_price_num")[0].innerHTML;
}
else {
var price = getElementsByClassName("rec_price_num")[0].innerHTML;
}
}
parseFloat(discount_price.innerHTML) will return a truthy value if the discount price can be parsed to a floating point number different from 0.
You can use the CSS rule text-decoration: line-through; to have a cross line on the value.
var itemPrices = document.querySelectorAll('.slider-wrapper .pricebox');
for(var i=0; i<itemPrices.length; i++){
var discount_price = itemPrices[i].getElementsByClassName("dynamic-price")[0];
var price = itemPrices[i].getElementsByClassName("regular-price")[0];
if(parseFloat(discount_price.innerHTML)){
price.style.textDecoration = "line-through";
} else {
discount_price.style.display = "none";
}
}
<div class="slider-wrapper">
<div class="pricebox">
<p class="dynamic-price">0</p>
<p class="regular-price">5</p>
</div>
<hr>
<div class="pricebox">
<p class="dynamic-price">4</p>
<p class="regular-price">5</p>
</div>
</div>
Don't need javascript. can be solved by css3
.pricebox p {
font-weight: bold;
font-size: 1.5rem;
color: red;
margin: 0 0 1rem;
}
.pricebox .dynamic-price {
margin-bottom: 0;
}
.pricebox .dynamic-price:empty {
display: none
}
.pricebox .dynamic-price:not(:empty) + .regular-price {
font-size: .875rem;
color: gray;
text-decoration: line-through;
}
<div class="slider-wrapper">
<div class="slider-wrapper">
<div class="pricebox">
<p class="dynamic-price"></p>
<p class="regular-price">
<span class="rec_price_num">200.00</span>
</p>
</div>
<div class="pricebox">
<p class="dynamic-price">100.00</p>
<p class="regular-price">
<span class="rec_price_num">150.00</span>
</p>
</div>
</div>
</div>

Can't change divs ID of first element from <tempate>

I have this HTML template:
<template id="single_feed">
<div class="ibox" id="FIRST_DIV">
<div class="ibox-title">
<h5 id="naslov"></h5>
</div>
<div class="ibox-content">
<form method="get" _lpchecked="1">
<div class="form-group row"><label class="col-sm-2 col-form-label">Naziv</label>
</form>
</div>
</div>
</template>
Now I want to clone and change first div ID (now set to: "FIRST_DIV"). But don't know how. I am able only to change 2nd,3rd.... divs.
My jquery code for cloning is:
$(".btn-RSS-single").click(function(e) {
var idClicked = e.target.id;
const $template = $( $('#single_feed')[0].innerHTML );
$template.find("div:first").attr("id", "NEW_ID_"+idClicked);
$('#kolona_1').append($template);
});
P.S:
I removed unnecessary parts to make code more readable.
jQuery has .html() function to retrieve the inner html and .clone() function to clone the element. You can use both to achieve what you want and make the code more readable.
See this example (I have changed some values to make the example clearer):
let clicked = 0;
$(".btn-RSS-single").click(function(e) {
var idClicked = e.target.id;
idClicked = clicked++;
const template = $("#single_feed").html();
$template = jQuery(template).clone().attr("id", "NEW_ID_" + idClicked);
$('#kolona_1').append($template);
});
#kolona_1 {
border: 1px solid gray;
}
#kolona_1 > div {
background-color: rgba(180, 180, 180, 0.2);
margin: 1em;
}
.btn-RSS-single {
background-color: lightblue;
padding: 0.2em 1em;
text-align: center;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="kolona_1"></div>
<div class="btn-RSS-single">ADD</div>
<template id="single_feed">
<div class="ibox" id="FIRST_DIV">
<div class="ibox-title">
<h5 id="naslov"></h5>
</div>
<div class="ibox-content">
<form method="get" _lpchecked="1">
<div class="form-group row"><label class="col-sm-2 col-form-label">Naziv</label></div>
</form>
</div>
</div>
</template>
Hope this will helps,
const template = (document.getElementsByTagName("template")[0]).content.cloneNode(true);
const firstDiv = template.querySelector("div");
firstDiv.id = "new id";
document.body.querySelector('#kolona_1').appendChild(firstDiv);
Try something like below
$(".btn-RSS-single").click(function(e) {
var idClicked = e.target.id;
const $template = $( $('#single_feed')[0].innerHTML );
$template.find("div:first").attr("class", "template-new"+idClicked);
$('#kolona_1').append($template);
$('#kolona_1').find('.template-new' + idClicked).attr('id', 'NEW_ID_' + idClicked);
});

Creating a function for a button that can be used for a certain class using JavaScript

Ultimately, my objective here is to create a JS script where I can use for my quizzes. In a page, I may put more than one item. In this regard, I will have more than one button, one button per item. What you see here is a prototype. (I wanted to see how each element interacts with one another.) In the process of trying to get it work, I looked over what others have done. However, I came to a point where I am stuck and could not see what I am doing wrong. I have a sense of where the problem is but I am not certain of it. Anyway, please see where my mistakes are and let me know.
This is the html part. What I want to happen here is I click the top button and the background of the text, "Hello" at top turns red. I press the middle and the text background turn red, and so on. Currently, I press any button and they all turn red.
<div class="q">
<div class="p">
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>
<div class="q">
<div class="p">
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>
<div class="q">
<div class="p">
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>
The link to the js script is located in the head section.
<script src="../js/s3.js"></script>
Here is the js. I suspect my mistake is in the second half. The reason for this is that I made the var in the second for the same as in the first one and still got the same result. It made me wonder whether if the computer is ignoring this part. I could be wrong. I tried querySelectorAll and the result is the same as well. By the way, when is it advantageous to use querySelectorAll and getElementsByClassName if class is involved?
window.onload = function () {
let c = document.getElementsByClassName('q');
for (var ii = 0; ii < c.length; ii++) {
c[ii].addEventListener('click', function () {
let a = document.getElementsByClassName('p');
for (var i = 0; i < a.length; i++) {
a[i].classList.add('cellRed');
}
});
}
}
Here is the CSS.
.cellGreen {
background-color: green;
color: white;
}
.cellRed {
background-color: red;
color: white;
}
I was told to keep things separate. So I did.
First thing you should do when tackling a problem is to think about what you're trying to accomplish. It really does help to list it in steps.
In every Question div
Get the Button
Get the Paragraph
When the Button is clicked
Turn the Paragraph Red
This allows us to build our code rather simply from step 1 onward. This isn't always perfect, but it is always helpful.
Get All Questions
let questions = document.querySelectorAll(".q");
For Each Question
questions.forEach(question => {
// ... do something
});
Get the Button
questions.forEach(question => {
let btn = question.querySelector("button");
});
Get the Paragraph
questions.forEach(question => {
let btn = question.querySelector("button");
let p = question.querySelector("p");
});
When the Button is Clicked
questions.forEach(question => {
let btn = question.querySelector("button");
let p = question.querySelector("p");
btn.addEventListener("click", function() {
// ... do something
});
});
Turn the Paragraph Red
questions.forEach(question => {
let btn = question.querySelector("button");
let p = question.querySelector("p");
btn.addEventListener("click", function() {
p.classList.add("cellRed");
});
});
Final Example:
window.onload = function() {
let questions = document.querySelectorAll(".q");
questions.forEach(question => {
let btn = question.querySelector("button");
let p = question.querySelector("p");
btn.addEventListener("click", function() {
p.classList.add('cellRed');
});
})
}
.cellGreen {
background-color: green;
color: white;
}
.cellRed {
background-color: red;
color: white;
}
<div class="q">
<div class="p">
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>
<div class="q">
<div class="p">
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>
<div class="q">
<div class="p">
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>
That second loop is unnecessary. Just use let instead of var in first loop.
According to MDN:
let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used. This is unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope.
Look at example below:
window.onload = function () {
let c = document.getElementsByClassName('q');
for (let i = 0; i < c.length; i++) {
c[i].addEventListener('click', function () {
let a = document.getElementsByClassName('p');
a[i].classList.add('cellRed');
});
}
}
.cellGreen {
background-color: green;
color: white;
}
.cellRed {
background-color: red;
color: white;
}
<div class="q">
<div class="p">
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>
<div class="q">
<div class="p">
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>
<div class="q">
<div class="p" >
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>`
I know you want help with your javascript code, but others have already helped you, so I mostly wanted to show that this can be solved with pure CSS only without javascript. :) I'm basically using radio-buttons and sibling selector.
div.p > p {
margin-bottom: 0;
}
div.p > input {
display: none;
}
div.p > label {
cursor: pointer;
font-size: 90%;
margin-right: 1rem;
}
div.p > input:checked ~ p {
color: white;
background-color: red;
}
div.p > input:checked[value="correct"] ~ p {
background-color: green;
}
<div class="q">
<div class="p">
<input type="radio" name="q1" id="q1_alt1" value="correct" />
<input type="radio" name="q1" id="q1_alt2" />
<p>Hello</p>
<label for="q1_alt1">Answer 1</label>
<label for="q1_alt2">Answer 2</label>
</div>
</div>
<div class="q">
<div class="p">
<input type="radio" name="q2" id="q2_alt1" />
<input type="radio" name="q2" id="q2_alt2" value="correct" />
<p>Hello</p>
<label for="q2_alt1">Answer 1</label>
<label for="q2_alt2">Answer 2</label>
</div>
</div>
<div class="q">
<div class="p">
<input type="radio" name="q3" id="q3_alt1" />
<input type="radio" name="q3" id="q3_alt2" />
<input type="radio" name="q3" id="q3_alt3" value="correct" />
<p>Hello</p>
<label for="q3_alt1">Answer 1</label>
<label for="q3_alt2">Answer 2</label>
<label for="q3_alt3">Answer 3</label>
</div>
</div>

Read and print the CSS values of a class with pure Javascript

I am trying to create a function, which:
Grabs an element with a specific data element, i.e. "data-findDeclaration = element"
From this element, the class is read
It reads out all the css values appointed to this class
Displays inside another specific data element (i.e. data-writeDeclaration="element") all the classes' rules/values.
Here's where I am so far:
HTML:
<span class="slap0" data-finddeclaration="element">The great white fox</span>
<div class="description" data-writedeclaration="element">
</div>
<span class="slap1" data-finddeclaration="element">The great white fox</span>
<div class="description" data-writedeclaration="element">
</div>
<span class="slap2" data-finddeclaration="element">The great white fox</span>
<div class="description" data-writedeclaration="element">
</div>
<span class="slap3" data-finddeclaration="element">The great white fox</span>
<div class="description" data-writedeclaration="element">
</div>
JS:
function readOutCssRules() {
var dataElement = document.querySelectorAll('[data-finddeclaration="element"]');
var classRules = document.styleSheets[0].rules || document.styleSheets[0].cssRules;
var writeDataElement = document.querySelectorAll('[data-writedeclaration="element"]');
for (var i = 0; i < dataElement.length; i++) {
dataElement[i].className;
if (classRules[i].selectorText == "." + dataElement[i].className) {
console.log(classRules[i].cssText);
writeDataElement[i].innerHTML = classRules[i].cssText;
}
}
}
readOutCssRules();
But the function is not working as expected.
Any ideas?
Thanks in advance.
Your code is working.
You just have to remove one line in the for loop:
for (var i = 0; i < dataElement.length; i++) {
//dataElement[i].className; --> remove this
if (classRules[i].selectorText == "." + dataElement[i].className) {
console.log(classRules[i].cssText);
writeDataElement[i].innerHTML = classRules[i].cssText;
}
}
After that changes it will work, as you can see in this fiddle.
Check this
https://jsfiddle.net/g6tu77mg/1/
var element = classRules[i].cssText
var css= element.substring(element.lastIndexOf("{")+1,element.lastIndexOf("}"));
writeDataElement[i].innerHTML = css;
Output:
The great white fox
color: blue;
The great white fox
color: red;
The great white fox
color: yellow;

How to create pair game using node values and set a setTimeout() method

I want to create a pair game that if the same textnode is matched it will set the background in white to reveal the matched textnode if not it will set a timeout and get back in original state.
The Problem of this is if I use the childNodes.nodeValue in match it saids that ChildNodes.nodeValue is not a function. And I try another code. I declare a variable that calls the element tag name of div which is I append a textNode in div. I want to compare two consecutive childNodes of div and if it is the same node, I change the color of the background to white. and I use the setTimout method, if not the color of background will go back again in original state which is black, I am pretty confused about this.
can you scan my code and help me to figure out what is the problem of this code?
here is the code.
<html>
<head>
<style>
div.row {
clear : left;
margin: auto;
width: 520px;
}
div.col {width:100px;
height:100px;
border: 3px solid black;
float : left;
margin: 10px;
font-size: 75px;
text-align: center;
background-color: black;
}
</style>
</head>
<body>
<div class="row">
<div id="00" class="col"></div>
<div id="01"class="col"></div>
<div id="02"class="col"></div>
<div id="03"class="col"></div>
</div>
<div class="row">
<div id="10" class="col"></div>
<div id="11"class="col"></div>
<div id="12"class="col"></div>
<div id="13"class="col"></div>
</div>
<div class="row">
<div id="20" class="col"></div>
<div id="21"class="col"></div>
<div id="22"class="col"></div>
<div id="23"class="col"></div>
</div>
<div class="row">
<div id="30" class="col"></div>
<div id="31"class="col"></div>
<div id="32"class="col"></div>
<div id="33"class="col"></div>
</div>
<script>
var size = 4;
var player = 0;
var board = new Array(size);
for (var i = 0; i < size; i++) {
board[i] = new Array(size);
for (var j = 0; j < size; j++) {
board[i][j] = 0;
}
}
var div_elements = document.getElementsByClassName("col");
for (var i = 0; i < div_elements.length;i++) {
div_elements[i].addEventListener("click", function() {mclick(this);});
}
var count=0;
function mclick(obj) {
if(match(div_elements.childNodes[0].nodeValue) == match(div_elements.childNodes[1].nodeValue)
{
obj.style.backgroundColor="white";
}
else{
setTimeout(function(){ obj.style.backgroundColor="white" }, 1000);
}
}
function shuffle() {
var value;
var text;
var text_node;
for (var i = 0; i < (size * size) ; i++) {
value = Math.ceil(Math.random() * 8);
board[Math.floor(i/4)][i %4] = value;
}
for (var i = 0; i < div_elements.length; i++)
{
text = board[Math.floor(i/4)][i%4];
text_node = document.createTextNode( text);
div_elements[i].appendChild(text_node);
}
}
shuffle();
</script>
</body>
</html>
You must be more specific. What kind of problem are you having? What are the error messages? What do you do that triggers the problem?
At least, put the code in a pastebin.com or something similar so that others don't need to setup a project for testing your whole stuff.

Categories