This is a follow up to my question, seen here
I am trying to write that when a user enters in their name (string) into the field and hits enter, it pushes it into an array. It works, kinda. But I get an error when I try it one and then it produces multiple arrays when I try it another. I don't want to use jQuery.
Here is the HTML
<input type="text"
class="theplayer pre"
name="Player"
id="bind"
placeholder="Enter Names"
/>
<button type="button" id="thego" class="pre enterteam" value="click">Go</button>
Here is my js that works but it creates multiple arrays instead of pushing everything into one array (because the nextElementSibling is not called, I know this, see next block
let namesOfPlayers = [];
let currentValue = document.getElementById("bind").value;
let button = currentValue.nextElementSibling;
document.addEventListener('keypress', function (e) {
const key = e.which || e.keyCode;
if (key === 13) {
namesOfPlayers.push(currentValue);
console.log('namesOfPlayers', namesOfPlayers);
}
});
Here is my js that throws an error (I don't want to use jQuery)
I want that when a user hits enter or clicks the button that the string is submitted and added into the empty array. I can't for the life of me figure out how to make that work.
Thanks for your help!
You fetch the value of the input too soon. You should fetch it only when the button is clicked, not before.
Secondly, the button does not have a keypress event, nor a keyCode associated with it. You need to listen to the click event.
So do this:
let namesOfPlayers = [];
let input = document.getElementById("bind");
let button = input.nextElementSibling;
button.addEventListener('click', function (e) {
namesOfPlayers.push(input.value);
console.log('namesOfPlayers', namesOfPlayers);
});
<input type="text"
class="theplayer pre"
name="Player"
id="bind"
placeholder="Enter Names" />
<button type="button" id="thego" class="pre enterteam" value="click">Go</button>
Try this code, i added a click (for the button) and keypress (for the text input) events
so if you click enter when you focus on the text input the text in the input will be in the array.
and the same will happen if you click "Go" button
let namesOfPlayers = [];
let currentElement = document.getElementById("bind");
let button = currentElement.nextElementSibling;
let addPlayer = () => {
namesOfPlayers.push(currentElement.value);
console.log(namesOfPlayers); // Just for testing
}
currentElement.addEventListener('keypress', function (e) {
if (e.which === 13 || e.keyCode === 13) {
addPlayer();
}
});
button.addEventListener('click', addPlayer);
<input type="text"
class="theplayer pre"
name="Player"
id="bind"
placeholder="Enter Names"
/>
<button type="button" id="thego" class="pre enterteam" value="click">Go</button>
CurrentValue is defined outside of the event listener, so it only gets called once, on initialisation. That's why the push call only injects empty strings. Also, the button doesn't do anything because it doesn't have a listener.
Here's the updated code:
let namesOfPlayers = [];
// It's better to get the button by id instead of getting it by a previous child.
// This is because it might cause some unexpected behaviour if someone changed the HTML.
const button = document.getElementById("thego");
button.addEventListener('click', function (e) {
addItemToArray(namesOfPlayers);
});
document.addEventListener('keypress', function (e) {
const key = e.which || e.keyCode;
if (key === 13) {
addItemToArray(namesOfPlayers);
}
});
function addItemToArray(namesOfPlayers) {
const currentValue = document.getElementById("bind").value;
namesOfPlayers.push(currentValue);
console.log('namesOfPlayers', namesOfPlayers);
}
https://fiddle.jshell.net/4k4a9m6y/
But, you're better off with a form to improve performance.
let namesOfPlayers = [];
const form = document.getElementById("form");
form.addEventListener('submit', function (e) {
const currentValue = document.getElementById("bind").value;
namesOfPlayers.push(currentValue);
console.log('namesOfPlayers', namesOfPlayers);
});
<form id="form"
action="javascript:void(0);">
<input type="text"
class="theplayer pre"
name="Player"
id="bind"
placeholder="Enter Names"
/>
<button type="submit" id="thego" class="pre enterteam" value="click">Go</button>
</form>
https://fiddle.jshell.net/4k4a9m6y/2/
Related
Here's my current setup:
I have a barcode scanner in keyboard mode. I am trying to scan to a hidden and out of focus input.
The barcode I am trying to read is as follows: asterisk [barcode-info] asterisk.
<form method="post">
<input type="hidden" name="action" value="barcode-scan"/>
<input type="hidden" name="barcode-input" value="" id="barcode-input" onchange="this.form.submit()" />
</form>
When a barcode input is made, Javascript should capture it and update the "barcode-input" hidden input, which will then submit itself to the server.
Someone recommended trying to use a paste event listener, but it simply didn't seem to capture the input at all.
Update: because of wonderful suggestions below, I've been able to get the input working! The form will test to see if two specific inputs follow each other, then it will execute the next function. Otherwise, it will erase any information contained in the log const. Ultimately, yes, I got this working correctly!
document.addEventListener('keyup', function(e){
const log = document.getElementById('barcode-input');
log.textContent += ' ' + e.code;
document.getElementById('barcode-input').value = log.textContent;
if (log.textContent.startsWith(' ShiftLeft')) {
if (log.textContent.startsWith(' ShiftLeft Backslash')) {
document.getElementById('barcode-input').form.submit();
console.log('e.code, submit barcode info');
}
}
else {
log.textContent = '';
document.getElementById('barcode-input').value = '';
}
});
Without an input[type="text"] element on the screen, you will need to capture the keyboard input manually. Something along the lines of:
document.addEventListener('keydown', (ev) => {
if (ev.ctrlKey || ev.altKey) return; // Ignore command-like keys
if (ev.key == 'Enter') {
// ...submit the content here...
} else if (ev.key == 'Space') { // I think IE needs this
document.getElementById('barcode-input').value += ' ';
} else if (ev.key.length == 1) { // A character not a key like F12 or Backspace
document.getElementById('barcode-input').value += ev.key;
}
});
That should get you most of the way...
Alternatively, rather than looking for events on the input or values of the input (*'s), define an event on the value and use the input event to simply set the value.
Once input has stopped, be it 1 second (or most likely much less) then fire off the form.
If you have to place the cursor into input, then scan. your prob only option is to use autofocus attribute and hide the input as you cant focus a hidden element, though you also cant focus multiple so keep that in mind if you're looking to scan into multiple inputs, then you will have to show the inputs, no way around it.
For example
let elm = document.querySelector('input[name="barcode-input"]')
// watcher on the value, after 1 second, it invokes an event, i.e post form
let timer = 0
Object.defineProperty(window, 'barcode', {
get: function () { return this.value },
set: function (value) {
clearTimeout(timer)
this.value = value
timer = setTimeout(() => {
console.log('Post form')
}, 1000) // do some tests, tweak if much less then 1 second to input the value
}
})
// it should trigger input even if its a keyboard
elm.addEventListener("input", e => barcode = e.target.value)
// ignore, below this line..
// set a value of barcode at intervals, only when its stopped entering (>1 second), then will it fire the callback
let i = 0
let t = setInterval(() => {
barcode = (barcode || '')+"X"
if (i >= 40) clearInterval(t)
i++
}, 100)
// ignore... grab value from hidden input, put in #current
setInterval(() => document.querySelector('#current').innerHTML = barcode, 1000)
<input type="text" name="barcode-input" autofocus style="display:none" />
<div id="current"></div>
Here's demonstrator using keypress that scans the incoming key stream for *[ and captures the barcode until it sees ]*. Then it sends the code to the server. Although I've reproduced the form in your HTML, the code here doesn't use it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Working...
<form method="post">
<input type="hidden" name="action" value="barcode-scan"/>
<input type="hidden" name="barcode-input" value="" id="barcode-input" onchange="this.form.submit()" />
</form>
<p id="response"></p>
<script>
(function(){
"use strict";
const bcAst = '*';
const bcLeft = '[' ;
const bcRight = ']';
let barcodeIncoming = false;
let lastChar = 0;
let barcode = '';
document.addEventListener('keypress', function(e){
function sendCode(barcode) {
console.log(barcode);
let fd = new FormData();
fd.append('barcode', barcode);
fetch('myFile.php', {
method: 'POST',
body: fd
})
.then(resp=>{
resp.text().then(txt=>{document.getElementById('response').innerText = txt;})
});
}
console.log(e.key);
switch (e.key) {
case bcAst:
if (barcodeIncoming && (lastChar === bcRight)) {
barcodeIncoming = false;
sendCode(barcode);
}
break;
case (bcLeft):
if (lastChar === bcAst) {
barcodeIncoming = true;
barcode = '';
}
break;
case (bcRight):
break;
default:
barcode += (barcodeIncoming)?e.key:'';
break;
}
lastChar = e.key;
});
})();
</script>
</body>
</html>
The current server file is very rudimetary, but serves the purpose here:
<?php
if (isset($_POST['barcode'])) {
echo "Your barcode is {$_POST['barcode']}";
} else {
echo "No barcode found";
}
Note - this has had only basic testing. You'll want to improve its resilience against possible collisions with similar data in the key stream.
transfrom
<input type="hidden" name="barcode-input" value="" id="barcode-input" onchange="this.form.submit()" />
in
<input type="test" name="barcode-input" value="" id="barcode-input" onchange="this.form.submit()" style="display:none;" />
I am trying to code a program which when a user inputs some numbers it will reverse it it and display it on the page. I have to tried to use 'Object.assign', but it doesn't work for me. I have also tried '.toArray', but it still doesn't work(maybe my formatting is wrong?). I am just a beginner so go easy on me. Thanks for t. This is what i have so far:
not working code but what i wanted
This works though:
Working code but not what i wanted
edit: when I reread the question, I realized you wanted the array in reverse. Updated answer at the bottom.
press enter to add the input. If you don't want only numbers delete type='number'.
var arr = [];
const input = document.getElementById('inpt');
input.addEventListener("keydown", event => {
if (event.keyCode === 13) {
arr[arr.length]=input.value;
input.value="";
console.log(arr);
}
});
<input placeholder="Enter a number" type='number' id ='inpt'/>
var arr = [];
const input = document.getElementById('inpt');
const output = document.getElementById('output');
input.addEventListener("keydown", event => {
if (event.keyCode === 13) {
arr[arr.length]=input.value;
input.value="";
var arr2= [...arr].reverse();
output.innerHTML='';
arr2.forEach(element => output.innerHTML+= element+' ');
console.log(arr);
}
});
<input placeholder="Enter a number" type='number' id ='inpt'/>
<div id = 'output'>
</div>
The issue here is that I have designed a basic website which takes in a users input on a form, what I then intend to do is print that value out to the console.log. however, when I check the console under developer tools in Google Chrome, all I get printed out is []length: 0__proto__: Array(0)
and not the value the user has inputted.
<input type="text" name="username" value="testuser">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
function error() {
var error1 = [];
var list_of_values = [];
username_error = $('input[name="username"]').val();
if (!username_error){
error1.push('Fill in the username field.');
}
console.log(error1);
if (error1.length > 0){
for(let username_error of error1){
alert(username_error);
return false;
}
}
string = $('input[name="username"]').val('');
if(string.length <= 1){
for (let list_of_values of string){
string.push();
}
console.log(string);
return true;
}
}
error();
</script>
Suggestion, you can make it actually things easier with the following code.
the function below scans all input fields under fieldset element
$("fieldset *[name]").each....
the issue above is multiple alert, what if you have a lot of inputs, it would alert in every input, which wont be nice for the users :) instead you can do this
alert(error1.toString().replace(/,/g, "\n"));
to alert the lists of errors at once.
string = $('input[name="username"]').val('');
that is actually clearing your value.. so it wont give you anything in console.log().
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset>
<input type="text" name="name" value="" placeholder="name"/><br/><br/>
<input type="text" name="username" value="" placeholder="username"/><br/><br/>
<button onclick="error()">check</button>
</fieldset>
<script>
function error() {
var error1 = [];
var list_of_values = [];
$("fieldset *[name]").each(function(){
var inputItem = $(this);
if(inputItem.val()) {
return list_of_values.push(inputItem.val());
}
error1.push('Fill in the '+inputItem.attr('name')+' field!')
});
if(error1.length > 0) {
console.log(error1);
alert(error1.toString().replace(/,/g, "\n"));
}
if(list_of_values.length > 0) {
console.log(list_of_values);
}
}
</script>
Register the <input> to the input event. When the user types anything into the <input> the input event can trigger an event handler (a function, in the demo it's log()).
Demo
Details commented in demo
// Reference the input
var text = document.querySelector('[name=username]');
// Register the input to the input event
text.oninput = log;
/*
Whenever a user types into the input...
Reference the input as the element being typed into
if the typed element is an input...
log its value in the console.
*/
function log(event) {
var typed = event.target;
if (typed.tagName === 'INPUT') {
console.log(typed.value);
}
}
<input type="text" name="username" value="testuser">
I have created a javascript script in which all clicks and action of a particular IP it tracked down when attached in a page. It all works fine except when the user searches something from an input field. I need to track that text which user has searched.
But I don't have any information regarding that input field i.e id or class also a page can have.
multiple input fields i.e A form for submission too.
I need to get that text when the enter key is pressed or any button(search) is pressed
In my case at present html page, I have below code.
<div class="navbar-form navbar-right">
<!-- Search Page -->
<div id="search-container" class="search-container" style="float: left;">
<div class="search-wrapper">
<div class="search-input-wrapper">
<input type="text" class="search-layouts-input" ng-model="searchQuery" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="So, what are you looking for?" ng-keyup="$event.keyCode == 13 ? actionSearch() : null">
<button type="submit" class="s-layout-btn" ng-click="actionSearch();">
<svg id="Layer_1" width="20px" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="#222">
<defs>
<style>.cls-1{fill:none;stroke:#222;stroke-miterlimit:10;stroke-width:2px;}</style>
</svg>
</button>
</div>
</div>
</div>
<!-- Search Page -->
</div>
Is this the kind of thing that you're looking to implement? Of course most of it is pseudo code, but it's pretty straight-forward, just get all relevant inputs and buttons and whatnot, attach some event handler to them and update the application state.
I've included some basic functions that you may wish to fire in certain scenarios, such as onStateUpdate, there may be no need for this function, but it probably wouldn't hurt to keep it for the sake of simplcity.
I've used mostly ES6 oriented syntax because it allows you to achieve the same results with less code, I'm just that lazy.
The reason why I used a self invoked function just so there's no issues with variable names and nothing can be manipulated on the global scope, etc. If you'd like to read or know more about why self invoked functions can be pretty good, then I suggest you read sources such as this.
// Self invoked anonymous function.
(function() {
// The application state.
const state = {};
// Lazy way to use querySelectorAll
const $e = qs => document.querySelectorAll(qs);
// Make a copy of the state and make it global.
const getState = () => {
window.state = { ...state};
console.clear();
console.log(window.state);
};
// A function to run when the state updates.
const onStateUpdate = () => {
// Do some other stuff...
getState();
};
// Handle the key up event.
const inputHandler = (i, index) => i.onkeyup = () => {
i.id == null || i.id == '' ? i.setAttribute("id", index) : null;
const id = i.id;
state[id] = i.value;
onStateUpdate();
};
// Handle a button being clicked.
const clickHandler = btn => btn.onclick = onStateUpdate;
// Handle the enter key being pressed.
const enterHandler = e => e.keyCode == 13 ? onStateUpdate() : null;
// Assign all relevant events to the relevant functions.
const dispatchEvents = () => {
const inputs = $e("#search-container input[type=text]");
const buttons = $e("#search-container button");
inputs.forEach((i, index) => inputHandler(i, index));
buttons.forEach(b => clickHandler(b));
window.onkeypress = enterHandler;
};
// Fire the dispatch function.
dispatchEvents();
}());
<!-- this one does nothing as it's outside of the search-container element -->
<input type="text" id="testing" placeholder="I do nothing!" />
<div id="search-container">
<input type="text" id="test" />
<input type="text" id="demo" />
<input type="text" id="markup" />
<input type="text" />
<button>Search</button>
</div>
Older Syntax
// Self invoked anonymous function.
(function() {
// The application state.
var state = {};
// Lazy way to use querySelectorAll
var $e = function(qs) {
return document.querySelectorAll(qs);
};
// Make a copy of the state and make it global.
var getState = function() {
window.state = JSON.parse(JSON.stringify(state));
console.clear();
console.log(window.state);
};
// A function to run when the state updates.
var onStateUpdate = function() {
// Do some other stuff...
getState();
};
// Handle the key up event.
var inputHandler = function(i, index) {
i.onkeyup = function() {
if (i.id == null || i.id == '') {
i.setAttribute("id", index);
}
var id = i.id;
state[id] = i.value;
onStateUpdate();
};
};
// Handle a button being clicked.
var clickHandler = function(btn) {
btn.onclick = onStateUpdate;
};
// Handle the enter key being pressed.
var enterHandler = function(e) {
if (e.keyCode == 13) {
onStateUpdate();
};
};
// Assign all relevant events to the relevant functions.
var dispatchEvents = function() {
var inputs = $e("input[type=text]");
var buttons = $e("button");
inputs.forEach(function(i, index) {
inputHandler(i, index)
});
buttons.forEach(function(b) {
clickHandler(b)
});
window.onkeypress = enterHandler;
};
// Fire the dispatch function.
dispatchEvents();
}());
<input type="text" id="test" />
<input type="text" id="demo" />
<input type="text" id="markup" />
<input type="text" />
<button>Search</button>
What I want is filtering user's input. Remove newline and limit its length.
I tried two methods.
https://jsfiddle.net/mj111/356yx1df/3/
html
<div>
<textarea id="text1" placeholder="write down"></textarea>
</div>
<div>
<textarea id="text2" placeholder="write down"></textarea>
</div>
script
document.getElementById('text1')
.addEventListener('input', function (evt) {
evt.preventDefault(); // prevent value change
const msg = evt.target.value.replace(/\n/g, '')
if (msg.length <= 10) {
document.getElementById('text1').value = msg
}
})
document.getElementById('text2')
.addEventListener('input', function (evt) {
const msg = evt.target.value.replace(/\n/g, '').slice(0, 10)
document.getElementById('text2').value = msg
})
First one is not working, because preventDefault is not working. As MDN doc says. 'input' event is not cancelable.
So, I tried second method; just overwrite textarea value.
I think there's a better way to do this. If anyone has a good idea, please answer.
use keyup event to limit length or you can just add maxlength manually to the HTML as an attribute. If you want to set it dynamically you can use Element.setAttribute. For preventing new lines you can prevent the return key, as long as it is not shift. You can still use replace to replace things you feel need replacing, a regular expression will most effectively get the job done.
var text = document.getElementsByTagName('textarea');
var text1 = text[0];
var text2 = text[1];
text1.addEventListener('keydown', function(event) {
let val = event.target.value;
let limit = 25;
// limit the value once you reach a particular length
if (val.length > 3) {
event.target.value = val.substr(0, limit)
};
// prevent new line by preventing enter key press
if (event.keyCode === 13 && !event.shiftKey) {
event.preventDefault();
alert('no new lines please');
return false;
}
// and you can filter with replace
})
<div>
<textarea id="text1" placeholder="write down"></textarea>
</div>
<div>
<textarea id="text2" placeholder="write down"></textarea>
</div>