Display output to multiple classes via JavaScript - javascript

I am writing a "Gamebook Engine" which offers the possibility of setting a user name. The Name is taken from an input with the id="setUserNameInput" and saved by the function setUserName(). It is displayed / loaded into an element containing the class="displayUserName" and loaded by the function displayUserName(). It works fine with only one class one the page, but as soon as I add more I have to define which one to target as it won't target them all automatically. I have tried to use document.getElementById, document.getElementsByName as well as document.querySelectorAll and document.querySelector, none of which work. (I use Bulma as my CSS Framework, by the way)
Here is the code I have so far (though it will show an error as it cannot access the localStorage inside the snippet):
This page http://scampsblog.com/docs/example-de.html contains an (working, haha) example. Since it is a documentation (page lies on my testing sever, thus the domain) you might want to take a look at http://scampsblog.com/docs/character-enginedotjs-de.html which explains / shows the individual elements (the documentation is in German but I can provide a translation if you need one).
The part of the JS I am struggling with is right in the first line but if you suggest some overall improvements, I will be happy to take them.
var userNameOutput = document.getElementsByClassName('displayUserName')[0];
function setUserName() {
var usernameinput = document.getElementById('setUserNameInput').value;
localStorage.setItem('userName', usernameinput);
if (!localStorage.getItem('userName')) {
setUserName();
} else {
var storedUserName = localStorage.getItem('userName');
userNameOutput.innerHTML = storedUserName;
}
}
function displayUserName() {
if (!localStorage.getItem('userName')) {
setUserName();
} else {
var storedUserName = localStorage.getItem('userName');
userNameOutput.innerHTML = storedUserName;
}
}
window.onload = function displayUserName() {
if (!localStorage.getItem('userName')) {
setUserName();
} else {
var storedUserName = localStorage.getItem('userName');
userNameOutput.innerHTML = storedUserName;
}
}
<input type="text" class="input" placeholder="Your name goes here" id="setUserNameInput">
<input type="button" class="button" value="Set your username" onclick="setUserName()" />
<input type="button" class="button" value="Display on click" onclick="displayUserName()" />
<br> So you shall be called <span class="displayUserName"></span>! But dont worry, <span class="displayUserName"></span>, it will be all fine.

Instead of getting the first item in the collection (using [0]) you could iterate through it (using for...of) and set the innerHTML of each element having the class displayUserName.
e.g.
var userNameOutputs = document.querySelectorAll('.displayUserName');
for (let ele of userNameOutputs) {
ele.innerHTML = userName;
}
Full code, with some optimizations to structure:
function setUserName() {
var usernameinput = document.getElementById('setUserNameInput').value;
localStorage.setItem('userName', usernameinput);
displayUserName(true); // pass true to avoid recursion
}
function displayUserName(skipSet) {
var userName = localStorage.getItem('userName');
if (!userName && !skipSet) {
setUserName();
} else {
var userNameOutputs = document.querySelectorAll('.displayUserName');
for (let ele of userNameOutputs) {
ele.innerHTML = userName;
}
}
}
window.onload = displayUserName;
<input type="text" class="input" placeholder="Your name goes here" id="setUserNameInput">
<input type="button" class="button" value="Set your username" onclick="setUserName()" />
<input type="button" class="button" value="Display on click" onclick="displayUserName()" />
<br> So you shall be called <span class="displayUserName"></span>! But dont worry, <span class="displayUserName"></span>, it will be all fine.
Working fiddle: https://jsfiddle.net/hosney/3pxfybrc/1/

var userNameOutput = document.getElementsByClassName('displayUserName')[0];
the [0] selects the first element of the array of elements of the class name.

Related

Count down from user entered number in HTML and Javascript

