带有标签+字段单元的表单可以包装,但在包裹

时间:2016-08-03 12:42:44

标签: javascript html css

我有一个流体设计的表格,由一系列标签和字段组成,我希望它们一个接一个地流动,并在必要时包裹以支持窗口的宽度。 (标签和输入必须作为一个单元流动,在一行的末尾没有悬挂标签,其输入在下一行。)但是当它们换行时,我希望这些字段以整齐的方式排列。有没有办法用HTML和CSS做到这一点? (不幸的是,我必须支持没有CSS3列的旧浏览器[如果他们甚至在这里帮助]。)

我尝试了几件事,例如给标签(好吧,跨度)一个固定的长度(你想要点击全屏'按钮在代码段中,因此代码段窗口宽度没有固定)



.wrapped-fields label {
  display: inline-block;
}
.wrapped-fields label > span {
  display: inline-block;
  width: 8em;
  white-space: nowrap;
}

<form class="wrapped-fields">
  <label>
    <span>Short:</span>
    <input type="text" size="5">
  </label>
  <label>
    <span>Long label for field:</span>
    <input type="text" size="5">
  </label>
  <label>
    <span>Medium label:</span>
    <input type="text" size="5">
  </label>
  <label>
    <span>Short:</span>
    <input type="text" size="5">
  </label>
  <label>
    <span>Long label for field:</span>
    <input type="text" size="5">
  </label>
  <label>
    <span>Medium label:</span>
    <input type="text" size="5">
  </label>
</form>
&#13;
&#13;
&#13;

......但由于以下几个原因,这种情况令人不满意:

  1. 它要求我为标签跨度设置固定大小,但这些标签的名称可以来自配置,因此我不想在运行时测量它们中的每一个并调整固定大小到最大。

  2. 当他们在每列中堆放最长的标签时看起来没问题:

    enter image description here

    ...但是可怕的,当他们不是,例如:

    enter image description here

    ...或:

    enter image description here

  3. 理想情况下,每个&#34;列&#34;将采用其中最长标签或字段的大小(尽管现在所有字段都是相同的大小),相应地,标签+字段对包装。

    无法使用HTML / CSS解决方案,是否有一个简单的JavaScript解决方案? (如果没有,我会编写复杂的代码;不要求人们做大量的代码,如果需要的话。)

    如果相关:

    • 我使用Bootstrap,所以如果网格系统有帮助(我没有运气),我们就可以使用

    • 我使用jQuery,如果我们需要JavaScript解决方案

2 个答案:

答案 0 :(得分:1)

警告:此解决方案使用JavaScript

要使用JavaScript执行此操作,您需要首先确定应该有多少列。如果你在知道列数之前尝试设置宽度,你最终可能会将输入推到最后并且搞砸了。

我计算列数的方法是通过将它们全部放在一行中向后工作。对于每种可能性,我将最大列宽(和其他额外空间)相加,并检查该总数是否大于可用空间。如果总数较大,则我减去一列并再次尝试,从而确保最大列数。

最后,当我有一个解决方案时,我将每个style.width的{​​{1}}设置为该列的最大宽度,以便每列中的所有span都具有相同的大小

一个问题是,如果第一列比其他列窄得多,那么除了该列中的第一个元素之外的所有列都可能无法正确包裹。为了解决这个问题,我从可用空间中减去一行中元素的总宽度,然后将每行中最后label的{​​{1}}设置为该数字(减去4个像素,为安全)。

以下是一个工作示例。继续全屏并调整大小;我有一个margin-right事件处理程序,所以它应该可以工作。

label
resize
jQuery(function($) {
  var availableWidth;
  var $elements = $('.wrapped-fields span');
  var widths = [];

  $elements.each(function setWidth() {
    widths.push($(this).width());
  });

  var inputWidth = $elements.first().parent().width() - widths[0];

  function getMaxWidth(size, column) {
    var max = 0;
    var row = 0;
    var length = widths.length;
    var index = column + (size * row);


    while (index < length) {
      width = widths[index];

      if (width > max) {
        max = width;
      }

      row++;
      index = column + (size * row);
    }

    return max;
  }

  function tryGroup(n) {
    // Start with inline-block space
    var total = 4 * (n - 1);
    var maxWidths = [];
    var w;

    var i = 0;
    for (; i < n; i++) {
      w = getMaxWidth(n, i);
      total += w + inputWidth;
      maxWidths.push(w);
    }

    if (total < availableWidth) {
      return [maxWidths, total];
    }
  }

  function alignColumns() {
    // Set the global available width
    availableWidth = $('.wrapped-fields').width();

    var i = widths.length;
    var result;

    for (; i > 0; i--) {
      result = tryGroup(i);

      if (result) {
        break;
      }
    }

    if (!result) {
      console.log('Error: not enough space');
      return;
    }

    var maxWidths = result[0];
    var total = result[1];

    var size = maxWidths.length;
    var afterSpace = availableWidth - total - 4;

    $elements.each(function setWidths(index, el) {
      var width = maxWidths[index % size];
      var parent = el.parentElement;

      el.style.width = width + 'px';

      if (index % size === size - 1) {
        parent.style.marginRight = afterSpace + 'px';
      } else {
        parent.style.marginRight = '';
      }
    });
  }

  alignColumns();

  $(window).resize(alignColumns);
});

答案 1 :(得分:0)

我认为最好的解决方案是将所有标签放在div中并将所有输入放在div中。然后,我会将输入组分成列。

以下是一个例子:

.column {
  display: inline-block;
  margin: 10px 0px 10px 0px;
}

.labels {
  display: inline-block;
}

.inputs {
  display: inline-block;
  margin-left: 10px;
}
<form class="form">
  <fieldset class="fieldset">
    <legend>Forms</legend>
    <div class="column">
      <div class="labels">
        <label>Field Name:</label>
        <br>
        <label>Short:</label>
      </div>
      <div class="inputs">
        <input type="text" size="5">
        <br>
        <input type="text" size="5">
      </div>
    </div>
    <div class="column">
      <div class="labels">
        <label>Field Name:</label>
        <br>
        <label>A Much Longer Field Name:</label>
      </div>
      <div class="inputs">
        <input type="text" size="5">
        <br>
        <input type="text" size="5">
      </div>
    </div>
    <div class="column">
      <div class="labels">
        <label>Some More Field Names:</label>
        <br>
        <label>Not So Long:</label>
      </div>
      <div class="inputs">
        <input type="text" size="5">
        <br>
        <input type="text" size="5">
      </div>
    </div>
  </fieldset>
</form>

这是你在找什么?