Как я замораживаю первые и последние столбцы таблицы HTML в отделении с возможностью прокрутки?

Вы должны создать миграцию данных. Подробнее о них см. В документах

Шаг 1 - создание пустых миграций данных

python manage.py makemigrations --empty yourappname

Шаг 2 - Добавить пользовательские sql для миграции:

# -*- coding: utf-8 -*-
# Generated by Django 1.11.14 on 2018-09-20 08:01
from __future__ import unicode_literals

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('yourapp', '0001_name_of_depending_migration'),
    ]

    operations = [
        migrations.RunSQL(
            sql="CREATE INDEX my_article_idx ON article (regexp_replace(url, '\?.*, ''))",
            reverse_sql='DROP INDEX my_article_idx ON article'
        )
    ]

13
задан Christopher Rapcewicz 10 December 2013 в 19:30
поделиться

6 ответов

Я экспериментировал с несколькими методами (спасибо всем, кто помогал), и вот что я придумал, используя jQuery. Кажется, он хорошо работает во всех протестированных мной браузерах. Смело берите его и используйте как хотите. Следующим шагом для меня будет превращение его в плагин jQuery многократного использования.

Резюме:

Я начал с обычной таблицы со всем в ней ( Id = "ladderTable" ) и написал Три метода - один для удаления первого столбца, один для удаления последнего столбца и один для фиксации высоты строк.

Метод stripFirstColumn создает новую таблицу ( Id = "nameTable" ), просматривает исходную таблицу, извлекает первый столбец и добавляет эти ячейки в nameTable.

​​Метод stripLastColumn делает в основном то же самое, за исключением того, что он извлекает последний столбец и добавляет ячейки в новую таблицу с именем totalTable .

Метод fixHeights просматривает каждую строку в каждой таблице, вычисляет максимальную высоту и применяет ее к связанным таблицам.

В событии готовности документа я вызвал все три метода по порядку. Обратите внимание, что все три таблицы перемещаются влево, поэтому они будут располагаться горизонтально.

Структура HTML:

<h1>Current Ladder</h1> 
<div id="nameTableSpan" style="float:left;width:100px;border-right:2px solid gray;"></div> 
<div id="ladderDiv" style="float:left;width:423px;overflow:auto;border:1px solid gray;margin-top:-1px;"> 
    <table id="ladderTable" class="ladderTable">
        <thead> 
            <tr><td>Name</td><td>Round 1</td> ... <td>Round 50</td><td class="scoreTotal">Total</td></tr>
        </thead>
        <tr><td>Bob</td><td>11</td> ... <td>75</td><td>421</td></tr>
           ... (more scores)
    </table>
</div>
<div id="totalTableSpan" style="float:left;width:70px;border-left:2px solid gray;"></div> 

jQuery:

function stripFirstColumn() {                
    // pull out first column:
    var nt = $('<table id="nameTable" cellpadding="3" cellspacing="0" style="width:100px;"></table>');
    $('#ladderTable tr').each(function(i)
    {
        nt.append('<tr><td style="color:'+$(this).children('td:first').css('color')+'">'+$(this).children('td:first').html()+'</td></tr>');
    });
    nt.appendTo('#nameTableSpan');
    // remove original first column
    $('#ladderTable tr').each(function(i)
    {
        $(this).children('td:first').remove();
    });
    $('#nameTable td:first').css('background-color','#8DB4B7');
}

function stripLastColumn() {                
    // pull out last column:
    var nt = $('<table id="totalTable" cellpadding="3" cellspacing="0" style="width:70px;"></table>');
    $('#ladderTable tr').each(function(i)
    {
        nt.append('<tr><td style="color:'+$(this).children('td:last').css('color')+'">'+$(this).children('td:last').html()+'</td></tr>');
    });
    nt.appendTo('#totalTableSpan');
    // remove original last column
    $('#ladderTable tr').each(function(i)
    {
        $(this).children('td:last').remove();
    });
    $('#totalTable td:first').css('background-color','#8DB4B7');
}

