首页 > 解决方案 > 需要限制表中字段的大小

问题描述

管理面板的表格是使用 javascript 呈现的。我有以下功能,我需要对其中的字段大小进行限制。以前通过限制代码后的整个表来设法做到这一点。

var drawTable = function () {
        tableHeaderLevels = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []};
        tableStructurePaths = [];
        var tableHtml = '<div class="table-cont" id="table-cont" style="table-layout: fixed; width: 850%;">';
        tableHtml += '<table class="table table-striped table-bordered" style="table-layout: fixed">';
        if ($('#data').text()) {
            let users = JSON.parse($('#data').text());
            tableStructure = {};
            users.forEach((user, i) => {
                parseHeaderTemplate(user, tableStructure);
            });
            tableHtml += renderTableHeader(tableStructure);
            tableHtml += '<tbody>';
            tableHtml += renderFilterRow(tableStructure);
            users.forEach((user, i) => {
                tableHtml += renderUserRow(tableStructure, user, i % 2 != 0);
            });
            tableHtml += '</tbody>';
            tableHtml += '</table>';
            tableHtml += '</div>';
            $('#content').html(tableHtml);
        }
    };

但这不是正确的解决方案,需要尽量限制函数中的 td 标签。

var renderUserRow = function (tableStructure, user, striped = false) {
        var html = '';
        var values = {1: []};
        var rowspan = 1;
        var show_more_ids = $("#show-more-list").val().split(',')
        tableStructurePaths.forEach(path => {
            var value = getPathValue(user, path);
            if (Array.isArray(value)) {
                var stats = $.inArray('' + user['id'], show_more_ids);
                if (stats == -1) {
                    values[1].push({value: value[0], deepness: 1});
                } else {
                    if (value.length == 0) {
                        values[1].push({value: '', deepness: 1});
                    }
                    if (value.length > rowspan) rowspan = value.length;
                    value.forEach((val, index) => {
                        if (!values[index + 1]) values[index + 1] = [];
                        if (index == value.length - 1) {
                            values[index + 1].push({value: val, deepness: value.length});
                        } else {
                            values[index + 1].push({value: val, deepness: 0});
                        }
                    });
                }
            } else {
                values[1].push({value: value, deepness: 1});
            }
        });
        Object.keys(values).forEach(rowNumber => {
            html += '<tr' + (striped ? ' class="striped-row"' : '') + '>';
            values[rowNumber].forEach(valDesc => {
                if (valDesc.value === null || valDesc.value === undefined) valDesc.value = '';
                html += '<td style="line-height: 2px;white-space: nowrap;overflow:hidden;" rowspan="' + (valDesc.deepness ? rowspan - valDesc.deepness + 1 : 1) + '">' + valDesc.value + '</td>';
            });
            html += '</tr>';
        });
        return html;
    };

更新:: 渲染源代码

function showFullInfo(obj) {
  arr = $("#show-more-list").val().split(',')

  var stats = $.inArray(obj.id, arr);
  if (stats == -1) {
    arr.push(obj.id);
  } else {
    arr = arr.filter(function(value, index, arr) {
      return value != obj.id;
    });
  }
  $("#show-more-list").val(arr);
  refreshTable();
  /*id = '#' + obj.id
  if (obj.text === 'more...'){
      $(id).text('less...');
      refreshTable();
  } else {$(id).text('more...'); refreshTable();}*/
}

function previewImageOn(input) {
  id = '#' + input.id + '-hidden'
  $(id).show();
}

function previewImageOff(input) {
  id = '#' + input.id + '-hidden'
  $(id).hide();
}

var tableHeaderLevels;
var tableStructurePaths;
var tableStructure;

var parseHeaderTemplate = function(entry, parentContainer) {
  var rowspan = 1;
  if (typeof entry === 'object') {
    Object.keys(entry).forEach(key => {
      if (!parentContainer[key]) {
        parentContainer[key] = {};
      }
      if (Array.isArray(entry[key])) {
        entry[key].forEach(nextEntry => {
          var newRowspan = parseHeaderTemplate(nextEntry, parentContainer[key] = parentContainer[key] || {});
          if (newRowspan > rowspan) {
            rowspan = newRowspan;
          }
        })
      } else if (entry[key] && typeof entry[key] === 'object') {
        if ((parentContainer[key].colspan || -1) < Object.keys(entry[key]).length) {
          parentContainer[key].colspan = Object.keys(entry[key]).length;
        }
        var newRowspan = parseHeaderTemplate(entry[key], parentContainer[key] = parentContainer[key] || {}) + 1;
        if (newRowspan > rowspan) {
          rowspan = newRowspan;
        }
      } else {
        if (rowspan < 2) {
          rowspan = 2;
        }
      }
    });
    parentContainer.colspan = 0;
    Object.keys(entry).forEach(key => {
      parentContainer.colspan += parentContainer[key].colspan || 1;
    });
    parentContainer.rowspan = parentContainer.rowspan > rowspan ? parentContainer : rowspan;
  }
  return rowspan;
};

var constructTableHeader = function(tableStructure, deepness, key, fullPath = '') {
  let rowspan = tableStructure.rowspan;
  if (key) {
    tableStructure = tableStructure[key];
  }
  if (Object.keys(tableStructure).length > 0) {
    Object.keys(tableStructure).forEach(key => {
      if (!['colspan', 'rowspan'].includes(key)) {
        constructTableHeader(tableStructure, deepness + 1, key, fullPath == '' ? key : fullPath + '.' + key);
      }
    });
    if (deepness > 0) tableHeaderLevels[deepness].push('<th colspan="' + tableStructure.colspan + '">' + key + '</th>')
  } else {
    if (!['colspan', 'rowspan'].includes(key)) {
      var sortButton = '<span class="sort-input glyphicon glyphicon-sort" order="ignore" path="' + fullPath + '" onclick="changeSort(this)"></span>';
      tableHeaderLevels[deepness].push('<th rowspan="' + (7 - deepness) + '"><span style="white-space: nowrap;">' + key + '&nbsp;' + sortButton + '</span></th>');
      tableStructurePaths.push(fullPath);
    }
  }
};
var renderTableHeader = function(tableStructure) {
  constructTableHeader(tableStructure, 0);
  var html = '<thead>';
  for (var i = 1; i <= Object.keys(tableHeaderLevels).length; i++) {
    html += '<tr style="line-height: 2px; table-layout: fixed; width: 80%;;">';
    tableHeaderLevels[i].forEach(th => {
      html += th;
    });
    html += '</tr>';
  }
  html += '</thead>';
  return html;
};
var renderFilterRow = function(tableStructure) {
  var html = '<tr id="filter-row">';
  for (var i = 0; i < tableStructure.colspan; i++) {
    html += '<td><input oninput="changeFilter()" class="form-control filter-input" type="text" name="' + i + '"/></td>';
  }
  html += '</tr>';
  return html;
};

var getPathValue = function(entry, path) {
  var pathParts = path.split('.');
  pathParts.forEach(part => {
    if (!entry) return;
    if (Array.isArray(entry)) {
      var newEntry = [];
      let index = -1;
      entry.forEach((val) => {
        index++;
        if (!val) return;
        if (Array.isArray(val)) {
          val.forEach(val_item => {
            newEntry[index] = val_item[part];
            index++;
          });
        } else {
          newEntry[index] = val[part];
        }
      });
      entry = newEntry;
    } else {
      entry = entry[part];
    }
  });
  return entry;
};

var renderUserRow = function(tableStructure, user, striped = false) {
  var html = '';
  var values = {
    1: []
  };
  var rowspan = 1;
  var show_more_ids = $("#show-more-list").val().split(',')
  tableStructurePaths.forEach(path => {
    var value = getPathValue(user, path);
    if (Array.isArray(value)) {
      var stats = $.inArray('' + user['id'], show_more_ids);
      if (stats == -1) {
        values[1].push({
          value: value[0],
          deepness: 1
        });
      } else {
        if (value.length == 0) {
          values[1].push({
            value: '',
            deepness: 1
          });
        }
        if (value.length > rowspan) rowspan = value.length;
        value.forEach((val, index) => {
          if (!values[index + 1]) values[index + 1] = [];
          if (index == value.length - 1) {
            values[index + 1].push({
              value: val,
              deepness: value.length
            });
          } else {
            values[index + 1].push({
              value: val,
              deepness: 0
            });
          }
        });
      }
    } else {
      values[1].push({
        value: value,
        deepness: 1
      });
    }
  });
  Object.keys(values).forEach(rowNumber => {
    html += '<tr' + (striped ? ' class="striped-row"' : '') + '>';
    values[rowNumber].forEach(valDesc => {
      if (valDesc.value === null || valDesc.value === undefined) valDesc.value = '';
      html += '<td style="line-height: 2px;white-space: nowrap;overflow:hidden;" rowspan="' + (valDesc.deepness ? rowspan - valDesc.deepness + 1 : 1) + '">' + valDesc.value + '</td>';
    });
    html += '</tr>';
  });
  return html;
};

var clearFilters = function() {
  $('.filter-input').val('');
  $('.sort-input').removeClass('glyphicon-sort-by-attributes');
  $('.sort-input').removeClass('glyphicon-sort-by-attributes-alt');
  $('.sort-input').addClass('glyphicon-sort');
  $('.sort-input').attr('order', 'ignore');
  sortInputs = [];
  refreshTable();
};

var timeout;
var changeFilter = function() {
  clearTimeout(timeout);
  timeout = setTimeout(function() {
    refreshTable();
  }, 500);
};

var applyFilters = function(users) {
  var filters = [];
  $('.filter-input').map(function() {
    if (this.value.trim().length > 0) {
      filters.push({
        index: +$(this).attr('name'),
        value: this.value.trim()
      });
    }
  });
  filters.forEach(filter => {
    filter.path = tableStructurePaths[filter.index];
  });
  return users.filter(function(user) {
    var filterPassed = true;
    filters.forEach(filter => {
      var filterValues = filter.value.split(',');
      var value = getPathValue(user, filter.path);
      if (Array.isArray(value)) {
        var passed = false;
        value.forEach(val => {
          filterValues.forEach(filterValue => {
            if (filterValue.trim().length == 0) return;
            var years = filterValue.match(/^(\d+)\s?-\s?(\d+)$/);
            if (years) {
              var year = (new Date(val)).getFullYear();
              passed = passed || (year >= years[1] && year <= years[2]);
            } else {
              passed = passed || (val && val.toString().toLowerCase().includes(filterValue.trim().toLowerCase()));
            }
          });
        });
        filterPassed = filterPassed && passed;
      } else {
        var passed = false;
        filterValues.forEach(filterValue => {
          if (filterValue.trim().length == 0) return;
          var years = filterValue.match(/^(\d+)\s?-\s?(\d+)$/);
          if (years) {
            var year = (new Date(value)).getFullYear();
            passed = passed || (year >= years[1] && year <= years[2]);
          } else {
            passed = passed || (value && value.toString().toLowerCase().includes(filterValue.trim().toLowerCase()));
          }
        });
        filterPassed = filterPassed && passed;
      }
    });
    return filterPassed;
  })
};

var changeSort = function(element) {
  var order = $(element).attr('order');
  var path = $(element).attr('path');
  if (order == 'ignore') {
    $(element).attr('order', 'asc');
    sortInputs.push({
      path: path,
      value: 'asc'
    });
    $(element).removeClass('glyphicon-sort');
    $(element).addClass('glyphicon-sort-by-attributes');
  } else if (order == 'asc') {
    $(element).attr('order', 'desc');
    sortInputs.forEach((input, index) => {
      if (input.path == path) {
        input.value = 'desc';
      }
    });
    $(element).removeClass('glyphicon-sort-by-attributes');
    $(element).addClass('glyphicon-sort-by-attributes-alt');
  } else if (order == 'desc') {
    $(element).attr('order', 'ignore');
    var inputIndex = -1;
    sortInputs.forEach((input, index) => {
      if (input.path == path) {
        inputIndex = index;
      }
    });
    sortInputs.splice(inputIndex, 1);
    $(element).removeClass('glyphicon-sort-by-attributes-alt');
    $(element).addClass('glyphicon-sort');
  }
  refreshTable();
};
var sortInputs = [];
var applySorting = function(users) {
  return users.sort(function(a, b) {
    var order = 0;
    var i = 0;
    while (order == 0 && i < sortInputs.length) {
      var aValue = getPathValue(a, sortInputs[i].path);
      var bValue = getPathValue(b, sortInputs[i].path);

      if (aValue > bValue) {
        order = 1;
      } else if (aValue < bValue) {
        order = -1;
      }
      if (sortInputs[i].value == 'desc') {
        order = order * -1;
      }
      i++;
    }
    return order;
  });
};

var drawTable = function() {
  tableHeaderLevels = {
    1: [],
    2: [],
    3: [],
    4: [],
    5: [],
    6: []
  };
  tableStructurePaths = [];
  var tableHtml = '<div class="table-cont" id="table-cont">';
  tableHtml += '<table class="table table-striped table-bordered" >';
  if ($('#data').text()) {
    let users = JSON.parse($('#data').text());
    tableStructure = {};
    users.forEach((user, i) => {
      parseHeaderTemplate(user, tableStructure);
    });
    tableHtml += renderTableHeader(tableStructure);
    tableHtml += '<tbody>';
    tableHtml += renderFilterRow(tableStructure);
    users.forEach((user, i) => {
      tableHtml += renderUserRow(tableStructure, user, i % 2 != 0);
    });
    tableHtml += '</tbody>';
    tableHtml += '</table>';
    tableHtml += '</div>';
    $('#content').html(tableHtml);
  }
};

var refreshTable = function() {
  var tableHtml = '';
  let users = JSON.parse($('#data').text());
  users = applyFilters(users);
  users = applySorting(users);
  users.forEach((user, i) => {
    tableHtml += renderUserRow(tableStructure, user, i % 2 != 0);
  });
  $("tbody tr:not(#filter-row)").remove();
  $("tbody").append(tableHtml);
};

$(document).on('turbolinks:load', function() {
  drawTable();
});


window.onload = function() {
  var tableCont = document.querySelector('#table-cont')

  /**
   * scroll handle
   * @param {event} e -- scroll event
   */
  function scrollHandle(e) {
    var scrollTop = this.scrollTop;
    this.querySelector('thead').style.transform = 'translateY(' + scrollTop + 'px)';
  }

  tableCont.addEventListener('scroll', scrollHandle)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="statistics">
  <input type="button" onclick="clearFilters()" value="Clear filters" />
  <a class="btn" href="http://localhost:3000/statistics/csv">Export CSV</a>
  <a class="btn" href="http://localhost:3000/statistics/xlsx">Export XLSX</a>
  <div id="content"></div>
</div>

<input type="hidden" name="show-more-list" id="show-more-list" value="" />

标签: javascript

解决方案


推荐阅读