Отсортировать статьи по дате

291
06 марта 2018, 05:50

Есть такой код, нужно отсортировать статьи по дате при нажатии на кнопку Sort by date, но без jQuery, всяких плагинов и т.д., исключительно на Javascript.

Код:

var url = 'https://api.nytimes.com/svc/mostpopular/v2/mostviewed/movies/30.json?api-key='; 
 
var xhttp = new XMLHttpRequest(); 
 
xhttp.onreadystatechange = function () { 
    if (this.readyState == 4 && this.status == 200) { 
        var data = JSON.parse(xhttp.responseText).results; 
        var posts = data.map(mapToPost); 
 
        document.getElementById('demo').innerHTML = getPostsTemplate(posts); 
    } 
}; 
 
xhttp.open("GET", url, true); 
xhttp.send(); 
 
function mapToPost(post) { 
    return { 
        link: post.url, 
        img: post.media[0] ? post.media[0]["media-metadata"][2].url : null, 
        description: post.abstract, 
        title: post.title, 
        date: post.published_date 
    }; 
} 
 
function getPostsTemplate(posts) { 
    return posts.reduce(function (tmpl, post) { 
        tmpl += '<div class="post">\n' + 
                    '<h2 class="post-title">' + post.title + '</h2>\n' + 
                    '<img src=' + post.img + '>\n' + 
                    '<p class="post-description">' + post.description + '</p>\n' + 
                    '<a class="post-link" href=' + post.link + '>Read more</a>\n' + 
                    '<p class="post-date"> Publication date: ' + post.date + '</p>\n' + 
                    '<hr> <br> <br>\n' + 
                '</div>\n'; 
 
        var arr = []; 
        arr.push(post.date); 
        console.log(arr); 
 
        return tmpl; 
    }, ''); 
}
<button>Sort by date</button> 
 
<div id="demo"></div>

Answer 1

Шаги.

Сохраняем массив с данными в переменную, которую потом будем сортировать.

Сортируем с помощью метода sort.

Показываем результат.

var url = 'https://gist.githubusercontent.com/Stepan-Kasyanenko/ee48c8b9fd14508ae5afa8f997dbdd81/raw/e1722f1c649af591bb3d3bea2e23909b5c50e8b9/Article%2520for%2520nytimes'; 
 
//Для сохранение исходного массива 
var posts = []; 
// Флаг для убывания\возрастания 
var isDesc = false; 
 
var xhttp = new XMLHttpRequest(); 
 
xhttp.onreadystatechange = function() { 
  if (this.readyState == 4 && this.status == 200) { 
    var data = JSON.parse(xhttp.responseText).results; 
    posts = data.map(mapToPost); 
    //Сортируем по возрастанию при первом показе 
    document.getElementById('demo').innerHTML = getPostsTemplate(sortByField(posts, 'date', isDesc)); 
  } 
}; 
 
xhttp.open("GET", url, true); 
xhttp.send(); 
 
function sortClick() { 
  isDesc = !isDesc; 
  document.getElementById('demo').innerHTML = getPostsTemplate(sortByField(posts, 'date', isDesc)); 
} 
 
// Сортируем массив по данному полю 
function sortByField(array, field, isDesc) { 
  var sign = isDesc ? -1 : 1; 
 
  return array.sort((a, b) => { 
    if (a[field] > b[field]) return sign; 
    else if (a[field] === b[field]) return 0 
    else return -sign; 
  }); 
} 
 
function mapToPost(post) { 
  return { 
    link: post.url, 
    img: post.media[0] ? post.media[0]["media-metadata"][2].url : null, 
    description: post.abstract, 
    title: post.title, 
    date: post.published_date, 
    date_: new Date(post.published_date) // поле нужно для правильной сортировки 
  }; 
} 
 
function getPostsTemplate(posts) { 
  return posts.reduce(function(tmpl, post) { 
    tmpl += '<div class="post">\n' + 
      '<h2 class="post-title">' + post.title + '</h2>\n' + 
      '<img src=' + post.img + '>\n' + 
      '<p class="post-description">' + post.description + '</p>\n' + 
      '<a class="post-link" href=' + post.link + '>Read more</a>\n' + 
      '<p class="post-date"> Publication date: ' + post.date + '</p>\n' + 
      '<hr> <br> <br>\n' + 
      '</div>\n'; 
 
    return tmpl; 
  }, ''); 
}
<button onclick="sortClick()">Sort by date</button> 
 
<div id="demo"></div>

Answer 2

Готовый код вам врядли кто-то напишет. Но у меня была бы последовательность действий такая:

1) Забираю все объекты с API, кладу их в массив

2) При помощи reduce отсортировываю объекты по дате.

Пример кода:

 let arr= [
  {
    id: 1,
    date: "2018-02-18"
  },
  {
    id: 2,
    date: "2018-02-06"
  },
  {
    id: 3,
    date: "2018-02-22"
  }
];

let newArr = arr.reduce(function(result, item) {
  const val = item['date'];
  result[val] = result[val] || [];
  result[val].push(item)
  return result;
}, {});
console.log(newArr);
READ ALSO
Как добавить outerHTML в куки?

Как добавить outerHTML в куки?

Как добавить HTML код определенных элементов в куки?Точнее есть генератор который при нажатии генерирует div элемент с рандомным цветом и в рандомный...

259
Организация JS кода с Webpack

Организация JS кода с Webpack

Есть сайтик на phpВстал вопрос организациии js

258
jQuery: как избежать глобальных переменных в калькуляторе?

jQuery: как избежать глобальных переменных в калькуляторе?

Калькулятор состоит из нескольких чекбоксов, ползунков и селектовИ в принципе работает, но обновление результатов происходит только после...

218
Настройка Slick слайдера

Настройка Slick слайдера

Всем "Зраствуйте"! У меня проблема: мне нужно настроить slick slider таким образом, чтобы он автоматически прокручивался до последнего слайдера...

237