Trying to make a web page that will get each letter a user inputs and output it in a phonetic alphabet. For example (user types: Hello)(Output: Hotel , Echo , Lima, Lima, Oscar). This is what I have so far just need some guidance on how to get the value of each letter and compare it to like an Array to get the output.
//define UI variables
const userInput = document.querySelector('#input');
const phoneticAlphabet = ["Alpha"," Bravo","Charlie"];
//load all event listeners
loadEventListeners();
function loadEventListeners() {
//add submit event
form.addEventListener('submit', submitInput);
}
//submit user input
function submitInput(e) {
console.log(userInput.value);
if (userInput.value === '') {
alert('Add Input');
}
e.preventDefault();
}
I presume that you would like to replace non-convertible characters from the input. For the same, I am using regular expression. I have also added the response in a "p" tag. And the code runs on clicking "Submit".
Update:
Extended my array for all alphabets :)
Update 2:
Thanks #CharlieBatista for pointing out. Now, the input accepts uppercase characters as well.
//define UI variables
const form = document.phoneticForm;
const userInput = document.querySelector('#input');
const output = document.querySelector('#output');
const phoneticAlphabet = ['Alpha','Bravo','Charlie','Delta','Echo','Foxtrot','Golf','Hotel','India','Juliet','Kilo','Lima','Mike','November','Oscar','Papa','Quebec','Romeo','Sierra','Tango','Uniform','Victor','Whiskey','X-ray','Yankee','Zulu'];
//load all event listeners
loadEventListeners();
function loadEventListeners() {
//add submit event
form.addEventListener('submit', submitInput);
}
//submit user input
function submitInput(e) {
e.preventDefault();
var value = userInput.value;
if (value === '') {
alert('Add Input');
} else {
value = value.replace(/[^a-zA-Z]/gi,'');
userInput.value = value;
value = value.toLowerCase();
var outputArr = [];
for(var i = 0; i < value.length; i++){
outputArr.push(phoneticAlphabet[value.charCodeAt(i)-97]);
}
output.innerHTML = outputArr.join(', ');
}
}
<form name="phoneticForm">
<input type="text" id="input">
<input type="submit">
</form>
<p id="output"></p>
You can use the key property on the keydown event of the field to get the character that was pressed.
Then check if the key is a printable key using key.length === 1 (see this answer).
If the key is printable, convert it to uppercase, then to its character code using String.prototype.charCodeAt() and then subtract 65 from it (character A). This will give you the index in your array.
If this index is within the bounds of the array, access the array and print the character.
const phoneticAlphabet = ['Alpha','Bravo','Charlie','Delta','Echo','Foxtrot','Golf','Hotel','India','Juliet','Kilo','Lima','Mike','November','Oscar','Papa','Quebec','Romeo','Sierra','Tango','Uniform','Victor','Whiskey','X-ray','Yankee','Zulu'];
document.querySelector('#input').addEventListener('keydown', e => {
const isPrintable = e.key.length === 1;
console.clear();
if (isPrintable) {
const idx = e.key.toUpperCase().charCodeAt(0) - 65;
if (idx >= 0 && idx < phoneticAlphabet.length) {
const phoneme = phoneticAlphabet[idx];
console.log(phoneme);
}
}
});
<input type="text" id="input">
Related
I have three inputs and three variables, my goal is to change variables values with the values inside the inputs
const inputs = [
document.querySelector(".bill-input"),
document.querySelector(".custom"),
document.querySelector(".people-number"),
];
var bill = 0;
var tip = 0;
var people = 0;
i accomplished to do it this way
inputs[0].addEventListener("keyup", (e) => {
bill = Number(e.target.value);
});
inputs[1].addEventListener("keyup", (e) => {
tip = Number(e.target.value);
});
inputs[2].addEventListener("keyup", (e) => {
people = Number(e.target.value);
});
I'm pretty sure this is not the optimal way to do it, so i wanted to ask if there's a way to do it with forEach or any other method that does not require for me to write every single one each time.
Add a data attribute to each input.
Use an object to maintain the state of those inputs instead of n variables.
Have one handler that can update the object properties based on their id.
// Initialise the values object
const values = { bill: 0, tip: 0, people: 0 };
// Cache the inputs, and add listeners to them
const inputs = document.querySelectorAll('input');
inputs.forEach(input => input.addEventListener('keyup', handleChange));
// Grab the id from the input's dataset, and
// set the values object property to match
// the input value
function handleChange() {
const { id } = this.dataset;
values[id] = this.value;
console.log(JSON.stringify(values));
}
input { display: block; }
Bill<input data-id="bill">
Tip <input data-id="tip">
People <input data-id="people">
Additional documentation
Destructuring assignment
Yes, you can use forEach. I used a switch to get the index of the input element (in inputs const) to know what variable update.
Please see snippet below :
var bill = 0;
var tip = 0;
var people = 0;
const inputs = [
document.querySelector(".bill-input"),
document.querySelector(".custom"),
document.querySelector(".people-number"),
];
inputs.forEach(function(item,index){
item.addEventListener("keyup", (e) => {
const val = Number(e.target.value);
switch(index){
case 0 : bill = val; break;
case 1 : tip = val; break;
case 2 : people = val; break;
}
console.log(bill,tip,people)
});
});
<input value="3" type="number" class="bill-input">
<input value="10" type="number" class="custom">
<input value="100" type="number" class="people-number">
I have a controlled <input /> in my React application where the user would type.
I want to keep track on it and replace the occurrences of $.text and $.lang to random hashes/number.
from
let string = 'I may have multiple $.text and $.lang like $.textand$.lang';
I want all occurrences of $.text and $.lang to have a random number(or anything unique):
to
updatedString = 'I may have multiple 123 and 245 like 744and111';
What I have done so far
let temp = value.split('').reverse().join(''); // reverse it to find the latest occurrence
let reText = /txet.\$/i;
let reLang = /gnal.\$/i;
let updated;
if (value.includes('$.text')) {
updated = temp.replace(reText, `${hash}#`); // replace the latest occurrence
} else {
updated = temp.replace(reLang, `${hash}#`); // replace the latest occurrence
}
updatedValue = updated.split('').reverse().join(''); // re reverse it
The issue is it replaces the but onChange RESETS the input state and it only changes the last occurrence of it.
So im doing it on click. So lets say user type something and then clicking on Replace Template button will replace the $.text and $.lang by some random number. You can insert your specific hash or number if needed.
const replaceTemplateByRandom = (val, temp) => {
while(val.indexOf(temp) != -1){
const numb = Math.floor(Math.random()*1000);
val = val.replace(temp, numb);
}
return val;
}
inside this arrow function I'm running the while loop till we find the template to replace, and replace occurrence by random number.
const replaceTemplateByRandom = (val, temp) => {
while(val.indexOf(temp) != -1){
const numb = Math.floor(Math.random()*1000);
val = val.replace(temp, numb);
}
return val;
}
function App(props){
const [val, setVal] = React.useState('default text is $.text, and language is $.lang.');
const updateVal = (e) => {
const newVal = e.target.value;
setVal(newVal);
}
const replaceTemplate = ()=>{
let currentVal = val;
currentVal = replaceTemplateByRandom(currentVal, '$.text');
currentVal = replaceTemplateByRandom(currentVal, '$.lang');
setVal(currentVal);
}
return <div>
<input type="text" value={val} onChange={updateVal} style={{"width":"100%"}}/>
<button onClick={replaceTemplate}>Replace Template</button>
</div>;
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
You can make use of .replace()'s acceptance of a function for custom and dynamic substitution:
function myHashFunction(match)
{
// Uncomment this line to see the various matches coming through
//console.log(match);
// I'm just returning a random number, you need to change this to your hash algorithm
return Math.floor(Math.random() * Math.floor(999999999999));
}
let str = `I may have multiple $.text and $.lang like $.textand$.lang`;
console.log(str.replace(/\$\.(?:text|lang)/g, myHashFunction));
function myFunction() {
var theString = "How are $.you doing $.you today?";
var splitString = theString.split("$.you");
var joinedString = "";
for(index = 0; index < splitString.length-1; index++){
joinedString += splitString[index] + Math.random();
}
document.getElementById("demo").innerHTML = joinedString;
}
Something simple like this could probably do the job.
So spliting the string into an array of strings and then joining it back with a specific string.
Not React specifically, but the idea is there.
I'm using a function that if the user left any input empty then it should print an error msg, otherwise it should be submitted.
I was testing this below code for the name input only and it works that if I left the input empty it will show an error, otherwise it will do submit.
let submitFORM = document.forms[0][4].addEventListener("click", val);
let name = document.forms[0][0];
let error = document.getElementById("error");
function val() {
if (!name.value) {
error.innerHTML = "Error";
return false;
} else {
document.forms[0].submit();
}
}
But since I have multiple inputs, I would like to check on all of them, what I did here I add a for loop and store all the messages that like if the user left three inputs empty then it would print three statements of the error ..
Otherwise, if the user filled all the inputs, then it should submit it ..
but the issue is I miss something that because if I fill one of the inputs only it will do submit! what should I do to stop doing submitting unless all the values aren't empty?
let submitFORM = document.forms[0][4].addEventListener("click", val);
let name = document.forms[0][0];
let error = document.getElementById("error");
function val() {
let allinputs = document.forms[0].querySelectorAll('input');
let item = "";
let i;
let stat = true;
for(i = 0; i < t.length - 1; i++){
if(!t[i].value){
item += "your " + t[i].getAttribute('name') + " shouldn't be blank !";
stat = false;
}else{
stat = true;
document.forms[0].submit();
}
}
error.innerHTML = item;
}
It's because, you are calling submit inside for loop, submit will be called on first valid input.
You can refactor like this:
const invalidInputs = allInputs.map(input => !input.value);
invalidInputs.forEach((input) => {
item += "your " + input.getAttribute('name') + " shouldn't be blank !";
});
if (invalidInputs.length === 0) {
document.forms[0].submit();
}
HTML has the required attribute to accomplish this. If you set any input to be required, modern browsers won't let you submit the form if those fields are empty.
<input type="text" name="name" required="required">
Is there any specific reason why you want to do it from javascript?
If you still want to use your solution, you need to adjust the "submit" part to be out of the loop, something like this:
let submitFORM = document.forms[0][4].addEventListener("click", val);
let name = document.forms[0][0];
let error = document.getElementById("error");
function val() {
let allinputs = document.forms[0].querySelectorAll('input');
let item = "";
let shouldSubmit = true;
for(let i = 0; i < allinputs.length - 1; i++){
if(!allinputs[i].value){
item += "your " + allinputs[i].getAttribute('name') + " shouldn't be blank !";
shouldSubmit = false;
}
}
if (shouldSubmit) {
document.forms[0].submit();
}
error.innerHTML = item;
}
From what i see, you submit too soon, you should first test every input in your for loop, set a boolean to false as soon as you find a missing value. And only then, outside the loop, check if this boolean is set to true and submit if it is.
Maybe try to check all the input fields in a single if statement.
if(!t[0].value && !t[1].value && !t[2].value){}
Something like this
I've been on this all day.
HTML Code
<label>Input values</label>
<input type="text" id="arrays" placeholder="Enter Array" >
<button id="objectify" type= "button">Click</button>
<div id="results"></div>
JavaScript
var input= document.getElementById('arrays').value; //["book", 3, "pin", 4];//
var btn = document.getElementById('objectify');
var output = document.getElementById('results');
function objectifyArr(x) {
var myObject = {
String: [],
Number: []
};
for (var i = 0; i < x.length; i++) {
if (typeof x[i] === 'string' || x[i] instanceof String){
myObject.String.push(x[i]);
} else if (typeof x[i] === 'number' || x[i] instanceof Number){
myObject.Number.push(x[i]);
}
}
return myObject;
}
btn.onclick = function () {
output.textContent = JSON.stringify(objectifyArr(inputValue));
}
The code seems to work when I assign 'inputValue' a range of array values but doesn't when I get the array via getElementbyId.value. Is there an input type for arrays specifically or did I assign the wrong value to my variable?
Regardless of what the mistake is, I'll be glad if someone pointed it out for me.
How about just using JSON.parse() and waiting to get the value of the input until you actually click the button?
Also (FYI), label requires that you either nest the element that it is a label for within it or that you add the for attribute and give it the value of the id of the element that it is a label "for".
var input= document.getElementById('arrays'); //["book", 3, "pin", 4];//
var btn = document.getElementById('objectify');
var output = document.getElementById('results');
btn.addEventListener("click", function () {
let myArray = JSON.parse(input.value);
output.textContent = myArray;
console.log(myArray);
});
<label for="arrays">Input values</label>
<input id="arrays" placeholder="Enter Array" value='["book", 3, "pin", 4]'>
<button id="objectify" type= "button">Click</button>
<div id="results"></div>
Your first problem is that you declare this in the top of your JS file:
var input= document.getElementById('arrays').value
This is literally saying "assign the current value of the element to my input variable". Obviously, the input element at the start of the script is empty, therefore the value is ''.
After that, the other problem is that as your input only accepts text, all the characters inside will be String type, so looping and checking for the typeof of each character will always yield it as a String.
A workaround for that would be using a RegExp.
Here's a working JSFiddle
I want to detect if a user types one of the strings of my list and then output in what string the user typed in the console.
HTML
<input id="input"></input>
JS
window.onload = function(){
var input = document.getElementById('formula');
var strings = ["string1", "string2", "string3", "string4"]
formula.onkeypress = function (e) {
if (input.value.includes(strings)) {
console.log("Input contains a the string:" + string???)
}
};
}
Try using String.indexOf() and Array.filter()
window.onload = function() {
var strings = ["string1", "string2", "string3", "string4"];
/* replaced `formula` with `input` */
document.getElementById('input').oninput = function(e) {
var find = this.value;
if (0 < find.length) {
var matches = strings.filter(function(s) {
return -1 !== s.indexOf(find);
});
console.log('find string', find, ', matches found', matches);
}
};
};
<input id="input" />
You are fetching element by the wrong ID. The ID of the input is input, and not formula. Ignoring this typo, you need to check the inclusion in the array instead. Replace this:
if (input.value.includes(strings)) {
with this:
if (strings.includes(input.value)) {
Additionally, using keypress event doesn't serve the purpose as the updated value will be fetched after you press one more key. Use oninput instead.
Edit 1:
You can use Array#some to check if the input value contains any string from the array.
window.onload = function() {
var input = document.getElementById('input');
var strings = ["string1", "string2", "string3", "string4"]
input.oninput = function(e) {
if (strings.some(str => input.value.includes(str))) {
console.log("Input contains a the string:" + input.value)
}
};
}
<input id="input"></input>
use like it:-
formula.onkeypress = function (e) {
if (strings.includes(input.value)) {
console.log("Input contains a the string:" + input.value)
}
};
There are several issues in your code:
The id is incorrect for input element
You need to use onkeyup event to get the immediately typed character
You need to use includes() in array type variable.
window.onload = function(){
var input = document.getElementById('formula');
var strings = ["string1", "string2", "string3", "string4"]
input.onkeyup = function (e) {
if (strings.includes(input.value)) {
console.log("Input contains a the string:" + input.value)
}
};
}
<input id="formula" />
If you want to make an autocomplete form : Autocomplete