Pagination JSON

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour à tous,

J'aurais besoin d'un coup de main pour de la pagination en Javascript. J'ai récupéré depuis un call Ajax des données en JSON (about 5000). Du coup je souhaiterais faire une pagination de ce call mais mes données ne s'affichent que sur la première page :/

Je ne vois absolument pas comment faire :/

Voici mon début de code :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
mobile: function(min, max){

    var _self = this;

    _self.getData({ 'cPosMin' : min, 'cPosMax' : max, 'mobile': true, 'isActive': _self._active}, function(data){

        var listAdmin = jQuery('<ul>'),
            listUser = jQuery('<ul>'),
            paginate = jQuery('<div class="car_nav">'),
            nbElemPerPages = 20,
            page = 0;;

        jQuery('#user_list').html('');
        jQuery('#admin_list').html('');

        // sort name ascending
        data.results.sort(function(a,b){return a.name -b.name});

        jQuery.each(data.results, function(key, user){
            // displaying info
            var item = jQuery('<li class="type'+user.type+'" rel="'+ user.id + ' ">');
            item.append(jQuery('<div class="add">'));
            item.append(jQuery('<h3>').html(user.label);
            ...// other stuff

            if(user.type == 2){ // admin
                listAdmin.append(item);
            }
            else {
                listUser.append(item);
            }
            nbElemPerPages--;
            if(nbElemPerPages === 0){
                page++;
                nbElemPerPages = 20;
                paginate.append('<a href="#" onclick="showPage(' + page + ');">&lt;</a>');
                jQuery('#user_list').append(list);
            }
        });

        jQuery('#user_list').append(list);
        jQuery('#admin_list').append(listAdmin);
        return false;
    });
}

Mon code HTML:

1
2
3
4
<div id="content_list">
    <div id="user_list"></div>
    <div id="admin_list"></div>
</div>

Je n'arrive pas à faire en sorte que lorsque je clique sur mes pages 1/2/etc.. il affiche un contenu différent. J'ai pensé à faire un énorme tableau se composant de tableaux de 20 éléments uniquement mais je suis confronté au même problèmes car je ne vois pas comment lui dire lors du clic sur la page 2 charge les éléments.

Je ne souhaite pas refaire un call Ajax. Je voudrais le faire en une fois.

Quelqu'un pourrait il m'aider?

Merci d'avance

EDIT: Le soucis aussi ici, c'est que je suis dans une librairie custom. Je voudrais donc pouvoir tout faire dans la même méthode si possible ou faire appelle à mes méthodes mais dans ma librairie.

EDIT 2 : En fait avec ta méthode je vais faire boucle sur boucle non ? Ce n'est pas trop génial pour les perfs si ?

Édité par zaewyr

+0 -0

Voici ce que je ferais. Je ne sais pas si c'est une bonne solution, mais voici.

  1. Faire une fonction qui prend la description d'un item et retourne l'élément DOM à afficher.
  2. Mapper cette fonction sur la liste des descriptions.
  3. Couper la liste en plusieurs listes de la taille voulue au plus.
  4. Pour chacune de ces listes, construire l'élément DOM correspondant au tableau à afficher.
  5. Faire une fonction pour changer de page affichée et une fonction pour changer la barre avec les numéros des pages affichées.
  6. Avoir une variable maintenant l'id de la page affichée, une fonction pour en changer.

Je ne vais pas détailler tout ça, ça me semble pas très compliqué mais un peu long. Est-ce qu'une étape en particulier te bloque ?

PS : Je trouve ça pas génial de modifier nbElemPerPage (en tous cas ça m'a pris trop de temps pour comprendre ce qui se passe, je trouve, inutile de ne pas faire clair quand on peut). Je trouve que tu gagnerais en clarté à ne pas traiter séquentiellement chaque item par une grosse fonction mais à faire comme j'ai dit plus haut (par exemple, pour découper ton tableau en "chunks", ne le fais pas à la main, fais une fonction pour le faire et appliques-la). Pour gérer le fait que tu as deux listes, je pense qu'il vaudrait mieux séparer les items avant tout traitement et appliquer le code pour faire un tableau aux deux listes séparément.

+0 -0
Auteur du sujet

Salut et merci pour ta réponse,

J'avoue ne pas avoir trop compris tes différentes étapes… Par contre j'ai avancé dans ce que je voulais faire. Voici ce que ça donné :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
mobile: function(min, max){

    var _self = this;

    _self.getData({ 'cPosMin' : min, 'cPosMax' : max, 'mobile': true, 'isActive': _self._active}, function(data){

        var listAdmin = jQuery('<ul>'),
            listUser = jQuery('<ul>'),
            paginate = jQuery('<div class="car_nav">'),
            nbElemPerPages = 20,
            page = 0
            arrayPagination = [],
            pagination = [];

        jQuery('#user_list').html('');
        jQuery('#admin_list').html('');

        // sort name ascending
        data.results.sort(function(a,b){return a.name -b.name});

        jQuery.each(data.results, function(key, user){
            // displaying info
            var item = jQuery('<li class="type'+user.type+'" rel="'+ user.id + ' ">');
            item.append(jQuery('<div class="add">'));
            item.append(jQuery('<h3>').html(user.label);
            ...// other stuff

            if(user.type == 2){ // admin
                listAdmin.append(item);
            }
            else {
                listUser.append(item);
            }
            arrayPagination.push(item[0]);
            nbElemPerPages--;
            if ( nbElemPerPages === 0 ){
                page++;
                pagination.push(arrayPagination);
                arrayPagination = [];
                nbElemPerPages = 20;
                paginate.append('<a href="#" >' + page + '</a>');
           }
    });

    for(var i = 0; i< pagination.length; i++){
        (function(page){
            paginate.on('click', function(){
                console.log(pagination[page]);
                jQuery('#user_list').append(pagination[0]);
            });
        })(i);
    }

    jQuery('#user_list').append(paginate);
    return false;
});

Lorsque je clique sur ma page, il affiche tout de même mon tableau avec mes 4 éléments dedans (en gros toutes les données) mais lorsque je lui demande d'fficher que le premier sous tableau, il m'affiche bien que mes 20 premiers éléments. (normal vous me direz ^^)

EDIT : Re, Finalement, je ne vois pas trop ce qui change entre ta méthode et la mienne.. Peut être principalement de séparer le tout et de faire appelle à des méthodes mais sinon je pense que c'est le même raisonnement non ? Ton 1, je ne vois pas ce que tu veux dire quand tu dis :

fonction qui prend la description d'un item et retourne

Tu entends quoi par là ?

Et sinon je ne vois pas non plus ce que tu entends dans ton PS. En fait je voulais éviter de déclarer une autre variable pour mes pages, c'est pourquoi j'ai fait ça. Après je peux très bien tout faire en méthode mais je ne pense pas que ça changera grand chose. Je te fais et je repost.

Édité par zaewyr

+0 -0

Oui, c'était pas très clair cette « fonction qui prend la description d'un item et retourne l'élément DOM correspondant ». Dans ton code, c'est la partie en-dessous de // displaying info : on prend la description donnée par le JSON et on la transforme en un élément DOM.

Je trouve ton code vraiment pas clair. À quoi te sert listUser et listAdmin ? C'est quoi #store_list ? Veux-tu faire un tableau « user » ou un « admin » ou un seul ? Je ne comprends pas ta dernière boucle, etc.

Ce que je te conseille, c'est de faire étape par étape, en séparant bien les choses indépendantes. Déjà, oublies l'interface utilisateur avec les boutons pour changer de page. Si tu veux pas tout bien séparer, je peux comprendre. C'est sans doute exactement la même chose, mais j'ai personnellement pas envie de lire du code comme ça.

+0 -0
Auteur du sujet

Yop,

Désolé pour cette réponse tardive. En effet, j'ai tenté de tout mettre dans une nouvelle balise nommée store_list mais finalement je reste avec listUser. J'ai d'ailleurs réédité mon code dans le messsage précédent.

Sinon j'ai trouvé ma solution. Voici ce que j'ai rajouté. (J'ai utilisé la bibliothèque jQuery)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
for(var i = 0; i< pagination.length; i++){
    (function(page){
        paginate
          .find("a:eq("+page+")")
          .on('click', function(){
            jQuery('#user_list').find("ul").remove();
            jQuery('#user_list').append(pagination[page]);
          });
    })(i);
}

jQuery('#user_list').append(paginate);
jQuery('#user_list').find('a:eq(0)').get(0).click();

Il me manque juste un truc mais je referais le tout en suivant tes conseils. Je n'ai pas eu le temps d'y retoucher car j'ai une autre tâche à faire en urgence mais je reviendrais sous peu c'est aussi pourquoi je laisse le sujet en non résolu pour l'instant :)

+0 -0
Auteur du sujet

Yop,

Voilà ma solution finale si ça intéresse :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var nbElementPerPage = 20,
    contentList = jQuery('#mylist'),
    list = jQuery('<ul>'),
    containerList = [[]];

    jQuery.each(data.results, function (key, info) {
        if (containerList[containerList.length - 1].length === nbElementPerPage) {
            containerList.push([]);
            containerList[containerList.length - 2].unshift(designItem(closest(info.distance, data.results)));
        }
        if (info.type !== 2) {
            containerList[containerList.length - 1].push(designItem(info));
        }
    });

    var paginate = jQuery('<div class="nav">');
    paginate.html('');
    for (var i = 0; i < containerList.length; i++) {
        paginate.append('<a href="#" >' + (i + 1) + '</a>');
    }

    paginate.on('click', 'a', function () {
        var i = jQuery(this).index();
        jQuery(this).addClass('active');
        jQuery(this).siblings().removeClass('active');
        list.html('');
        jQuery.each(containerList[i], function (key, info) {
            list.append(info);
        });
    });
    contentList.html('');
    contentList.append(paginate);
    contentList.append(list);

    paginate.find('a:eq(0)').trigger('click');
    return false;
});

Amicalement, Zaewyr

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte