动态创建的 table 中的 <td> 之一必须取消分配宽度以强制其他 <td> 宽度
One of the <td> in dynamically created table has to be width unassigned to force other <td> width
我遇到了一个问题,我不知道最好的解释方式是什么。
我正在用 HTML 5 创建一个动态 table。由于它是动态的,所以我正在形成一个循环来根据数据创建 tr 和 td。
正在为一周中的每一天创建 td。用户可以 select 他想看哪一天,因此根据 select 显示 td 的天数。
我已经为 tbody 实现了滚动,因此使 thead 和 tbody 都具有 'display:block'。因此,我为 header 指定了固定宽度,现在我必须为列指定固定宽度以对齐它们。
现在,当我将宽度值分配给 td 时,我必须不保留 td 宽度值之一,以便可以对 td 的其余部分强制执行宽度。因此,这个未分配的 td 宽度太大。
如果我将宽度 td 全部放入,那么 none 其中的宽度由我分配,整个 table 不同步。
我将我的 HTMl 放在我在循环中生成 td 的地方作为 header。如您所见,没有为循环中的一个 td 分配宽度。我正在为 css 使用 bootstrap。请让我知道我在这段代码中做错了什么。很抱歉粘贴所有代码,因为我认为我无法在 fiddle.
中重现此问题
<table class="table table-hover table-striped table-condensed" >
<thead style="display:block;">
<tr>
<th rowspan="2"><div style="width:50px">@Helpers.SortableColumnHeader("Zip", actionName, BuyInfo.SortBy.Zip, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
<th rowspan="2" class="text-right"><div style=" width:80px">@Helpers.SortableColumnHeader("Households", actionName, BuyInfo.SortBy.Households, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
<th rowspan="2" class="text-right"><div style=" width:40px">@Helpers.SortableColumnHeader("Sales", actionName, BuyInfo.SortBy.Sales, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
@if (!String.IsNullOrWhiteSpace(c.Client.MpiNames[0]))
{
<th rowspan="2" class="text-right"><div style=" width:50px">@Helpers.SortableColumnHeader(c.Client.MpiNames[0], actionName, BuyInfo.SortBy.Mpi1, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
}
@if (!String.IsNullOrWhiteSpace(c.Client.MpiNames[1]))
{
<th rowspan="2" class="text-right"><div style=" width:50px">@Helpers.SortableColumnHeader(c.Client.MpiNames[1], actionName, BuyInfo.SortBy.Mpi2, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
}
@if (!String.IsNullOrWhiteSpace(c.Client.MpiNames[2]))
{
<th rowspan="2" class="text-right"><div style=" width:50px">@Helpers.SortableColumnHeader(c.Client.MpiNames[2], actionName, BuyInfo.SortBy.Mpi3, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
}
<th rowspan="2"><div style=" width:75px">@Helpers.SortableColumnHeader("Zone", actionName, BuyInfo.SortBy.Zone, Model, containerId, rvd)</div></th>
<th rowspan="2"><div style=" width:50px">@Helpers.SortableColumnHeader("NAPI", actionName, BuyInfo.SortBy.NapiId, Model, containerId, rvd)</div></th>
<th rowspan="2"><div style=" width:100px">@Helpers.SortableColumnHeader("Pub", actionName, BuyInfo.SortBy.Pub, Model, containerId, rvd)</div></th>
<th rowspan="2"><div style=" width:35px">@Helpers.SortableColumnHeader("Type", actionName, BuyInfo.SortBy.PubType, Model, containerId, rvd)</div></th>
@for (int d = 0; d < dows.Length; d++)
{
<th colspan="3" class="text-center"><div style=" width:162px">@dows[d].ToDisplayString()</div></th>
}
</tr>
<tr>
@for (int d = 0; d < dows.Length; d++)
{
<th class="text-right"><div style=" width:42px">@Helpers.SortableColumnHeader("Zip Circ", actionName, (BuyInfo.SortBy)Enum.Parse(typeof(BuyInfo.SortBy), dows[d].ToString()), Model, containerId, rvd)</div></th>
<th class="text-right"><div style=" width:50px">Zone Circ</div></th>
<th class="text-center"><div style=" width:70px">Buy</div></th>
}
</tr>
</thead>
<tbody style="display:block;
height: 500px;
overflow-y: auto;
/*width:auto;
table-layout:fixed*/">
@foreach (Zip zip in Model.PageList)
{
IComparer<Zone> comparer;
BuyInfo.SortBy sortBy = (BuyInfo.SortBy)Model.SortInfo.SortBy;
if (sortBy.ToString().EndsWith("day"))
{
DayOfWeek dow = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), sortBy.ToString());
Dictionary<Zone, int> circs = new Dictionary<Zone, int>();
foreach (Zone zo in b[zip].Keys)
{
circs.Add(zo, b[zip][zo].ContainsKey(dow) ? b[zip][zo][dow] : 0);
}
comparer = BuyInfo.GetZoneComparer(sortBy, Model.SortInfo.SortForward, circs);
}
else
{
comparer = BuyInfo.GetZoneComparer(sortBy, Model.SortInfo.SortForward);
}
int sales = Model.SalesInfo.ContainsKey(zip.Id) ? Model.SalesInfo[zip.Id].Sales : 0;
SortedDictionary<Zone, SortedDictionary<DayOfWeek, int>> zones = new SortedDictionary<Zone, SortedDictionary<DayOfWeek, int>>(b[zip], comparer);
if (zones.Count == 0)
{
<tr class="zip">
<td><div style=" width:50px">@zip.Title</div></td>
<td class="text-right"><div style=" width:80px">@zip.Households.ToString("n0")</div></td>
<td class="text-right"><div style=" width:40px">@sales.ToString("c0")</div></td>
@MpiRows(c.Client, zip, 1)
<td colspan="@((dows.Length * 3) + 4)" class="text-center"><div style="width:@((dows.Length+4)*143)px">n/a</div></td>
</tr>
continue;
}
bool isFirstRow = true;
foreach (Zone zone in zones.Keys)
{
<tr class="@(isFirstRow ? "zip" : "")"; width="500px">
@if (isFirstRow)
{
<td rowspan="@zones.Count"><div style="width:50px">@zip.Title</div></td>
<td rowspan="@zones.Count" class="text-right"><div style="width:80px">@zip.Households.ToString("n0")</div></td>
<td rowspan="@zones.Count" class="text-right"><div style="width:40px">@sales.ToString("c0")</div></td>
@MpiRows(c.Client, zip, zones.Count)
isFirstRow = false;
}
<td style="width:85px;" class="text-left"><div style=" width:75px; display:block">@zone.Title</div></td>
<td style="width:60px;" class="text-left" ><div style=" width:50px; display:block">@zone.Pub.NapiId</div></td>
<td style="width:110px;" class="text-left">
<div style="width:100px; display:block">
<span>@zone.Pub.Title</span><br />
<span class="text-muted">@zone.Pub.Location</span>
@Ajax.ActionLink("mins", "GetMinBuys", "Pub", new { id = zone.Pub.Id },
new AjaxOptions { HttpMethod = "GET", InsertionMode = InsertionMode.Replace, UpdateTargetId = "min-buy-list-container", OnFailure = "alert('Error!');", OnSuccess = "showMinBuys(this);" }, new { @class = "btn btn-xs btn-default" })
</div>
</td>
<td class="text-left" style="width:45px"><div style="width:35px; display:block">@zone.Pub.Type</div></td>
@for (int d = 0; d < dows.Length; d++)
{
DayOfWeek dow = dows[d];
int zipCirc = zones[zone].ContainsKey(dow) ? zones[zone][dow] : 0;
int zoneCirc = zone.Circ != null ? (zone.Circ.ContainsKey(dow) ? zone.Circ[dow] : 0) : 0;
int households = zip.Households;
decimal penetration = households == 0 ? Decimal.Zero : (decimal)zipCirc / households;
int minBuy = zone.Pub.MinBuys.ContainsKey(dow) ? zone.Pub.MinBuys[dow] : 0;
int buy = zone.Buy != null ? (zone.Buy.ContainsKey(dow) ? zone.Buy[dow] : 0) : 0;
<td class="text-right" style="width:52px;">
<div style="width:42px; display:block">
@zipCirc<br />
<span class="text-muted">@penetration.ToString("p0")</span>
</div>
</td>
<td class="text-right" style="width:60px;">
<div style="width:50px; display:block">
@if (zoneCirc > 0)
{
<a class="zone-circ" href="#">@zoneCirc</a>
}
else
{
@zoneCirc
}
</div>
</td>
##<td class="text-right">##
<div style="width:70px; display:block">
@if (zoneCirc > 0)
{
string className = String.Empty;
if (buy > 0)
{
className = (buy >= minBuy) ? "min-met" : "min-not-met";
}
<input type="text" class="form-control input-sm min @(className)" placeholder="@minBuy" value="@(buy > 0 ? buy.ToString() : String.Empty)" data-campaign-id="@(c.Id)" data-zone-id="@(zone.Id)" data-dow-id="@((int)dow)" />
}
</div>
</td>
}
</tr>
}
}
@if (Model.List.Count == 0)
{
<tr>
<td colspan="4">No pubs exist for this campaign (check the search term).</td>
</tr>
}
</tbody>
jsfiddle 对于宽度为 1 td 的渲染代码:jsfiddle.net/9psjobhc
我找到了解决我的问题的方法。我只是循环了几天并在循环的最后一天插入了空白 td 。因此,td 所需的 space 在最后分配,同步保持不变。
我遇到了一个问题,我不知道最好的解释方式是什么。
我正在用 HTML 5 创建一个动态 table。由于它是动态的,所以我正在形成一个循环来根据数据创建 tr 和 td。
正在为一周中的每一天创建 td。用户可以 select 他想看哪一天,因此根据 select 显示 td 的天数。
我已经为 tbody 实现了滚动,因此使 thead 和 tbody 都具有 'display:block'。因此,我为 header 指定了固定宽度,现在我必须为列指定固定宽度以对齐它们。
现在,当我将宽度值分配给 td 时,我必须不保留 td 宽度值之一,以便可以对 td 的其余部分强制执行宽度。因此,这个未分配的 td 宽度太大。 如果我将宽度 td 全部放入,那么 none 其中的宽度由我分配,整个 table 不同步。
我将我的 HTMl 放在我在循环中生成 td 的地方作为 header。如您所见,没有为循环中的一个 td 分配宽度。我正在为 css 使用 bootstrap。请让我知道我在这段代码中做错了什么。很抱歉粘贴所有代码,因为我认为我无法在 fiddle.
中重现此问题 <table class="table table-hover table-striped table-condensed" >
<thead style="display:block;">
<tr>
<th rowspan="2"><div style="width:50px">@Helpers.SortableColumnHeader("Zip", actionName, BuyInfo.SortBy.Zip, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
<th rowspan="2" class="text-right"><div style=" width:80px">@Helpers.SortableColumnHeader("Households", actionName, BuyInfo.SortBy.Households, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
<th rowspan="2" class="text-right"><div style=" width:40px">@Helpers.SortableColumnHeader("Sales", actionName, BuyInfo.SortBy.Sales, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
@if (!String.IsNullOrWhiteSpace(c.Client.MpiNames[0]))
{
<th rowspan="2" class="text-right"><div style=" width:50px">@Helpers.SortableColumnHeader(c.Client.MpiNames[0], actionName, BuyInfo.SortBy.Mpi1, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
}
@if (!String.IsNullOrWhiteSpace(c.Client.MpiNames[1]))
{
<th rowspan="2" class="text-right"><div style=" width:50px">@Helpers.SortableColumnHeader(c.Client.MpiNames[1], actionName, BuyInfo.SortBy.Mpi2, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
}
@if (!String.IsNullOrWhiteSpace(c.Client.MpiNames[2]))
{
<th rowspan="2" class="text-right"><div style=" width:50px">@Helpers.SortableColumnHeader(c.Client.MpiNames[2], actionName, BuyInfo.SortBy.Mpi3, new ListModel() { SortInfo = Model.RootSortInfo }, containerId, rvd, null, "Root")</div></th>
}
<th rowspan="2"><div style=" width:75px">@Helpers.SortableColumnHeader("Zone", actionName, BuyInfo.SortBy.Zone, Model, containerId, rvd)</div></th>
<th rowspan="2"><div style=" width:50px">@Helpers.SortableColumnHeader("NAPI", actionName, BuyInfo.SortBy.NapiId, Model, containerId, rvd)</div></th>
<th rowspan="2"><div style=" width:100px">@Helpers.SortableColumnHeader("Pub", actionName, BuyInfo.SortBy.Pub, Model, containerId, rvd)</div></th>
<th rowspan="2"><div style=" width:35px">@Helpers.SortableColumnHeader("Type", actionName, BuyInfo.SortBy.PubType, Model, containerId, rvd)</div></th>
@for (int d = 0; d < dows.Length; d++)
{
<th colspan="3" class="text-center"><div style=" width:162px">@dows[d].ToDisplayString()</div></th>
}
</tr>
<tr>
@for (int d = 0; d < dows.Length; d++)
{
<th class="text-right"><div style=" width:42px">@Helpers.SortableColumnHeader("Zip Circ", actionName, (BuyInfo.SortBy)Enum.Parse(typeof(BuyInfo.SortBy), dows[d].ToString()), Model, containerId, rvd)</div></th>
<th class="text-right"><div style=" width:50px">Zone Circ</div></th>
<th class="text-center"><div style=" width:70px">Buy</div></th>
}
</tr>
</thead>
<tbody style="display:block;
height: 500px;
overflow-y: auto;
/*width:auto;
table-layout:fixed*/">
@foreach (Zip zip in Model.PageList)
{
IComparer<Zone> comparer;
BuyInfo.SortBy sortBy = (BuyInfo.SortBy)Model.SortInfo.SortBy;
if (sortBy.ToString().EndsWith("day"))
{
DayOfWeek dow = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), sortBy.ToString());
Dictionary<Zone, int> circs = new Dictionary<Zone, int>();
foreach (Zone zo in b[zip].Keys)
{
circs.Add(zo, b[zip][zo].ContainsKey(dow) ? b[zip][zo][dow] : 0);
}
comparer = BuyInfo.GetZoneComparer(sortBy, Model.SortInfo.SortForward, circs);
}
else
{
comparer = BuyInfo.GetZoneComparer(sortBy, Model.SortInfo.SortForward);
}
int sales = Model.SalesInfo.ContainsKey(zip.Id) ? Model.SalesInfo[zip.Id].Sales : 0;
SortedDictionary<Zone, SortedDictionary<DayOfWeek, int>> zones = new SortedDictionary<Zone, SortedDictionary<DayOfWeek, int>>(b[zip], comparer);
if (zones.Count == 0)
{
<tr class="zip">
<td><div style=" width:50px">@zip.Title</div></td>
<td class="text-right"><div style=" width:80px">@zip.Households.ToString("n0")</div></td>
<td class="text-right"><div style=" width:40px">@sales.ToString("c0")</div></td>
@MpiRows(c.Client, zip, 1)
<td colspan="@((dows.Length * 3) + 4)" class="text-center"><div style="width:@((dows.Length+4)*143)px">n/a</div></td>
</tr>
continue;
}
bool isFirstRow = true;
foreach (Zone zone in zones.Keys)
{
<tr class="@(isFirstRow ? "zip" : "")"; width="500px">
@if (isFirstRow)
{
<td rowspan="@zones.Count"><div style="width:50px">@zip.Title</div></td>
<td rowspan="@zones.Count" class="text-right"><div style="width:80px">@zip.Households.ToString("n0")</div></td>
<td rowspan="@zones.Count" class="text-right"><div style="width:40px">@sales.ToString("c0")</div></td>
@MpiRows(c.Client, zip, zones.Count)
isFirstRow = false;
}
<td style="width:85px;" class="text-left"><div style=" width:75px; display:block">@zone.Title</div></td>
<td style="width:60px;" class="text-left" ><div style=" width:50px; display:block">@zone.Pub.NapiId</div></td>
<td style="width:110px;" class="text-left">
<div style="width:100px; display:block">
<span>@zone.Pub.Title</span><br />
<span class="text-muted">@zone.Pub.Location</span>
@Ajax.ActionLink("mins", "GetMinBuys", "Pub", new { id = zone.Pub.Id },
new AjaxOptions { HttpMethod = "GET", InsertionMode = InsertionMode.Replace, UpdateTargetId = "min-buy-list-container", OnFailure = "alert('Error!');", OnSuccess = "showMinBuys(this);" }, new { @class = "btn btn-xs btn-default" })
</div>
</td>
<td class="text-left" style="width:45px"><div style="width:35px; display:block">@zone.Pub.Type</div></td>
@for (int d = 0; d < dows.Length; d++)
{
DayOfWeek dow = dows[d];
int zipCirc = zones[zone].ContainsKey(dow) ? zones[zone][dow] : 0;
int zoneCirc = zone.Circ != null ? (zone.Circ.ContainsKey(dow) ? zone.Circ[dow] : 0) : 0;
int households = zip.Households;
decimal penetration = households == 0 ? Decimal.Zero : (decimal)zipCirc / households;
int minBuy = zone.Pub.MinBuys.ContainsKey(dow) ? zone.Pub.MinBuys[dow] : 0;
int buy = zone.Buy != null ? (zone.Buy.ContainsKey(dow) ? zone.Buy[dow] : 0) : 0;
<td class="text-right" style="width:52px;">
<div style="width:42px; display:block">
@zipCirc<br />
<span class="text-muted">@penetration.ToString("p0")</span>
</div>
</td>
<td class="text-right" style="width:60px;">
<div style="width:50px; display:block">
@if (zoneCirc > 0)
{
<a class="zone-circ" href="#">@zoneCirc</a>
}
else
{
@zoneCirc
}
</div>
</td>
##<td class="text-right">##
<div style="width:70px; display:block">
@if (zoneCirc > 0)
{
string className = String.Empty;
if (buy > 0)
{
className = (buy >= minBuy) ? "min-met" : "min-not-met";
}
<input type="text" class="form-control input-sm min @(className)" placeholder="@minBuy" value="@(buy > 0 ? buy.ToString() : String.Empty)" data-campaign-id="@(c.Id)" data-zone-id="@(zone.Id)" data-dow-id="@((int)dow)" />
}
</div>
</td>
}
</tr>
}
}
@if (Model.List.Count == 0)
{
<tr>
<td colspan="4">No pubs exist for this campaign (check the search term).</td>
</tr>
}
</tbody>
jsfiddle 对于宽度为 1 td 的渲染代码:jsfiddle.net/9psjobhc
我找到了解决我的问题的方法。我只是循环了几天并在循环的最后一天插入了空白 td 。因此,td 所需的 space 在最后分配,同步保持不变。