onchange not working with input field selected by class name - javascript

When I select the input field element by class name, the onchange event is not working. I want to change the value of the current changed input field. Codes are below:
// change current input field
function upperCase() {
// change current change input field
let x = document.getElementsByClassName('fname');
x.value = x.value.toUpperCase();
}
// call function when current element change
document.getElementsByClassName('fname').onChange = upperCase;
<input type="text" class="fname">
<input type="text" class="fname">
<input type="text" class="fname">
<input type="text" class="fname">
Please, I also want to change the value of the current change input field.

document.getElementsByClassName returns a collection of elements, but you're trying to access the value like a single element.
You need to access each individual element, like this:
let inputs = document.getElementsByClassName('fname');
inputs[0].value = inputs[0].value.toUpperCase();
or even better would be to loop through them:
let inputs = document.getElementsByClassName('fname');
for (let i of inputs) {
i.value = i.value.toUpperCase();
}
edit to add the event it should be the same idea:
function upperCase() {
// change current change input field
let inputs = document.getElementsByClassName('fname');
for (let i of inputs) {
i.value = i.value.toUpperCase();
}
}
let inputs = document.getElementsByClassName('fname');
for (let i of inputs) {
i.addEventListener('change', upperCase);
}
<input type="text" class="fname">
<input type="text" class="fname">
<input type="text" class="fname">
<input type="text" class="fname">

let x = document.getElementsByClassName('fname'); returns an array of objects, you need to work with the values of the array, for example:
let arrayFName = document.getElementsByClassName('fname');
for (let i of arrayFName) {
i.value = i.value.toUpperCase();
}
And the same happens with the onchange property:
for (let j of arrayFName) {
j.onChange = upperCase;
}
Hope it helps!

Replace your
document.getElementsByClassName('fname').onChange = upperCase;
with
const selectElement = document.querySelector('.fname');
selectElement.addEventListener('change', () => {
upperCase();
});

As others point out, when you have more then one element you should illiterate all and call function when it change. So basically something like this will do the work:
var x = document.getElementsByClassName('fname');
for (var i=0; i < x.length; i++) {
x[i].addEventListener('change', changeToUpperCase);
}
function changeToUpperCase(t) {
this.value= this.value.toUpperCase().replace(/ /g,'');
}
<input type="text" class="fname">
<input type="text" class="fname">
<input type="text" class="fname">
<input type="text" class="fname">

Related

Disable input field if is already filled Javascript (Sudoku)

I am bulding a Sudoku Solver. All fields of the sudoku can be edited. When the user clicks on "New Sudoku" some of those fields are filled with numbers. At the moment these "filled" fields can still be edited by the user. I want them to be disabled so that the number of the "filled" fields can not be changed.
I am a beginner and grateful for any help :)
My sudoku so far
function createField(event) {
let gridCont;
let fieldCont;
let sudokuBox = document.getElementById("sudokuBox");
gridCont = document.createElement("div");
gridCont.classList.add("grid-cont");
for(row=1; row<=9; row++) {
fieldCont = document.createElement("div") //The 3x3 grid
fieldCont.classList.add("field-cont");
fieldCont.classList.add("indexBig"); //gives index (3x3)
for(col=1; col<=9; col++) {
let dataCell = document.createElement("input")
dataCell.classList.add("sudoku-cell");
dataCell.classList.add("data-cell");
dataCell.classList.add("indexSmall");
fieldCont.appendChild(dataCell);
}
gridCont.appendChild(fieldCont);
}
sudokuBox.appendChild(gridCont);
}
function populateSudoku(JObject){
let fill = document.querySelectorAll(".indexBig");
JObject.sudokuJSON.forEach((bigCellEl, i)=> {
bigCellEl.forEach((cellNumb, j)=> {
if(cellNumb > 0){
fill[i].children[j].value=cellNumb;
//cellNumb.disabled = true; My first idea, but it doesn't work...**
}
});
});
}
You can use the readonly property:
fill[i].children[j].readonly = true;
You could attach event.preventDefault() to onkeydown for all the generated inputs:
const createNew = () => {
//irrelevant
let inputs = document.querySelectorAll("input");
let random = Math.floor(inputs.length * Math.random());
let input = inputs[random]
input.value = Math.round(Math.random() * 10);
//attach prevent default on keydown
input.onkeydown = (event) => event.preventDefault();
}
<input type="text"/>
<input type="text"/>
<input type="text"/>
<input type="text"/>
<input type="text"/>
<input type="text"/>
<input type="text"/>
<input type="text"/>
<button onclick="createNew()">Click</button>

Javascript get value of current number input field

I am trying to make a shopping cart. Now i want to update the price of the item when the amount is changed, but when there are more than one items the onchange method only reacts on the first one. They have the same name. I can give them an other name but how will i then get the name of that input field.
I hope someone can help me with this.
Thanks in advance.
function updatePrice() {
var element = this;
console.log(element.value);
}
Your onchange event should iterate over all input fields.
If you give your fields a common identifier (a data-id attribute or a class name), then the process is quite trivial:
document.body.addEventListener("change", ()=> calc());
function calc(){
let items = document.querySelectorAll(".inp");
let total = 0.0;
for (let i = 0; i < items.length; i++) {
total += parseFloat(items[i].value);
}
document.querySelector(".result").value = total.toFixed(2);
}
calc();
<input type="text" class="inp" value="10.00">
<input type="text" class="inp" value="15.00">
<input type="text" class="inp" value="50.99">
<p>Result: <input type="text" class="result" value="00.00"></p>

Search for equal numbers or alphanumeric values inserted in input elements

I want to loop through all the input elements and find if the same value exists.
For example when a user inserts 1(one) and then inserts again the number 1(one), I would like to apply CSS to change the background color of the input element for these 2 equal values or no matter how many they may be.
If the user tries to insert an alphanumerical value then JavaScript handles the code and adds the selected-wrong-input CSS class.
I would like on that element to have a setInterval for 2 seconds and take out the alphanumerical value from the input in order for the user to be able to insert a number again.
I don't mind if the proposed solution is with JavaScript, jQuery or a combination of both.
The html code:
<div class="bus-builder-seat-box-container" id="dynamic-bus-builder-1">
<input id="posA100" type="text" class="input seat_box" onchange="bc.seatBoxHandleEvent(this)">
<input id="posA101" type="text" class="input seat_box" onchange="bc.seatBoxHandleEvent(this)">
<input id="posA102" type="text" class="input seat_box" onchange="bc.seatBoxHandleEvent(this)">
<input id="posA103" type="text" class="input seat_box" onchange="bc.seatBoxHandleEvent(this)">
<input id="posA104" type="text" class="input seat_box selected" onchange="bc.seatBoxHandleEvent(this)">
<input id="posA105" type="text" class="input seat_box selected" onchange="bc.seatBoxHandleEvent(this)">
<input id="posA106" type="text" class="input seat_box selected" onchange="bc.seatBoxHandleEvent(this)">
<input id="posA107" type="text" class="input seat_box selected-wrong-input" onchange="bc.seatBoxHandleEvent(this)">
</div>
The JavaScript code. The first is the event which is called in the html input element onchange
bc.seatBoxHandleEvent = function (el) {
bc.checkInput(el);
var seatNumberFirstFloor = $('#dynamic-bus-builder-1');
if (seatNumberFirstFloor && seatNumberFirstFloor.valueOf()) {
var leftStreaming = (event.target.id);
var rightStreaming = 'posB1' + leftStreaming.substring(5, 7);
document.getElementById(rightStreaming).innerHTML = event.target.value;
}
}
bc.checkInput = function (el) {
let $el = $(el);
var targetValue = event.target.value;
var id = event.target.id;
var classOfInput = event.target.classList;
if (targetValue !== 8 && targetValue !== 0 && (targetValue < 48 || targetValue > 57)) {
console.log('valid number');
console.log(classOfInput);
$(el).toggleClass('selected');
}
else {
console.log('invalid character');
$(el).toggleClass('selected-wrong-input');
//console.log(el.value);
}
var array = new Array(120);
var existsValue = false;
for(var i = 0; i <= array.length; i++) {
console.log(el.value);
console.log(i);
if (el.value === array[i]) {
console.log('hi');
console.log(el.value);
console.log(array[i]);
var existsValue = true;
console.log('existsValue');
console.log('equal number forbidden');
//break;
}
}
I'd suggest to use IsNaN() function to check if the input is a number. Also a keyup event is better for input fields.
var inputList = [];
$('.seat_box').keyup(function(elem){
if(IsNaN(elem.value)) return; //input isn't numeric, add your functionality
if (!valueExists(elem)) inputList.push(elem.value);
else //dublicate value, add functionality
});
function valueExists(elem) {
$(".seat_box").each(function(elem) {
if ($.inArray(this.value, inputList) != -1) return true;
else return false;
});
}

JavaScript form same values

How can I make a form so they cannot repeat the same values in the Input?
I tried a way like:
var text1 = document.getElementById('num1').value;
var text2 = document.getElementById('num1').value;
var textform = [text1,text2];
if (
text1 == text2 ||
text2 == text1
) {
alert("repeated numbers");
return false;
}
But this is gets me into two troubles:
- If I put no value, it will say: Repated Numbers
- If I want to make this for 100 form values, it takes a lot of code
You could give all of your text elements the same class, and grab their values by class name to simplify building the array of text values.
<input type="text" class="checkDupe" id="input1" />
<input type="text" class="checkDupe" id="input2" />
Then grab their values in javascript
var checkDupes = document.getElementsByClassName('checkDupe');
var textArray = [];
for(var i = 0; i < checkDupes.length; i++){
textArray.push(checkDupes[i].value);
}
Now that we have an array of values that they entered, check to see if any of them repeat by sorting the array, and seeing if any two elements side-by-side are the same.
textArray.sort();
var dupes = false;
for(var i = 0; i < textArray.length; i++){
if(textArray[i] === textArray[i + 1]) dupes = true;
}
If we find any duplicates, let the user know.
if(dupes) alert('Repeated numbers!');
You could do something like this:
var text1 = document.getElementById('num1').value;
var text2 = document.getElementById('num2').value;
var textform = [text1, text2];
var seen = {};
textform.forEach(function(value) {
if (seen[value]) {
alert('Bad!');
}
seen[value] = true;
});
In the code above, we loop over each value in the array. The first time we encounter it, we push it into a map. Next time (if) we hit that value, it will exist in the map and it will tell us we've seen it before.
If you give all the input's a common class then you quickly loop through them.
The HTML:
<input type="text" name="num1" class="this that number"></input>
<input type="text" name="num2" class="this number"></input>
<input type="text" name="num3" class="that number"></input>
<input type="text" name="num4" class="number"></input>
<input type="text" name="num5" class=""></input> <!-- we don't want to check this one -->
<input type="text" name="num6" class="number that this"></input>
<input type="text" name="num7" class="this that number"></input>
The JavaScript:
// get all the inputs that have the class numbers
var ins = document.querySelectorAll("input.numbers");
// a tracker to track
var tracker = {};
// loop through all the inputs
for(var i = 0, numIns = ins.length; i < numIns; ++i)
{
// get the value of the input
var inValue = ins[i].value.trim();
// skip if there is no value
if(!inValue) continue;
// if the value is already tracked then let the user know they are a bad person
// and stop
if(tracker[inValue])
{
alert("You are a bad person!");
return;
}
// track the value
tracker[inValue] = true;
}
You could also enhance this to let the user know which inputs have duplicate values:
// get all the inputs that have the class numbers
var ins = document.querySelectorAll("input.numbers");
// a tracker to track
var tracker = {};
// loop through all the inputs
for(var i = 0, numIns = ins.length; i < numIns; ++i)
{
// get the value of the input
var inValue = ins[i].value.trim();
// skip if there is no value
if(!inValue) continue;
// if the value is already tracked then error them
if(tracker[inValue])
{
// mark the current input as error
ins[i].className += " error";
// mark the first found instance as an error
ins[tracker[inValue]].className += " error";
}
// save the index so we can get to it later if a duplicate is found
tracker[inValue] = i;
}
Here's a way of doing it that automatically picks up all the text inputs in your document and validates based on what you're looking for. Would be simple enough to expose the valid value and make this the validation handler (or part of one) that handles a form submission.
<meta charset="UTF-8">
<input id="num1" type="text" value="foobar1">
<input id="num2" type="text" value="foobar2">
<input id="num3" type="text" value="foobar3">
<input id="num4" type="text" value="foobar4">
<input id="num5" type="text" value="foobar5">
<button onClick="checkValues();">Validate</button>
<script>
function checkValues() {
var inputs = document.getElementsByTagName('input');
arrInputs = Array.prototype.slice.call(inputs);
var valid = true;
var valueStore = {};
arrInputs.forEach(function(input) {
if (input.type == 'text') {
var value = input.value.toUpperCase();
if (valueStore[value]) {
valid = false;
} else {
valueStore[value] = true;
}
}
});
if (valid) {
alert('Valid: No matching values');
} else {
alert('Invalid: Matching values found!');
}
}
</script>
With jquery you can iterate directly over the inputs.
<form>
<input type="text" >
<input type="text" >
<input type="text" >
<input type="text" >
<input type="text" >
<input type="text" >
<button>
TEST
</button>
</form>
function checkValues(){
var used = {};
var ok = true;
$('form input[type="text"]').each(function(){
var value = $(this).val();
if(value !== ""){
if(used[value] === true){
ok = false;
return false;
}
used[value] = true;
}
});
return ok;
}
$('button').click(function(event){
event.preventDefault();
if(!checkValues()){
alert("repeated numbers");
};
});
https://jsfiddle.net/8mafLu1c/1/
Presumably the inputs are in a form. You can access all form controls via the form's elements collection. The following will check the value of all controls, not just inputs, but can easily be restricted to certain types.
If you want to include radio buttons and checkboxes, check that they're checked before testing their value.
function noDupeValues(form) {
var values = Object.create(null);
return [].every.call(form.elements, function(control){
if (control.value in values && control.value != '') return false;
else return values[control.value] = true;
});
}
<form id="f0" onsubmit="return noDupeValues(this);">
<input name="inp0">
<input name="inp0">
<input name="inp0">
<button>Submit</button>
</form>
For old browsers like IE 8 you'll need a polyfill for every.
You can simply get all inputs iterate them twice to check if they are equals
var inputs = document.getElementsByTagName('input');
for (i = 0; i < inputs.length; i++) {
for (j = i + 1; j < inputs.length; j++) {
if (inputs[i].value === inputs[j].value) {
console.log('value of input: ' + i + ' equals input: ' + j);
}
}
}
<input value="56" />
<input value="12" />
<input value="54" />
<input value="55" />
<input value="12" />

Form element values equal to another form values using a loop

I want to have text field values in one form equal to another form values when a radio button is checked. I can do it manually, but is there a way to do it using a loop? Thanks in advance!
<script type"text/javascript>
function setfields()
{
var radioSel = document.getElementById('radioChoice');
if(radioSel.checked)
{
//loop to set fields
}
}
</script>
<input name="radioChoice" type="radio" id="radioChoice" onChange="setFields">
<field set>
First Name:<input id="fname1" name="fname1" type="text"><br>
Last Name:<input id="lname1" name="lname1" type="text"><br>
</field set>
<!--make second field set values equal to first field set values-->
<field set>
First Name:<input id="fname2" name="fname2" type="text"><br>
Last Name:<input id="lname2" name="lname2" type="text"><br>
</field set>
You can specify the names (except the trailing 1 or 2) in an array and iterate through that:
var names = ['fname', 'lname', ...];
for (var i = 0; i < names.length; i++) {
var src = document.getElementById(names[i] + '1');
var dst = document.getElementById(names[i] + '2');
dst.value = src.value;
}
Or you could find the names yourself by iterating through children of the <field> block -- let's assume you've given the first one id="fields1":
var fields = document.getElementById('fields1').childNodes;
for (var i = 0; i < fields1.length; i++) {
if (fields[i].nodeType == 1 /*ELEMENT_NODE*/ && fields[i].tagName == 'input') {
var baseId = fields[i].id.substr(0, fields[i].id.length - 1);
document.getElementById(baseId + '2').value = fields[i].value;
}
}

Categories

Resources