Mam pętlę foreach działającą w Laravel, która ma listę rozwijaną. Lista rozwijana ma informować ludzi o statusie danej ankiety (wysłane, niewysłane, otrzymane itp.). Chodzi o to, że stan określonej ankiety jest przechowywany lokalnie. Tak więc nawet po odświeżeniu strony stan zostanie zapamiętany.
@foreach($surveys as $sur)
<tr>
<td style="padding:5px 25px 0 0;">{{$sur->titel}}</td>
<td style="padding:5px 25px 0 0;">
<select id="myDynamicSelectBox">
<option>None</option>
<option>Not send</option>
<option>Sent</option>
<option>Answer received</option>
</select>
</td>
@endforeach
Mój JavaScript wygląda tak:
const mySel = document.getElementById("myDynamicSelectBox");
mySel.addEventListener("change",function() {
localStorage.setItem("selValue",this.value); // save it
});
let val = localStorage.getItem("selValue");
if (val) mySel.value=val; // set the dropdown
// trigger the change in case there are other events on the select
mySel.onchange();
</script>
Tak więc problem, z którym się zmagam, polega na tym, że zapisuje stan pierwszej ankiety w pętli foreach. Ale z jakiegoś powodu inne ankiety nie mogą zawierać wartości. Jakieś pomysły?
Dziękuję za Twój czas,
Twoje zdrowie,
2 odpowiedzi
Problem w tym, że masz wiele select
z tym samym ID
. Javascript szuka w dokumencie pierwszego pasującego elementu mającego wymagane ID
i zatrzymuje wyszukiwanie. W tym celu należy użyć atrybutu class
i znaleźć elementy z document.querySelector('select.someClassNameHere')
, aby uzyskać wszystkie potrzebne menu.
id="myDynamicSelectBox"
w select
na class="myDynamicSelectBox"
iw moim skrypcie document.getElementById("myDynamicSelectBox");
na document.querySelector('select.myDynamicSelectBox');
, ale to nie działa. Nadal mogę zapisać tylko pierwszy wpis w mojej pętli foreach.
document.querySelector('select.myDynamicSelectBox');
. Następną rzeczą, którą musisz zrobić, to przejść przez tę tablicę elementów i dołączyć eventListener do każdego elementu.
let items = document.querySelector('select.myDynamicSelectBox'); for(let i in items) { items[I].addEventListener('change', function() {}); }…
i nie bój się z nim eksperymentować.
document.querySelector
zwraca pojedynczy element, nie tablicę. document.querySelectorAll
zwraca tablicę ze wszystkimi pasującymi elementami.
Musisz określić unikalną wartość dla każdego identyfikatora wybranych elementów. Proponuję użyć identyfikatora z obiektu ankiety jako takiego:
@foreach($surveys as $sur)
<tr>
<td style="padding:5px 25px 0 0;">{{$sur->titel}}</td>
<td style="padding:5px 25px 0 0;">
<select onChange="doStuff({{$sur->id}})" id="myDynamicSelectBox{{$sur->id}}">
<option>None</option>
<option>Not send</option>
<option>Sent</option>
<option>Answer received</option>
</select>
</td>
@endforeach
Następnie obsługujesz zmiany według zdarzenia według identyfikatora ankiety, ponieważ dodajesz odbiornik w sekcji HTML, nie musisz już dodawać go w skrypcie. Musisz tylko napisać samą funkcję i sprawić, by przyjęła identyfikator, którego używasz.
function doStuff(id){
let selector = "myDynamicSelectBox"+id;
let mySel = document.getElementById(selector);
let stored = localStorage.getItem("selectedValues");
let data;
if(store){
data = JSON.parse(stored);
} else {
data = {};
}
data[selector] = mySel.value; //or mySel.options[mySel.selectedIndex].value if using a real select element...
localStorage.setItem("selectedValues", JSON.stringify(data));
}
W ten sposób zapisujesz dane, aby załadować dane, musisz napisać coś, co pobiera właściwości z przechowywanego obiektu. Możesz to znaleźć tutaj na SO. Wyszukaj właściwości pobierania z obiektu. Następnie zapętlasz tę listę i wprowadzasz potrzebne zmiany DOM.
function loadData(){
let data = localStorage.getItem("selectedValues");
if(data){
let stored = JSON.parse(data);
// get property names from stored.
// loop over them and get the select elements by id given by the keys
// assign values
// other logic...
}
}