1
votes

Le tri de ma liste ne fonctionne pas correctement dans jQuery

J'ai créé un tri à 4 voies dans jQuery sur mes attributs de données. Mais lorsque je clique sur une option de tri, elle trie toujours par ordre alphabétique de A à Z pour une fois. Lorsque je clique une autre fois sur un tri, cela ne fait rien.

Lorsque je fais un journal de console pour voir sur quel élément est cliqué, j'obtiens les résultats suivants:

jQuery('body').on('click', '.sort #js-az', function(){
    jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

    function sort_li(a,b){
        return (jQuery(b).data('name')) < (jQuery(a).data('name')) ? 1 : -1;    
    }
});

jQuery('body').on('click', '.sort #js-za', function(){
    jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

    function sort_li(b,a){
        return (jQuery(b).data('name')) < (jQuery(a).data('name')) ? 1 : -1;    
    }
});

jQuery('body').on('click', '.sort #js-1-10', function(){
    jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

    function sort_li(a,b){
        return (jQuery(b).data('count')) < (jQuery(a).data('count')) ? 1 : -1;    
    }
});

jQuery('body').on('click', '.sort #js-10-1', function(){
    jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

    function sort_li(b,a){
        return (jQuery(b).data('count')) < (jQuery(a).data('count')) ? 1 : -1;    
    }
});

Vous pouvez trouver l'aperçu en direct ici: https://mpdb.space/mp-songs/


7 commentaires

Veuillez noter que vous avez fermé votre avec , AZ ... Corrigez ça et ça marche.


Oh non, c'était un mauvais copier-coller de mon code. La période de fermeture est dans mon code


Regardez ce violon, ce n'est pas ce que vous voulez jsfiddle.net/d9vge654


Votre violon fonctionne en effet, mais pas dans mon projet. Veuillez voir l'aperçu en direct: mpdb.space/mp-songs


J'ai également testé votre violon sur mon site Web et cela n'a pas fonctionné. Mais ça marche sur le site jsfiddle.net


Dennis vos travées ne sont PAS FERMÉES sur votre site Web.


Essayez de regarder cette image imgur.com/CVrfnRr


3 Réponses :


1
votes

Comme documenté ici , par défaut, le sort () < / code> trie les valeurs sous forme de chaînes par ordre alphabétique et croissant. Cependant, vous pouvez modifier son comportement en passant une fonction de comparaison. Vous n'avez pas spécifié le résultat que vous souhaitez obtenir, vous devrez donc créer une fonction avec la logique de tri souhaitée.


2 commentaires

Mais le truc, c'est que lorsque je colle le code dans la fenêtre de la console, cela fonctionne


Étrange ... essayez de corriger les balises de fermeture de span et voyez si cela aide



1
votes

