I have created a QR code generator. The user can create multiple QR codes.
I would like the user to be able to name each QR code (referred to as a checkpoint) by writing the desired checkpoint name in the text input field, clicking the Assign Name button and having the text input field disappear, being replaced by the name the user typed into the field.
The user can input checkpoint names, however, it only works for the first QR code printed, and the label only appears below the QR code. Below is the code that I have so far. Any help or suggestions to help me get the ball rolling on this would be very much appreciated. Thank you!
Note: If you try to run this to see the QR codes, you will have to enter something in the text field and press generate. They won't appear automatically.
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: arial, sans-serif;
}
section {
margin: 50px auto;
max-width: 350px;
text-align: center;
}
textarea {
width: 50%;
height: 50px;
margin-bottom: 10px;
}
#size {
max-width: 64px;
}
label {
display: inline-block;
width: 140px;
text-align: left;
}
</style>
<script src="/scripts/snippet-javascript-console.min.js?v=1"></script>
</head>
<body>
<section>
<h1>QR Code Generator</h1>
<p>Enter a URL or some text bellow and hit the Generate button (<kbd>Ctrl</kbd>+<kbd>Enter</kbd>)!</p>
<textarea id="textarea" autofocus></textarea>
<div class="block">
<label for="size">Size (px):</label>
<input align="left" id="size" type="number" value="150" min="50" max="500" step="50">
<label for="amount">Amount of Labels:</label>
<input align="left" id="amount" type="number" value="1" min="1" max="500" step="1">
<button id="genQRcode">Generate</button>
</div>
<div id="content" style="display: none;"></div>
</section>
<p id="demo" align="center"></p>
<script>
function myFunction() {
var x = document.getElementById("cpname").value;
document.getElementById("demo").innerHTML = x;
}
</script>
<script id="template-qr-code" type="text/html">
<p> <img id="qrcode" src="{{src}}" /></p>
<label for="checkpoint"> Checkpoint Name:</label>
<input id="cpname" type="text" value="">
<button onclick="myFunction()">Assign Name</button>
</script>
<script type="text/javascript">
window.addEventListener('load', function() {
var textarea = document.getElementById("textarea"),
content = document.getElementById("content"),
amount = document.getElementById("amount"),
qrTemplate = document.getElementById('template-qr-code');
function genQRcode() {
var data = encodeURIComponent(textarea.value),
size = document.getElementById("size").value,
chart = "http://chart.googleapis.com/chart?cht=qr&chs=" + size + "x" + size + "&choe=UTF-8&chld=L|0&chl=" + data;
if (data === "") {
alert("Please enter valid data!");
textarea.focus();
content.style.display = "none";
} else {
for (var i = 0; i < amount.value; i++) {
var qrSrc = qrTemplate.innerHTML;
qrSrc = qrSrc.replace(new RegExp('{{src}}', 'g'), chart);
qrSrc = qrSrc.replace(new RegExp('{{i}}', 'g'), i);
content.insertAdjacentHTML('beforeEnd', qrSrc);
}
content.style.display = "";
}
}
document.getElementById("genQRcode").addEventListener("click", genQRcode);
document.addEventListener("keydown", function(e) {
if (e.ctrlKey && e.keyCode == 13) {
genQRcode();
}
});
});
</script>
</body>
</html>
Your click function
function myFunction() {
var x = document.getElementById("cpname").value;
document.getElementById("demo").innerHTML = x;
}
is getting and setting an element by ID. That will only ever affect a single element on the page (usually the first one that the browser runs into with that specific id). You need to use a different selector / way of getting the label you want to change because you can't reuse ids.
Basically you need to make your label fields distinct so you can actually select them
Related
A javascript program to concate the first name and last name, but the concated string gets displayed as the cursor moves out from the last name text box
`
<!DOCTYPE html>
<html lang="en">
<head>
<title>Practical 3</title>
<style>
#concatenator {
background-color: white;
height: 150px;
width: 330px;
border-width: 4px;
border-color: black;
border-style: solid;
padding: 5px;
}
</style>
<script>
function concat() {
fst = String(myform.fst.value);
snd = String(myform.snd.value);
result = fst.concat(" ", snd);
myform.result.value = result;
}
function refresh() {
location.reload();
}
</script>
</head>
<body id="concatenator">
<form name="myform">
Enter first name: <input type="text" name="fst"><br><br>
Enter second name: <input type="text" name="snd"><br><br>
<input type="Button" name="" value="Refresh" onclick="refresh()">
<input type="Button" name="" value="Full Name" onclick="concat()"><br><br>
Full Name: <input type="text" name="result">
</form>
</body>
</html>
`
I have to makes changes in this so that the full name button is gone and the two name are concatenated instantly
To achieve that result you may use a keyup event handler on your input elements so that a given logic will be executed every time the user type something.
Such logic just fetches the values of those input elements, concatenates the two string and sets the value of the return input element.
I used a general approach as far as possible so that the conditions to fetch those two input elements are defined as css selectors in the targetSelectors array.
//selectors relative to the root document for the input element to concat
const targetSelectors = ['#myform [name=fst]', '#myform [name=snd]'];
//adds a keyup event handler to all the elements in targetSelectors
targetSelectors.forEach( (targetSelector) => {
document.querySelector(targetSelector)
.addEventListener('keyup', (event) => {
//concats the fields value
const concatenated = concatFields(' ');
//refreshes the result input field value with the new one
refreshField('input[name=result]', concatenated);
});
});
//sets the value of the input element found with targetSelector
function refreshField(targetSelector, value){
document.querySelector(targetSelector).value = value;
}
//returns the concatenated values from the input elements in targetSelectors (separated by spacer)
function concatFields(spacer = ''){
return targetSelectors.map( targetSelector => document.querySelector(targetSelector).value ).join(spacer);
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Practical 3</title>
<style>
#concatenator {
background-color: white;
height: 150px;
width: 330px;
border-width: 4px;
border-color: black;
border-style: solid;
padding: 5px;
}
</style>
<script>
function concat() {
fst = String(myform.fst.value);
snd = String(myform.snd.value);
result = fst.concat(" ", snd);
myform.result.value = result;
}
function refresh() {
location.reload();
}
</script>
</head>
<body id="concatenator">
<form id="myform">
Enter first name: <input type="text" name="fst"><br><br>
Enter second name: <input type="text" name="snd"><br><br>
Full Name: <input type="text" name="result">
</form>
</body>
</html>
And this an attempt went too far with the generalization able to keep an arbitrary number of inputs bound to each other in the aim of concatenating their values inside an output element when the change event occurs on any of those inputs.
*the answer was accepted already.. it was for the sake of making sense of the generalized approach and nothing else
const c = new Concatenator(
retrieveClassSelectors('#showingMaxPotential input.concat'),
'#showingMaxPotential input[name=result]');
//returns an array of selector (sorted) based on the class attribute belonging to all the elements grabbed by the matchingSelector
function retrieveClassSelectors(matchingSelector){
const specificSelectors =
[...document.querySelectorAll(matchingSelector)]
.map(target => {
const classesSelector =
target.getAttribute('class')
.replace(/[^\s]+/g, '.$&')
.replace(/\s/g, '');
return classesSelector;
}).sort();
return specificSelectors;
}
function Concatenator(targetSelectors, outputSelector) {
this.init = () => {
//adds a keyup event handler to all the elements in targetSelectors
this.targetSelectors.forEach((targetSelector) => {
document.querySelector(targetSelector)
.addEventListener('keyup', (event) => {
//refreshes the result input field value with the new one
this.refreshField(this.outputSelector, this.concatFields(' '));
});
});
}
//sets the value of the input element found with targetSelector
this.refreshField = (targetSelector, value) => {
document.querySelector(targetSelector).value = value;
}
//returns the concatenated values from the input elements in targetSelectors (separated by spacer)
this.concatFields = (spacer = '') => {
return this.targetSelectors.map(targetSelector => document.querySelector(targetSelector).value).join(spacer);
}
this.targetSelectors = targetSelectors;
this.outputSelector = outputSelector;
this.init();
}
form#showingMaxPotential{
border: solid 1px darkgray;
padding: 1em;
}
form#showingMaxPotential > label,
form#showingMaxPotential > input{
display: block;
}
form#showingMaxPotential > input{
margin-bottom: 1em;
}
<form id="showingMaxPotential">
<label>Enter <b>first</b> item name:</label>
<input type="text" name="i1" class="concat item-1">
<label>Enter <b>last</b> item name:</label>
<input type="text" name="i3" class="concat item-3">
<label>Enter <b>middle</b> item name:</label>
<input type="text" name="i2" class="concat item-2">
<label>Full Name:</label>
<input type="text" name="result" disabled>
</form>
I have a function that displays text in a div as its typed into an input. Right now it simply checks for each ID go get the value and display the text.
I want to make this function reusable so that I can match different inputs with different divs without writing a unique function for each case.
Here is an example that works using a single input and div:
<body>
<input type='text' name='name' id='inputBox'>
<div id='displayBox'></div>
<script type="text/javascript">
var displayText = document.getElementById('inputBox');
displayText.onkeyup = function() {
document.getElementById('displayBox').innerHTML = inputBox.value;
}
</script>
</body>
And I want to be able to repeat this for different sets of unique inputs & divs with a reusable function.
<body>
<!-- First set -->
<input type='text' name='name' id='inputBox'>
<div id='displayBox'></div>
<!-- Second set -->
<input type='text' name='name' id='inputBox'>
<div id='displayBox'></div>
<!-- etc... -->
<script type="text/javascript">
var displayText = document.getElementById('inputBox');
displayText.onkeyup = function() {
document.getElementById('displayBox').innerHTML = inputBox.value;
}
</script>
</body>
If you wrap each "set" in a container, and swap your ids for classes, you can can add listeners to each input to watch for changes, find the parent container, find the display box and update its text content.
// Get all of the inputs
const displayText = document.querySelectorAll('.inputBox');
// Attach listeners to all of them
displayText.forEach(input => {
input.addEventListener('keyup', handleChange, false);
});
function handleChange() {
// Find the closest div ancestor element (the container)
const parent = this.closest('div');
// Then locate the display box and update the text content
parent.querySelector('.displaybox').textContent = this.value;
}
.container { margin-bottom: 1em; }
.displaybox { margin-top: 0.2em; height: 1.3em; width: 300px; border: 1px solid black; }
<div class="container">
<input type="text" name="name" class="inputBox" placeholder="Type here">
<div class="displaybox"></div>
</div>
<div class="container">
<input type="text" name="age" class="inputBox" placeholder="Type here">
<div class="displaybox"></div>
</div>
<div class="container">
<input type="text" name="location" class="inputBox" placeholder="Type here">
<div class="displaybox"></div>
</div>
It seems you would need to get the ID of each input box and each output box?
function showTypedInput(inputID, outputID) {
var inputBox = document.getElementById(inputID);
var outputBox = document.getElementById(outputID);
inputBox.onkeyup = function(){
outputBox.innerHTML = inputBox.value;
};
}
Then you just reuse this?
showTypedInput("myInputBox", "myOutputBox");
You can create this functionality using following:
function listener(target){
return function(e){target.innerHTML = e.target.value};
}
function init(){
var elems = document.querySelectorAll("input[data-keyuptarget]");
for(var elem of elems){
var target = document.getElementById(elem.getAttribute('data-keyuptarget'));
if (target) elem.onkeyup = listener(target);
}
}
init();
In html just use
<input type='text' name='name' data-keyuptarget="displayBox1">
<div id='displayBox1'></div>
<input type='text' name='name' data-keyuptarget="displayBox2">
<div id='displayBox2'></div>
JS Bin : https://jsbin.com/piwiyapohe/edit?html,output
I am trying to change the display property of some text using JS, upon button click.
I have confirmed that the function is firing and running correctly using debugger, but for some reason, I can't grab the specific element I need to change, and assign it to a variable. I also have jquery set up on the page.
I have tried using the console, and document.getElementById('warning-textID') returns the correct element, but when I try to set it to a variable in console, it returns undefined. Am I missing something super obvious here?
Here is the HTML, function and css.
//adding event listener
$(function() {
document.getElementById("submitdiscount").addEventListener("click", putCookie);
});
// click function
function putCookie() {
var enteredValue = document.getElementById("nameBox").value;
var validParam = "test";
var warning = document.getElementById("warning-textID");
var cookieCreated = false;
if(enteredValue == validParam){
console.log('do the thing')
if(cookieCreated == false && enteredValue == validParam){
warning.innerText = "Please enable cookies";
warning.style.display = "";
return;
} else {
warning.innerText = "Please enter the correct code."
warning.style.display = "";
enteredValue.value = "";
return;
}
}
.warning-text {
color: red; text-align: center;
margin-bottom: 0px;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="employee-code-input-wrapper" id="employee-code-input">
<div class="employee-code-input-header">
<h2>Enter the employee code you received via email</h2>
</div>
<div class="search-bar emplyoee-code-input-input-wrapper" >
<input class="emplyoee-code-input-input" type="text" placeholder="Enter Employee Code" code="" id="nameBox" name="pass">
<button class="btn btn--submit-employee-form" value="Submit" id="submitdiscount" type="button">submit</button>
</div>
<h2 class="warning-text" id="warning-textID">
Please enter the correct code.
</h2>
</div>
I fixed some mistakes and it worked.
//adding event listener
$(function() {
document.getElementById("submitdiscount").addEventListener("click", putCookie);
// click function
function putCookie() {
var enteredValue = document.getElementById("nameBox").value;
var validParam = "test";
var warning = document.getElementById("warning-textID");
var cookieCreated = false;
if (enteredValue === validParam) {
console.log('do the thing')
if (cookieCreated == false && enteredValue === validParam) {
warning.innerText = "Please enable cookies";
warning.style.display = "block";
return;
}
} else {
warning.innerText = "Please enter the correct code."
warning.style.display = "block";
enteredValue.value = "";
return;
}
}
});
.warning-text {
color: red;
text-align: center;
margin-bottom: 0px;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="employee-code-input-wrapper" id="employee-code-input">
<div class="employee-code-input-header">
<h2>Enter the employee code you received via email</h2>
</div>
<div class="search-bar emplyoee-code-input-input-wrapper">
<input class="emplyoee-code-input-input" type="text" placeholder="Enter Employee Code" code="" id="nameBox" name="pass">
<button class="btn btn--submit-employee-form" value="Submit" id="submitdiscount" type="button">submit</button>
</div>
<h2 class="warning-text" id="warning-textID">
Please enter the correct code.
</h2>
</div>
I am making a simple word counter program in JavaScript. I am fairly new in JavaScript world so excuse me if I am asking an rudimentary and simple enough question. I'm getting everything working that the string of text from textarea is splitted into words array and i can log number of words to console but can't display them into a text field where I want them to appear. Hope that someone can help here. Thanks
var btn = document.getElementById("btn");
var numWords = document.getElementById("output");
var str = document.getElementById("txtBox");
btn.onclick = function()
{
var words = str.value.split(" ");
numWords.innerHTML.value = words.length;
console.log( words.length );
};
.container
{
width: 600px;
margin: 0 auto;
}
textarea
{
width: 560px;
padding: 10px;
background-color: #dfdfdf;
color: #333;
font-size: 18px;
}
input
{
text-align: center;
padding: 10px;
margin-top: 15px;
}
input[type="submit"]
{
float: right;
margin-right: 15px;
background-color: #84ac49;
border: 0;
color: #fff;
font-weight: bold;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<from>
<textarea name="txtBox" id="txtBox" cols="30" rows="10"></textarea><br/>
<input type="text" value = 0 id="output">
<input type="submit" value="Count Words" id="btn">
</from>
</div>
</body>
</html>
move getting value in click function event
btn.onclick = function()
{
var str = document.getElementById("txtBox").value
var words = str.split(" ");
numWords.value = words.length;
console.log( words.length );
};
JSFIDDLE
btn.onclick = function () {
var words = str.value.split(" ");
numWords.value = words.length;
console.log(words.length);
};
also you can set input like this:
<input value="Count Words" id="btn">
when You click on count button You will get word count.
HTML
<textarea id="inputString" cols="50" rows="4"></textarea>
<br>
<input type="button" name="Convert" value="Count Words" onClick="countWords();">
<input id="wordcount" type="text" value="0" size="6">
Javascript
countWords=function(){
s=document.getElementById("inputString").value;
s = s.replace(/(^\s*)|(\s*$)/gi,"");
s = s.replace(/[ ]{2,}/gi," ");
s = s.replace(/\n /,"\n");
document.getElementById("wordcount").value = s.split(' ').length;
}
Here is a demo :https://jsfiddle.net/DhwaniSanghvi/tdn3x72g/
I am using - and + buttons to change the number of the text box, I am having troubles dealing with different text fields, here is my code:
var unit = 0;
var total;
// if user changes value in field
$('.field').change(function() {
unit = this.value;
});
$('.add').click(function() {
unit++;
var $input = $(this).prevUntil('.sub');
$input.val(unit);
unit = unit;
});
$('.sub').click(function() {
if (unit > 0) {
unit--;
var $input = $(this).nextUntil('.add');
$input.val(unit);
}
});
button {
margin: 4px;
cursor: pointer;
}
input {
text-align: center;
width: 40px;
margin: 4px;
color: salmon;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id=field1>
field 1
<button type="button" id="sub" class=sub>-</button>
<input type="text" id="1" value=0 class=field>
<button type="button" id="add" class=add>+</button>
</div>
<div id=field2>
field 2
<button type="button" id="sub2" class=sub>-</button>
<input type="text" id="2" value=0 class=field>
<button type="button" id="add2" class=add>+</button>
</div>
And here's the DEMO
You can see in the demo that the values change correctly only if you click buttons on the same field, but if you alternate between fields the values don't change properly.
This should be all you need:
$('.add').click(function () {
$(this).prev().val(+$(this).prev().val() + 1);
});
$('.sub').click(function () {
if ($(this).next().val() > 0) $(this).next().val(+$(this).next().val() - 1);
});
By using the unit variable you were tying both inputs together. And the plus in +$(this) is a shorthand way to take the string value from the input and convert it to a number.
jsFiddle example
You're using the same variable to hold the values of your two inputs. One simple option would be to use two variables instead of one:
var unit_1 = 0;
$('#add1').click(function() {
unit_1++;
var $input = $(this).prev();
$input.val(unit_1);
});
/* Same idea for sub1 */
var unit_2 = 0;
$('#add2').click(function() {
unit_2++;
var $input = $(this).prev();
$input.val(unit_2);
});
/* Same idea for sub2 */
and unit = unit just assigns the value of unit to itself, so that's no very useful and you can certainly leave it out.
An alternative approach is to use data attributes and have each element store its own value. Edit: it already stores its own value. Just access it.
var total;
// if user changes value in field
$('.field').change(function() {
// maybe update the total here?
}).trigger('change');
$('.add').click(function() {
var target = $('.field', this.parentNode)[0];
target.value = +target.value + 1;
});
$('.sub').click(function() {
var target = $('.field', this.parentNode)[0];
if (target.value > 0) {
target.value = +target.value - 1;
}
});
button {
margin: 4px;
cursor: pointer;
}
input {
text-align: center;
width: 40px;
margin: 4px;
color: salmon;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id=field1>
field 1
<button type="button" id="sub" class=sub>-</button>
<input type="text" id="1" value=0 class=field>
<button type="button" id="add" class=add>+</button>
</div>
<div id=field2>
field 2
<button type="button" id="sub2" class=sub>-</button>
<input type="text" id="2" value=0 class=field>
<button type="button" id="add2" class=add>+</button>
</div>