[ nemchus @ 14.01.2016. 23:34 ] @
Zdravo svima. :) Početnik sam i možda sam zagrizao više nego što mogu da progutam. Trudim se da napravim neki vid online shop-a i nešto je zapelo oko stranice gde su mi izlistani produkti. Produkte izvlačim iz baze putem AJAX-a, i nekoliko funkcija obrađuje to što stigne. Dobar deo stvari sam sredio ali ne mogu da dovedem u red pagination. Skinuo sam par skripti ali jedino što je pokazivalo znake života je nešto što sam pokupio preko jednog tutorijala na yt. Pagination sam vezao za AJAX poziv, to jest za funkciju koja filtrira i sortira podatke dobijene preko AJAX-a. Ova konkretna verzija pagination skripte sve izlistane produkte podeli produkte po "stranicama" tako što neke sakrije a neke otkrije ( jQuery show/hide). Kada se otvori zadata stranica, brojevi stranica se vide ali se vide i svi produkti što ne bi trebalo da se desi. Kada se klikne, npr. na 1, on sakrije sve osim prve dve (ili više) stranice, tj. tad skripta profunkcioniše. Ne znam u čemu je problem. Ostaviću deo koda ako neko može da me barem usmeri u logici....
Code:

    function checkedFilters(){
        var opts = [];
        $checkboxes.each(function(){
            if(this.checked){
                opts.push(this.id);
            }
        });

        return opts;
    }

    var $checkboxes = $("input:checkbox");
    $checkboxes.on("change", function(){
        var opts = checkedFilters();
        var $orderBy = $("#by-price").val();
        fetchData(opts, $orderBy);

    });
    $checkboxes.trigger("change");

    $("#by-price").on("change", function() {
        var opts = checkedFilters();
        var $orderBy = $("#by-price").val();
        fetchData(opts, $orderBy);
    });

    function fetchData (opts, $orderBy){
        $.ajax({
            type: 'post',
            url: 'submit.php',
            dataType : 'json',
            cache: false,
            success: function(records){
                globalContent(jQuery.parseJSON(formatData(records)), opts, $orderBy);

            }

        });
    }





    Array.prototype.contains = function(obj) {
        var i = this.length;
        while (i--) {
            if (this[i] == obj) {
                return true;
            }
        }
        return false;
    };

    function globalContent (result, opts, $orderBy) {
        var orderBy = $orderBy;
        var results = [];
        var filterOpt = opts;
        for (var x = 0; x < result.length; x++) {
            for (var i = 0; i < filterOpt.length; i++) {
                if (result[x].colors[i] !== null) {
                    if (result[x].colors.contains(filterOpt[i]) || filterOpt[i] === result[x].brand || filterOpt[i] === result[x].format) {
                        if (results.contains(result[x]) === false) {
                            results.push(result[x]);
                        }
                    }
                }
            }
        }


        if (results.length == 0) {
            if (orderBy == 1) {
                result.sort(function (a, b) {

                    return parseInt(a.price, 10) - parseInt(b.price, 10);

                });
                $('#products-section').html(makeContent(result));
            } else {

                result.sort(function (a, b) {

                    return parseInt(b.price, 10) - parseInt(a.price, 10);

                });
                $('#products-section').html(makeContent(result));
            }

        }
        else {
            if (orderBy == 1) {
                results.sort(function (a, b) {

                    return parseInt(a.price, 10) - parseInt(b.price, 10);

                });
                $('#products-section').html(makeContent(results));
            } else {

                results.sort(function (a, b) {

                    return parseInt(b.price, 10) - parseInt(a.price, 10);

                });
                $('#products-section').html(makeContent(results));
            }

        }
        $(".paginate").trigger("custom");
    }

    $(".paginate").on("custom", function () {
        $(".paginate").customPagination({
            itemsForPage : ".product",
            itemsPerPage : 2
        });
        $(".paginate ul:not(:first)").remove();
    });

