2

HTML

<table id="tableAppointment" bgcolor="#fcfcfc" border="1" cellspacing="1" width="100%">
 <thead>
  <tr>
   <td class="csstextheader" width="70px"></td>
   <td class="csstextheader" width="70px"><b>Time Slot&nbsp;</b></td>
   <td><b>Room 7</b></td>
   <td><b>Room 8</b></td>
   <td><b>Room 9</b></td>
   <td><b>Room 10</b></td>
  </tr>
 </thead>
 <tbody>
  <tr class="csstablelisttd">
   <td width="70px">08:00AM</td>
   <td>00</td>
   <td class="csstdred">John</td>
   <td>&nbsp;</td>
   <td>&nbsp;</td>
   <td>&nbsp;</td>
  </tr>
 </table> 

C#

private void GenerateTable() {
    for(int i = 0; i < tableAppointment.Rows.Count; i++) {
        foreach(DataRow dr in dataTableAcqModality.Rows) {
            cell = new HtmlTableCell() {
                InnerHtml = "&nbsp;"
            };
            cell.Style.Add("word-wrap", "break-word");
            cell.Attributes.Remove("class");
            cell.Attributes.Remove("rowspan");
            cell.Style.Remove("display");

            tableAppointment.Rows[i].Cells.Add(cell);
            tableAppointment.Style.Add("table-layout", "fixed");

            if(i == 0) {
                cell.Attributes.Add("ID", RoomID.ToString());
                cell.InnerHtml = String.Format(
                    "<span id='{0}'>{1}</span>",
                    RoomID, Roomname
                );
                tableAppointment.Rows[0].Attributes.Add("class", "csstextheader");
            }
        }
    }
}

protected void Page_Load(object sender, EventArgs e) {
    for(int i = 0; i < tableAppointment.Rows.Count; i++) {
        for(int j = 0; j < tableAppointment.Rows[i].Cells.Count; j++) {
            // This is where I need to remove the extra cells added 
            // after providing rowspan :(
        }
    }
}

这个 JSBinrowspan中,您可以看到由于添加到上面行中的单元格而卡在我的行右侧的额外单元格。我试图弄清楚如何删除这些。任何建议表示赞赏!

4

5 回答 5

3

尽管我不知道你想要什么,或者不知道为什么,我还是写了一些 jQuery来删除多余的列,因为这就是我们在 StackOverflow 上所做的。

我不保证此代码的效率或实际有用性。

$(document).ready(function() {
  $('table tr').each(function(i, v) {
    var cols = $(this).find('td');
    $(this).find('td[rowspan]').each(function() {
      var idx = $(this).index();
      console.log(idx);
      for(var j = 1; j < $(this).prop('rowspan'); j++) {
        $('table tr').eq(i+j).find('td').eq(idx).hide();
      }
    });
  });
});

编辑:显然你只需要给行一个高度,以避免崩溃到彼此的行为:

tr { height: 30px; }

编辑 2:我确实更新了我的 jQuery 以隐藏具有行跨度的单元格下方的单元格。在您的示例中,您似乎有冲突的约会。开个玩笑,您可能想要确保没有调度冲突并且首先不编写那些额外的单元格。

提前处理此问题的一般策略是将与cellsUsed表相同大小的布尔值的多维数组(例如)初始化为 false,然后在打印具有行跨度的单元格时,将行跨度 - 1 数组位置标记为 true . 然后,当需要编写一个对应于设置为 true 的数组索引的单元格时,您就不会输出任何内容。如果碰巧在您标记为不输出的单元格中定义了实际约会,那么您将遇到一个完全不同的问题,并且必须处理它。

编辑:这里演示了为什么您必须隐藏多余的单元格或两次遍历表格以删除它们以避免错误:

这是一个示例表,其中“a”是行跨度 > 1 的单元格。“x”指定需要删除的额外单元格,“-”表示空白,该空白应为空白。

这是表中的起始数据:

a-a-
x-xa
xaxx
-x-x

如果您从左下角到右上角开始删除,就会发生这种情况。删除倒数第二行中连接到约会的额外单元格后,最后一行中只有三个单元格。因此,当您从下一个约会向下遍历以删除该行中的第四个单元格时,您会收到错误消息。

a-a-
x-xa
xaxx
--x!

如果您尝试从右上角到左下角删除,当您删除第二个约会时,您最终会错误地删除另一个约会(两个“a”相邻堆叠)。

a-a-
-xa
axx
-x-x

避免在生成表格后删除单元格出现问题的唯一方法是标记要删除的所有单元格,然后从右到左删除每行中的单元格。

