Ok magos, alguien sabe cómo hacer esto ...

Tengo un control personalizado muy complejo que representa la información de disponibilidad para x número de personas (podría ser 1 podría ser 100). el calendario representa cualquier intervalo de fechas dado como se especifica en las propiedades de control.

Lo que esto significa es que el control tiene el potencial de ser muy largo y todos estos datos se representan como una tabla html.

Con el nombre de cada persona que aparece en la primera columna, estoy tratando de arreglar esa columna y dejar que el resto de la tabla se desplace horizontalmente para que el usuario pueda navegar a través del rango completo de fechas pero mantener visibles los nombres de las personas.

Entonces, ¿cómo puedo arreglar la primera columna en su lugar en la tabla que se parece al código a continuación ...

<table>
  <tr><td></td><td colspan='31'>Jan</td><td colspan='28'>feb</td>...</tr>
  <tr><td></td><td>1</td><td>2</td><td>3</td> ...<tr/>
  <tr><td>Person 1</td><td></td><td></td><td>Busy</td> ...<tr/>
  <tr><td>Person 2</td><td></td><td>Busy</td><td>Busy</td> ...<tr/>
</table>

En caso de que sea útil de alguna manera, esta es una aplicación C # (asp.net) y estoy abierto a usar JavaScript si es necesario.

Gracias chicos :)

1
War 26 jul. 2011 a las 12:32

3 respuestas

La mejor respuesta

De acuerdo con la tabla anterior que ya tengo, tuve que asumir que la columna fija tendría un ancho fijo, pero logré hacer esto ...

<div style="position:relative;">
    <div style="width:100%; overflow:scroll; height:400px;">

<table style="margin-left:100px;">
  <tr><td style="position:absolute;"></td><td colspan='31'>Jan</td><td colspan='28'>feb</td>...</tr>
  <tr><td style="position:absolute;"></td><td>1</td><td>2</td><td>3</td> ...<tr/>
  <tr><td style="position:absolute;">Person 1</td><td></td><td></td><td>Busy</td> ...<tr/>
  <tr><td style="position:absolute;">Person 2</td><td></td><td>Busy</td><td>Busy</td> ...<tr/>
</table>

    </div>
</div>

Esto da como resultado que las celdas marcadas tomen una posición absoluta a la izquierda y la tabla permanezca desplazable ... Se requiere un poco de trabajo para limpiarla y hacer que se vea bonita, pero esencialmente mi código cuando se extrae se ve así ...