function fixHeights() {
    // change heights:
    var curRow = 1;
    $('#ladderTable tr').each(function(i){
        // get heights
        var c1 = $('#nameTable tr:nth-child('+curRow+')').height();    // column 1
        var c2 = $(this).height();    // column 2
        var c3 = $('#totalTable tr:nth-child('+curRow+')').height();    // column 3
        var maxHeight = Math.max(c1, Math.max(c2, c3));

        //$('#log').append('Row '+curRow+' c1=' + c1 +' c2=' + c2 +' c3=' + c3 +'  max height = '+maxHeight+'<br/>');

        // set heights
        //$('#nameTable tr:nth-child('+curRow+')').height(maxHeight);
        $('#nameTable tr:nth-child('+curRow+') td:first').height(maxHeight);
        //$('#log').append('NameTable: '+$('#nameTable tr:nth-child('+curRow+')').height()+'<br/>');
        //$(this).height(maxHeight);
        $(this).children('td:first').height(maxHeight);
        //$('#log').append('MainTable: '+$(this).height()+'<br/>');
        //$('#totalTable tr:nth-child('+curRow+')').height(maxHeight);
        $('#totalTable tr:nth-child('+curRow+') td:first').height(maxHeight);
        //$('#log').append('TotalTable: '+$('#totalTable tr:nth-child('+curRow+')').height()+'<br/>');

        curRow++;
    });

    if ($.browser.msie)
        $('#ladderDiv').height($('#ladderDiv').height()+18);
}

$(document).ready(function() {
    stripFirstColumn();
    stripLastColumn();
    fixHeights();
    $("#ladderDiv").attr('scrollLeft', $("#ladderDiv").attr('scrollWidth'));    // scroll to the last round
});

Если у вас есть какие-либо вопросы или что-то непонятное, я обращаюсь к вам больше. чем рад помочь.

Мне потребовалось довольно много времени, чтобы понять, что нет ничего, что я мог бы использовать повторно, и мне потребовалось немного больше времени, чтобы написать это. Я бы не хотел, чтобы кто-то попал в такую ​​же неприятность.

2
ответ дан 2 December 2019 в 00:19
поделиться

Могу ли я предложить несколько неортодоксальное решение?

Что вы думаете о размещении столбца «итого» после колонка «имя», а не в самом конце? Разве это не исключает необходимость прокручивать только часть таблицы?

Это не совсем то, о чем вы просите, но, возможно, это достаточное решение, учитывая, что альтернатива будет довольно грязной. (Например, размещение столбцов «total» и «name» вне таблицы создаст проблемы с выравниванием, когда не все строки имеют одинаковую высоту. Вы можете исправить это с помощью JavaScript, но тогда вы попадете в совершенно новый мир боль).

Кроме того, с точки зрения пользовательского интерфейса, может быть, что «имя» и «общее» являются наиболее важными данными, в этом случае имеет смысл объединить их, после чего следует своего рода «разбивка» по итогу. Конечно, у нас, кажется, есть интуиция, что «общее» должно следовать за его составными частями, но я не думаю, что это вызовет слишком большую путаницу для пользователя, если порядок будет изменен таким образом (хотя это вопрос для вы, основываясь на вашем продукте и ваших пользователях).

В любом случае, есть что рассмотреть.

РЕДАКТИРОВАТЬ:

Вот еще несколько неортодоксальных решений, теперь, когда я думаю, что немного лучше понимаю ваши намерения:

  1. Разбивайте оценки. Дайте самую последнюю десятку, скажем, и общее, и Я не думаю, что это вызовет слишком большую путаницу у пользователя, если заказ будет изменен следующим образом (хотя это вопрос для вас, основанный на вашем продукте и ваших пользователях).

    В любом случае, есть что рассмотреть.

    РЕДАКТИРОВАТЬ:

    Вот еще несколько неортодоксальных решений, теперь, когда мне кажется, что я немного лучше понимаю ваши намерения:

    1. Разбейте результаты. Дайте самую последнюю десятку, скажем, и общее, и Я не думаю, что это вызовет слишком большую путаницу у пользователя, если заказ будет изменен следующим образом (хотя это вопрос для вас, основанный на вашем продукте и ваших пользователях).

      В любом случае, есть что рассмотреть.

      РЕДАКТИРОВАТЬ:

      Вот еще несколько неортодоксальных решений, теперь, когда мне кажется, что я немного лучше понимаю ваши намерения:

      1. Разбейте результаты. Дайте самую последнюю десятку, скажем, и общее, и ссылка на более старые баллы, которые предоставляются по 10 одновременно
      2. Только дают имена, итоги и некоторые другие значимые показатели такие как Mean и SD, а затем предоставить ссылка для каждого имени, которое показывает все результаты, соответствующие этому имя. Вы могли бы также предоставить ссылка, показывающая все результаты для заданный балл установлен, так что сравнения между разными пользователями может быть изготовлен. Дело в том, что вы бы нужно только дать 1 измерение данные для каждого представления, а не с громоздким набором двумерных данных
      3. Сделайте строки сортируемыми (легко с помощью jQuery UI), так что если я хочу сравнить Мэри с Джейн, я могу перетащить и место один за другим, поэтому я не буду нужно продолжать прокручивать влево и право видеть, какие оценки соответствуют с именами
      4. Выделите строку при щелчке, изменив фон цвет или аналогичный, опять же, поэтому мне не нужно продолжать прокручивать влево и вправо.

      В любом случае, вы поняли идею. Возможно, лучше искать решение для пользовательского интерфейса, чем искаженное решение для разметки. В конечном счете, я бы задался вопросом, насколько важно представлять пользователю столько данных одновременно, что часть их должна прокручиваться определенным образом, чтобы данные были читаемыми. Возможно, вы создаете приложение для работы с электронными таблицами, и вам действительно нужно отображать матрицу 100x100 в одном представлении. Если нет, вы наверняка могли бы придумать более креативные способы, чем я, чтобы разделить результаты.

5
ответ дан 2 December 2019 в 00:19
поделиться

Сейчас оно не завершено (я просто очень быстро его смоделировал), но вот способ сделать это, используя прямой HTML. Вам нужны три таблицы ... две вне

и одна внутри
. Все три смещены влево, так что все они находятся на одной строке.

Table Test

и сам код:

  <table style="float: left;">
     <tr>
        <td>Name</td>
     </tr>
     <tr>
        <td>John</td>
     </tr>
     <tr>
        <td>Will</td>
     </tr>
  </table>
  <div id="tableWrapper" style="overflow-x: auto; width: 500px;float:left;padding-bottom: 10px;">
      <table>
        <tr>
           <td>Score1</td>
           <td>Score2</td>
           ...
        </tr>
        <tr>
           <td>5</td>
           <td>6</td>
           ...
        </tr>
        <tr>
           <td>3</td>
           <td>7</td>
           ...
        </tr>
        <tr>
           <td>7</td>
           <td>1</td>
           ...
        </tr>
      </table>
  </div>
  <table style="float: left;">
     <tr>
        <td>Total</td>
     </tr>
     <tr>
        <td>86</td>
     </tr>
     <tr>
        <td>82</td>
     </tr>
  </table>

Примечание. Нижний отступ элемента div предназначен для того, чтобы полоса прокрутки не закрывала таблицу в IE. Кроме того, ошибка, которую я должен решить, состоит в том, как указать ширину элементов заголовка внутри средней таблицы. По какой-то причине указание атрибута width = "" не работает. Таким образом, если текст элемента заголовка слишком широкий (и разбивается на другую строку), то макет разбивается (на одну строку)

2
ответ дан 2 December 2019 в 00:19
поделиться

Я полагаю, вы хотите прокрутить его только по горизонтали. В противном случае это может привести к путанице со статическими столбцами.

