如何使用jQuery插件将数据注入克隆下拉框?

时间:2012-01-12 01:17:04

标签: jquery jquery-plugins

我有一个动态表单并使用SheepIt!插件来克隆我的表单元素。我的表单有一组动态下拉框,其中第二个下拉框根据第一个下拉框中的选择显示一组值。

我的问题是这是一个“编辑”表单,因此当页面加载时需要将现有数据注入表单元素。幸运的是,SheepIt允许data-injection;但是,我遇到了困难,因为我的表格中的下拉框是“动态的”,如上所述。

有关如何解决此问题并将数据注入动态表单元素的任何想法?

使用Javascript:

<script>
$().ready(function() {

    var sheepItForm = $('#clone').sheepIt({
        separator: '',
        allowRemoveLast: true,
        allowRemoveCurrent: true,
        allowAdd: true,
        maxFormsCount: 3,
        minFormsCount: 1,
        iniFormsCount: 1,
        data: [
            {
                'item_1': 'CLONE #1 ITEM 1 DATA HERE',
                'item_2': 'CLONE #1 ITEM 2 DATA HERE',
            },
            {  
                'item_1': 'CLONE #2 ITEM 1 DATA HERE',
                'item_2': 'CLONE #2 ITEM 2 DATA HERE',
            },
            ...
        ]        
    });

    $("#item_1").live('change', function () {   

      var group_id = $(this).val();
      var self = $(this); 

      var $children = $(this).parent().next().children('select#item_2')

       $.ajax({
            type: "POST", 
            url: "../../db/groups.php?item_1_id=" + group_id, 
            dataType: "json",
            success: function(data){    
                $children.empty()
                $children.append('<option value="">Select</option>');           
                $.each(data, function(i, val){    
                   $children.append('<option value="' + val.group_id + '">' + val.name + '</option>');
                });
                $children.focus();
            },
            beforeSend: function(){
                $children.empty();
                $children.append('<option value="">Loading...</option>');
            },
            error: function(){
                $children.attr('disabled', true);
                $children.empty();
                $children.append('<option value="">No Options</option>');
            }
        })  

    });

});
</script>

HTML:

<label id="item_1_label" for="item_1" class="label">#1:</label>
<select id="item_1" name="item_1" />
    <option value="">Select</option>
    <?php
        $sth = $dbh->query ("SELECT id, name, level 
                             FROM groups
                             WHERE level = '1'
                             GROUP by name
                             ORDER BY name");                                   
        while ($row = $sth->fetch ()) { 
            echo '<option value="'.$row['id'].'">'.$row['name'].'</option>'."\n";       
        }
     ?>
</select>

<label id="item_2_label" for="item_2" class="label">#2:</label>
<select id="item_2" name="item_2" />                        
</select>

PHP(groups.php)

<?php

require_once('../includes/connect.php');        

$item_1_id = $_GET['item_1_id'];

$dbh = get_org_dbh($org_id);

$return_arr = array();

$sth = $dbh->query ("SELECT id, name, level 
                     FROM groups
                     WHERE level = '2'
                     AND parent = $item_1_id
                     GROUP by name
                     ORDER BY name");   

while ($row = $sth->fetch ()) { 

    $row_array = array("name" => $row['name'], 
                       "id" => $row['id']); 

    array_push($return_arr,$row_array);     
}

echo json_encode($return_arr);

?>  

示例JSON输出:

[{"name":"A","id":"0"},{"name":"B","id":"1"},{"name":"C","id":"2"}]

2 个答案:

答案 0 :(得分:1)

它是在调用Ajax吗?可能是因为动态加载了以下内容而未被触发。

$("#item_1").change(function () {

也许尝试将其更改为

$("#item_1").live("change",function () {

至少可以在那里投入一个警报()来查看它是否被触发。

答案 1 :(得分:1)

问题在于您使用ID来控制“动态”选择框,但是通过添加sheepIt到混合中,您将克隆这些元素并且新对不再适合您的选择器。我首先使用类来定位你想要表现得类似的东西:

    <select id="item_1" name="item_1" class="firstSelect"/>
...
    <select id="item_2" name="item_2"  class="secondSelect"/>   

然后,您可以让更改处理程序适用于任何组,而不仅仅是原始组:

$(".firstSelect").live('change', function () {   
  ...
  var $children = $(this).parent().next().children('.secondSelect')

还有一些更改要做,但我们的想法是让您的代码保持尽可能通用,如果您想要一般行为,则没有理由定位独特的特征。 groups.php不应该关心世界卫生组织正在发送选择,只是选择了什么。然后它可以返回适当的选项。

同样地,您的javascript不需要固定为唯一ID,您已经通过在处理程序中包含遍历已经走了一半。为什么你会使用

var $children = $(this).parent().next().children('select#item_2') 

当您显然可以使用

时,移动到匹配的选择框
var $children = $('#item_2')