Страницы

Поиск по вопросам

среда, 22 января 2020 г.

Выборка объектов массива с их последующей вставкой в разметку страницы

#javascript #массивы #веб_программирование #циклы #объекты


Господа, прошу помощи, ибо никак не могу организовать логику скрипта, который находил
бы нужные объекты и вставлял их в разметку. Подробности ниже.

Есть таблица календаря, которая генерится а js, есть массив объектов, каждый объект
хранит в себе информацию о годе+месяце (year), дне месяца (day), событии (event), остальные
параметры не так важны. Нужен скрипт, который будет пробегать по массиву, сверять месяц+год
календаря с месяцем+годом в объектах, если все совпадает, то далее пробегать по таблице
и сверять день календаря с днями в объектах, если совпадает, то в ячейку с совпадающей
датой добавлять div с event, хранящимся в объекте.

Сейчас происходит почти то что нужно, НО если в массиве есть несколько объектов с
совпадающими day объекта и днем календаря, то в ячейку с датой добавляется ТОЛЬКО первый
объект, остальные игнорируются.

Вот так это выглядит сейчас:



let arr = [{
    dateEvent: "Первый тест",
    day: "11",
    description: "Первый тест",
    event: "Первый тест",
    names: "Первый тест",
    year: "Октябрь 2017"
  },
  {
    dateEvent: "Второй тест",
    day: "11",
    description: "Первый тест",
    event: "Первый тест",
    names: "Первый тест",
    year: "Октябрь 2017"
  },
  {
    dateEvent: "Третий тест",
    day: "11",
    description: "Первый тест",
    event: "Первый тест",
    names: "Первый тест",
    year: "Октябрь 2017"
  },
  {
    dateEvent: "Четвертый тест",
    day: "10",
    description: "Первый тест",
    event: "Первый тест",
    names: "Первый тест",
    year: "Октябрь 2017"
  },

]

const showAllEvents = () => {

  let arrEvents = arr,
    list = document.getElementById("organizer").getElementsByTagName('td');

  //берем первый день - внешний цикл
  for (let j = 0; j < list.length; j++) {

    //первый объект в массиве - внутренний цикл
    for (let i = 0; i < arrEvents.length; i++) {


      //проверяем соответсвие месяца и года с данными в объекте
      if (document.getElementById('year').innerHTML === arrEvents[i].year) {

        //проверяем день календаря и день объекта
        if (list[j].innerHTML === arrEvents[i].day) {

          //тут слайсится Событие
          let text = arrEvents[i].event,
            slicedEvent = text.slice(0, 15);

          if (slicedEvent.length < text.length) {

            slicedEvent += '...';
          }

          //создаем див, в него вставляем дивы с данными, которые должны хранится
в ячейке
          let appendDiv = document.createElement('div');
          appendDiv.className = 'event-div';

          appendDiv.innerHTML = `
                    
` + slicedEvent + `
`; //вставляем этот див в текущую ячейку document.getElementsByTagName('td')[j].appendChild(appendDiv); } //как я понимаю, внутренний цикл должен повториться и перейти ко второму объекту, //но почему-то вместо этого сразу начинается новая итерация внешнего цикла } } } }; showAllEvents(); body { width: 100%; height: 100%; margin: 0; padding: 0; position: relative; z-index: 333; } #calendar { width: 80%; height: 90%; margin: 0 auto; } #control-month span:first-child, #control-month span:last-child { cursor: pointer; } #control-month div { cursor: pointer; } #organizer { border-collapse: collapse; width: 100%; font-family: monospace; line-height: 1.2em; font-size: 15px; text-align: center; word-break: break-all; table-layout: fixed; } #organizer thead { color: rgb(50, 50, 50); font-size: 10px; } #organizer tbody tr { height: 80px; } #organizer tbody td { position: relative; color: rgb(44, 86, 122); font-size: 10px; vertical-align: top; cursor: pointer; border: 1px solid dimgrey; z-index: 33; } #organizer tbody td:nth-child(n+6), #organizer .holiday { color: rgb(231, 140, 92); } #organizer tbody td.today { background: rgb(220, 0, 0); color: #fff; } #cover-div { width: 15%; height: 25%; position: absolute; background: lightsteelblue; border: 1px solid darkgray; } #cover-div input, #cover-div textarea { box-sizing: border-box; } #overlay-div { width: 100%; height: 100%; top: 0; left: 0; position: fixed; } Title
Октябрь 2017
Сегодня
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          
Прошу сильно ссаными тряпками не кидаться, а объяснить что происходит, кажется я не совсем верно понимаю работу циклов. Или же в логике ошибка?


Ответы

Ответ 1



Проблема в том, что вы сравниваете list[j].innerHTML === arrEvents[i].day. После первого успешного совпадения list[j].innerHTML уже не будет только текст 11, потому что вы добавляете туда несколько новых элементов document.getElementsByTagName('td')[j].appendChild(appendDiv);. Для обхода этой ситуации можно хранить данные в data-* атрибутах элемента. Вообще, лучше данные хранить там, и по возможности стараться избегать сравнений вида list[j].innerHTML === arrEvents[i].day. Пример работающего кода. let arr = [{ dateEvent: "Первый тест", day: "11", description: "Первый тест", event: "Первый тест", names: "Первый тест", year: "Октябрь 2017" }, { dateEvent: "Второй тест", day: "11", description: "Первый тест", event: "Второй тест", names: "Первый тест", year: "Октябрь 2017" }, { dateEvent: "Третий тест", day: "11", description: "Первый тест", event: "Третий тест", names: "Первый тест", year: "Октябрь 2017" }, { dateEvent: "Четвертый тест", day: "10", description: "Первый тест", event: "Четвертый тест", names: "Первый тест", year: "Октябрь 2017" }, ] const showAllEvents = () => { let arrEvents = arr, list = document.getElementById("organizer").getElementsByTagName('td'), year = document.getElementById('year'); //берем первый день - внешний цикл for (let j = 0; j < list.length; j++) { let td = list[j]; //первый объект в массиве - внутренний цикл for (let i = 0; i < arrEvents.length; i++) { let event = arrEvents[i]; //проверяем соответсвие месяца и года с данными в объекте if (year.innerHTML === event.year) { //проверяем день календаря и день объекта if (td.getAttribute("data-day") === event.day) { //тут слайсится Событие let text = event.event, slicedEvent = text.slice(0, 15); if (slicedEvent.length < text.length) { slicedEvent += '...'; } //создаем див, в него вставляем дивы с данными, которые должны хранится в ячейке let appendDiv = document.createElement('div'); appendDiv.className = 'event-div'; appendDiv.innerHTML = `
` + slicedEvent + `
`; //вставляем этот див в текущую ячейку //document.getElementsByTagName('td')[j].appendChild(appendDiv); td.appendChild(appendDiv); // эквивалетно } //как я понимаю, внутренний цикл должен повториться и перейти ко второму объекту, //но почему-то вместо этого сразу начинается новая итерация внешнего цикла } } } }; showAllEvents(); body { width: 100%; height: 100%; margin: 0; padding: 0; position: relative; z-index: 333; } #calendar { width: 80%; height: 90%; margin: 0 auto; } #control-month span:first-child, #control-month span:last-child { cursor: pointer; } #control-month div { cursor: pointer; } #organizer { border-collapse: collapse; width: 100%; font-family: monospace; line-height: 1.2em; font-size: 15px; text-align: center; word-break: break-all; table-layout: fixed; } #organizer thead { color: rgb(50, 50, 50); font-size: 10px; } #organizer tbody tr { height: 80px; } #organizer tbody td { position: relative; color: rgb(44, 86, 122); font-size: 10px; vertical-align: top; cursor: pointer; border: 1px solid dimgrey; z-index: 33; } #organizer tbody td:nth-child(n+6), #organizer .holiday { color: rgb(231, 140, 92); } #organizer tbody td.today { background: rgb(220, 0, 0); color: #fff; } #cover-div { width: 15%; height: 25%; position: absolute; background: lightsteelblue; border: 1px solid darkgray; } #cover-div input, #cover-div textarea { box-sizing: border-box; } #overlay-div { width: 100%; height: 100%; top: 0; left: 0; position: fixed; } Title
Октябрь 2017
Сегодня
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          
P.S. Также немного отрефакторил ваш код.

Комментариев нет:

Отправить комментарий