简体   繁体   English

在表列中动态显示对象数组 - Javascript

[英]Displaying array of objects dynamically in table columns - Javascript

I am attempting to create an appointment slot selection grid.我正在尝试创建一个约会时段选择网格。 I have all the appointments grouped into dates.我已将所有约会分组到日期中。 I want to display the array of Objects below as a clickable grid.我想将下面的对象数组显示为可点击的网格。 I have everything I need but I'm having difficulty displaying it in columns.我有我需要的一切,但我很难在列中显示它。 My current output:我目前的输出: 在此处输入图片说明

As you can see it is displaying the correct appointments next to the correct date header however its adding the next one in the same row and so on.正如您所看到的,它在正确的日期标题旁边显示了正确的约会,但是它在同一行中添加了下一个约会,依此类推。 I want each date and its corresponding appointments to be displayed in separate columns.我希望每个日期及其相应的约会都显示在单独的列中。 Date header at the top with appointments listed below.顶部的日期标题和下面列出的约会。 I'm just using a main.js file and an index.html file.我只是使用一个 main.js 文件和一个 index.html 文件。

Grouped appointment slots array below looks something like this:下面的分组约会插槽数组如下所示:

2020-09-25: [{0:{AppointmentDateTime: "2020-09-25T13:00:00Z"}}]
2020-09-28: [{0:{AppointmentDateTime: "2020-09-28T08:00:00Z"}},{1:{AppointmentDateTime: "2020-09-28T10:30:00Z"}}, {2:{AppointmentDateTime: "2020-09-28T11:00:00Z"}}]
2020-09-29: [{0:{AppointmentDateTime: "2020-09-29T08:00:00Z"}},{1:{AppointmentDateTime: "2020-09-29T09:00:00Z"}}, {2:{AppointmentDateTime: "2020-09-29T11:00:00Z"}}]

Here is what I have so far:这是我到目前为止所拥有的:

let result = await response.json();
let groupedAppointments = {}

result.forEach((item) => {
    const date = item.AppointmentDateTime.split('T')[0]
    if (groupedAppointments[date]) {
        groupedAppointments[date].push(item);
    } else {
        groupedAppointments[date] = [item];
    }
})


var grid = clickableGrid(groupedAppointments, groupedAppointments, function(el, item) {
    console.log("You clicked on element:", el);
    selectedAppointment = item.AppointmentDateTime;
    console.log(selectedAppointment);
    el.className = 'clicked';
    if (lastClicked) lastClicked.className = '';
    lastClicked = el;
});

document.getElementById("clickable-grid").appendChild(grid);
function clickableGrid(groupedAppointments, index, callback) {
    var i = 0;
    var grid = document.createElement('table');

    grid.className = 'grid';

    Object.keys(groupedAppointments).forEach((item) => {

        var days = groupedAppointments[item];
        var tableRowHeader = grid.appendChild(document.createElement('tr'));
        var th = tableRowHeader.appendChild(document.createElement('th'));
        th.innerHTML = item;

        days.forEach((item) => {

            var tr = grid.appendChild(document.createElement('tr'));
            //var rowHeader = tr.appendChild(document.createElement('th'))
            var cell = tr.appendChild(document.createElement('td'));
            //rowHeader.innerHTML = item.SlotName;
            cell.innerHTML = item.AppointmentDateTime;
            cell.addEventListener('click', (function(el, item) {
                return function() {
                    callback(el, item);
                }
            })(cell, item), false);
        })

    })

    return grid;
}

I hope this is enough detail.我希望这是足够的细节。 Any questions just ask.有什么问题就问吧。 All help greatly appreciated.非常感谢所有帮助。

updated output:更新输出:

在此处输入图片说明

在此处输入图片说明

You shouldn't create a tr for each appointment.您不应该为每个约会创建一个tr

You need two loops.你需要两个循环。 One loop creates the header row with all the dates.一个循环创建包含所有日期的标题行。

