Zadanie dla początkującego (problem)

0

Cześć, dopiero zacząłem swoją przygodę z JS, w ramach nauki robię różne zadania i trafiłem na jedno, z którym mam problem. Mianowicie muszę wpisać imię i nacisnąć przycisk aby dodać imię do listy, żeby otrzymać coś w stylu "Marek: 1" (to wiem jak zrobić).. Problem mam w tym, że jeśli wpiszemy imię jeszcze raz, to mamy otrzymać np. "Marek: 2", a nie drugi raz "Marek: 1" :). Przypuszczam, że trzeba użyć funkcji "dataset", ale jak na razie mi nie wychodzi. Wiem, że zadanie jest pewnie banalnie proste i wstyd o takie rzeczy pytać, ale byłbym wdzięczny za jakieś podpowiedzi :).

2

Po pierwsze - doprecyzuj, czym jest ta lista.
Po drugie - pokaż, co już masz (czyli dodawanie bez numerków w przypadku powtórek) - wtedy pewnie coś razem wymyślimy ;)

0

Dzięki za odzew :). Jest to zwykła lista . W htmlu u mnie to wygląda tak:

    <label>Imie: <input id="imie" autofocus></label>
    <button id="dodaj">Dodaj</button>
    <ul id="imiona">
    </ul>

W JS "wymyśliłem" coś takiego:

document.getElementById("dodaj").onclick = function () {
    const imieInput = document.getElementById("imie");
    const imie = imieInput.value;
    const li = document.createElement("li");
    li.dataset.imie = imie;
    li.dataset.ilosc = 1;
    li.innerText = `${imie}:${li.dataset.ilosc}`;
    document.getElementById("imiona").appendChild(li);
    imieInput.value = "";
    imieInput.focus();
}
2

Nie musisz używać dataset, właściwie to nie wiem po co teraz go używasz.

Zapisuj sobie dodane imiona do jakiejś tablicy. Potem sprawdź ile ta tablica ma powtarzających się elementów. Na podstawie tego możesz dodać numerek.
Coś takiego

const addedNames = [];
    
document.getElementById("dodaj").onclick = function () {
      const imieInput = document.getElementById("imie");
      const imie = imieInput.value;
      const li = document.createElement("li");
      addedNames.push(imie);
      li.innerText = `${imie}:${addedNames.filter((name) => name === imie).length}`;
      document.getElementById("imiona").appendChild(li);
      imieInput.value = "";
      imieInput.focus();
}

Działający przykład tutaj

0

Dzięki za odpowiedź, z tablicami to dobra opcja, ale zapomniałem dodać, że jeśli się wpiszę imię raz, to już więcej się nie pojawia na liście. Np. po wpisaniu "Marek, Henryk, Marek" mamy listę:

  • Marek: 2
  • Henryk: 1
2

@slawomirus: Ja bym to zrobił tak, ale może to trochę przekombinowane

Tworzę mapę w której kluczem jest imię a wartością obiekt zawierający ilość powtórzeń i referencje do elementu li.

Dodając nowe imię sprawdzam czy obiekt o takim kluczu już istnieje:

  • Jeśli istnieje, to dodaje + 1 do ilości powtórzeń
  • Jeśli nie istnieje to go tworzę

No i potem zmieniam/dodaję treść elementu li

const addedNames = new Map();

document.getElementById("dodaj").onclick = function () {
      const imieInput = document.getElementById("imie");
      const imie = imieInput.value;
      let savedName = addedNames.get(imie);
 
      if (savedName) {
      	savedName.count += 1;
      } else {
      	const li = document.createElement("li");
      	addedNames.set(imie, { count: 1, element: li});
        savedName = addedNames.get(imie);
        document.getElementById("imiona").appendChild(savedName.element);
      }
      
      savedName.element.innerText = `${imie}:${savedName.count}`;
      imieInput.value = "";
      imieInput.focus();
}

jsfiddle

0

Dziękuje za pomoc. Muszę trochę poczytać o funkcji "map" :). Zadanie było z działu o "dataset", więc się tym sugerowałem :). Myślałem, że będzie trzeba stworzyć coś w stylu:

<ul>
<li data-imie='marek' data-ilosc='1'>marek: 1</li>
<li data-imie='henryk' data-ilosc='1'>henryk: 1</li>
</ul>

A potem tym "manipulować", ale tutaj się pojawia pytanie, czy w ogóle da się tym manipulować :).

4

@slawomirus: No z dataset też się to da zrobić, może nawet prościej

document.getElementById("dodaj").onclick = function () {
     	const imieInput = document.getElementById("imie");
      const imie = imieInput.value;
      let li = document.querySelector(`li[data-imie="${imie}"]`);
      if (li) {
      	li.dataset.ilosc = parseInt(li.dataset.ilosc, 10) + 1;
      } else {
      	li = document.createElement('li');
        li.dataset.imie = imie;
      	li.dataset.ilosc = 1;
      }
      
      li.innerText = `${imie}:${li.dataset.ilosc}`;
      document.getElementById("imiona").appendChild(li);
      imieInput.value = "";
      imieInput.focus();
}

https://jsfiddle.net/ebL5d9yz/

Zwykle operacje bezpośrednio na elementach DOM są wolniejsze, niż te wykonywane w pamięci JS. No ale akurat w tym przykładzie, przy tej ilości modyfikacji to właściwie nie ma znaczenia.

0

Dzięki wielkie za pomoc! :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1