@timofeus91
Junior Frontend Developer

Как создать пагинацию с многоточием?

Всем доброго дня! Никак не могу решить задачу с пагинацией . У нас есть большой массив объектов. Выглядит, в данный момент, он так - [ {page:1, index: 0, title: "1"},{page:2, index: 1, title: "2"}, ... тут много подобных объектов, {page:89, index: 88, title: "89"}]. Это все список доступных страниц. В объекте есть номер страницы, индекс этого элемента в массиве и текст, который по факту является копией page но только в виде строки. Ещё у меня есть константа maximumPagesButtonsState , в которой записано число. Это максимальное количество кнопок пагинации, которое должно быть в доступе. Сейчас там значение 5. Мне нужна функция , который этот массив обрежет и вернет новый, обрезанный с определенными условиями - первая и последняя page всегда должна оставаться в доступе. Остальное высчитывается в процентном соотношении. Например если цифра 5 в maximumPagesButtonsState , а активная страница 1 ., то значит что у нас на экране пагинации будет 1 ,2 , ... ,88,89. Там где многоточие это кнопка с текстом многоточия , которая может отправить нас примерно в 1/3 списка. То есть у этой кнопки объект будет выглядет ьследубющим образом {page: 35, index: 34, title : "35" }. Я пытался экспериментировать, но все никак не могу правильно рассчитать как должна работать функция. Пока у меня получился только следующий вариант, который работает некорректно

const generatePaginationButtons = (
  pagesData: PaginationItem[],
  activePage: number,
  maximumPagesButtonsState: number
): PaginationItem[] => {
  const result: { page: number | string; index: number | null; title: string }[] = [];

  if (pagesData.length <= maximumPagesButtonsState) {
    return pagesData;
  }

  const leftThreshold = Math.floor((maximumPagesButtonsState - 2) / 2);
  const rightThreshold = Math.ceil((maximumPagesButtonsState - 2) / 2);

  result.push(pagesData[0]);

  let startIndex: number, endIndex: number;

  if (activePage <= leftThreshold + 2) {
    startIndex = 1;
    endIndex = Math.min(maximumPagesButtonsState - 2, pagesData.length - 2);
  } else if (activePage >= pagesData.length - rightThreshold - 1) {
    startIndex = Math.max(pagesData.length - maximumPagesButtonsState + 2, 1);
    endIndex = pagesData.length - 2;
  } else {
    startIndex = activePage - leftThreshold;
    endIndex = activePage + rightThreshold;
    result.push({ page: '...', index: null, title: '...' });
  }

  for (let i = startIndex; i <= endIndex; i++) {
    result.push(pagesData[i]);
  }

  if (endIndex < pagesData.length - 2) {
    result.push({
      page: '...',
      index: null,
      title: '...',
    });
  }

  result.push(pagesData[pagesData.length - 1]);

  return result;
};
  • Вопрос задан
  • 271 просмотр
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы