代码之家  ›  专栏  ›  技术社区  ›  mpen

如何让这个ajax下拉选择器在所有浏览器上工作?

  •  2
  • mpen  · 技术社区  · 15 年前

    我写了这个代码来填充 <select> 包含ajax调用结果的框。。。

    (function() {
        var cache = {};
        var queue = {};
    
        $('select.country').live('change', function() {
            var $countrySel = $(this);
            var $provSel = $countrySel.closest('tr,.label-and-input').next().find('select.province');
            var $provInput = $provSel.siblings('input.province');
            var country = $countrySel.val();
            var province = $provInput.val();
    
            $provSel.empty();
            if(country == '' || country == null) {
                $provSel.trigger('change');
                return;
            }
    
            if(country in cache) {
                addOptions($provSel, cache[country]);
            } else if(country in queue) {
                $provSel.addClass('loading');
                queue[country].push($provSel);      
            } else {
                $provSel.addClass('loading');
                queue[country] = [$provSel]
                $.getJSON('/get-provinces.json', {country:country}, function(provinces) {
                    cache[country] = provinces;
                    while(queue[country].length > 0) {
                        var $select = queue[country].pop();
                        $select.removeClass('loading');
                        addOptions($select, cache[country]);    
                    }                               
                });
            }
        }).trigger('change');
    })();
    
    function addOptions($select, options) {
        $select.append('<option value="">- Select -</option>');
        for(var i in options) {
            $select.append('<option value="{0}">{1}</option>'.format(options[i][0], options[i][1]));
        }
        $select.val($select.siblings('input:first').val()).trigger('change');
    }
    

    在我测试过的所有浏览器上都能很好地工作,但当然,在我的客户机上不行。

    empty() 这个 <option> 列出,然后 append 新的 <options> 逐一地。在某些浏览器中,当您在国家/地区之间来回切换时,州/省列表无法正确刷新。。。它保留旧值,只添加新值,或者根本不添加新值。

    最便于携带的方法是什么?我是否应该将所有选项构建为一个大的html字符串,然后使用 .html() ? 我应该删除 <选择> 以确保正确清空?


    HTML:

    <tr class="address province">
        <th class="label-cell">
            <label for="id_pickup_address-province">
                Province/State
            </label>
        </th>
        <td class="field-cell">
            <input style="display: none;" id="id_pickup_address-province" class="address province" value="BC" name="pickup_address-province" type="text"><select class="province address"><option value="">- Select -</option><option value="AB">Alberta</option><option value="BC">British Columbia</option><option value="MB">Manitoba</option><option value="NB">New Brunswick</option><option value="NF">Newfoundland and Labrador</option><option value="NT">Northwest Territories</option><option value="NS">Nova Scotia</option><option value="NU">Nunavut</option><option value="ON">Ontario</option><option value="PE">Prince Edward Island</option><option value="QC">Quebec</option><option value="SK">Saskatchewan</option><option value="YT">Yukon</option></select>
        </td>
    </tr>
    

    省选择实际上是动态添加的,它会在更改时更新隐藏字段。必须这样做才能让它正确地与Django接口,并很好地降级。

    1 回复  |  直到 15 年前
        1
  •  1
  •   davehauser    15 年前

    不确定,如果这有帮助的话。我在填充时遇到了一些问题 <select>

    我可以通过在添加 <option> <选择> :

    $.getJSON('/get-provinces.json', {country:country}, function(provinces) {
        setTimeout(function() {
            cache[country] = provinces;
            while(queue[country].length > 0) {
                var $select = queue[country].pop();
                $select.removeClass('loading');
                addOptions($select, cache[country]);    
            }
        }, 1); // 1 millisecond delay
    });
    

    请你试一试。。。