Les attributs de données renvoient toujours une chaîne (d'ailleurs, les champs de saisie également, erreur courante), dont le résultat de la comparaison diffère de la comparaison des nombres:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="sort">
  <span class="sort__item" id="js-az">A-Z</span>
  <span class="sort__item" id="js-za">Z-A</span>
  <span class="sort__item" id="js-1-10">1-10</span>
  <span class="sort__item" id="js-10-1">10-1</span>
</div>

<div class="row js-songs-sortable" id="all-song-list">
  <div data-count="5" data-name="Strange Days">data-count="5" data-name="Strange Days"</div>
  <div data-count="1" data-name="Rock Bottom">data-count="1" data-name="Rock Bottom"</div>
  <div data-count="1" data-name="Moutain">data-count="1" data-name="Moutain"</div>
  <div data-count="3" data-name="Mad Sun">data-count="3" data-name="Mad Sun"</div>
  <div data-count="10" data-name="Another Ugly Tune">data-count="10" data-name="Another Ugly Tune"</div>
</div>

Vous devez les convertir en nombre avec un + :

(+ $ (a) .data ('count')

Mais comme vous devez renvoyer n'importe quel nombre positif ou négatif, vous pouvez simplement les soustraire. L'opérateur - les transformera automatiquement en nombres.

.sort__item {
  display: inline-block;
  cursor: pointer;
  border: 2px solid orange;
  margin: 5px;
  padding: 5px;
}

.sort__item.active { background-color: orange; }
var funcStorage = {
  az: (a, b) => $(a).data('name') < $(b).data('name') ? -1 : 1,
  za: (a, b) => $(a).data('name') > $(b).data('name') ? -1 : 1,
  "1-10": (a, b) => $(a).data('count') - $(b).data('count'),
  "10-1": (a, b) => $(b).data('count') - $(a).data('count'),
}; // If this seems `Alien-code`, Google → JS objects, JS arrow functions

//          (a,b) => a - b               The same
// function (a,b) { return a - b }       thig.

$('.sort__item').each(function(){
  $(this).on('click', function(){
    var func = funcStorage[ this.id.replace("js-","") ];
    // in fact, you don't need id, could store the sort key in data-sort
    $(".js-songs-sortable > div").sort(func).appendTo('.js-songs-sortable');
    
    $('.sort__item.active').removeClass('active');
    $(this).addClass('active');
  });
});

Et version abrégée de votre code:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="sort">
  <span class="sort__item" id="js-az">A-Z</span>
  <span class="sort__item" id="js-za">Z-A</span>
  <span class="sort__item" id="js-1-10">1-10</span>
  <span class="sort__item" id="js-10-1">10-1</span>
</div>

<div class="row js-songs-sortable" id="all-song-list">
  <div data-count="5" data-name="Strange Days">data-count="5" data-name="Strange Days"</div>
  <div data-count="1" data-name="Rock Bottom">data-count="1" data-name="Rock Bottom"</div>
  <div data-count="1" data-name="Moutain">data-count="1" data-name="Moutain"</div>
  <div data-count="3" data-name="Mad Sun">data-count="3" data-name="Mad Sun"</div>
  <div data-count="10" data-name="Another Ugly Tune">data-count="10" data-name="Another Ugly Tune"</div>
</div>
$('#js-az').on('click', function() {
  $(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');
  
  function sort_li(a, b) {
    return ( $(a).data('name') < $(b).data('name') ) ? -1 : 1;
  }
});

$('#js-za').on('click', function() {
  $(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(a, b) {
    return ( $(a).data('name') > $(b).data('name') ) ? -1 : 1;
  }
});

$('#js-1-10').on('click', function() {
  $(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');
  
  function sort_li(a, b) {
    return $(a).data('count') - $(b).data('count');
  }
});

$('#js-10-1').on('click', function() {
  $(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(a, b) {
    return $(b).data('count') - $(a).data('count')
  }
});
console.log( "9" > "111" ) // true
console.log( "310" > "31" ) // true


3 commentaires

Cela donne exactement le même résultat que ce qui est en direct en ce moment. Veuillez vérifier mpdb.space/mp-songs/


@Dennis Markup!) Vous avez az za 1 - 10 , doit être az za 1 - 10 ; Dans ce cas, cela a fonctionné correctement (testé sur votre site). De plus, avec l'erreur $ n'est pas une fonction , vous pouvez envelopper tout le code dans une autre fonction (function ($) {/ * utiliser librement $ * /}) (jQuery); - qui s'exécute automatiquement et crée une variable locale $ comme jQuery


Merci! La faute de frappe était l'un des problèmes. J'ai également changé .data ('nom') en .attr ('data-name'). Tout fonctionne comme il se doit.



0
votes

Le problème avec votre code est que vous utilisez .data alors que vous devez utiliser .attr().

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="sort">
  <span class="sort__item" id="js-az">A-Z</span>
  <span class="sort__item" id="js-za">Z-A</span>
  <span class="sort__item" id="js-1-10">1-10</span>
  <span class="sort__item" id="js-10-1">10-1</span>
</div>

<div class="row js-songs-sortable" id="all-song-list">
  <div class="col-md-4 col-sm-12" data-count="5" data-name="Strange Days">

  </div>
  <div class="col-md-4 col-sm-12" data-count="1" data-name="Rock Bottom">

  </div>
  <div class="col-md-4 col-sm-12" data-count="1" data-name="Moutain">

  </div>
  <div class="col-md-4 col-sm-12" data-count="3" data-name="Mad Sun">

  </div>
  <div class="col-md-4 col-sm-12" data-count="10" data-name="Another Ugly Tune">

  </div>
</div>
.sort {
  border-radius: 5px;
  background-color: #eee;
  display: inline-block;
  margin-bottom: 1rem;
}

.sort span {
  padding: 1rem;
  cursor: pointer;
  transition: all 0.3s;
  display: inline-block;
}

.sort span:hover {
  background-color: rgba(0, 0, 0, 0.1);
}

.row>div {
  padding: 0.5rem;
}

.row>div::after {
  content: "data-count= " attr(data-count) " data-name= " attr(data-name);
}
jQuery('body').on('click', '.sort__item', function() {
  const id = jQuery(this).attr("id");

  jQuery(".js-songs-sortable > div").sort(function(a, b) {
    let firstEl = jQuery(a);
    let secondEl = jQuery(b);
    let $return = 0;

    switch (id) {
      case "js-az":
        $return = (firstEl.attr('data-name') > secondEl.attr('data-name')) ? 1 : -1;
        break;

      case "js-za":
        $return = (firstEl.attr('data-name') < secondEl.attr('data-name')) ? 1 : -1;
        break;

      case "js-1-10":
        $return = (parseInt(firstEl.attr('data-count')) > parseInt(secondEl.attr('data-count'))) ? 1 : -1;
        break;

      case "js-10-1":
        $return = (parseInt(firstEl.attr('data-count')) < parseInt(secondEl.attr('data-count'))) ? 1 : -1;
        break;
    }

    return $return;
  }).appendTo('.js-songs-sortable');
});

De plus, vous pouvez modifier un peu votre code pour la maintenabilité et la lisibilité. Voir cet exemple:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="sort">
  <span class="sort__item" id="js-az">A-Z</span>
  <span class="sort__item" id="js-za">Z-A</span>
  <span class="sort__item" id="js-1-10">1-10</span>
  <span class="sort__item" id="js-10-1">10-1</span>
</div>

<div class="row js-songs-sortable" id="all-song-list">
  <div class="col-md-4 col-sm-12" data-count="5" data-name="Strange Days">

  </div>
  <div class="col-md-4 col-sm-12" data-count="1" data-name="Rock Bottom">

  </div>
  <div class="col-md-4 col-sm-12" data-count="1" data-name="Moutain">

  </div>
  <div class="col-md-4 col-sm-12" data-count="3" data-name="Mad Sun">

  </div>
  <div class="col-md-4 col-sm-12" data-count="10" data-name="Another Ugly Tune">

  </div>
</div>
.sort {
  border-radius: 5px;
  background-color: #eee;
  display: inline-block;
  margin-bottom: 1rem;
}

.sort span {
  padding: 1rem;
  cursor: pointer;
  transition: all 0.3s;
  display: inline-block;
}

.sort span:hover {
  background-color: rgba(0, 0, 0, 0.1);
}

.row>div {
  padding: 0.5rem;
}

.row>div::after {
  content: "data-count= " attr(data-count) " data-name= " attr(data-name);
}
jQuery('body').on('click', '.sort #js-az', function() {
  jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(a, b) {
    return (jQuery(b).attr('data-name')) < (jQuery(a).attr('data-name')) ? 1 : -1;
  }
});

jQuery('body').on('click', '.sort #js-za', function() {
  jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(b, a) {
    return (jQuery(b).attr('data-name')) < (jQuery(a).attr('data-name')) ? 1 : -1;
  }
});

jQuery('body').on('click', '.sort #js-1-10', function() {
  jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(a, b) {
    return (parseInt(jQuery(b).attr('data-count'))) < parseInt((jQuery(a).attr('data-count'))) ? 1 : -1;
  }
});

jQuery('body').on('click', '.sort #js-10-1', function() {
  jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(b, a) {
    return parseInt(jQuery(b).attr('data-count')) < parseInt(jQuery(a).attr('data-count')) ? 1 : -1;
  }
});


1 commentaires

Merci beaucoup de changer .data ('nom') en .attr ('data-name') fait l'affaire. Et bien sûr aussi la faute de frappe à