Then you loop over the array indexes to create the data rows.然后遍历数组索引以创建数据行。 Within that, you have a nested loop for each date, filling in that column in the row.其中,每个日期都有一个嵌套循环,填充行中的该列。 Since dates will have different numbers of appointments, you need to check if the current date has that many appointments.由于日期将有不同数量的约会,您需要检查当前日期是否有那么多约会。 If it is you fill in the cell, otherwise you leave it empty.如果是,则填写单元格,否则将其留空。

 function clickableGrid(groupedAppointments, callback) { var i = 0; var grid = document.createElement('table'); grid.className = 'grid'; var longest = 0; var headerRow = grid.appendChild(document.createElement('tr')); Object.entries(groupedAppointments).forEach(([item, day]) => { if (day.length > longest) { longest = day.length; } var th = headerRow.appendChild(document.createElement('th')); th.innerHTML = item; }); for (let i = 0; i < longest; i++) { var tr = grid.appendChild(document.createElement('tr')); Object.values(groupedAppointments).forEach(item => { var cell = tr.appendChild(document.createElement('td')); if (i < item.length) { let time = item[i].AppointmentDateTime.split('T')[1].split('Z')[0]; cell.innerHTML = time; cell.addEventListener('click', (function(el, item) { return function() { callback(el, item); } })(cell, item[i]), false); } }); } return grid; } var data = { "2020-09-25": [{ AppointmentDateTime: "2020-09-25T13:00:00Z" }], "2020-09-28": [{ AppointmentDateTime: "2020-09-28T08:00:00Z" }, { AppointmentDateTime: "2020-09-28T10:30:00Z" }, { AppointmentDateTime: "2020-09-28T11:00:00Z" }], "2020-09-29": [{ AppointmentDateTime: "2020-09-29T08:00:00Z" }, { AppointmentDateTime: "2020-09-29T09:00:00Z" }, { AppointmentDateTime: "2020-09-29T11:00:00Z" }] }; document.body.appendChild(clickableGrid(data, function(cell, date) { console.log("You clicked on " + date.AppointmentDateTime); }));

It looks like your table is all over the place, you create 2 table rows when actually you need to use only one for every date (with both the th and the appointments) and you only need to go to a new row when a new date is presented.看起来你的表格到处都是,你创建了 2 个表格行,而实际上你只需要为每个日期使用一个(包括 th 和约会),并且你只需要在新日期时转到新行被表达。 I've changed some namings to be more precise (item doesn't tell a lot about what it is, plus it gets confusing when you use the same name for different params).我已经更改了一些命名以使其更加精确(item 并没有说明它是什么,而且当您对不同的参数使用相同的名称时它会变得混乱)。 My commented-out lines are marked with a * .我注释掉的行标有*

function clickableGrid(groupedAppointments, index, callback) {
    var i = 0;
    var grid = document.createElement('table');

    grid.className = 'grid';

    Object.keys(groupedAppointments).forEach((date) => {

        //*var days = groupedAppointments[key]; --> since you don't copy and just refferencing a memory slot
        var tr = grid.appendChild(document.createElement('tr')); // renamed to tr because you need to have only one row, both for the header and the data
        var th = tr.appendChild(document.createElement('th'));
        th.innerHTML = date;

        groupedAppointments[date].forEach((appointment) => {

            //*var tr = grid.appendChild(document.createElement('tr')); --> cell and table hadder are in the same row
            //var rowHeader = tr.appendChild(document.createElement('th'))
            var cell = tr.appendChild(document.createElement('td'));
            //rowHeader.innerHTML = appointment.SlotName;
            cell.innerHTML = appointment.AppointmentDateTime;
            cell.addEventListener('click', (function(el, appointment) {
                return function() {
                    callback(el, appointment);
                }
            })(cell, appointment), false);
        })

    })

    return grid;
}

Hope it helped :)希望它有所帮助:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM