I'm creating dynamic bootstrap list-groups from data using a forEach loop. Inside the dynamic number of list groups created holds a few select elements. I have an on change listener set up to each select element that copies the first value selected to all the other select elements in the other listgroups. Then I remove the on change listener with .off() so a user can change the value of any of the select elements if they dont want it to have the same value as the first value selected. I'm trying to take the values of the select elements and place them in a data attribute on a button to be used for an ajax call later. My problem is, if I try to change the value of one of those select elements to place it into the data attribute, the data attribute value still takes in the very first value that was selected, rather than the new value.
This is an example of my HTML output. In this example, I'm focued on the middle element in the list group with a class of "reason", and the buttons at the bottom of each list group with a class of "submit". If I wanted to change the value of list-group 4 to three instead of one, I would also want the data attribute of 'data-reason' on the submit button to change to three. However, whenever I change the value, the data attribute doesn't change from the first value selected.
<div class="row">
<div class="col-md-4">
**//list-group 1**
<ol class="list-group list-group-numbered mb-4">
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Replacement</div>
<p>0 => 4910</p>
</div>
<span class="badge bg-primary rounded-pill">2020-05-24</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Steward</div>
<select class="form-select steward">
<option disabled="" selected="">Choose...</option>
<option>Grace Hsieh</option>
<option>Matt Stevens</option>
<option>Meagan Jones</option>
</select>
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Reason</div>
<select class="form-select reason" id="4910">
<option disabled="" selected="">Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Notes</div>
<textarea class="notes" rows="4" cols="45"></textarea>
<hr>
<div class="text-end">
<button data-replacement="4910" data-date="2020-05-24" type="button" class="btn btn-success submit" data-reason="1">Submit</button>
</div>
</div>
</li>
</ol>
</div>
<div class="col-md-4">
**//list-group 2**
<ol style="border-color: red" class="list-group list-group-numbered mb-4">
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Replacement</div>
<p>0 => 9183</p>
</div>
<span class="badge bg-primary rounded-pill">2020-05-25</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Steward</div>
<select class="form-select steward">
<option disabled="" selected="">Choose...</option>
<option>Grace Hsieh</option>
<option>Matt Stevens</option>
<option>Meagan Jones</option>
</select>
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Reason</div>
<select class="form-select reason" id="9183">
<option disabled="" selected="">Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Notes</div>
<textarea class="notes" rows="4" cols="45"></textarea>
<hr>
<div class="text-end">
<button data-replacement="9183" data-date="2020-05-25" type="button" class="btn btn-success submit" data-reason="1">Submit</button>
</div>
</div>
</li>
</ol>
</div>
<div class="col-md-4">
**//list-group 3**
<ol style="border-color: red" class="list-group list-group-numbered mb-4">
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Replacement</div>
<p>0 => 7474</p>
</div>
<span class="badge bg-primary rounded-pill">2020-05-26</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Steward</div>
<select class="form-select steward">
<option disabled="" selected="">Choose...</option>
<option>Grace Hsieh</option>
<option>Matt Stevens</option>
<option>Meagan Jones</option>
</select>
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Reason</div>
<select class="form-select reason" id="7474">
<option disabled="" selected="">Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Notes</div>
<textarea class="notes" rows="4" cols="45"></textarea>
<hr>
<div class="text-end">
<button data-replacement="7474" data-date="2020-05-26" type="button" class="btn btn-success submit" data-reason="1">Submit</button>
</div>
</div>
</li>
</ol>
</div>
<div class="col-md-4">
**//list-group 4**
<ol style="border-color: red" class="list-group list-group-numbered mb-4">
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Replacement</div>
<p>0 => 8186</p>
</div>
<span class="badge bg-primary rounded-pill">2020-05-27</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Steward</div>
<select class="form-select steward">
<option disabled="" selected="">Choose...</option>
<option>Grace Hsieh</option>
<option>Matt Stevens</option>
<option>Meagan Jones</option>
</select>
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Reason</div>
<select class="form-select reason" id="8186">
<option disabled="" selected="">Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Notes</div>
<textarea class="notes" rows="4" cols="45"></textarea>
<hr>
<div class="text-end">
<button data-replacement="8186" data-date="2020-05-27" type="button" class="btn btn-success submit" data-reason="1">Submit</button>
</div>
</div>
</li>
</ol>
</div>
</div>
This is one of the on change functions. I try to get the value of each individual select element by grabbing the id and then setting the data attribute of the .submit element with the id value. This doesn't work as the data attribute is still set to the first value that is selected. Any advice on how I can achieve this is greatly appreciated!
$('.reason').on('change', function () {
let x = $(this).val()
let id = $(this).attr('id')
$('.reason').each(function () {
$(this).val(x)
$(this).off('change')
$('.submit').attr('data-reason', $('#' id).val())
})
})
In case it helps, this is how I'm creating the list-groups
let replaceData = $table2.bootstrapTable('getSelections')
console.log(replaceData)
replaceData.forEach(function (item, i) {
if (i == 0) {
content = '<div class="row">'
}
content = `<div class="col-md-4">
<ol class="list-group list-group-numbered mb-4">
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Replacement</div>
<p>${item.Meter} => ${item.Expected}</p>
</div>
<span class="badge bg-primary rounded-pill">${item.Date}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Steward</div>
<select class="form-select steward">
<option disabled selected>Choose...</option>
<option>Grace Hsieh</option>
<option>Matt Stevens</option>
<option>Meagan Jones</option>
</select>
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Reason</div>
<select class="form-select reason" id=${item.Expected}>
<option disabled selected>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Notes</div>
<textarea class='notes' rows="4" cols="45"></textarea>
<hr>
<div class="text-end">
<button data-replacement=${item.Expected} data-date=${item.Date} type="button" class="btn btn-success submit">Submit</button>
</div>
</div>
</li>
</ol>
</div>`
if (i != 0 && i % 5 == 0) {
content = '</div><div class="row">'
}
})
content = '</div>'
container.append(content)
CodePudding user response:
Since you remove the change listener with off
, the data-reason
will of course only be set at the first change. You could keep the change listener and set an attribute after the first change to all of the relevant select elements. After that check if its the first change or any change after.
So you could do something like this to achieve what you want (i hope i got your question right):
$('.reason').on('change', function () {
let x = $(this).val();
let id = $(this).attr('id');
if(!$(this).attr('was-changed')){ // check if this select field was already changed
$('.reason').each(function () {
$(this).val(x);
$(this).attr('was-changed', true); // set the was-changed to true on first change
});
$('.submit').attr('data-reason', $('#' id).val()); // change all submit data-reason
}
// if its not the first change just change the submit of the belonging <ol> element
else {
$(this).closest('ol').find('.submit').attr('data-reason', $('#' id).val());
}
});
Working fiddle: https://jsfiddle.net/uoavkhqe/14/