[ agvozden @ 15.01.2016. 09:11 ] @
moj ti je savet da pises komentare u kodu, da bi ti mogao da pratis, a da bi i oni koji zele da ti pomognu mogli lakse da se snadju.
ovako treba procitati gomilu koda i razumeti ga, za sta retko ko ima vremena.
ako koristis plaginove, das napomenu...

npr, customPagination, to ti je neki jquery plagin?
[ dusans @ 15.01.2016. 09:32 ] @
Sav kod koji radi sve okolo je tu, osim onog što treba i koji je bitan - a to je onaj koji radi sakrivanje kada klikneš na paginaciju.

Inače, mislim da ideš pogrešnim pristupom ako je u pitanju online shop:
1. Sve što dovlačiš preko ajax-a i gradiš preko js je nevidljivo za search engines - ozbiljan problem.
2. Ne postoji način da preko url-a prikažeš određenu stranicu sa određenim filterima - problem.
3. Filterovanje, sortiranje i paging je posao DBMS-a a ređe PHP-a a pogotovo nije posao JS-a - razni problemi, u prvoj liniji performanse.

Dakle, ako učiš pa se igraš - onda je ovo u redu. Ako zaista praviš web shop - dizajn ti ne valja.
[ jablan @ 15.01.2016. 10:39 ] @
Citat:
dusans
1. Sve što dovlačiš preko ajax-a i gradiš preko js je nevidljivo za search engines - ozbiljan problem.
2. Ne postoji način da preko url-a prikažeš određenu stranicu sa određenim filterima - problem.

U principu oba ova problema su rešiva - kontroler može da vrati različite rezultate u zavisnosti od toga da li se stranica traži preko AJAX-a ili običnim web zahtevom, a pushState omogućava da se URL menja dinamički bez potrebe za reloadom cele stranice. :)
[ dusans @ 15.01.2016. 11:02 ] @
Slažem se, naravno da je rešivo (i ja sam koristio obe stvari).

Međutim, pisao sam u kontekstu njegove trenutne implementacije i šta se odatle vidi.

1. Ovime učitava podatke sa servera prvi put, dakle nije mu inicijalno server izrendao podatke već isključivo ide preko ajax-a:
Code:

$checkboxes.trigger("change");

2. Kada učita podatke preko ajax-a, nigde nije modifikovao url.


Iako je sve u principu rešivo/nabudživo, mislim da je krenuo od kraja a ne od početka, kako bi trebalo:
1. Filtering, sorting, paging u BP a ne u JS
2. Server da vraća kompletnu stranicu bez potrebe za naknadnim ajax-om (da uzima u obzir i url parametre)
3. Kao šlag na tortu - učitavati potrebne delove preko ajax-a sa modifikacijom url-a
4. Alternativno - bez ikakvog ajax-a, jednostavno da modifikuje url na svaku akciju i učitava celu stranicu svaki put
[ jablan @ 15.01.2016. 11:48 ] @
Slažem se sa svime. Mada, ako želi, može da proba da napravi neku vrstu fat client-a u JS, ali ja bih tu svakako koristio neki provereni JS frejmvork.
[ agvozden @ 15.01.2016. 12:00 ] @
nema inicijatora teme da komentariše,

@dusans pitanje je za šta on uopšte ovo koristi, može biti da mu je ovo modul samo za određenu stranicu, a da postoje stranice koje su generisane po seo pravilima

npr imam slično rešenje, samo što nije paginacija, već infinity scroll (ne učitava sve proizvode odjednom nego sukcesivno, možda smo mogli na to da mu skrenemo pažnju), a na kategorijama postoji ceo prikaz. Plus razne sitemap (xml, html...) koje sugerišu pretraživačima...
[ nemchus @ 15.01.2016. 12:29 ] @
Hvala vam ljudi, svaka sugestija mi je bitna. ;) Projekat radim za sebe, pre svega, radi vežbanja a u budućnosti može da preraste u isplativ projekat i deo portfolia. Bitno mi je da rešenje ne bude previše komplikovano jer sve radim sam a više sam orijentisan ka front-end-u. Verujem da cela ova priča može bolje da se odradi preko nekog frameworka za php ili slično ali ja imam ograničena znanja.
Pre ovog konkretnog rešenja, filtriranje je išlo preko php-a odnosno u samom mysql query sam prosleđivao id-je čekiranih polja preko AJAX-a i tako pronalazio ono što mi treba. Nešto nije funkcionisalo pa sam digao ruke od tog pristupa a i neki ljudi su mi rekli da bi bilo bolje da sve podatke povučem iz baze pa da ih onda preko js/jquery-ja formatiram, filtriram, sortiram itd.
Iz vaših komentara mi se čini da nisam baš na pravom putu ali da može da se sredi?
Evo koda sa komentarima:

Code:

//    Ovo mi je glavna funkcija za serviranje sadržaja. Argumenti koji se prosledjuju su result, podaci sa AJAX-a,
//      onda opts, niz sa id čekiranih polja i na kraju $orderBy, gde se prosleđuje 1 ili 2 iz select box-a (sortiranje po ceni).


    function globalContent (result, opts, $orderBy) {
        var orderBy = $orderBy;
        console.log(orderBy);
        var results = [];
        var filterOpt = opts;
        for (var x = 0; x < result.length; x++) {
            for (var i = 0; i < filterOpt.length; i++) {
                if (result[x].colors[i] !== null) {
                    if (result[x].colors.contains(filterOpt[i]) || filterOpt[i] === result[x].brand || filterOpt[i] === result[x].format) {
                        if (results.contains(result[x]) === false) {
                            results.push(result[x]);
                        }
                    }
                }
            }
        }


        if (results.length == 0) {
            if (orderBy == 1) {
                result.sort(function (a, b) {

                    return parseInt(a.price, 10) - parseInt(b.price, 10);

                });
                $('#products-section').html(makeContent(result));
            } else {

                result.sort(function (a, b) {

                    return parseInt(b.price, 10) - parseInt(a.price, 10);

                });
                $('#products-section').html(makeContent(result));
            }

        }
        else {
            if (orderBy == 1) {
                results.sort(function (a, b) {

                    return parseInt(a.price, 10) - parseInt(b.price, 10);

                });
                $('#products-section').html(makeContent(results));
            } else {

                results.sort(function (a, b) {

                    return parseInt(b.price, 10) - parseInt(a.price, 10);

                });
                $('#products-section').html(makeContent(results));
            }

        }
//        Ovde sam ubacio trigger za .paginate funkciju jer tako jedino funkcioniše u mom slučaju.
//        Moja zamisao je bila da po aktiviranju AJAX-a i dopremanja podataka, customPagination() izdeli po stranicama odmah po dolasku na stranicu.
        $(".paginate").trigger("custom");
    }

    $(".paginate").on("custom", function () {
        $(".paginate").customPagination({
            itemsForPage : ".product",
            itemsPerPage : 2
        });
//        Ovo sam morao da dodam jer mi se ponavlja ul sa brojevima paginacije. To je neki bug koji je vezan za paljenje AJAX-a.
        $(".paginate ul:not(:first)").remove();
    });




Ovde mi je php kod koji izvlači podatke iz baze:

Code:

<?php

include ("database.php");
$pdo = database::connect();
$select = 'SELECT naziv, cena, slika, boja_naziv, brand_naziv, format_naziv';
$from = ' FROM produkti LEFT JOIN boja_kon ON produkti_id = produkti.id
                        LEFT JOIN format ON format_id = format.id
                        LEFT JOIN brand ON brand_id = brand.id
                        LEFT JOIN boja ON boja_id = boja.id';
$whereBrand = ' WHERE TRUE';

$sql = $select . $from . $whereBrand;
$statement = $pdo->prepare($sql);
$statement -> execute();
$results = $statement -> fetchAll(PDO::FETCH_ASSOC);
$json = json_encode($results);
echo($json);


?>