有時候我們必需要動態產生下拉式選單時,用以前的Javascript去寫實在太麻煩了,不過自從有了jquery,一切都簡單多了。所以我自己寫了一個dynamicSelector.js的程式,來方便完成下拉式選單的動作。這次的寫法,每個選單都是用Ajax的方式取得。而且可以套用在多層下拉式選單,只要定義明確都可以運作。

在HTML部分所以,<select>的title屬性定義了三個變數。

  • url:資料來源,此選單是讀取來源網址回傳的json資料
  • parent:父層名稱,表示此選單會依照此父層的改變而一起變動
  • varname:變數名稱,此選單會抓取父層的值,然後配給此變數名稱後,傳給資料來源網址

初始的<option>就等同於預設選項,所以不必再去設定selected="selected",只要確認初始<option>中的value是符合與讀取出來的資料索引匹配,就會被視為預設選項。@_@說的好模糊耶,還是直接看線上展示好了

《LIVE DEMO》

不過比較遺憾的是把屬性定義在title,不過select已沒有其它屬性可以用了@_@!,雖然可以用自訂的屬性,不過這樣子在HTML驗證器就會出現警告了,呃…我好像有點完美主義?!

下列所需的js檔,可以直接複製後,再貼到新文件,記得文件要用UTF8編碼唷

$(document).ready(function(){
    //代替反斜線(避免HTML驗證器的警告)
    var slash = '/';
    //抓起需動態產生的選單
    var dynamicSelector = $('select[class="dynamicSelector"]');
    //針對每個動態選單預始化與事件設定
    $.each(dynamicSelector,function(){        
        //目前執行的選單
        var selector = $(this);
        //取得設定檔(定義於title屬性中)
        var config = eval('('+selector.attr('title')+')');
        //如果有父層選單,取得父層的預設值
        if(config.parent != null){
            //父選單物件
            var parentSeletor = $(config.parent);
            //父選單目前的值
            var parentValue = ($('option:selected',parentSeletor).attr('value'));
            //初始Ajax的URL網址,並加上變數
            if(config.varname != null){
                var iniUrl = config.url+'&amp;'+config.varname+'='+parentValue;
            } else {
                var iniUrl = config.url+'/'+parentValue;
            }            
            //進行遠端讀取選項
            $.getJSON(iniUrl,function(json){
                //該選單的預設值
                var defaultValue = ($('option:selected',selector).attr('value'));
                //用來存放動態產生的選項
                var opts = '';
                //
                var maxlength = 0;
                $.each(json,function(value,option){
                    if(option.length > maxlength){
                        maxlength = option.length;
                    }
                    if(value == defaultValue){
                        opts += '<option value="'+value+'" selected="selected">'+option+'<'+slash+'option>';
                    } else {
                        opts += '<option value="'+value+'">'+option+'<'+slash+'option>';
                    }                    
                });
                //註冊事件,當父層異動時,重新抓取父層值後更新自身選項
                parentSeletor.change(function(){
                    parentValue = $(this).val();
                    if(config.varname != null){
                        var changeUrl = config.url+'&amp;'+config.varname+'='+parentValue;
                    } else {
                        var changeUrl = config.url+'/'+parentValue;
                    } 
                    $.getJSON(changeUrl,function(json){
                        var defaultValue = ($('option:selected',selector).attr('value'));
                        var opts = '';
                        var maxlength = 0;
                        $.each(json,function(value,option){
                            if(option.length > maxlength){
                                maxlength = option.length;
                            }
                            if(value == defaultValue){
                                opts += '<option value="'+value+'" selected="selected">'+option+'<'+slash+'option>';
                            } else {
                                opts += '<option value="'+value+'">'+option+'<'+slash+'option>';
                            }                    
                        });
                        selector.html(opts);
                        autoWidth = (maxlength+2)*selector.css('font-size').split('px').shift()
                        selector.css('width',autoWidth);
                        $(selector).trigger('change');
                    });
                });
                //刷新選單內的選項
                selector.html(opts);
                autoWidth = (maxlength+2)*selector.css('font-size').split('px').shift()
                selector.css('width',autoWidth);                
            });
        } else {
            $.getJSON(config.url,function(json){
                //取得選單中預設的選項
                var defaultValue = ($('option:selected',selector).attr('value'));               
                var opts = '';
                var maxlength = 0;
                $.each(json,function(value,option){
                    if(option.length > maxlength){
                        maxlength = option.length;
                    }
                    if(value == defaultValue){
                        opts += '<option value="'+value+'" selected="selected">'+option+'</option>';
                    } else {
                        opts += '<option value="'+value+'">'+option+'</option>';
                    }                    
                });
                selector.html(opts);
                autoWidth = (maxlength+2)*selector.css('font-size').split('px').shift()
                selector.css('width',autoWidth);                
            });
        }        
    });
});

低溫烘培 發表在 痞客邦 PIXNET 留言(1) 人氣()


留言列表 (1)

發表留言
  • 艾
  • 這個功能真是太棒了~請問要怎樣選完第三欄後跳出連結頁面?
  • 我的建議是用jquery的捕捉change事件再進行location.href轉頁

    低溫烘培 於 2010/08/24 17:14 回覆

【 X 關閉 】

【PIXNET 痞客邦】國外旅遊調查
您是我們挑選到的讀者!

填完問卷將有機會獲得心動好禮哦(注意:關閉此視窗將不再出現)

立即填寫取消