So i have an input box that a user can enter a number into and upon clicking Commit, that number displays in a tag.
I then want this number to start counting down when I click Start.
I am new to Javascript and this is essentially a little project to help me learn, maybe I've thrown myself in too far, but I'm too invested now and would appreciate any help.
My HTML:
<span style="font-size: 36pt; font-family: homiziothin; color: black; padding-right: 20px;">£</span>
<input id="inputvalue" type="number" name="Value" min="0" max="500">
<button id="commitprice" type="submit" onclick="submitPrice()">Commit Price</button>
<p id="submittedprice"></p>
<button id="startauction" type="submit" onclick="startAuction()">Start Auction</button>
and my current Javascript to get the user value into the tag (and a rough guess going from multiple searches on google of how to start the countdown)
<script type="text/javascript">
function submitPrice()
{
var $pricesubmitted = $("#inputvalue").val();
$("#submittedprice").text($pricesubmitted);
}
function startAuction()
{
debugger;
var $startingprice = $("#inputvalue").val();
var $bidcountdown = setInterval(function()
{
$startingprice--;
document.getElementById("#inputvalue").textContent = $startingprice;
if($startingprice <= 0)
clearInterval($bidcountdown);
}, 1000);
}
</script>
At the moment it's erroring and saying that textContent can't be NULL.
Also just to point out the Actual populating of the P tag is working, its the countdown that isn't.
textContent property represents the text between opening and closing tags of an element. With your input, you need value property, because you don't have any text between those tags.
More info: How do I get the value of text input field using JavaScript?
I have implemented your requirement in a fiddle, you can check
function submitPrice() {
var $pricesubmitted = document.getElementById("inputvalue");
document.getElementById("submittedprice").innerText = $pricesubmitted.value;
}
function startAuction() {
var msgElement = document.getElementById("showMessage");
msgElement.innerText = "Count Down Started..";
var _el = document.getElementById("inputvalue");
var $startingprice = parseInt(_el.value);
var $bidcountdown = setInterval(function() {
msgElement.innerText = "Count Value " + $startingprice;
$startingprice--;
msgElement.innerText = $startingprice;
if ($startingprice < 0) {
msgElement.innerText = "Count Down ends ...";
clearInterval($bidcountdown);
}
}, 1000);
}
<span style="font-size: 36pt; font-family: homiziothin; color: black; padding-right: 20px;">£</span>
<input id="inputvalue" type="number" name="Value" min="0" max="500" value="">
<button id="commitprice" onclick="submitPrice()">Commit Price</button>
<p id="submittedprice"></p>
<button id="startauction" type="button" onclick="startAuction()">Start Auction</button>
<div id="showMessage"></div>
jsfiddle link
You have a couple of issues in your code. First, as noted by Mladen, you should be using .value instead of .textContent. Second, you should not use the "#" in the .getElementById selector.
This should fix it for you.
function startAuction()
{
debugger;
var $startingprice = document.getElementById("inputvalue").value;
var $bidcountdown = setInterval(function()
{
$startingprice--;
// document.getElementById("inputvalue").value = $startingprice;
document.getElementById("submittedprice").innerHTML= $startingprice;
if($startingprice <= 0)
clearInterval($bidcountdown);
}, 1000);
}
By the way, I highly recommend not jumping back and forth between jQuery and vanilla JS DOM selectors to avoid this kind of confusion.
Edit:
Commented out the line targeting the text input and added a line targeting the <p> tag. Note that instead of .value, you will need to use .innerHTML to make the change to the <p> tag (because it is updating the HTML contained within the opening and classing brackets of the <p>).

Fill textbox from url query and call function

