When you check an item, it stores the value into an array. When you uncheck the item, it creates an undefined value within the array.
This is not too much of an issue, but having the empty value inside the array counts as a length value which I'm trying to remove. I'm wondering how to remove unchecked array items without storing them as undefined inside the array.
const list = Array.from(document.querySelectorAll("input[type='checkbox']"));
const specArr = []
function check(e) {
// a) If checked than add value into array
if (e.target.checked == true) {
specArr.push(`${e.target.value}`);
console.log(specArr);
// b) If unchecked than remove index from array
} else if (e.target.checked === false) {
let index = specArr.indexOf(e.target.value);
if (index != -1) {
delete specArr[index]
console.log(specArr);
}
}
}
list.forEach(function (listItems) {
listItems.addEventListener('change', check)
})
<form class="form specialization">
<p> <u> Select Item </u> </p>
<br>
<div class="list">
<div class="list-items">
<input type="checkbox" name="specialization" value = "Item-1">Item-1
<br>
<input type="checkbox" name="specialization" value="Item-2">Item-2
<br>
<input type="checkbox" name="specialization" value="Item-3" >Item-3
<br>
<input type="checkbox" name="specialization" value="Item-4" >Item-4
</div>
</form>
You are using delete. As per the delete docs:
Non-configurable properties cannot be removed. This includes properties of built-in objects like Math, Array, Object and properties that are created as non-configurable with methods like Object.defineProperty().
delete deletes the object property, but does not reindex the array or update its length.
Use Array.prototype.splice() instead.
const list = Array.from(document.querySelectorAll("input[type='checkbox']"));
const specArr = []
function check(e) {
// a) If checked than add value into array
if (e.target.checked == true) {
specArr.push(`${e.target.value}`);
console.log(specArr);
// b) If unchecked than remove index from array
} else if (e.target.checked === false) {
let index = specArr.indexOf(e.target.value);
if (index != -1) {
specArr.splice(index, 1);
console.log(specArr);
}
}
}
list.forEach(function(listItems) {
listItems.addEventListener('change', check)
})
<form class="form specialization">
<p> <u> Select Item </u> </p>
<br>
<div class="list">
<div class="list-items">
<input type="checkbox" name="specialization" value="Item-1">Item-1
<br>
<input type="checkbox" name="specialization" value="Item-2">Item-2
<br>
<input type="checkbox" name="specialization" value="Item-3">Item-3
<br>
<input type="checkbox" name="specialization" value="Item-4">Item-4
</div>
</form>
Related
I have two checkboxes, and I want whenever I click on any checkbox then their values (static array) should be inserted into "final" array (empty array). If I uncheck that checkbox then its value (static array) should be remove from "final array".
Right now I am inserting/pushing "static" array into blank array (final array), but I want to know that how can I remove this "static" array after uncheck checkbox ?
var myarray = [];
var model = ["Height", "size", "bust"];
var Hostess = ["Height", "bust"];
$("input:checkbox.country").click(function() {
var value = $(this).val();
if (!$(this).is(":checked"))
alert('you are unchecked ' + $(this).val());
else
myarray.push(model);
});
console.log('Final array is ', myarray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form>
<fieldset>
<legend>Choose your interests</legend>
<div>
<input type="checkbox" id="model" class="country" name="interest" value="model">
<label for="model">model</label>
</div>
<div>
<input type="checkbox" id="Hostess" class="country" name="interest" value="Hostess">
<label for="hostess">Hostess</label>
</div>
<div>
<button type="submit">Submit form</button>
</div>
</fieldset>
</form>
As noted in the comments, you can rebuild the array each time.
Assuming you want a 1-dimensional array rather than an array of arrays, you can use
myarray.push(...modelarray);
to add the array items.
I've used a switch here to match the checkbox value with the array variable, but a better solution for this part (already provided in another answer) is to use an object and get the array by key. I've kept this with the switch to show the difference and use of .push(...array)
var myarray = [];
var modelarray = ["A", "B", "C"];
var hostessarray = ["X", "Y"];
$("input:checkbox.country").click(function() {
// rebuild myarray
myarray = [];
$("input:checkbox.country:checked").each(function() {
switch ($(this).val())
{
case "model":
myarray.push(...modelarray);
break;
case "hostess":
myarray.push(...hostessarray);
break;
}
});
console.log('Updated array is ', myarray);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form>
<fieldset>
<legend>Choose your interests</legend>
<div>
<input type="checkbox" id="model" class="country" name="interest" value="model">
<label for="model">model</label>
</div>
<div>
<input type="checkbox" id="hostess" class="country" name="interest" value="hostess">
<label for="hostess">hostess</label>
</div>
<div>
<button type="submit">Submit form</button>
</div>
</fieldset>
</form>
Also in fiddle: https://jsfiddle.net/cwbvqmp4/
You need to generate the array from the checked boxes each time
I suggest an object, where you can get the values based on key
I renamed the class (country) - it does not match the actual values (attributes based on interest)
let myArray;
let interests = {
"model": ["Height", "size", "bust"],
"hostess": ["Height", "bust"]
}
$("input:checkbox.interest").on("click", function() {
myArray = $("input:checkbox.interest:checked")
.map(function() { console.log(this.value,interests[this.value])
return interests[this.value]
}) // get checked boxes and their interests
.get() // return an array
.filter(val => val); // remove empty slots
console.log('Final array is ', myArray);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form>
<fieldset>
<legend>Choose your interests</legend>
<div>
<input type="checkbox" id="model" class="interest" name="interest" value="model">
<label for="model">model</label>
</div>
<div>
<input type="checkbox" id="Hostess" class="interest" name="interest" value="hostess">
<label for="hostess">Hostess</label>
</div>
<div>
<button type="submit">Submit form</button>
</div>
</fieldset>
</form>
Use conditions like below while you have static array for both checkboxes.
var myarray = [];
var model = ["Height", "size", "bust"];
var Hostess = ["Height", "bust"];
$("input:checkbox.country").click(function() {
var value = $(this).val();
if(value === "model"){
if (!$(this).is(":checked")){
myarray.splice(myarray.indexOf(model), 1);
}
else{
myarray.push(model);
}
}
else if(value === "Hostess"){
if (!$(this).is(":checked")){
myarray.splice(myarray.indexOf(Hostess), 1);
}
else{
myarray.push(Hostess);
}
}
console.log('Final array is ', myarray);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form>
<fieldset>
<legend>Choose your interests</legend>
<div>
<input type="checkbox" id="model" class="country" name="interest" value="model">
<label for="model">model</label>
</div>
<div>
<input type="checkbox" id="Hostess" class="country" name="interest" value="Hostess">
<label for="hostess">Hostess</label>
</div>
<div>
<button type="submit">Submit form</button>
</div>
</fieldset>
</form>
I'm trying to build system that will recognize when new checkbox is checked, once the checkbox is checked, the user will have to choose one of the options: left, right, all.
Once one of the three is chosen, the checked checkboxes will be pushed into their specific array. (all[], right[], left[])
The problem:
Lets assume I check checkbox number 1, and click all.
Debugging:
all["1"]
then I check checkbox number 3, and click left.
I will get the following debugging:
Debugging:
all["1"]
left["1", "3"]
Desired result:
all["1"]
left["3"]
I want left[] array to get only the new checkbox checking, but without unchecking the checkboxes.
Codepen
$(document).ready(function () {
//Adding each checked checkbox to array
let checked = [], all = [], left = [], right = [];
$box = $('.ppom-check-input');
$box.on('change', function() {
checked = $box.filter(':checked').map((i,c) => c.value).get();
$('#choose').addClass('active');
console.log( checked );
});
//Push the value to array
$('.all,.left,.right').on('click', function() {
if( $(this).is('.all') ) {
all = [...new Set( all.concat(checked) )];
$('#choose').removeClass('active');
} else if( $(this).is('.left') ) {
left = [...new Set( left.concat(checked) )];
$('#choose').removeClass('active');
} else if( $(this).is('.right') ){
right = [...new Set( right.concat(checked) )];
$('#choose').removeClass('active');
}
console.log( 'all',all, 'left', left, 'right', right );
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" value="1" class="ppom-check-input" />
1
<br/>
<input type="checkbox" value="2" class="ppom-check-input" />
2
<br/>
<input type="checkbox" value="3" class="ppom-check-input" />
3
<br/>
<input type="checkbox" value="4" class="ppom-check-input" />
4
<br/>
<input type="checkbox" value="5" class="ppom-check-input" />
5
<br/>
<div id="choose">
left
right
all
</div>
How can I push to an array new values only (not all checked checkboxes)?
One way to do above is giving some class to checkboxes whenever its checked using addClass("selected_new") then remove same only when any of a tag is clicked then only checkboxes which is newly selected will be added in array.
Demo Code :
$(document).ready(function() {
//Adding each checked checkbox to array
let checked = [],
all = [],
left = [],
right = [];
$box = $('.ppom-check-input');
$box.on('change', function() {
//if checked then only
if ($(this).is(":checked")) {
//added new class
$(this).addClass("selected_new")
//or
//$(this).attr("data-selected", "selected_new")
}
//or [data-selected=selected_new]:checked
checked = $box.filter('.selected_new:checked').map((i, c) => c.value).get();
$('#choose').addClass('active');
});
$('.all,.left,.right').on('click', function() {
console.clear()
//remove class once any link is clicked
$("input[type=checkbox]").removeClass("selected_new")
//or
//$("input[type=checkbox]").attr("data-selected", "")
if ($(this).is('.all')) {
all = [...new Set(all.concat(checked))];
$('#choose').removeClass('active');
} else if ($(this).is('.left')) {
left = [...new Set(left.concat(checked))];
$('#choose').removeClass('active');
} else if ($(this).is('.right')) {
right = [...new Set(right.concat(checked))];
$('#choose').removeClass('active');
}
console.log('all', all, 'left', left, 'right', right);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" value="1" class="ppom-check-input" /> 1
<br/>
<input type="checkbox" value="2" class="ppom-check-input" /> 2
<br/>
<input type="checkbox" value="3" class="ppom-check-input" /> 3
<br/>
<input type="checkbox" value="4" class="ppom-check-input" /> 4
<br/>
<input type="checkbox" value="5" class="ppom-check-input" /> 5
<br/>
<div id="choose">
left
right
all
</div>
I've got the following function that gets all checked checkboxes on my html form with the given element Name. I have a loose understanding that a reduce function can replace the .map and .join sections so was looking for a poke in the right direction of how to implement that and also if there is any other steps I could take to optimise this function?
function getCheckedValuesOf(elmName){
return [...document.getElementsByName(elmName)].filter(box=>box.checked==true).map(box=>box.value).join(", ")
}
function getCheckedValuesOf(elmName) {
return [...document.getElementsByName(elmName)]
// acc is value returned by previous iteration
// curr is the current iterated element
.reduce((acc, curr) => {
// do nothing on unchecked
if (curr.checked) {
// add a , only if acc is not empty, to prevent useless starting ,
acc += (acc !== "" ? ", " : "") + curr.value
}
// always return acc, or next iteration will have acc === undefined
return acc;
// second argument of reduce is the initial value of acc
// if not set then it default to the first element of the array
// and the iteration starts on the second element
}, '')
}
document.getElementById("log").onclick = () => console.log(getCheckedValuesOf("name"))
console.log(getCheckedValuesOf("name"))
<input type="checkbox" name="name" checked="false" value="i1"/>i1
<input type="checkbox" name="name" value="i2"/>i2
<input type="checkbox" name="name" checked="false" value="i3"/>i3
<input type="checkbox" name="name" value="i4"/>i4
<input type="checkbox" name="name" checked="false" value="i5"/>i5
<input type="checkbox" name="name" value="i6"/>i6
<button id="log">log</button>
Can you try this one? Let me know if it works.
function getCheckedValuesOf(elmName) {
return [...document.getElementsByName(elmName)].reduce((a, b) => b.checked && b.value && (a.length>0 ? `${a}, ${b.value}`: `${a} ${b.value}`) || a, "");
}
You can do it with reduce only. modified from #akshaybande 's answer to fix the errors (like leading ", " etc.)
function getCheckedValuesOf(elmName) {
return [...document.getElementsByName(elmName)].reduce((acc, cur) => {
if (cur.checked && cur.value){
return acc.length >= 1 ? `${acc}, ${cur.value}` : `${cur.value}`
}
return acc;
}, "");
}
document.getElementById("log").onclick = () => console.log(getCheckedValuesOf("name"))
console.log(getCheckedValuesOf("name"))
<input type="checkbox" name="name" checked="false" value="1"/>1
<input type="checkbox" name="name" value="2"/>2
<input type="checkbox" name="name" value="3"/>3
<input type="checkbox" name="name" value="4"/>4
<input type="checkbox" name="name" checked="false" value="5"/>5
<input type="checkbox" name="name" value="6"/>6
<button id="log">log</button>
something like this?
function getCheckedValuesOf(elmName) {
return [...document.getElementsByName(elmName)]
.reduce((str, box) => {
if (box.checked == true) {
str += box.value +', '
}
return str;
}, '');
}
document.querySelector('button').onclick = () => {
console.log(getCheckedValuesOf('input'))
}
<input type="checkbox" checked name="input" value="1">
<input type="checkbox" name="input" value="2">
<input type="checkbox" name="input" value="3">
<input type="checkbox" checked name="input" value="4">
<input type="checkbox" name="input" value="5">
<button>click</button>
I am currently working on a fee calculator. Here are the rules for the part of it that I am working on:
There are 9 number input fields, A through I
Input fields D, E, & F are mandatory. The user MUST input a number (greater than 0) in AT LEAST 1 of these 3 input boxes (I have taken care of this aspect already)
The user can only enter a number (greater than 0, no limit) into up to 6 of the 9 inputs, maximum
Something I have already achieved with this app, I have a few check boxes on the page, and the user must select at least 1, up to 5 maximum. Once a user checks 5 of those boxes, they cannot check a 6th. If they un-check one of the 5, they can re-check a different one.
So, I am looking to achieve a similar effect with these number inputs.
Once the user has entered a number (again, greater than 0) in up to 6 of the 9 input fields, they cannot enter something in the one of the 3 remaining inputs. But if they were to remove their input from one of the 6 fields, they should be able to enter a number in one of the 4 other inputs, as now only 5 of them have something entered. Again this number can be any value greater than 0. It could be 10, 10,000 or 100,000, etc. The total values across the inputs doesn't matter, just HOW MANY of the 9 inputs you put a value in (again up to 6 maximum).
I am NOT asking for help with the calculations themselves, nor am I asking for help with the check boxes. I am just wanting some help on the functionality mentioned in the paragraph above.
Also, this must be done in plain vanilla JavaScript, no jQuery.
Any help finding this solution would be much appreciated! Thanks!
Here is the HTML:
<div>
<div>
<label for="Input A">Input A</label>
<input class="entity-input license-input" type="number" name="Input A" value="0" min="0">
</div>
<div>
<label for="Input B">Input B</label>
<input class="entity-input license-input" type="number" name="Input B" value="0" min="0">
</div>
<div>
<label for="Input C">Input C</label>
<input class="entity-input license-input" type="number" name="Input C" value="0" min="0">
</div>
<div>
<label for="Input D">Input D</label>
<input class="entity-input license-input-mandatory" type="number" name="Input D" value="0" min="0">
</div>
<div>
<label for="Input E">Input E</label>
<input class="entity-input license-input-mandatory" type="number" name="Input E" value="0" min="0">
</div>
<div>
<label for="Input F">Input F</label>
<input class="entity-input license-input-mandatory" type="number" name="Input F" value="0" min="0">
</div>
<div>
<label for="Input G">Input G</label>
<input class="entity-input distribution-input" type="number" name="Input G" value="0" min="0">
</div>
<div>
<label for="Input H">Input H</label>
<input class="entity-input distribution-input" type="number" name="Input H" value="0" min="0">
</div>
<div>
<label for="Input I">Input I</label>
<input class="entity-input distribution-input" type="number" name="Input I" value="0" min="0">
</div>
</div>
And here is the JavaScript I have so far:
// Select all elements with class of entity-input
const ENTITY_INPUTS = document.querySelectorAll('.entity-input');
// Prevent user from entering a number on 7th number input (cannot fill in more than 6)
ENTITY_INPUTS.forEach((input) => {
const MAX = 6;
// Upon leaving the input, assign a data-changed attr with a value of true or false depending on whether the value has changed
input.addEventListener('blur', () => {
if (input.value == 0) {
input.removeAttribute('data-changed', 'true');
input.setAttribute('data-changed', 'false');
} else if (input.value !== 0) {
input.removeAttribute('data-changed', 'false');
input.setAttribute('data-changed', 'true');
}
let unchangedInputs = document.querySelectorAll('[data-changed="false"]');
if (unchangedInputs.length !== []) {
console.log(`The number of inputs with a value still at zero is ${unchangedInputs.length}`);
}
});
// Count the number of inputs with data-changed set to true - can't be more than 6
input.addEventListener('focus', () => {
let changedInputs = document.querySelectorAll('[data-changed="true"]');
console.log(`The number of inputs with a value more than zero is ${changedInputs.length}`);
if (changedInputs.length == MAX && input.value > 0) {
console.log(`You may change this element`);
} else if (changedInputs.length == MAX) {
console.log(`You can't enter any more numbers!`);
}
});
});
EDIT: I was able to solve this after some slight modifications to my HTML and JS.
I gave all 9 inputs the attribute data-changed="false" by default, instead of having it assigned dynamically based on user input. And similar to #7iiBob's answer, I put everything into blur, and I got the effect I needed:
ENTITY_INPUTS.forEach((input) => {
const REMAINING_INPUTS = 3;
// Upon leaving the input, assign a data-changed attr with a value of true or false depending on whether the value has changed
input.addEventListener('blur', () => {
if (input.value == 0) {
input.removeAttribute('data-changed', 'true');
input.setAttribute('data-changed', 'false');
} else if (input.value !== 0) {
input.removeAttribute('data-changed', 'false');
input.setAttribute('data-changed', 'true');
}
// upon leaving, check number of elements still with data-changed set to false
// if the number of elements is equal to 3, set them to disabled
// else, leave them alone (set disabled to false)
let unchangedInputs = document.querySelectorAll('[data-changed="false"]');
if (unchangedInputs.length == REMAINING_INPUTS) {
unchangedInputs.forEach((input) => {
input.disabled = true;
});
} else {
unchangedInputs.forEach((input) => {
input.disabled = false;
});
}
});
});
You look pretty darn close to having this solved.
Why not put everything into blur?
// Select all elements with class of entity-input
const ENTITY_INPUTS = document.querySelectorAll('.entity-input');
// Prevent user from entering a number on 7th number input (cannot fill in more than 6)
ENTITY_INPUTS.forEach(input => {
const MAX = 6;
// Upon leaving the input, assign a data-changed attr with a value of true or false depending on whether the value has changed
input.addEventListener('blur', () => {
if (input.value == 0) {
input.removeAttribute('data-changed', 'true');
input.setAttribute('data-changed', 'false');
} else if (input.value !== 0) {
input.removeAttribute('data-changed', 'false');
input.setAttribute('data-changed', 'true');
}
let changedInputs = document.querySelectorAll('[data-changed="true"]');
let unchangedInputs = document.querySelectorAll('[data-changed="false"]');
if (changedInputs.length == MAX) {
unchangedInputs.forEach(inputToDisable =>
inputToDisable.setAttribute('disabled', 'true')
);
} else if (changedInputs.length < MAX) {
unchangedInputs.forEach(inputToEnable =>
inputToEnable.setAttribute('disabled', 'false')
);
}
});
});
This is the logic.
Implant on checkboxes:
let inputCheckboxesLength = 0; // initial counter to 0
const inputCheckboxes = document.querySelectorAll('#inputCheck input'); // target the checkboxes
for (var i=0; i < inputCheckboxes.length; i++) { // iterate checkboxes
inputCheckboxes[i].addEventListener('change', function() { // listen to changne event:
if (this.checked) { // if one of the checkboxes selected:
++inputCheckboxesLength; // increase the count
if (inputCheckboxesLength === 6) { // if the count more then 5 (equal to 6)
alert ('You cannot check more then 5 checkboxes!'); // alert error message
inputCheckboxesLength = 5; // change the count back to 5
this.checked = false; // remove the checked for the last checkbox
}
}
else {
--inputCheckboxesLength // decrease the count - will tirgger when user remove check-mark from checkbox
}
});
}
<fieldset id="inputCheck">
<label for="check1">1<input type="checkbox" id="check1" /></label>
<label for="check2">2<input type="checkbox" id="check2" /></label>
<label for="check3">3<input type="checkbox" id="check3" /></label>
<label for="check4">4<input type="checkbox" id="check4" /></label>
<label for="check5">5<input type="checkbox" id="check5" /></label>
<label for="check6">6<input type="checkbox" id="check6" /></label>
<label for="check7">7<input type="checkbox" id="check7" /></label>
<label for="check8">8<input type="checkbox" id="check8" /></label>
</fieldset>
Implant on inputs:
let inputNumberLength = 0; // initial counter to 0
const inputNumbers = document.querySelectorAll('#inputNumber input'); // target the inputs
for (var i=0; i < inputNumbers.length; i++) { // iterate inputs
inputNumbers[i].addEventListener('change', function() { // listen to changne event:
if (this.value.length > 0) {
++inputNumberLength; // increase the count
if (inputNumberLength === 6) { // if the count more then 5 (equal to 6)
alert ('You cannot put more then 5 values!'); // alert error message
inputNumberLength = 5; // change the count back to 5
this.value = ''; // remove the value for the last input
}
}
else {
--inputNumberLength // decrease the count - will tirgger when user remove check-mark from checkbox
}
});
}
<fieldset id="inputNumber">
<label for="a"><input type="number" id="a" /></label>
<label for="b"><input type="number" id="b" /></label>
<label for="c"><input type="number" id="c" /></label>
<label for="d"><input type="number" id="d" /></label>
<label for="e"><input type="number" id="e" /></label>
<label for="f"><input type="number" id="f" /></label>
<label for="g"><input type="number" id="g" /></label>
<label for="h"><input type="number" id="h" /></label>
<label for="i"><input type="number" id="i" /></label>
</fieldset>
I have 3 groups of inputs, in chronological order (manufacturer info, repair info, test info). When the user hits the "confirm button", I want an if statement to iterate through each input, compare if (input.val() !== ""), and then make sure it is the most recent data (ie. repair info will supercede mfg info) before pushing that value to the #asreceived fields.
I have manually done an if statement for each set of inputs to iterate through, however I would have to add to the function if I wanted to enter more fields.
This is what I have currently:
$("#model-received").val(function() {
if ($("#model-test").val() != "") {
return $("#model-testonly").val();
} else if ($("#model-repair").val() != "") {
return $("#model-repair").val();
} else {
return $("#model-initial").val();
}
});
I have used this code for each set of inputs (roughly 50)
I have tried to compare groups using the .each(), but I am stuck here.
let $inputMfg = $("#manufacturers-tag").find("input , select").each(function() {
if ($(this).attr("name").indexOf("-initial") > -1) {
return
}
});
let $inputRep = $("#repairtag-old").find("input , select").each(function() {
if ($(this).attr("name").indexOf("-repair") > -1) {
return
}
});
let $inputTO = $("#testonlytag-old").find("input , select").each(function() {
if ($(this).attr("name").indexOf("-testonly") > -1) {
return
}
});
let $inputAsRec = $("#asreceived").find("input , select").each(function() {
if ($(this).attr("name").indexOf("-received") > -1) {
return
}
});
$("#asreceived"),$("#testonlytag-old"),$("#repairtag-old"),$("#manufacturers-tag") are all the same HTML, minus the name suffix on each input ("-initial")
HTML
<div id="repairtag-old" hidden>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">Company: </label>
<input class="entry-input" type="text" name="company-repair">
</div>
</div>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">Date: </label>
<input class="entry-date" type="date" name="date-repair">
</div>
</div>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">VR Stamp: </label>
<select class="entry-select" id="vrstamp-old" name="vrstamp-old">
<option></option>
<option>Yes</option>
<option>No</option>
</select>
<label class="entry-bylabel">VR: </label>
<input class="entry-input" type="text" name="vrnumber-old">
</div>
</div>
<div class="entry-col2">
<div class="entry-line">
<label class="entry-label">Job Number: </label>
<input class="entry-input" type="text" name="jobnumber-repair">
</div>
</div>
<div class="entry-col2">
<div class="entry-line">
<label class="entry-label">Model Number: </label>
<input class="entry-input" id="model-repair" type="text" name="model-repair">
</div>
</div>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">Set Pressure: </label>
<input class="entry-input" id="setpressure-repair" type="text" name="setpressure-repair">
<select class="entry-select" name="setunit-repair">
<option>psig</option>
</select>
</div>
</div>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">Cold Test Pressure: </label>
<input class="entry-input" type="text" name="coldpressure-repair">
<select class="entry-select" name="coldunit-repair">
<option>psig</option>
</select>
</div>
</div>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">Capacity: </label>
<input class="entry-input" type="text" name="capacity-repair">
<select class="entry-select" name="capacityunit-repair">
<option>scfm</option>
</select>
</div>
</div>
<br>
</div>
The final result should push the value of the most important value (test only 1st, repair 2nd, mfg 3rd). If the (input.val === ""), it should use the older values.
---UPDATED---
I figured it out. Code snippet below. Thank you for the responses, I was a little intimated in trying to implement them (I am new at coding). However, Mark Meyer's response got me on the right track. This works exactly as intended.
$("#copybtn-received").click(function(i) {
$("#asreceived").find("input, select").each(function() {
let $output = $(this).attr("name").split("-received")[0];
let $inputTO = $("#testonlytag-old").find("[name^=" + $output + "]");
let $inputRep = $("#repairtag-old").find("[name^=" + $output + "]");
let $inputMfg = $("#manufacturers-tag").find("[name^=" + $output + "]");
if ($inputTO.val() !== "") {
$(this).val($inputTO.val());
} else if ($inputRep.val() !== "") {
$(this).val($inputRep.val());
} else if ($inputMfg.val() !== "") {
$(this).val($inputMfg.val());
} else {
$(this).val("");
}
});
});
You could put your values in an array that is in the order of precedence you want then use find() which returns the first value found. In the find callback just return whether the value is truth, which "" isn't. This will allow you to decide arbitrary orders without all the if/else statements.
Here's a simplified example. It will log the highest value filled in.
function getBest(){
/* values in the order values will be found */
let values = [
document.getElementById("one").value,
document.getElementById("two").value,
document.getElementById("three").value,
document.getElementById("four").value
]
/* find the first truthy value */
let best = values.find(val => val)
console.log(best)
}
<input id="one" type ="text"><br />
<input id="two" type ="text"><br />
<input id="three" type ="text"><br />
<input id="four" type ="text"><br />
<button onclick="getBest()">Go</button>
I'm not sure I understand the question correctly, so this is a bit of a guess. Perhaps something like this would do?:
const findFirst = (ids, idx = ids.find(id => $(`#${id}`).val() !== '')) =>
idx > -1 ? $(`#${id}`).val() : 'not found'
$("#model-received").val(findFirst(
['model-testonly', 'model-repair', 'model-initial']
))
You can then update the list by simply appending to that array. And if the 'model-' prefix is universal, you can include that in the function and only pass ['testonly', 'repair', 'initial'] in the call.
I don't know if you have a better default than the 'not found' here.