I have a set of checkboxes, and based on which items are selected, different upload fields will display. To facilitate this, I want to dynamically create an array that contains all the classes I want to fetch (without duplication).
I have created an object with the details:
var uploadReq = {
a: [".document-2"],
b: [".document-1", ".document-3"],
c: [".document-1"],
d: [".document-2", ".document-3"],
e: [],
f: [".document-3"]
};
In this example, if someone chose Category A and Category B, we should end up with an array something like [".document-2", ".document-1", ".document-3"]
(order is unimportant).
I have an event listener like this:
$("#client-cat").change(function() {
var arr = $("#client-cat input");
var classes = [];
for(i=0; i<arr.length; i++) {
if(arr[i].checked) {
var value = arr[i].value;
var arr2 = uploadReq[value];
$.extend(classes, arr2);
}
};
console.log(classes);
})
HTML:
<form>
<div class="segment">
<label for="client-cat">Client category:</label>
<div id="client-cat">
<div>
<input type="checkbox" tabindex="0" name="client-cat" value="a">
<label>Category A</label>
</div>
<div>
<input type="checkbox" tabindex="0" name="client-cat" value="b">
<label>Category B</label>
</div>
<div>
<input type="checkbox" tabindex="0" name="client-cat" value="c">
<label>Category C</label>
</div>
<div>
<input type="checkbox" tabindex="0" name="client-cat" value="d">
<label>Category D</label>
</div>
<div>
<input type="checkbox" tabindex="0" name="client-cat" value="e">
<label>Category E</label>
</div>
<div>
<input type="checkbox" tabindex="0" name="client-cat" value="f">
<label>Category F</label>
</div>
</div>
</div>
<div class="segment">
<div class="document-1">
<label for="document-1">Upload a copy of Document 1:</label>
<input type="file" id="document-1" name="1" accept=".pdf">
</div>
<div class="document-2">
<label for="document-2">Upload a copy of Document 2:</label>
<input type="file" id="document-2" name="2" accept=".pdf">
</div>
<div class="document-3">
<label for="document-3">Upload a copy of Document 3:</label>
<input type="file" id="document-3" name="3" accept=".pdf">
</div>
</div>
</form>
However, when I run the code with Category A and Category B checked, I only get [".document-1", ".document-3"]
.
I believe what is happening is that every time the for loop restarts, it is reverting to the original value for classes
, instead of taking the value from the end of the loop and restarting it.
Research/attempted fixes:
- Looked at this thread which discusses using
$.extend
to solve a similar problem (e.g. combine two arrays without catching duplicates) Tested to see if it's a scoping issue by trying the code:
$("#client-cat").change(function() { var arr = $("#client-cat input"); var classes = []; for(i=0; i<arr.length; i++) { if(arr[i].checked) { classes.push("bob"); } } console.log(classes); })
But the above logs an array with as many
"bob"
s as there are checkboxes, so I don't think it's an issue with the scope ofclass
.Considered other methods of combining the data. Example:
push
works, but I end up with arrays inside arrays, which isn't what I want. Example:map
might do it, but doesn't clear out duplicates.