使用`collection_check_boxes`进行垂直排序

时间:2013-08-15 06:48:04

标签: ruby-on-rails ruby

我有一个由我的控制器用@cities = City.order :name加载的城市列表。

并在我的视图中的复选框中显示以下内容:

f.collection_check_boxes :cities_ids, @cities, :id, :name

每个复选框都包含在33%宽的div中,其输出方式如下:

city_A   |   city_B   |   city_C
city_D   |   city_E   |   city_F
city_G   |   city_H   |   city_I
city_J   |            |   

我尝试在将@cities传递给构建器之前对其进行排序,因此它可以在3列上垂直对齐:

city_A   |   city_E   |   city_H
city_B   |   city_F   |   city_I
city_C   |   city_G   |   city_J
city_D   |            |   

在尝试EnumerableArray方法的不同组合(以及鼻出血和2种阿司匹林)后,我决定问你们。谢谢!

临时解决方案

通过写一个助手,我可以解决问题,如果你们能提出一个更好的更紧凑的解决方案,我将不胜感激。看看这个

def per_column(records, number_of_columns = 3)
  collection = records.dup
  result = []

  return collection if records.count <= number_of_columns

  # Build columns
  number_of_columns.times do |column_index|
    number_of_items = (collection.count.to_f / (number_of_columns - column_index)).ceil
    result << collection.slice!(0, number_of_items)
  end

  # Ensure each columns has same number of lines
  result.each {|column| column << nil until column.count == result[0].count }

  # Transpose
  result.transpose.flatten.compact
end

然后我打电话给

f.collection_check_boxes :cities_ids, per_column(@cities), :id, :name

似乎适用于任意数量的记录。再一次,如果你能指出我更优雅的解决方案,我将不胜感激

2 个答案:

答案 0 :(得分:3)

嘿,我自己刚刚实施了这个!要在列中列出表单中的collection_check_boxes项,请使用一点CSS。

1)为3列创建一个CSS类:

.form-3-col {
  -webkit-column-count: 3; /* Chrome, Safari, Opera */
  -moz-column-count: 3; /* Firefox */
  column-count: 3; 
}

我建议将此课程放在名为forms.css.scss的样式表中,您需要application.css *= require forms

您可以在此处找到一些有用的样式加载项,例如列间距:http://www.w3schools.com/css/css3_multiple_columns.asp

2)在表单中实现CSS类:

 <li>
  <%= f.label :city %>
  <div class="form-3-col">
    <%= f.collection_check_boxes :cities_ids, @cities, :id, :name %>
  </div> <!-- form-3-col -->
 </li>

请注意div如何仅包含f.collection_check_boxes erb标记,因为它会对其中的任何内容进行列举。

答案 1 :(得分:1)

执行此操作的正确方法可能是将每个“列”包装在div中,而不是每个复选框。

但是,如果这不可行 - 如果您想使用collection_check_boxes则不行 - 请查看我刚刚发布的in_columns gem

那应该允许你做

f.collection_check_boxes :cities_ids, InColumns.columnize(@cities, 3).flatten.compact, :id, :name

f.collection_check_boxes :cities_ids, @cities.in_columns(3).flatten.compact, :id, :name

如果您在gem中使用Array扩展名。