0

我在 Rails 3 中使用 CoffeeScript 中的构建将项目从一个选择列表移动到另一个选择列表并返回。这适用于以下代码:

$ ->
   $('#add').click (event) ->
     $('#geo_country_exclude option:selected').remove().appendTo('#geo_country_include');  

   $('#remove').click (event) ->
     $('#geo_country_include option:selected').remove().appendTo('#geo_country_exclude');

选择列表的代码:

<%= select :geo, :country_exclude, @countries, {}, {:multiple => true, :size => 15} %>
<%= select :geo, :country_include, @countries, {}, {:multiple => true, :size => 15} %>

问题是它将一个新项目附加到列表的末尾。我希望列表再次按字母顺序排序。我该怎么做呢?谢谢。

4

1 回答 1

1

基本上,您需要将<option>s 从 target中拉出<select>,将选项添加到该数组,手动对其进行排序,然后将 target <select>s <option>s 替换为排序列表。jQuery 对这类事情没有多大帮助,但低级 DOM 版本并不是非常困难,如下所示:

exc = $('#geo_country_exclude')[0]
inc = $('#geo_country_include')[0]

by_option_value = (a, b) ->
    return +1 if(a.value > b.value)
    return -1 if(a.value < b.value)
    return  0

mv = (from, to) ->
    # to.options looks like an array and smells like an array but
    # it isn't an array so we employ the standard arrayification trick.
    opts = [].slice.call(to.options)
    # Move the <option>
    opts.push(from.options[from.selectedIndex])
    from.remove(from.selectedIndex)
    # Sort and replace.
    to.remove(0) for i in [ 0 ... to.options.length ]
    to.add(opt) for opt in opts.sort(by_option_value)

$('#add'   ).click (event) -> mv(exc, inc)
$('#remove').click (event) -> mv(inc, exc)

您可能需要调整by_option_value比较功能,并且您可能希望在<select>移动后调整 s 中的选定项目,但您可以轻松地对其进行排序。

演示:http: //jsfiddle.net/ambiguous/qRw3K/

如果您需要处理多选,那么只需稍作修改即可mv

mv = (from, to) ->
    opts = [].slice.call(to.options)
    while from.selectedIndex >= 0
        opts.push(from.options[from.selectedIndex])
        from.remove(from.selectedIndex)
    to.remove(0) for i in [ 0 ... to.options.length ]
    to.add(opt) for opt in opts.sort(by_option_value)

您只需要将opts.pushand包裹from.remove在一个while小循环中。

演示:http: //jsfiddle.net/ambiguous/qRw3K/1/

于 2012-08-18T17:55:45.560 回答