Вы можете поместить переполнение: auto только на содержащий элемент из внутренних ячеек таблицы ... Я не уверен, как браузеры справятся с этим, но вы можете поставить элементы, которые вы хотите зафиксировать внутри элементов thead и tfoot, и поместите прокручиваемую часть в элемент tbody и установите для его переполнения значение auto.

В противном случае вам может понадобиться отбросить семантику и кодировать левый столбец и правый столбец за пределами Таблица.

Лично я бы попробовал закодировать его как можно более семантическим, а затем использовать JavaScript для позиционирования левого и правого столбцов. Без JavaScript вы должны сделать так, чтобы он изящно перестал работать только с широкой таблицей (не уверен, насколько это будет сложно, как вы говорите, у вас фиксированная ширина)

Вы можете попробовать этот (грубый) пример jQuery, чтобы поместить значения первого столбца наружу.

var nameTable = '<table id="outside-name-col">
                  <thead>
                   <tr>
                    <th>Name</th>
                   </tr>
                  </thead>
                 <tbody>'; // start making a table for name column only

$('#scoreTable tbody tr').each(function() { // iterate through existing table

   var nameCol = $(this).find(':first'); // get column of index 0, i.e. first

   var cellHeight = nameCol.height(); // get the height of this cell

   $(this).find('td').height(cellHeight); // equalise the height across the row so removing this element will not collapse the height if it is taller than the scores and total       

   nameTable += '<tr><td style="height: ' + cellHeight + 'px">' + nameCol.html() + '</td></tr>'; // append the next row with new height and data

   nameCol.remove(); // remove this cell from the table now it's been placed outside

});

nameTable += '</tbody></table>'; // finish table string


$('#scoreTable').before(nameTable); // insert just before the score table

Используйте CSS, чтобы расположить их для правильного выравнивания. Это не проверено, но оно должно дать вам некоторое представление.

2
ответ дан 2 December 2019 в 00:19
поделиться

Вы имели в виду горизонтальную прокрутку ??

Если вы хотите добиться горизонтальной прокрутки, тогда вы можете использовать 3 контейнера.

  1. Для первого столбца (Имя)
  2. Для столбцов, которые вы хотите прокрутить. Установите для стиля контейнера overflow-x значение auto
  3. . Для последнего столбца (всего)
1
ответ дан 2 December 2019 в 00:19
поделиться

Прокрутка содержимого таблиц является проблематичной проблемой, поскольку для этого не существует простого и безопасного для браузера решения.

Лучший и самый безопасный способ сделать это требует JavaScript. Вы бы легко достигли даже горизонтальной прокрутки (это бесплатно) с помощью этой техники, которую я использовал. Вы можете легко преобразовать это в вашу проблему:

1) Я создал 3 таблицы

2) Поместил среднюю таблицу, в которой хранятся данные, внутри контейнера DIV

3) Установите стиль DIV на переполнение: auto

4) дал заголовок и таблицу нижнего колонтитула и div каждый шириной 100%

5) окружил все другим div для контроля общей ширины таблицы

6) убедился, что количество столбцов совпадает во всех три таблицы, и что все три имеют одинаковые стили в отношении отступов, поля и границы

теперь интересная часть:

6) ниже последнего элемента этой конструкции таблицы, напишите блок javascript (или включите его из файла)

7) напишите функцию, которая последовательно просматривает каждый столбец (используйте цикл for), начиная с первого. На каждой итерации этого цикла проверяйте ячейку td с первыми двумя таблицами в текущем столбце. Проверьте, какой из них больше, и назначьте его стилю меньшей ячейки TD. Возможно, вы захотите применить это значение и к таблице нижнего колонтитула.

8) вызвать эту функцию. Возможно, вы захотите сделать это через интервал или когда произойдут особые события, такие как новые данные в ячейках (например, при использовании ajax).

