Страницы

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

вторник, 12 марта 2019 г.

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

Господа, прошу помощи, ибо никак не могу организовать логику скрипта, который находил бы нужные объекты и вставлял их в разметку. Подробности ниже.
Есть таблица календаря, которая генерится а 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          

Прошу сильно ссаными тряпками не кидаться, а объяснить что происходит, кажется я не совсем верно понимаю работу циклов. Или же в логике ошибка?


Ответ

Проблема в том, что вы сравниваете 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. Также немного отрефакторил ваш код.

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

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