Reputation: 47
I've got this weird problem with my JavaScript code.
I'm trying to create dynamically loading select boxes without the luxury of something like React.
It compares values of other select boxes so that a value can only be selected in once. So if a value is already set in one select box, it cannot be selected again.
For this I use a list of original values, clone those values into a new variable and remove the ones already selected and then create new lists.
Works fine albeit the numerous loops. The only problem is that if I remove an item from the cloned variable, the original also changes.
Even if I push the original variable in a prototype object or use const
.
window.initial_abstract_list = ["Option one", "Option two", "Option three", "Option four", "Option five"];
// Set the option values
function reset_abstract_list() {
var in_list = [];
var new_list = window.initial_abstract_list;
console.log(window.initial_abstract_list); /// window.initial_abstract_list changes!!!
// Get selected value of all select boxes
$.each($('select.values-list'), function(index, value) {
in_list.push($(value).val().toString())
});
// Remove already set values from list
$.each($('select.values-list'), function(index, value) {
$.each(in_list, function(index2, value2) {
delete new_list[value2.toString()];
});
});
// Generate new options for select boxes
$.each($('select.values-list'), function(index, value) {
var current_selected_key = $(value).val().toString();
var current_selected_val = $('option:selected', value).text();
$(value).empty();
$(value).append($('<option></option>')
.attr('value', current_selected_key)
.text(current_selected_val));
for (var index2 in new_list) {
"use strict";
$(value).append($('<option></option>')
.attr('value', index2)
.text(new_list[index2]));
};
});
}
// Alter content on change select boxes
jQuery(document).ready(function($) {
$(document).on('click', 'button', function(e) {
reset_abstract_list();
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="values-list">
<option value="0">Option one</option>
<option value="1">Option two</option>
<option value="2">Option three</option>
<option value="3">Option four</option>
</select>
<select class="values-list">
<option value="0">Option one</option>
<option value="1">Option two</option>
<option value="2">Option three</option>
<option value="3">Option four</option>
</select>
<select class="values-list">
<option value="0">Option one</option>
<option value="1">Option two</option>
<option value="2">Option three</option>
<option value="3">Option four</option>
</select>
<button>Ye olde button</button>
Upvotes: 0
Views: 45
Reputation: 6416
By doing var new_list = window.initial_abstract_list;
you are only creating a reference to the original array. Any changes made to new_list
will reflect in the initial array.
What you want to do is create a deep copy of the initial array, so as to get a different variable but with the same values. You can do this like so:
var new_list = jQuery.extend(true, {}, window.initial_abstract_list);
Upvotes: 1
Reputation: 296
When you set your new_list to the default list, it's basically creating a reference to the original. You need to instead copy the values of the original list so they aren't coupled.
var new_list = window.initial_abstract_list.slice();
Upvotes: 3