Javascript: insert input number value into closest number variable array onchange - javascript

I need to insert a user input number value into the "41" var value=getClosestNum(41,intarray);.
I know "41" needs to be calling the name or the id from the input but my rusty Javascript attempts always seem to result with = 1. I've tried several getDocument, getID variants, sub functions, etc without success.
Ideally, the result would be instantaneous by using onChange on the input field without page reload.
Yes, it has to be JavaScript for incorporation later.
<html>
<head>
<title>Find nearest value in javascript</title>
<script language="javascript">
// big array to come, example numbers
var intarray=[1,2,3,5,7,9,11,33,40,42,44,55,66,77,88];
// Now this function used to find out the close value in array for given number
function getClosestNum(num, ar)
{
var i = 0, closest, closestDiff, currentDiff;
if(ar.length)
{
closest = ar[0];
for(i;i<ar.length;i++)
{
closestDiff = Math.abs(num - closest);
currentDiff = Math.abs(num - ar[i]);
if(currentDiff < closestDiff)
{
closest = ar[i];
}
closestDiff = null;
currentDiff = null;
}
//returns first element that is closest to number
return closest;
}
//no length
return false;
}
</script>
</head>
<body>
<form>
<input type="number" id="test" name="test" onChange="?">
</form>
<script language="javascript">
document.write("Array: "+intarray+"<br>");
document.write("Value to find 41 <br>");
// CODE TO CHANGE "41" to id or named input
// 41 to reference input field
var value=getClosestNum(41,intarray);
document.write("Response Received "+value);
</script>
</body>
</html>

As I understand it, you are trying to use the input element to take a number, and you would like to return the closest number to that input from the array.
I registered a function that fires on an 'input' event. Try this:
HTML
Add the following element to see the output of the function. You can redirect it later to wherever you need it.
<p id="output"></p>
JavaScript
// wrap in an onload function to ensure
// that the elements exist before searching for them
window.onload = () => {
// cache of elements on the page you want to use
const testInputElement = document.getElementById('test');
const outputElement = document.getElementById('output');
// create a function that will fire whenever input is received
testInputElement.addEventListener('input', (event) => {
outputElement.innerHTML = getClosestNum(event.target.value, intarray);
})
};
onInput vs addEventListener('input')
Adding onInput directly to the HTML inside an element is not as secure as registering a function programmatically via addEventListener(). If you have a function called, say, handleInput(), simply pass that name to addEventListener as an argument like so
addEventListener('input', handleInput);
Your code with the changes
<html>
<head>
<title>Find nearest value in javascript</title>
<script language="javascript">
// big array to come, example numbers
var intarray=[1,2,3,5,7,9,11,33,40,42,44,55,66,77,88];
// Now this function used to find out the close value in array for given number
function getClosestNum(num, ar)
{
var i = 0, closest, closestDiff, currentDiff;
if(ar.length)
{
closest = ar[0];
for(i;i<ar.length;i++)
{
closestDiff = Math.abs(num - closest);
currentDiff = Math.abs(num - ar[i]);
if(currentDiff < closestDiff)
{
closest = ar[i];
}
closestDiff = null;
currentDiff = null;
}
//returns first element that is closest to number
return closest;
}
//no length
return false;
}
</script>
</head>
<body>
<form>
<input type="number" id="test" name="test" onChange="?">
</form>
<p id="output"></p>
<script language="javascript">
document.write("Array: "+intarray+"<br>");
document.write("Value to find 41 <br>");
// CODE TO CHANGE "41" to id or named input
// 41 to reference input field
var value=getClosestNum(41,intarray);
document.write("Response Received "+value);
// wrap in an onload function to ensure that the elements exist before searching for them
window.onload = () => {
// cache of elements on the page you want to use
const testInputElement = document.getElementById('test');
const outputElement = document.getElementById('output');
// create a function that will fire whenever input is received
testInputElement.addEventListener('input', (event) => {
outputElement.innerHTML = getClosestNum(event.target.value, intarray);
})
};
</script>
</body>
</html>

You're getting rid of your reference to the closestDiff on every loop, you need to keep that value throughout the loop and update it when the diff decreases.
function getClosestNum(num, arr) {
var closest;
if (arr.length > 0) {
closest = arr[0];
var diff = Math.abs(arr[0] - num);
for (var i = 1; i < arr.length; i++) {
var currentDiff = Math.abs(arr[i] - num);
if (diff > currentDiff) {
closest = arr[i];
diff = currentDiff;
}
}
}
return closest;
}

Related

Button function calling another function

im just a beginner and i want to find the answer to this problem.
This is my html code.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<input type = "text" name = "step" id = "step">
<button onclick="myFunction()">Submit</button>
<p id = "demo"></p>
</body>
</html>
This is my javascript code.
var step = document.getElementById("step").innerHTML;
parseInt(step);
function matchHouses(step) {
var num = 0;
var one = 1;
while (num != step){
one += 5;
num++;
}
return one;
}
function myFunction(){
document.getElementById("demo").innerHTML = matchHouses(step);
}
What I did is to call the function matchHouses(step) by the click of the button. But the output is always 1. I also put parseInt to the step id as it is string but it is still doesnt work. I was expecting an output of 1+5 if the input is 1, 1+5+5 if the input is two and so on. How do I make it work?
The two key things are that a) parseInt won't do the evaluation "in place". It either needs to be assigned to a variable, or the evaluation done as you're passing it into the matchHouse function, and b) you should be getting the value of the input element, not the innerHTML.
Here are some additional notes:
Cache all the elements first.
Add an event listener in your JavaScript rather than using inline JS in the HTML.
No need to have an additional variable for counting - just decrement step until it reaches zero.
Number may be a more suitable alternative to parseInt which requires a radix to work properly. It doesn't always default to base 10 if you leave it out.
Assign the result of calling the function to demo's textContent (not innerHTML as it is just a simple string, and not a string of HTML markup.
// Cache elements
const step = document.querySelector('#step');
const demo = document.querySelector('#demo');
const button = document.querySelector('button');
// Add a listener to the button
button.addEventListener('click', handleClick);
function matchHouses(step) {
let out = 1;
while (step > 0) {
out += 5;
--step;
}
return out;
}
function handleClick() {
// Get the value of the input string and
// coerce it to a number
const n = Number(step.value);
demo.textContent = matchHouses(n);
}
<body>
<input type="text" name="step" id="step">
<button type="button">Submit</button>
<p id="demo"></p>
</body>
I rewrote your code like this:
let step = 0;
function handleInput(e){
step = e.value;
}
function matchHouses(step) {
var num = 0;
var one = 1;
while (num != step){
one += 5;
num++;
}
return one;
}
function myFunction(){
document.getElementById("demo").innerHTML = matchHouses(step);
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<input type = "text" name="step" id="step" onkeyup='handleInput(this)'>
<button onclick="myFunction()">Submit</button>
<p id = "demo"></p>
</body>
</html>

How to execute local stored value by search function afther page reload / refresh

I use the following form and script to let users filter a td table on the input they give in. It filters the rows of the table and only shows the rows corresponding to their given value. They can update the rows that they are seeing, after they do this the page refreshes/reloads to refresh the table. After the page is refreshed/reloaded the search filter shows all rows again. I am searching for a way to keep the rows that they had before the update event happend based on their filter input. In other words, as if the refresh never happend.
Search form;
...
<p align='left' style="display:inline">
<table class="userprof" align='left'>
<tr>
<td class="footer">Filter:
<input type="text" id="myInput" name="filter" style="color:black !important;" placeholder="Filter table" onkeyup='saveValue(this);' />
</td>
</tr>
</table>
</p>
...
I use the folowing script to save their input as localstorage.
...
document.getElementById("myInput").value = getSavedValue("myInput"); // set the value to this input
/* Here you can add more inputs to set value. if it's saved */
//Save the value function - save it to localStorage as (ID, VALUE)
function saveValue(e) {
var id = e.id; // get the sender's id to save it .
var val = e.value; // get the value.
localStorage.setItem(id, val); // Every time user writing something, the localStorage's value will override .
}
//get the saved value function - return the value of "v" from localStorage.
function getSavedValue(v) {
if (!localStorage.getItem(v)) {
return ""; // You can change this to your defualt value.
}
return localStorage.getItem(v);
}
...
I use the following script to filter the table rows
...
function filterTable(event) {
var filter = event.target.value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 0; i < rows.length; i++) {
var nameCol = rows[i].cells[1].textContent.toUpperCase();
var rankCol = rows[i].cells[2].textContent.toUpperCase();
var rankerCol = rows[i].cells[5].textContent.toUpperCase();
var typeCol = rows[i].cells[6].textContent.toUpperCase();
var emailCol = rows[i].cells[3].textContent.toUpperCase();
if (nameCol.indexOf(filter) > -1 || rankCol.indexOf(filter) > -1 || rankerCol.indexOf(filter) > -1 || typeCol.indexOf(filter) > -1 || emailCol.indexOf(filter) > -1) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
document.querySelector('#myInput').addEventListener('keyup', filterTable, false);
...
You are almost there and only need minor modifications to make this happen.
I'd suggest that you change your flow up a bit.
First remove the onkeyup inline listener from your HTML. You are currently listening for that event 3 times on 1 element which seems overkill.
...
<p align='left' style="display:inline">
<table class="userprof" align='left'>
<tr>
<td class="footer">Filter:
<input type="text" id="myInput" name="filter" style="color:black !important;" placeholder="Filter table" />
</td>
</tr>
</table>
</p>
...
Then modify the filterTable to accept just a value, not an event object. This way you can call filterTable at any time and inject a value into it. And it allows you to call it immediately with the stored value when the page loads so that your initial filter will be set (or not if there is nothing stored).
Now listen for the keyup event with only a single listener which will both pass the value of the event to filterTable and the event itself to saveValue so that are both filtering and saving.
// Store the input in a variable for reference.
var myInput = document.getElementById("myInput");
var savedValue = getSavedValue("myInput");
// Immediately filter the table and set the input value.
filterTable(savedValue);
myInput.value = savedValue;
//Save the value function - save it to localStorage as (ID, VALUE)
function saveValue(e) {
var id = e.id; // get the sender's id to save it .
var val = e.value; // get the value.
localStorage.setItem(id, val); // Every time user writing something, the localStorage's value will override .
}
//get the saved value function - return the value of "v" from localStorage.
function getSavedValue(v) {
if (!localStorage.getItem(v)) {
return ""; // You can change this to your default value.
}
return localStorage.getItem(v);
}
function filterTable(value) {
console.log(value);
var filter = value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 0; i < rows.length; i++) {
var nameCol = rows[i].cells[1].textContent.toUpperCase();
var rankCol = rows[i].cells[2].textContent.toUpperCase();
var rankerCol = rows[i].cells[5].textContent.toUpperCase();
var typeCol = rows[i].cells[6].textContent.toUpperCase();
var emailCol = rows[i].cells[3].textContent.toUpperCase();
if (nameCol.indexOf(filter) > -1 || rankCol.indexOf(filter) > -1 || rankerCol.indexOf(filter) > -1 || typeCol.indexOf(filter) > -1 || emailCol.indexOf(filter) > -1) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
myInput.addEventListener('keyup', function(event) {
var value = event.target.value;
saveValue(event);
filterTable(value);
});

How do you make javascript(including function with array and return) write in div on button click without going to another page

I have had a lot of problems with this problem. When I console.log(sum); I get the answer I am looking for, but when I try to output the answer from a button click and an input field it does not work. I changed felt3.innerHTML=addnumber(ttt); to document.write(addnumber(ttt)); which made it work, but it is sending it to another page, which is something I do not want. How I can make this work:
<form id="form3">
Tall:<input type="number" id="number"><br>
<input type="button" id="button3" value="plusse"><br>
</form>
<div id="felt3"></div>
and:
var number = document.getElementById("number");
var felt3 = document.getElementById("tall3");
var form3 = document.getElementById("form3");
var button3 = document.getElementById("button3");
var sum=0;
function addnumber(x){
var array = [];
array.push(x);
for (var i = 0; i < array.length; i++) {
sum=sum+array[i];
}
return sum;
}
button3.onclick=function(){
var ttt=Number(number.value);
felt3.innerHTML=addnumber(ttt);
}
If I understand your question correctly, then the solution here is to update the argument that you are passing to getElementById("tall3"), rewriting it to document.getElementById("felt3");.
Doing this will cause your script to aquire the reference to the div element with id felt3. When your onclick event handler is executed, the result of addnumber() will be assigned to the innerHTML of the valid felt3 DOM reference as required:
var number = document.getElementById("number");
// Update this line to use "felt3"
var felt3 = document.getElementById("felt3");
var form3 = document.getElementById("form3");
var button3 = document.getElementById("button3");
var sum=0;
function addnumber(x){
var array = [];
array.push(x);
for (var i = 0; i < array.length; i++) {
sum=sum+array[i];
}
return sum;
}
button3.onclick=function(){
var ttt=Number(number.value);
// Seeing that felt3 is now a valid reference to
// a DOM node, the innerHTML of div with id felt3
// will update when this click event is executed
felt3.innerHTML=addnumber(ttt);
}
<form id="form3">
Tall:<input type="number" id="number"><br>
<input type="button" id="button3" value="plusse"><br>
</form>
<div id="felt3"></div>

Getting form element by value in Javascript

Hey guys I have a form which is stated below
<td><input type="text" id="NumberofRisks" name="Yeses" style="width: 25px" value ="<?php echo $row['Total-Score'];?> " </td>
The form has some data from a table as a value and I would like to take this value into my Javascript from to do a simple calculation. The function is listed below.
function sum()
{
sumField = document.getElementById("NumberofRisks");
var sum = 0;
$("input[name^='yanswer']:checked").each(function(){
sum++;
});
sumField.value = sum;
}
I need to get that value into the function as the value where it says NumberofRisks. Is there a way I can do this?
Try this to set sum to the initial value of #NumberofRisks.
var prevCheckedCount = 0;
function sum()
{
var sumField = document.getElementById("NumberofRisks");
// start sum with the inital value in HTML from DB
var valueOnClick = Math.floor(sumField.value);
var thisCheckedCount = 0;
$("input[name^='yanswer']:checked").each(function(){
thisCheckedCount++;
});
if(thisCheckedCount <= prevCheckedCount) {
sumField.value = valueOnClick - prevCheckedCount + thisCheckedCount;
} else {
sumField.value =valueOnClick + thisCheckedCount;
}
prevCheckedCount = thisCheckedCount;
}
Here's this code working: http://jsfiddle.net/t5hG4/
In order to grab the value of the input box you can use the following javascript:
var sum = document.getElementById("NumberofRisks").value;
Is this what you're trying to achieve?
As a side note, in the example you provided you did not close the input box so that might be giving you some errors as well.
EDIT:
If you're looking for a pure Javascript way to do this see below:
var elements = document.getElementsByTagName('input');
var sum = document.getElementById("NumberofRisks").value;
for (var i = 0; i < elements.length; i++) {
if (elements[i].checked) {
sum++
}
}
See fiddle - http://jsfiddle.net/es26j/

How do I compare the value of an element returned by getElementsByName to a string?

I'm making a quiz with a text input. This is what I have so far:
<html>
<head>
<script type="text/javascript">
function check() {
var s1 = document.getElementsByName('s1');
if(s1 == 'ō') {
document.getElementById("as1").innerHTML = 'Correct';
} else {
document.getElementById("as1").innerHTML = 'Incorrect';
}
var s2 = document.getElementsByName('s2');
if(s2 == 's') {
document.getElementById("as2").innerHTML = 'Correct';
} else {
document.getElementById("as2").innerHTML = 'Incorrect';
}
//(...etc...)
var p3 = document.getElementsByName('p3');
if(p3 == 'nt') {
document.getElementById("ap3").innerHTML = 'Correct';
} else {
document.getElementById("ap3").innerHTML = 'Incorrect';
}
}
</script>
</head>
<body>
1st sing<input type="text" name="s1"> <div id="as1"><br>
2nd sing<input type="text" name="s2"> <div id="as2"><br>
<!-- ...etc... -->
3rd pl<input type="text" name="p3"> <div id="ap3"><br>
<button onclick='check()'>Check Answers</button>
</body>
</html>
Every time I check answers it always says Incorrect and only shows the first question. I also need a way to clear the text fields after I check the answers. One of the answers has a macro. Thanks in advance.
The method getElementsByName returns a NodeList, you can't really compare that against a string. If you have only one element with such name, you need to grab the first element from that list using such code instead:
var s1 = document.getElementsByName('s1')[0].value;
To make it more flexible and elegant plus avoid error when you have typo in a name, first add such function:
function SetStatus(sName, sCorrect, sPlaceholder) {
var elements = document.getElementsByName(sName);
if (elements.length == 1) {
var placeholder = document.getElementById(sPlaceholder);
if (placeholder) {
var value = elements[0].value;
placeholder.innerHTML = (value === sCorrect) ? "Correct" : "Incorrect";
} else {
//uncomment below line to show debug info
//alert("placeholder " + sPlaceholder+ " does not exist");
}
} else {
//uncomment below line to show debug info
//alert("element named " + sName + " does not exist or exists more than once");
}
}
Then your code will become:
SetStatus('s1', 'ō', 'as1');
SetStatus('s2', 's', 'as2');
//...
document.getElementsByName('s1') is an array you should use document.getElementsByName('s1')[0] to get certain element(first in this case)

Categories