Strona 1 z 3 123 OstatniOstatni
Pokaż wyniki od 1 do 10 z 24

Wątek: [jQuery/JS] Dynamiczne aktywowanie/dezaktywowanie przycisków

  1. #1
    Zarejestrowany
    Dołączył
    Jan 2012
    Posty
    13

    Domyślnie [jQuery/JS] Dynamiczne aktywowanie/dezaktywowanie przycisków

    Witam,

    piszę grę przeglądarkową w 99% opartą na ajaxie, po zalogowaniu do gry nie ma żadnego przeładowania strony, aż do kliknięcia "Wyloguj".
    Więc na początku ładuje mi podstronę "home", natomiast pozostałe ładuje ajaxem, gdy są potrzebne. Każdy przycisk na każdej podstronie jest ładowany dynamicznie i ma klasę .but_box.

    Po kliknięciu w jakiś przycisk (np. Kup) jest wykonywany w tle odpowiedni skrypt, wynik odbieram w js i na jego podstawie podmieniam na stronie odpowiednie rzeczy (np. kup - aktualizacja liczby pieniędzy). Ale oprócz tego potrzebuję zmieniać przyciski.

    Przykład:
    Gracz ma $200, do kupienia są 2 towary - jeden za $100, drugi za $150. Obok każdego jest przycisk Kup. Po kupieniu pierwszego gracz ma już tylko $100 i nie może kupić drugiego towaru, zatem przycisk drugi powinien zostać dynamicznie dezaktywowany.

    Próbowałem zrobić tak, że przyciskowi przypisałem atrybut conditions, np tak:
    Kod html:
    <div class="but_box" conditions="money<500&&tokens<10">[...]</div>
    A po zakończeniu wykonywania dowolnego skryptu pobierałem metodą attr() te warunki i sprawdzałem, a potem w zależności od wyniku aktywowałem lub dezaktywowałem przyciski.
    Działa, ale niestety tylko częściowo.

    Czy ktoś mógłby podpowiedzieć jakiś łatwiejszy sposób? Może niepotrzebnie sobie utrudniam?

  2. #2
    Zasłużony Awatar Rodkan
    Dołączył
    Mar 2011
    Posty
    1,465

    Domyślnie

    Z atrybutami byłbym ostrożny, choć jeśli już chcesz to zrobić w oparciu o nie to dałbym atrybut w stylu "cost" i w nim byłaby cena przedmiotu (np. "cost=150"). Po kupieniu sprawdzałbym wszystkie przyciski i jeśli ilość pieniędzy na koncie byłaby mniejsza niż wymagana w atrybucie to blokowałbym przycisk poprzez dodanie jakieś klasy czy co tam sobie wymyślisz. Później może spróbuję napisać jakiś przykładowy kod jak nie będziesz mógł sobie sam z tym poradzić.

  3. #3
    Aktywny
    Dołączył
    Jul 2008
    Posty
    866

    Post

    A to jest przycisk, input button? Czy chodzi o klikanie na diva?
    Pomysłów mi nie brakuje, ale najlepsze rozwiązanie zależy od Twojego obecnego kodu.

    Możesz złapać wszystkie elementy z klasą 'but_box'. Następnie sprawdzić warunek. Masz odpowiedź prawa/fałsz. W takim razie pozostaje go tylko zablokować.
    Możesz dodać do $(this) / konkretnego elementu nowe zdarzenie onclick..

    Kod:
    $(".but_box").each( function() {
        //sprawdzasz warunek
        //niespełniony to blokuejsz
        $(this).bind("onclick", function() {
            return false;
        });
        //spełniony to odblokujesz
        $(this).unbind("onclick");
        });
    });
    Może to coś da. I odpowiednio unbind jeżeli się okaże, że można kupić. Nie do końca wiem jak kod wygląda, wiec nie mogę za bardzo pomóc.
    Gdyby to był zwykły input to można dorzucić atrybut "disabled" i po problemie.

    Możesz też mieć atrybut "data-disabled" równy 0 lub 1 i odpowiednio go zmieniać przy w zależności od warunku. W każdym razie musisz przejść przez wszystkie elementy o tej klasie, a do tego masz "each". Mając "data-disabled" przy skrypcie odpowiedzialnym za wysyłanie możesz to odpowiednio interpretować.

    Możesz też odświeżać cały sklep ajaxem.

    Kod:
    $("input").prop('disabled', true);
    $("input").prop('disabled', false);
    Z elementami "input" nie powinno być problemów, a z divami to nie wiem jak się zachowa.
    Kod html:
    <input type="button" value="lipa" disabled><br>
    <input type="button" value="dziala">
    Oczywiście znowu odpowiednio sprawdzając każdy element z jego warunkiem z osobna.

    Dodatkowo nie powinieneś tworzyć własnych atrybutów. Lepiej korzystać z "data-tokenCost", "data-moneyCost" itp. Radzę poczytać o atrybucie "data" w html5.
    Ostatnio edytowane przez Drikam ; 26-08-2013 o 20:33

  4. #4
    Zarejestrowany
    Dołączył
    Jan 2012
    Posty
    13

    Domyślnie

    Nie jest to input, tylko div, bo input nie wygląda ładnie.
    Poniższy kod:
    Kod html:
    $(".but_box").each(
    nie będzie działać, ale już wcześniej rozwiązałem problem, używając pluginu live query. Chyba chodzi o to, że przyciski są dynamicznie tworzone.

    Dzięki, jutro jeszcze będę coś kombinował.

  5. #5
    Aktywny
    Dołączył
    Jul 2008
    Posty
    866

    Domyślnie

    Nie będzie działać, bo? Nieważne czy masz 50 różnych formularzy, each się sprawdzi bez problemu. Jeden z wielu sposobów to dodanie dodatkowej klasy dla konkretnych formularzy albo jakoś je nazwać, rozróżniać.

    Kod:
    <div class="but_box sklepowy_input" conditions="money<500&&tokens<10">[...]</div>
    



    Kod:
    $(".sklepowy_input").each(..
    I nie ma "kolizji" z innymi formularzami/przyciskami w ten sposób, bo dokładnie wiadomo, które sprawdzać.

  6. #6
    Zasłużony Awatar Rodkan
    Dołączył
    Mar 2011
    Posty
    1,465

    Domyślnie

    http://jsfiddle.net/C5zDr/ - kod nie jest jakiś epicki, ale ukazuje o co mi chodziło.

    Co do .live() to ktoś płakał kiedyś że w nowszych wersjach jQuery nie ma już tego (choć sam używałem i nie wiem czemu rzekomo usunęli).

    Drikam - nie wiem czemu boisz się nowych atrybutów, jedyny błąd który zauważyłem przy ich używaniu, to że walidatory sypią błędami jakby je szatan opętał.

  7. #7
    Aktywny
    Dołączył
    Jul 2008
    Posty
    866

    Domyślnie

    No właśnie dlatego? Bo to nieprofesjonalne?

    To tak jakbym w php sobie zaczął nazywać zmienne rozpoczynające się '$_' a potem się będę wkurzał, że w nowszych wersjach dodano '$_SETTINGS' i mi się cały skrypt sypie?

    A może w html50 będzie coś takiego jak 'conditions'? Zakładając, że strona ma się rozwijać to nie można samemu sobie robić problemów. Mamy atrybut data- to z niego korzystajmy.
    Ostatnio edytowane przez Drikam ; 26-08-2013 o 22:22

  8. #8
    Zarejestrowany
    Dołączył
    Jan 2012
    Posty
    13

    Domyślnie

    Teraz działa w 100%, okazało się że dobrze kombinowałem ale zapomniałem o takiej głupocie, jak zmienne globalne i lokalne - porównywanie wartości i zmianę przycisków miałem w funkcji, która nie miała dostępu do zmiennych z zewnątrz .

  9. #9
    Zarejestrowany
    Dołączył
    Jan 2012
    Posty
    13

    Domyślnie

    Niestety jest jeszcze jeden problem, chyba wcześniej go nie zauważyłem...

    Mianowicie, gdy włączam podstronę "home" (lub jakąś inną tylko nie "shop"), odświeżam całą stronę normalnie, następnie przez ajax przełączam na "shop" i coś kupuję, to nie odświeża mi przycisków.
    Natomiast gdy mam włączone "shop" i wtedy odświeżam i kupuję, to już odświeża.

    W każdym skrypcie mam:
    Kod php:
    $objPlayer->session_jsUpdate(); 
    W klasie Player:
    Kod php:
    public function session_jsUpdate()
    {
        echo 
    "var tab=new Array(); ";
        
        foreach(
    $this->lastModifiedFields as $field)
        {
            echo 
    "tab['".$field."']='".$_SESSION[$field]."'; ";
        }
        
        
    $updateString="set(tab); ";
                
        echo 
    $updateString;

    A w game.php w kodzie JS:
    Kod php:
    function set(arFieldValues)
    {
        for(
    i in arFieldValues)
        {
            switch(
    i)
            {
                case 
    'money':
                    
    player['money']=arFieldValues[i];
                    $(
    '#header_moneybox p').text(player['money']);
                    break;
                case 
    'tokens':
                    
    player['tokens']=arFieldValues[i];
                    $(
    '#header_tokensbox p').text(player['tokens']);
                    break;
            }
        }
                    
        
    buttonsRefresh();

    Kod php:
    function buttonsRefresh()
    {
        
    alert('aaa');
        $(
    ".but_box[data-conditions!='']").each(function()
        {
            var 
    conditions=$(this).attr('data-conditions');
            var 
    ok=1;
            var 
    split1=conditions.split(';');
            
            var 
    conds='';
                
            for(
    i=0i<split1.lengthi++)
            {
                var 
    split2=split1[i].split('=');
                if(
    player[split2[0]]<split2[1])
                    
    ok=0;
                
    //poniższa linijka tylko żeby przygotować dane do wyśw. w alercie
                
    conds=conds+player[split2[0]]+'<'+split2[1]+' :: ';
            }
                    
            
    alert(conds);
                    
            if(
    ok==0)
                $(
    this).children(':first').next().show().prev().children(':first').hide();
            else
                $(
    this).children(':first').next().hide().prev().children(':first').show();
        });
        
        
    alert($(".but_box[data-conditions!='']").length);

    Te alerty pododawałem, żeby sprawdzić gdzie jest coś źle. Normalnie nie powinno ich być.
    I teraz w pierwszym przypadku, gdy nie odświeża przycisków, wyskakuje tylko pierwszy alert.
    A gdy odświeża, to wyświetla wszystkie alerty, a ten w .each() po kilka razy (bo jest kilka przycisków). Dlaczego w pierwszym przypadku nie wyświetla pozostałych? Skoro wyświetla pierwszy, to znaczy że funkcja buttonsRefresh() jest wywoływana, a więc i kolejne powinny się wyświetlić.

    Struktura html przycisku:
    Kod php:
    <div class="but_box" data-conditions="money=jakas_kwota;tokens=jakas_kwota">
        <a href="php/ajax/sub_shop_buy.php?type=typ_towaru&id=id_towaru" rel="ajax">
            <div class="but1"<?php if($_SESSION['money'] < $row['money'] || $_SESSION['tokens'] < $row['tokens']){echo " style=\"display:none;\"";} ?>>
                <input class="inp2" type="submit" value="r">";
                <div class="but1a"></div>
                <div class="but1b"><p>Kup</p></div>
                <div class="but1c"></div>
            </div>
        </a>
        <div class="butg"<?php if($_SESSION['money'] >= $row['money'] && $_SESSION['tokens'] >= $row['tokens']){echo " style=\"display:none;\"";} ?>>
            <input class="inp2" type="submit" value="r">
            <div class="butga"></div>
            <div class="butgb"><p>Kup</p></div>
            <div class="butgc"></div>
        </div>
    </div>
    .butg to szary, nieklikalny przycisk, który jest pokazywany gdy przycisk ma być dezaktywowany. Wtedy chowany jest .but1, czyli klikalny, zielony przycisk.
    Jeśli przycisk ma być aktywowany, to odwrotnie, jak zresztą widać w funkcji buttonsRefresh().

  10. #10
    Aktywny
    Dołączył
    Jul 2008
    Posty
    866

    Domyślnie

    A konsola błędów coś mówi?
    A jeżeli dasz

    Kod php:
    alert($(".but_box[data-conditions!='']").length); 
    Zamiast
    Kod:
    alert('aaa');
    na początku?

    Jeżeli drugi alert nie daje żadnego efektu to:
    1. albo jest pusty.
    2. albo kod przed nim ma błąd.

    .length zawsze coś zwróci, 0 lub inną liczbę, więc to pewnie coś z poprzednim kodem.

    Mnie dziwi
    Kod php:
    .but_box[data-conditions!=''
    A bez tego? Jest w ogóle jakikolwiek element '.but_box'?

    Konsola błędów coś mówi?

    W funkach ajax masz dataType ustawione na 'html' czy coś innego?
    A jak wygląda 'bind'owanie zdarzeń do elementów?


    bardzo mnie dziwi, że wykonuje się jeden alert. Tj który? 'aaa'? A drugi, poza each co zwraca? W ogóle się nie wykonuje?

Strona 1 z 3 123 OstatniOstatni

Informacje o wątku

Użytkownicy przeglądający ten wątek

Aktualnie 1 użytkownik(ów) przegląda ten wątek. (0 zarejestrowany(ch) oraz 1 gości)

Podobne wątki

  1. [Tutorial][jQuery] Dynamiczne wczytywanie strony
    Przez Bartek w dziale Poradniki
    Odpowiedzi: 7
    Ostatni post / autor: 30-04-2013, 13:47
  2. Ramki a dynamiczne wczytywanie
    Przez Komando w dziale Pytania dotyczące silnika Xnova
    Odpowiedzi: 3
    Ostatni post / autor: 21-01-2012, 09:43
  3. Dynamiczne nadawanie klasy
    Przez Grze_chu w dziale JavaScript/AJAX
    Odpowiedzi: 0
    Ostatni post / autor: 16-01-2010, 21:51
  4. Mintajax ->Dynamiczne zakladki
    Przez gylopl w dziale JavaScript/AJAX
    Odpowiedzi: 14
    Ostatni post / autor: 27-06-2009, 17:45
  5. [Dynamiczne]Edytowanie rekordów
    Przez Gomez w dziale JavaScript/AJAX
    Odpowiedzi: 16
    Ostatni post / autor: 15-03-2009, 20:01

Zakładki

Uprawnienia umieszczania postów

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •