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

あなたのためにそれを単純化するために..

セルで使用する場合[rowspan="2"]->次の行から1つのセルを削除する必要があります

例 :

<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"]を使用する場合は、次の2つの行から1つのセルを削除する必要があります

例 :

<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 に答える
3

あなたが何を望んでいるのか、またはその理由がわからない場合でも、余分な列を削除するためのjQuery をいくつか作成しました。

このコードの効率性や実際の有用性については保証しません。

$(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 に初期化し、rowspan を持つセルを印刷するときに、rowspan - 1 配列の場所を true としてマークすることです。 . 次に、true に設定された配列インデックスに対応するセルを書き込むときは、何も出力しません。出力しないようにマークしたセルに実際の予定が定義されている場合は、まったく別の問題があり、それに対処する必要があります。

編集:エラーを回避するために、余分なセルを非表示にするか、テーブルを2回調べて削除する必要がある理由のデモンストレーションを次に示します。

以下は、'a' が行スパン > 1 を持つセルであるテーブルの例です。

これは、表の開始データです。

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

これは、左下から右上に向かって削除を開始するとどうなるかです。最後から 2 番目の行の予定に接続されている余分なセルを削除すると、最後の行には 3 つのセルしかありません。そのため、次の予定から下方向にトラバースしてその行の 4 番目のセルを削除すると、エラーが発生します。

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

右上から左下に削除しようとすると、2 番目の予定を削除しようとすると、誤って別の予定が削除されてしまいます (2 つの「a」が隣り合って積み重なっています)。

a-a-
-xa
axx
-x-x

テーブルの生成後にセルを削除する際の問題を回避する唯一の方法は、削除するすべてのセルにマークを付けてから、各行のセルを右から左に削除することです。

于 2012-11-28T05:12:30.590 に答える
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

コードが欠落しているため、データの取得、データの外観、テーブルへの予定の追加方法などを推測する必要がありました。

この問題を解決するために行ったことが 2 つあります。1 - ループの順序を入れ替えました。各部屋を一定時間ループするのではなく、次の部屋に移動する前に、1 つの部屋のすべての時間スパンをループしました。2 - 変更 #1 により、削除する必要のあるセルの数だけタイム スパン カウンターをインクリメントできました (推奨されません)。

Default.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 に答える