于 2012-11-28T05:12:30.590 回答
3

为您简化它..

如果您[rowspan="2"]在单元格中使用 --> 那么您必须从下一行中删除一个单元格

例子 :

<table id="Table1" >
    <tr>
        <td rowspan="2" style="border-style:solid"></td>
        <td style="border-style:solid"></td>
    </tr>
    <tr>
        <td style="border-style:solid"></td>          
    </tr>
</table>

如果您在单元格中使用 [ rowspan="3" ] --> 那么您必须从接下来的行中删除一个单元格

例子 :

<table id="Table1" >
    <tr>
        <td rowspan="3" style="border-style:solid"></td>
        <td style="border-style:solid"></td>
    </tr>
    <tr>
        <td style="border-style:solid"></td>          
    </tr>
    <tr>
        <td style="border-style:solid"></td>          
    </tr>
</table>
于 2012-12-02T23:39:43.603 回答
2

尝试这样的事情

protected void Page_Load(object sender, EventArgs e)
{
    for(int i = 0; i < tableAppointment.Rows.Count; i++)
    {
        for(int j = 0; j < tableAppointment.Rows[i].Cells.Count; j++)
        {
             // Assuming you have set the rowSpan by now.
             // TODO: Handle the possibility of missing rowspan attribute.
             int rowSpan = int.Parse(tableAppointment.Rows[i].Cells[j].Attributes["rowspan"]);
             if (rowSpan > 0) {
                // Now try to look ahead for rows and remove their j'th cell.
                for (int k = j+1; k < j + rowSpan; k++)
                {
                   tableAppointment.Rows[k].Cells.RemoveAt(j);
                   // TODO: Validate if k is not beyond available rows. It shoudn't be if rowspans are correct.
                }
             }
        }        //Here i have to remove those extra cell added after giving rowspan       
    }
}

注意:此代码未经测试,甚至未经编译。提供更多作为指导。

话虽如此,我相信您可以在生成表格时更好地处理这个问题。如果我理解正确(可能是我没有理解)你已经静态创建了表,然后你注入了约会。这就是为什么你会患上这种细胞外综合症。如果您动态生成整个表,这不应该发生在您身上。

于 2012-11-29T16:54:10.460 回答
1

如果您的单元格是空白的,那么您可以从 CSS 中隐藏。像;

table{empty-cells:hide;}    
于 2012-11-29T13:56:11.793 回答
1

由于缺少代码,我不得不做出假设:获取数据、数据是什么样的、约会如何添加到表中。

我做了两件事来解决这个问题。1 - 我切换了循环的顺序,而不是循环遍历每个房间一段时间,而是循环遍历一个房间的所有时间跨度,然后再移动到下一个房间。2 - 由于更改 #1,我能够将时间跨度计数器增加需要删除的单元格数量(不推荐)

默认.aspx.cs

public partial class _Default : Page
{
  //Used to store generated data.
  List<Room> Rooms = new List<Room>();

  protected void Page_Load(object sender, EventArgs e)
  {
    if (!IsPostBack)
    {
      //To simulate the datasource
      GenerateData();

      //Generate the output
      GenerateTable();
    }
  }

  private void GenerateData()
  {
    //Generate Rooms
    foreach (var roomNumber in Enumerable.Range(7, 4))
    {
      var newRoom = new Room();

      newRoom.RoomID = roomNumber;
      newRoom.Roomname = "Room " + roomNumber.ToString();
      //Generate 40 15-minute time slot appointments for each room
      for (var count = 0; count < 40; ++count)
      {
        var newAppointment = new Appointment();

        newAppointment.Id = (roomNumber * 40) + count;
        newAppointment.Name = " ";
        newAppointment.NumberOfTimeSlots = 1;

        newRoom.Appointments.Add(newAppointment);
      }

      Rooms.Add(newRoom);
    }

    Rooms[0].Appointments[0].Name = "John";
    Rooms[0].Appointments[0].NumberOfTimeSlots = 1;

    Rooms[0].Appointments[2].Name = "John";
    Rooms[0].Appointments[2].NumberOfTimeSlots = 3;

    Rooms[1].Appointments[14].Name = "calc";
    Rooms[1].Appointments[14].NumberOfTimeSlots = 3;

    //More can be added
  }