<style type="text/css">
    .Calendar                   { max-height:400px; border-collapse:collapse; table-layout:fixed; margin-left:105px; }
    .Calendar .Resources  { width:100px; position:absolute; left:0px; background:white; }
    .Calendar tr                { vertical-align:top; }
    .Calendar td               { border:solid 1px black; vertical-align:top; padding:2px; border:solid 1px  #EFEFEF; }
    .Calendar .day            { background:#FFFBD6; border:solid 1px #FEEFB3; }
    .Calendar .dayWithEvent   { background:white; border:solid 1px #FEEFB3; border-top:solid 1px blue; }
</style>

<div style="position:relative;">
    <div style="width:100%; overflow:scroll; height:400px;">
        <table class="Calendar">
            <asp:Repeater ID="ui_calMonths" runat="server" onitemdatabound="ui_calMonths_ItemDataBound">
                    <HeaderTemplate>
                        <tr><td class="Resources" style="background:white; border:none;">&nbsp;</td>
                    </HeaderTemplate>
                    <ItemTemplate>
                        <td colspan='<%# ((Month)Container.DataItem).Days.Length %>'><%# Eval("Name") %></td>
                    </ItemTemplate>
                    <FooterTemplate>
                        </tr>
                        <tr><td class="Resources" style="background:white; border:none;">&nbsp;</td>
                            <asp:Repeater ID="ui_calDays" runat="server">
                                <ItemTemplate>
                                    <td><%# ((DateTime)Container.DataItem).ToString("dd") %></td>
                                </ItemTemplate>
                            </asp:Repeater>
                        </tr>
                    </FooterTemplate>
                </asp:Repeater> 
            <asp:Repeater ID="ui_grdResources" runat="server">
                <HeaderTemplate><tr></HeaderTemplate>
                <ItemTemplate>
                    <td class="Resources"><%# Eval("Text") %></td>
                    <%# ResourceEvents(((RowContext)Container.DataItem)) %>
                </ItemTemplate>
                <FooterTemplate></tr></FooterTemplate>
            </asp:Repeater>
        </table>    
    </div>
</div>

Básicamente, el código subyacente calcula cuántas celdas se representan en cada fila (los repetidores son fundamentales en este trabajo, pero el resultado es esencialmente una tabla bien formateada que contiene los nombres de los meses para el rango de fechas dado en la primera fila, los días de esos meses en el segundo y en el tercero, una columna fija que contiene los nombres y los elementos dinámicamente poblados de mis elementos internos del calendario API ... ¡¡¡genial !!!

1
War 26 jul. 2011 a las 09:33

Obtener el complemento jquery datatables fixedcolumns

http://datatables.net/extras/fixedcolumns/

0
john ktejik 31 jul. 2012 a las 20:26

Aquí hay una solución de Markku Uttula que hace esto con una combinación de CSS y HTML ( abajo). Funciona con un rendimiento razonable incluso en IE6, para mi sorpresa. V. trabajo impresionante. Las barras de desplazamiento en Chrome, Opera y Firefox terminan debajo de las columnas / filas congeladas por alguna razón, pero es de esperar que las barras sean lo suficientemente grandes como para que eso no sea un problema ...

Css:

body { margin: 0; height: 100% }
.b { border-collapse: collapse }
.b td { border: 1px solid #f80; vertical-align: top }
p { margin: 1px; padding: 0; font-size: 9px; font-family: Arial }
p.c { text-align: center; font-size: 12px }
p span { font-size: 12px; white-space:nowrap; color: #888 }
/* TopLeft fixed corner */
td.bg101 { background-color: #ffc }
/* Top fixed rows */
td.bg000 { background-color: #f8c }
td.bg001 { background-color: #f4c }
/* Left fixed rows */
td.bg110 { background-color: #fcc }
td.bg111 { background-color: #fcf }
/* The scrollable content area */
td.bg010 { background-color: #fff }
td.bg011 { background-color: #ff4 }

Javascript:

var ieBug = ((document.all) && (!window.opera)); // IE doesn't really handle fixed elements well :)
var fpElement = false;
function fpCW() { return document.documentElement ? document.documentElement.clientWidth : document.clientWidth; }
function fpCH() { return document.documentElement ? document.documentElement.clientHeight : document.clientHeight; }
function fpTopLeft(elementNode, iTop, iLeft) {
    elementNode.style.top = (iTop)+"px";
    elementNode.style.left = (iLeft)+"px";
}
function fpDefaults(elementNode) {
    elementNode.style.position = ieBug ? "absolute" : "fixed";
    fpTopLeft(elementNode,0,0);
    return elementNode;
}
function fpClone(elementNode, cloneZindex) {
    var clone = fpDefaults(elementNode.cloneNode(true));
    clone.style.background = "#fff";
    clone.style.overflow = "hidden";
    clone.style.border = "none";
    clone.style.zIndex = cloneZindex;
    return clone;
}
function fpInitFreezePanes(fpTableElementId, fpTableContainerDivElementId, fpPivotCellId, fpDisableBodyScrollbars) {
    if (fpElement !== false) {
      alert("Page already contains an element with fixed panes.");
    } else {
        var fpTableElement = document.getElementById(fpTableElementId);
        var fpTableContainerDivElement = document.getElementById(fpTableContainerDivElementId);
        var fpPivotCell = document.getElementById(fpPivotCellId);
        if ((!fpTableElement) || (!fpTableContainerDivElement) || (!fpPivotCell)) {
            alert("Unable to find table, container or pivoting cell?");
        } else {
            fpElement = fpTableContainerDivElement;
            if (fpDisableBodyScrollbars) {
                var x = document.getElementsByTagName("body")[0];
                x.style.overflow = "hidden";
                x = document.getElementsByTagName("html")[0];
                x.style.overflow = "hidden";
            }
            fpTableContainerDivElement = fpDefaults(fpTableContainerDivElement);
            fpTableContainerDivElement.style.width = (fpCW()-2)+"px";
            fpTableContainerDivElement.style.height = (fpCH()-2)+"px";
            fpTableContainerDivElement.fpPT = fpPivotCell.offsetTop;
            fpTableContainerDivElement.fpPL = fpPivotCell.offsetLeft;

            var copy1 = fpClone(fpTableContainerDivElement, 4);
            copy1.style.width = (fpTableContainerDivElement.fpPL)+"px";
            copy1.style.height = (fpTableContainerDivElement.fpPT)+"px";
            var copy2 = fpClone(fpTableContainerDivElement, 3);
            copy2.style.width = (fpTableElement.offsetWidth)+"px";
            copy2.style.height = (fpTableContainerDivElement.fpPT)+"px";
            var copy3 = fpClone(fpTableContainerDivElement, 2);
            copy3.style.width = (fpTableContainerDivElement.fpPL)+"px";
            copy3.style.height = (fpTableElement.offsetHeight)+"px";

            fpTableContainerDivElement.style.zIndex = 1;
            fpTableContainerDivElement.appendChild(copy1);
            fpTableContainerDivElement.copy1 = copy1;
            fpTableContainerDivElement.appendChild(copy2);
            fpTableContainerDivElement.copy2 = copy2;
            fpTableContainerDivElement.appendChild(copy3);
            fpTableContainerDivElement.copy3 = copy3;
            fpTableContainerDivElement.repositioning = false;
            fpTableContainerDivElement.oldST = -1;
            fpTableContainerDivElement.oldSL = -1;
            fpTableContainerDivElement.style.overflow = "scroll";

            /* JUST SOME STYLING HERE */
            copy1.style.borderRight = "1px dashed #000";
            copy1.style.borderCollapse = "collapse";
            copy2.style.borderBottom = "1px dashed #000";
            copy2.style.borderCollapse = "collapse";
            copy3.style.borderRight = "1px dashed #000";
            copy3.style.borderCollapse = "collapse";
            /* JUST SOME STYLING HERE */

            // if (ieBug) {
            if (fpTableContainerDivElement.style.setExpression) {
                function fpIeBugFix(elementNode, containerNodeId, arrayOfExpressionsToSet) {
                    for (var i in arrayOfExpressionsToSet) {
                        if (arrayOfExpressionsToSet[i][2]) {
                            elementNode.style.setExpression(arrayOfExpressionsToSet[i][0], arrayOfExpressionsToSet[i][1]+"document.getElementById('"+containerNodeId+"')."+arrayOfExpressionsToSet[i][2]+"+'px'");
                        } else {
                            elementNode.style.setExpression(arrayOfExpressionsToSet[i][0], arrayOfExpressionsToSet[i][1]);
                        }
                    }
                }
                fpIeBugFix(fpTableContainerDivElement.copy3, fpTableContainerDivElementId, [["top","","scrollTop"],["left","","scrollLeft"],["marginTop","-","scrollTop"]]);
                fpIeBugFix(fpTableContainerDivElement.copy2, fpTableContainerDivElementId, [["top","","scrollTop"],["left","","scrollLeft"],["marginLeft","-","scrollLeft"]]);
                fpIeBugFix(fpTableContainerDivElement.copy1, fpTableContainerDivElementId, [["top","","scrollTop"],["left","","scrollLeft"]]);
                fpIeBugFix(fpTableContainerDivElement, fpTableContainerDivElementId, [["width","fpCW()+'px'"],["height","fpCH()+'px'"]]);
                document.recalc(true);
            } else {
                fpElement.onmousemove = fpElement.onscroll = function() {
                    if (!this.repositioning) {
                        this.repositioning = true;
                        var st = this.scrollTop;
                        var sl = this.scrollLeft;
                        if ((this.oldST != st) || (this.oldSL != sl)) {
                            this.oldST = st;
                            this.oldSL = sl;
                            // this.copy3.previousDisplay = this.copy3.style.display;
                            // this.copy3.style.display = "none";
                            this.copy3.style.marginTop = "-"+(st)+"px";
                            // this.copy3.style.display = this.copy3.previousDisplay;
                            // this.copy2.previousDisplay = this.copy2.style.display;
                            // this.copy2.style.display = "none";
                            this.copy2.style.marginLeft = "-"+(sl)+"px";
                            // this.copy2.style.display = this.copy2.previousDisplay;
                        }
                        fpElement.repositioning = false;
                    }
                };
                window.onresize = function() {
                    fpElement.style.width = fpCW()+"px";
                    fpElement.style.height = fpCH()+"px";
                }
            }
        }
    }
}
3
T.J. Crowder 26 jul. 2011 a las 08:55