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,

-1
Rik Rödel 21 listopad 2019, 12:00
Id = "myDynamicSelectBox" identyfikator powinien być unikalny dla każdego selektora
 – 
Pavlo Kovchuk
21 listopad 2019, 12:04
Więc .. czy powinienem zmienić id na coś innego, np. class?
 – 
Rik Rödel
21 listopad 2019, 12:18

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.

0
Rodion Baskakov 21 listopad 2019, 12:06
Zmieniłem więc 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.
 – 
Rik Rödel
21 listopad 2019, 12:16
W swoim kodzie masz tablicę elementów po uruchomieniu 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.
 – 
Rodion Baskakov
21 listopad 2019, 12:20
Doceniam twoją pomoc, ale szczerze nie mam pojęcia, jak mam to zrobić.
 – 
Rik Rödel
21 listopad 2019, 12:27
Nie różni się to zbytnio od kodu, który podałeś w swoim questingu. Zacznij od let items = document.querySelector('select.myDynamicSelectBox'); for(let i in items) { items[I].addEventListener('change', function() {}); }… i nie bój się z nim eksperymentować.
 – 
Rodion Baskakov
21 listopad 2019, 12:31
2
document.querySelector zwraca pojedynczy element, nie tablicę. document.querySelectorAll zwraca tablicę ze wszystkimi pasującymi elementami.
 – 
Lennholm
21 listopad 2019, 12:34

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...
    }
}
0
Espen 21 listopad 2019, 15:25
Dzięki za poświęcony czas, ale szczerze nie mam pojęcia, jak mam to przetłumaczyć na mój js..
 – 
Rik Rödel
21 listopad 2019, 12:28