<input type="text" id="tnum" maxlength="50" placeholder="Enter Your Tracking ID" />
<input class="btn" type="button" value="TRACK" onclick="doTrack()" />
<div id="YQContainer"></div>
So basically, I have a page that can track packages for my customers. I want to be able to send them a link in their email that will automatically track their package from the link. ( they don't have to type in their tracking id and click track when they go to my tracking page )
example.com/track?tnum=3298439857
This is what i'm using to track packages.
https://www.17track.net/en/externalcall/single
The basic idea is as follows:
Wait for page to load
Parse the URL and extract needed query parameter
Set the value of the form element
Call the doTrack() function
// Handy function to parse the URL and get a map of the query parameters
function parseQueryParameters(url) {
var qp = {};
if (!url) {
return qp;
}
var queryString = url.split('?')[1];
if (!queryString) {
return qp;
}
return queryString.split('&')
.reduce(function(m, d) {
var splits = d.split('=');
var key = splits[0];
var value = splits[1];
if (key && value) {
m[key] = value;
}
return m;
}, qp);
}
//Wait for page to load
window.onload = function() {
//Extract tnum query parameter
var qp = parseQueryParameters(window.location.href);
//If no parameter is provided, do nothing
if (!qp.tnum) return;
//Set the value of the form element
document.getElementById("tnum").value = qp.tnum;
// Call doTrack
doTrack();
}
//Temporary doTrack function - remove when integrating ;)
function doTrack() {
console.log(document.getElementById("tnum").value)
}
<input type="text" id="tnum" maxlength="50" placeholder="Enter Your Tracking ID" />
<input class="btn" type="button" value="TRACK" onclick="doTrack()" />
<div id="YQContainer"></div>
<html>
<head>
<script>
function setURL(){
var dt_value = document.getElementById("tnum").value;
//just test here ..what is coming..
alert(dt_value );
var sjdurl = "example.com/track?tnum="+dt_value;
popup = window.open(sjdurl,"popup"," menubar =0,toolbar =0,location=0, height=900, width=1000");
popup.window.moveTo(950,150);
}
</script>
</head>
<body>
<input type="Text" id="tnum" maxlength="25" size="25"/>
<input type='button' onclick='setURL()' value='SUBMIT'>
</body>
</html>
function doTrack(tnum) {
var trackNumber = tnum;
window.open("example.com/track?tnum="+trackNumber);
}
$(".btn").on('click',function(e) {
e.preventDefault();
var tnum = $('#tnum').val();
if (tnum!="") {
doTrack(tnum);
} else {
return false;
}
});

Textfields not passing values properly

I'm willing to use two textfields to pass on values via url.
Here are my textfields:
<h3 class="title1">Email</h3>
<input type="text" id="myTextField1" />
<br/><br/>
<h3 class="title2">Secret</h3>
<input type="text" id="myTextField2" />
<br/><br/>
There's a link below them:
<a id="myLink" href="index2.php"></a>
Then there's a function I use, which should create something like:
index2.php?email=value1&secret=value2
However what I am getting is:
index2.php?email=value1, secret=value1&email=value2, secret=value2
This is the function I use:
document.querySelector('#myBtn').addEventListener('click', function change() {
function isInvalid(input) {
return input.value.length == 0;
}
var inputs = [...document.querySelectorAll('[id^="myTextField"]')];
var anchor = document.getElementById('myLink');
var querystring = inputs.map((input) => {
// Remove all leading non-digits to get the number //ex bladiebla1 = 1
var number = input.id.replace( /^\D+/g, '');
var titles = [...document.querySelectorAll('.title'+ number)];
titles.forEach((title) => title.innerHTML = input.value);
return `email=${input.value}`+` secret=${input.value}`;
});
anchor.href = `index2.php?${querystring.join('&')}`;
document.getElementById('result').innerHTML = querystring;
});
I realize that it is wrong and I get why this doesn't return what I want however I do not know how to fix this..
Could anybody tweek my code and point me in the right direction?
You're overcomplicating things here a bit.
You have the inputs in the inputs variable. If they had a name attribute in the html you can simply map over them and get the values out.
You don't really need the bit where you parse the number from the ID.
document.querySelector('#myBtn').addEventListener('click', function change() {
function isInvalid(input) {
return input.value.length == 0;
}
var inputs = [...document.querySelectorAll('[id^="myTextField"]')];
var anchor = document.getElementById('myLink');
var querystring = inputs.map((input) => {
return `${input.name}=${input.value}`;
});
anchor.href = `index2.php?${querystring.join('&')}`;
document.getElementById('result').innerHTML = querystring.join('&');
});
<h3 class="title1">Email</h3>
<input type="text" name="email" id="myTextField1" />
<br/><br/>
<h3 class="title2">Secret</h3>
<input type="text" name="secret" id="myTextField2" />
<br/><br/>
<button id=myBtn>Run the function</button>
<a id=myLink>Target Link</a>
<h3>Results:</h3>
<div id=result></div>
You iterate through each input and set email and secret for each of two inputs. Just add check for id. Something like return number === 1 ? email=${input.value} : &secret=${input.value};

enable buttons in javascript/jquery based on regex match

I'm having trouble getting the match to bind to the oninput property of my text input. Basically I want my submit button to be enabled only when the regular expression is matched. If the regex isn't matched, a message should be displayed when the cursor is over the submit button. As it stands, typing abc doesn't enable the submit button as I want it to. Can anyone tell me what I'm doing wrong? Thank you.
<div id="message">
</div>
<form method="POST">
<input type="text" id="txt" oninput="match()" />
<input type="submit" id="enter" value="enter" disabled />
</form>
<script>
var txt = $("#txt").value();
var PATTERN = /abc/;
var REQUIREMENTS = "valid entries must contain the string 'abc'";
// disable buttons with custom jquery function
jQuery.fn.extend({
disable: function(state) {
return this.each(function() {
this.disabled = state;
});
}
});
$('input[type="submit"]).disable(true);
var match = function(){
if (txt.match(PATTERN)){
$("#enter").disable(false)
}
else if ($("#enter").hover()){
function(){
$("#message").text(REQUIREMENTS);
}
}
</script>
Your code would be rewrite using plain/vanille JavaScript.
So your code is more clean and better performance:
<div id="message"></div>
<form method="POST">
<input type="text" id="txt" oninput="match()" />
<input type="submit" id="enter" value="enter" disabled />
</form>
<script>
var txt;
var enter = document.getElementById('enter');
var message = document.getElementById('message');
var PATTERN = /abc/;
var REQUIREMENTS = "valid entries must contain the string 'abc'";
function match() {
txt = document.getElementById('txt').value;
if (PATTERN.test(txt)) {
enter.disabled = false;
} else if (isHover(enter)) {
enter.disabled = true;
message.innerHTML = REQUIREMENTS;
} else {
enter.disabled = true;
}
}
function isHover(e) {
return (e.parentElement.querySelector(':hover') === e);
}
</script>
If you wanted to say that you want handle the events in different moments, your code should be the following.
Note: the buttons when are disabled doesn't fired events so, the solution is wrapper in a div element which fired the events. Your code JavaScript is more simple, although the code HTML is a bit more dirty.
<form method="POST">
<input type="text" id="txt" oninput="match()" />
<div style="display: inline-block; position: relative">
<input type="submit" id="enter" value="enter" disabled />
<div id="buttonMouseCatcher" onmouseover="showText(true)" onmouseout="showText(false)" style="position:absolute; z-index: 1;
top: 0px; bottom: 0px; left: 0px; right: 0px;">
</div>
</div>
<script>
var txt;
var enter = document.getElementById('enter');
var message = document.getElementById('message');
var PATTERN = /abc/;
var REQUIREMENTS = "valid entries must contain the string 'abc'";
function match() {
txt = document.getElementById('txt').value;
if (PATTERN.test(txt)) {
enter.disabled = '';
} else {
enter.disabled = true;
}
}
function showText(option) {
message.innerHTML = option ? REQUIREMENTS : "";
}
</script>
Two problems here:
The variable txt is defined once outside the function match, so the value is fixed to whatever the input with id txt has when the script/page is loaded.
You should move var txt = $("#txt").val(); into the match function.
Notice I changed the function value() to val().
Problems identified:
jQuery events don't happen on disabled inputs: see Event on a disabled input
I can't fix jQuery, but I can simulate a disabled button without it actually being disabled. There's other hacks you could do to get around this as well, for example, by overlaying a transparent element which actually captures the hover event while the button is disabled.
Various syntactical errors: format your code and read the console messages
.hover()){ function() { ... } } is invalid. It should be .hover(function() { ... })
else doesn't need to be followed by an if if there's no condition
.hover( handlerIn, handlerOut ) actually takes 2 arguments, each of type Function
$('input[type="submit"]) is missing a close '
Problems identified by #Will
The jQuery function to get the value of selected input elements is val()
val() should be called each time since you want the latest updated value, not the value when the page first loaded
Design issues
You don't revalidate once you enable input. If I enter "abc" and then delete the "c", the submit button stays enabled
You never hide the help message after you're done hovering. It just stays there since you set the text but never remove it.
https://jsfiddle.net/Lh4r1qhv/12/
<div id="message" style="visibility: hidden;">valid entries must contain the string 'abc'</div>
<form method="POST">
<input type="text" id="txt" />
<input type="submit" id="enter" value="enter" style="color: grey;" />
</form>
<script>
var PATTERN = /abc/;
$("#enter").hover(
function() {
$("#message").css('visibility', $("#txt").val().match(PATTERN) ? 'hidden' : 'visible');
},
$.prototype.css.bind($("#message"), 'visibility', 'hidden')
);
$('form').submit(function() {
return !!$("#txt").val().match(PATTERN);
});
$('#txt').on('input', function() {
$("#enter").css('color', $("#txt").val().match(PATTERN) ? 'black' : 'grey');
});
</script>

Fill data in input boxes automatically

I have four input boxes. If the user fills the first box and clicks a button then it should autofill the remaining input boxes with the value user input in the first box. Can it be done using javascript? Or I should say prefill the textboxes with the last data entered by the user?
On button click, call this function
function fillValuesInTextBoxes()
{
var text = document.getElementById("firsttextbox").value;
document.getElementById("secondtextbox").value = text;
document.getElementById("thirdtextbox").value = text;
document.getElementById("fourthtextbox").value = text;
}
Yes, it's possible. For example:
<form id="sampleForm">
<input type="text" id="fromInput" />
<input type="text" class="autofiller"/>
<input type="text" class="autofiller"/>
<input type="text" class="autofiller"/>
<input type="button"value="Fill" id="filler" >
<input type="button"value="Fill without jQuery" id="filler2" onClick="fillValuesNoJQuery()">
</form>
with the javascript
function fillValues() {
var value = $("#fromInput").val();
var fields= $(".autofiller");
fields.each(function (i) {
$(this).val(value);
});
}
$("#filler").click(fillValues);
assuming you have jQuery aviable.
You can see it working here: http://jsfiddle.net/ramsesoriginal/yYRkM/
Although I would like to note that you shouldn't include jQuery just for this functionality... if you already have it, it's great, but else just go with a:
fillValuesNoJQuery = function () {
var value = document.getElementById("fromInput").value;
var oForm = document.getElementById("sampleForm");
var i = 0;
while (el = oForm.elements[i++]) if (el.className == 'autofiller') el.value= value ;
}
You can see that in action too: http://jsfiddle.net/ramsesoriginal/yYRkM/
or if input:checkbox
document.getElementById("checkbox-identifier").checked=true; //or ="checked"

Categories

Resources