Примечание. При горизонтальной прокрутке размеры столбцов синхронизируются. Но вам придется синхронизировать позицию прокрутки таблицы верхнего и нижнего колонтитула с таблицей содержимого. В качестве альтернативы вы просто позволяете полному div прокручивать все по горизонтали, но не по вертикали. Это была бы работа DIV, которая содержит таблицу данных.

Этот метод очень хорошо работал во всех основных браузерах в проекте диаграммы Гопта с очень коплексом.

Примечание: Вы можете легко придумать эту концепцию под углом 90 градусов повернут таким образом, чтобы при прокрутке вы исправляли первый и последний столбец заголовка.

Редактировать: Вот еще один пример из моей базы кода, который может помочь вам найти решение:

var left_td = document.getElementById("left_td");
var right_td = document.getElementById("right_td");
var contentDiv = document.getElementById("contentDiv");
window.setInterval(function(){
    var left_td_width = Math.round((parseInt(contentDIV.offsetWidth) - 120) / 2);
    var right_td_width = (parseInt(contentDIV.offsetWidth) - left_td_width - 120;

    left_td.style.width = left_td_width + "px";
    right_td.style.width = right_td_width + "px";
}, 25);

Этот код выполняет следующие действия: , таблица с 3 столбцами всегда выглядит так: первый и последний столбцы имеют одинаковый размер, а центральный столбец имеет ширину 120 пикселей. В качестве альтернативы вы просто позволяете полному div прокручивать все по горизонтали, но не по вертикали. Это была бы работа DIV, которая содержит таблицу данных.

Этот метод очень хорошо работал во всех основных браузерах в проекте диаграммы Гопта с очень коплексом.

Примечание: Вы можете легко придумать эту концепцию под углом 90 градусов повернут таким образом, чтобы при прокрутке вы исправляли первый и последний столбец заголовка.

Редактировать: Вот еще один пример из моей базы кода, который может помочь вам найти решение:

var left_td = document.getElementById("left_td");
var right_td = document.getElementById("right_td");
var contentDiv = document.getElementById("contentDiv");
window.setInterval(function(){
    var left_td_width = Math.round((parseInt(contentDIV.offsetWidth) - 120) / 2);
    var right_td_width = (parseInt(contentDIV.offsetWidth) - left_td_width - 120;

    left_td.style.width = left_td_width + "px";
    right_td.style.width = right_td_width + "px";
}, 25);

Этот код выполняет следующие действия: , таблица с 3 столбцами всегда выглядит так: первый и последний столбцы имеют одинаковый размер, а центральный столбец имеет ширину 120 пикселей. В качестве альтернативы вы просто позволяете полному div прокручивать все по горизонтали, но не по вертикали. Это была бы работа DIV, которая содержит таблицу данных.

Этот метод очень хорошо работал во всех основных браузерах в проекте диаграммы Гопта с очень коплексом.

Примечание: Вы можете легко придумать эту концепцию под углом 90 градусов повернут таким образом, чтобы при прокрутке вы исправляли первый и последний столбец заголовка.

Редактировать: Вот еще один пример из моей базы кода, который может помочь вам найти решение:

var left_td = document.getElementById("left_td");
var right_td = document.getElementById("right_td");
var contentDiv = document.getElementById("contentDiv");
window.setInterval(function(){
    var left_td_width = Math.round((parseInt(contentDIV.offsetWidth) - 120) / 2);
    var right_td_width = (parseInt(contentDIV.offsetWidth) - left_td_width - 120;

    left_td.style.width = left_td_width + "px";
    right_td.style.width = right_td_width + "px";
}, 25);

Этот код выполняет следующие действия: , таблица с 3 столбцами всегда выглядит так: первый и последний столбцы имеют одинаковый размер, а центральный столбец имеет ширину 120 пикселей. Конечно, это не относится непосредственно к вашей особой проблеме, но может дать вам отправную точку в динамическом манипулировании таблицами с помощью JavaScript.

0
ответ дан 2 December 2019 в 00:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: