[jQuery] pętla i tablice

0

Witajcie, mam taki problem.

muszę napisać skrypt w jquery który pobiera dane z htmla.

Jest to listing produktów w sklepie. Na jednej stronie będę około 10 takich produktów, i każdy ma takie same pola do wczytania do tablicy.

HTML

Kod:

<div id="pola">
<span class="czytaj">
                    <input type="hidden" name="test" class="defaultPrice" value="199.00"/>
                    <input type="hidden" name="test" class="promoPrice" value="199.00"/>
                    <input type="hidden" name="test" class="time" value="199.00"/>
                    <input type="hidden" name="test" class="limited" value="true"/>
</span> 
</div>

Napisałem już jQuery dotyczące pola Limited.
Jeśli w limited value == true to wyświetla się obrazek.

Kod:

$(document).ready(function() {
   $("#pola .czytaj").each(function(){
         $(".limited", limited).each(function(){
            if ($(limited).val()=="false"){
               $(".prod .limited").remove();   
            }
            else {
               $(".prod .zegar .cena .limited").replaceWith("<div class='limited'><img src='images/limit_ikona.png' /></div>");
            }
         });
      });
});

Nie radze sobie z napisaniem pętli która przelatywała by przez wszystkie produkty. Teraz jak zmieniam opcje z true na false w pierwszej ofercie to znaczek znika lub pojawia się we wszystkich.

0

Trzecia linijka mi coś podśmiarduje, że się tak wyrażę :)

$(document).ready(function() {
   $("#pola .czytaj").each(function(){
         $(".limited", limited).each(function(){ // <-- co to? co to takiego>

Konkretnie chodzi mi o drugi parametr, jaki przekazujesz funkcji $. Piszesz:

$(".limited", limited)

Co to jest to drugie limited? Masz taką zmienną gdzieś? Jeśli nie, to funkcji $ przekazujesz zły kontekst (undefined), który w najlepszym razie zostanie zignorowany, zależnie od szczegółów implementacyjnych funkcji $.

PS. Jeszcze taka mała podpowiedź, bo niestety na forum trudno znaleźć odpowiednie instrukcje: zamiast zamykać kod w bloku < code > </ code > (bez tych spacji, wstawiłem je żeby w tym miejscu nie zrobiło mi bloku z kodem) użyj < code = javascript > </ code > (również bez spacji). Włączy to kolorowanie składni, dzięki czemu kod będzie tu czytelniejszy. Zamiast javascript możesz też wpisać inne języki, np. php, czy c.

0

Wybacz wstawiłem kawałek kodu z przez kilku minut.

Dopisałem "pętlę" jeśli można to tak nazwać - przetesowałem to przez Alert ("test"); i Okienko z napisem "test" pojawiło się dokłądnie tyle razy ile jest produktów czyli - dobrze :)

mój kod wyglada teraz tak :

$(document).ready(function(obiekt) {
					   
	$(".prod").each(function(obiekt){
		$("#pola .czytaj").each(function(){
			$(".limited", this).each(function(){
				if ($(this).val()=="false"){
					$(".prod .limited").remove();	
				}
				else {
					$(".prod .zegar .cena .limited").replaceWith("<div class='limited'><img src='images/limit_ikona.png' /></div>");
				}
			});
		});  
	});
});

W dalszym ciągu sa jakieś błędy, bo po zmianie pierwszego produktu (limited == true) zmieniają się wszystkie.

Może robie banalne błędy ale pierwszy raz pisze coś sam w jQuery i już nie mam pomysłów na to.

0

O widzisz, z kolorowaniem składni już wygląda lepiej :)

Wywołanie:

$(selectorString);

zwraca obiekt jQuery zawierający WSZYSTKIE elementy w dokumencie pasujące do selektora selectorString. Możesz jednak skorzystać z tego, z czego już korzystasz w innym miejscu tego skryptu:

$(selectorString, contextElement);

To obejmie mniej elementów: wszystkie te elementy w dokumencie, które spełniają selektor selectorString oraz jednocześnie są potomkami (niekoniecznie bezpośrednimi) elementu contextElement.

0

Mógł byś dokładniej określić jak tego użyć ?

Bo w dokumentacji nic nie mogę znaleźć na ten temat.

0

Najpierw musisz zdobyć referencję do potrzebnego Ci elementu zawierającego, tj. tego elementu, który zawiera dane o pojedynczym produkcie.

Nie wiem, czy zamieszczony przez Ciebie HTML jest aktualny i chyba nie jest kompletny (bo np. nie ma w nim żadnego zegara, a w selektorze takowego poszukujesz). Usuwasz jednak (w ifie) element .prod .limited, który znajduje się w elemencie .czytaj.

Z HTML-a wynika, że każdy produkt ma swój element .czytaj. W wywołaniu each iterujesz po wszystkich tych elementach. Należy teraz (przy każdej iteracji) zdobyć referencję do bieżącego elementu .czytaj.

W jQuery jest często tak, że w funkcjach wywołania zwrotnego (np. tych podawanych za argument funkcji each) kontekst, czyli this, ustawiany jest na bieżący element.

Przykładowo, w wywołaniu:

$('.dupa').each(
  function() {  // (*)
  }
);

funkcja wywołania zwrotnego oznaczona gwiazdką będzie wywołana tyle razy, ile elementów o klasie dupa znajduje się w dokumencie. Podczas pierwszego wywołania tej funkcji, "wskaźnik" this wewnątrz niej będzie ustawiony na pierwszy element o klasie dupa. W drugim wywołaniu this będzie ustawione na drugi element o klasie dupa i tak dalej.

Ty masz jednak trzy zagnieżdżone eache, w każdym this jest ustawiany inaczej:

$(".prod").each(function(obiekt) {
        // (1) tu this jest ustawiany na bieżący element .prod
        $("#pola .czytaj").each(function() {
                // (2) tu this jest ustawiany na bieżący element .czytaj
                $(".limited", this).each(function(){
                        // (3) tu this jest ustawiany na bieżący element .limited

                        if ($(this).val()=="false"){ 
                                // (4) tu wybieramy (i usuwamy!) wszystkie elementy .prod .limited,
                                // a chcemy tylko ten bieżący
                                $(".prod .limited").remove(); // (4A)
                        } else {
                                // analogicznie jak wyżej, ale co to za element?
                                // w kodzie nie widzę żadnego zegara
                                $(".prod .zegar .cena .limited").replaceWith('...'); // (4B)
                        }
                }
        }
}

W przypadku (4) widzimy, że this jest ustawione na bieżący element .limited. Stwierdzenie to jest prawdziwe w całej funkcji, również w miejscu (4A). Nawet korzystasz z tej własności w warunku ifa, pisząc $(this). Skorzystaj z niej ponownie w miejscu (4A) i zamień tamtą linijkę na:

$(this).remove();

Czy możesz to zrobić w miejscu (4B)? Nie mam pojęcia. Nie wiem, co to jest ten zegar. Nie wiem jaka jest różnica pomiędzy elementami z (4A) i (4B). Czy na pewno to rozgałęzienie jest w ogóle potrzebne? Czy nie chodzi Ci o usunięcie bieżącego elementu .limited w obu przypadkach?

edit: Tak po prawdzie to Ci powiem, że nie znając całej struktury kodu produktów nie do końca widzę sens tego, co napisałeś :).

0

Faktycznie troche za mało dałem kodu ;)

Cały kod HTML na produkt:

<!-- Produkt -->
            <div class="prod">
            	<div class="foto"><a href="#"><img src="images/dupa2.png" /></a></div>
                <div class="opis"><a href="#"><span class="nazwa">Nazwa produktu</span> sit amet enim. Etiam ullam corper. Suspendisse a pellentesque dui, non felis. Suspendisse a pellentesque dui, non felis.</a>
                <div class="galeria">Najbliżej ciebie</div>
                </div>
                <div class="zegar">
                	<div class="czas">Czas</div>
                    <div class="cena">
                    	<div class="limited"></div>
                        <div class="ceny">
                    	<span class="new">1990,00 zł</span>
                        <span class="old"> / 2230,00 zł</span>
                        </div>
                    </div>
                    <input type="hidden" name="test" class="defaultPrice" value="199.00"/>
                    <input type="hidden" name="test" class="promoPrice" value="199.00"/>
                    <input type="hidden" name="test" class="time" value="199.00"/>
                    <input type="hidden" name="test" class="limited" value="true"/>                    
                </div>
                <div class="dodatkowe">Dodatkowe Informacje</div>
            </div>

Kod jQuery po przeróbkach

$(function(){
   $('#pola .czytaj').each(function(){
      if($('.limited', this).val() == "false"){
         $(this).remove();
      } else {
         $(".prod .zegar .cena .limited").replaceWith("<div class='limited'><img src='images/limit_ikona.png' /></div>");
      }
   });
});

W dalszym ciągu po zmienie pierwszego zmieniają się wszystkie.
Czy tutaj nie trzeba skorzystać z tablic ? I jak je dorzucić do tego kodu ?

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