重构jQuery动态表单脚本以供通用使用

时间:2012-10-19 19:01:13

标签: jquery

我有一个简单的表单,用户可以选择颜色,然后选择该颜色类别的东西。第二个选择输入基于第一个输入进行更新。

我有一个jQuery脚本,它允许我基于id定位第一个元素,并在指定id时相应地更改下一个元素。现在我想把它变成一个可重用的脚本,这样我就可以选择任意选择并相应地更新NEXT选择。我可以处理内部逻辑(url,GET参数)。

在我的jQuery脚本中:获取参数),但是我无法弄清楚如何在选择一个之后定位下一个select元素(我尝试使用next()但它没有用)。

$(document).ready(function () {
    var nextSelect = $('#id_colour');
    nextSelect.change(function () {
        function updateChoices() {
            var selected = nextSelect.val();
            if (selected) {
                // this line shown for completeness - will be refactored
                $.getJSON(url, {
                    colour_id: selected
                }, function (data, jqXHR) {
                    var options = [];
                    for (var i = 0; i < data.length; i++) {
                        output = '<option value="' + data[i].id + '"';
                        if (nextSelect.val() == data[i].id) {
                            output += ' selected="selected"';
                        }
                        output += '>' + data[i].name + '</option>';
                        options.push(output);
                    }
                    $('#id_thing').html(options.join(''));
                });
            }
        }
        updateChoices();
        $('#id_thing').change(updateChoices);
    });
});

任何帮助都非常感激。

修改 这是html。所以我希望当一个人改变时,NEXT将成为目标。我不能依赖于ID或类。

<form action="" method="post">
    <!-- colour -->
    <div class="form_div">
        <p><label for="colour">Colour:</label></p>
        <p>
            <select name="colour" id="id_colour">
                <option value="" selected="selected">---------</option>
                <option value="1">Green</option>
                <option value="2">Brown</option>
                <option value="3">Blue</option>
            </select>
        </p>
    </div>  
    <!-- thing -->
    <div class="form_div">
        <p><label for="thing">Thing:</label></p>
        <p>
            <select name="thing" id="id_thing">
                <option value="" selected="selected">---------</option>
                <option value="1">Branch</option>
                <option value="2">Leaf</option>
                <option value="3">Sky</option>
            </select>
        </p>
    </div> 

    <p><input type="submit" value="Submit Choice" /></p>
</form>

2 个答案:

答案 0 :(得分:1)

如果您想制作可重复使用的代码(可以在其他脚本中使用),您可以创建utility function

只需使用三个参数调用nextSelect; (1)第一个选择,(2)第二个选择,它将根据select1,(3)你执行请求的URL进行更改。

JQuery(v1.8.2):

// Utility function
$.nextSelect = function(selectOne, selectTwo, url) {
    var s1 = $(selectOne);
    s1.on('change', function() {
        var colourID = s1.val();
        if (colourID) {
            $.getJSON(url, {colour_id: colourID}, function(data, jqXHR){
                $(selectTwo + ' option:selected').removeAttr('selected');
                $(selectTwo + ' option[value="' + data[0].id + '"]').attr('selected', 'selected');
            });
            //Example of what the getJSON might do:
            $(selectTwo + ' option:selected').removeAttr('selected');
            $(selectTwo + ' option[value="' + 1 + '"]').attr('selected', 'selected');
            //End example. Remove/comment example when going live.
        }
    });        
};
//I have left the url empty for now,
//$.nextSelect('#id_colour', '#id_thing', '');
//If you allowed to at least select the container div:
$mySelectedForm = $('.form_div').first();
$.nextSelect("#" + $mySelectedForm.find('select').attr('id'), "#" + $mySelectedForm.next().find('select').attr('id'), '');

HTML(我刚刚缩短了它):

<div class="form_div">
    <select name="colour" id="id_colour">
        <option value="" selected="selected">---------</option>
        <option value="1">Green</option>
        <option value="2">Brown</option>
        <option value="3">Blue</option>
    </select>
</div>
<div class="form_div">
    <select name="thing" id="id_thing">
        <option value="" selected="selected">---------</option>
        <option value="1">Branch</option>
        <option value="2">Leaf</option>
        <option value="3">Sky</option>
    </select>
</div>

这是fiddle

如果这不是你想要的,请提供反馈,我会调整代码。

干杯!

编辑:

  

这样我就可以选择任意选择并相应地更新NEXT选择。

好的,所以如果我理解正确你想要能够选择第一个'选择' - &gt;意味着你以某种形式需要硬核引用id / class。这不需要是select本身,它可以是一个包装类。第二个选择将自动选择。

修改代码和小提琴以调整它。

答案 1 :(得分:0)

$(this).next()适合我

http://jsfiddle.net/cWQhg/1/

HTML

<div id="parent">
<div class="nextsel">I'm div</div>
<div class="nextsel">I'm div</div>
<div class="nextsel">I'm div</div>
<div class="nextsel">I'm div</div>
<div class="nextsel">I'm div</div>
<div class="nextsel">I'm div</div>
<div class="nextsel">I'm div</div>
</div>
​

CSS

.nextsel {
  margin: 5px;
  border: 1px solid black;    
  height: 40ps;
    width: 100px;
    cursor: pointer;
}
.nextsel.current {
 background: red;    
}
.nextsel.next {
 background: blue;    
}

JS

var nextsel=$('.nextsel');
nextsel.click(function(e) {
    var t=$(this);
    t.addClass('current');
    t.siblings('.nextsel').removeClass('current');
    nextsel.removeClass('next');
    console.log(t.nextAll('.nextsel').first().addClass('next'));

});
​


来自您提问的样本:

http://jsfiddle.net/FU7fZ/

HTML

<form action="" method="post">
    <!-- colour -->
    <div class="form_div">
        <p><label for="colour">Colour:</label></p>
        <p>
            <select name="colour" id="id_colour">
                <option value="" selected="selected">---------</option>
                <option value="1">Green</option>
                <option value="2">Brown</option>
                <option value="3">Blue</option>
            </select>
        </p>
    </div>  
    <!-- thing -->
    <div class="form_div">
        <p><label for="thing">Thing:</label></p>
        <p>
            <select name="thing" id="id_thing">
                <option value="" selected="selected">---------</option>
                <option value="1">Branch</option>
                <option value="2">Leaf</option>
                <option value="3">Sky</option>
            </select>
        </p>
    </div> 
     <!-- next -->
    <div class="form_div">
        <p><label for="thing">Next:</label></p>
        <p>
            <select name="next" id="id_thing">
                <option value="" selected="selected">---------</option>
                <option value="1">Tree</option>
                <option value="2">Nut</option>
                <option value="3">Deep</option>
            </select>
        </p>
    </div> 

JS

var selector='.form_div select';
var changef=function () {
    var t=$(this);

    var n=t.parents('.form_div').nextAll('.form_div').first().find('select').val(t.val()); 
    if (n.length==0) {
        //it is last ....
        n=t.parents('.form_div').siblings().first().find('select').val(t.val())  ;
    }
    //uncomment to change all in recursive way
      /*
    t.addClass('changed');    
    if (!n.hasClass('changed')) {n.trigger('change');return;}
    $(selector).removeClass('changed');
    */
}
             
             
$(selector).change(changef);​