  private void GenerateTable()
  {
    //Moved outside of the loop since it is globally setting the table and does not need to run for each row.
    tableAppointment.Style.Add("table-layout", "fixed");

    /**********************************************************************************************
     * Major change 1:
     * I flipped the order of the loops, I changed it from row->column to column->row.
     * What this allows you to do is skip the step of adding additional rows for the current room
     * by increment the row counter (not a good practice, need to refactor code).
     **********************************************************************************************/

    //You had: foreach(DataRow dr in dataTableAcqModality.Rows) {
    //I am assuming that this is a list of rooms to display
    foreach (var dr in Rooms)      
    {

      for (int i = 0; i < tableAppointment.Rows.Count; ++i)
      {
        var cell = new HtmlTableCell();

        cell.Style.Add("word-wrap", "break-word");
        cell.Attributes.Remove("class");
        cell.Attributes.Remove("rowspan");
        cell.Style.Remove("display");

        tableAppointment.Rows[i].Cells.Add(cell);

        if (i == 0) //Indicating the header row
        {
          cell.Attributes.Add("ID", dr.RoomID.ToString());
          cell.InnerHtml = String.Format(
              "<span id='{0}'>{1}</span>",
              dr.RoomID, dr.Roomname
          );
          tableAppointment.Rows[0].Attributes.Add("class", "csstextheader");
        }
        else
        {

          /***********************************************************************
           * Assumption that this is how you are adding the appointments to the 
           * table, did not see it in your quesiton
           ***********************************************************************/ 
          //i-1 to offset the header row
          cell.InnerHtml = dr.Appointments[i-1].Name;

          //NumberOfTimeSlots does not have to be part of the object, you are already doing it one way (not shown)
          cell.RowSpan = dr.Appointments[i - 1].NumberOfTimeSlots;

          //This is the inportant part, incrementing the row counter for this table by the number of cells you need to be removed becasue of the rowspan.
          //NOTE: I do not like the idea of messing with a loop counter, I would try to refactor your code, but since it was not provided this is a temporary fix.
          i += dr.Appointments[i - 1].NumberOfTimeSlots - 1;
        }
      }
    }
  }
}

public class Room
{
  public int RoomID { get; set; }
  public string Roomname { get; set; }
  public List<Appointment> Appointments { get; set; }

  public Room()
  {
    Appointments = new List<Appointment>();
  }
}

public class Appointment
{
  public int Id { get; set; }
  public string Name { get; set; }
  public int NumberOfTimeSlots { get; set; }
}

默认.aspx:

  时隙 08:00AM00 15 30 40

    <tr><td>09:00AM</td><td>00</td></tr>
    <tr><td>&nbsp;</td><td>15</td></tr>
    <tr><td>&nbsp;</td><td>30</td></tr>
    <tr><td>&nbsp;</td><td>40</td></tr>

    <tr><td>10:00AM</td><td>00</td></tr>
    <tr><td>&nbsp;</td><td>15</td></tr>
    <tr><td>&nbsp;</td><td>30</td></tr>
    <tr><td>&nbsp;</td><td>40</td></tr>

    <tr><td>11:00AM</td><td>00</td></tr>
    <tr><td>&nbsp;</td><td>15</td></tr>
    <tr><td>&nbsp;</td><td>30</td></tr>
    <tr><td>&nbsp;</td><td>40</td></tr>

    <tr><td>12:00PM</td><td>00</td></tr>
    <tr><td>&nbsp;</td><td>15</td></tr>
    <tr><td>&nbsp;</td><td>30</td></tr>
    <tr><td>&nbsp;</td><td>40</td></tr>

    <tr><td>01:00PM</td><td>00</td></tr>
    <tr><td>&nbsp;</td><td>15</td></tr>
    <tr><td>&nbsp;</td><td>30</td></tr>
    <tr><td>&nbsp;</td><td>40</td></tr>

    <tr><td>02:00PM</td><td>00</td></tr>
    <tr><td>&nbsp;</td><td>15</td></tr>
    <tr><td>&nbsp;</td><td>30</td></tr>
    <tr><td>&nbsp;</td><td>40</td></tr>

    <tr><td>03:00PM</td><td>00</td></tr>
    <tr><td>&nbsp;</td><td>15</td></tr>
    <tr><td>&nbsp;</td><td>30</td></tr>
    <tr><td>&nbsp;</td><td>40</td></tr>

    <tr><td>04:00PM</td><td>00</td></tr>
    <tr><td>&nbsp;</td><td>15</td></tr>
    <tr><td>&nbsp;</td><td>30</td></tr>
    <tr><td>&nbsp;</td><td>40</td></tr>

    <tr><td>05:00PM</td><td>00</td></tr>
    <tr><td>&nbsp;</td><td>15</td></tr>
    <tr><td>&nbsp;</td><td>30</td></tr>
    <tr><td>&nbsp;</td><td>40</td></tr>
  </tbody>
</table>
于 2012-12-04T04:01:50.253 回答