0

我正在尝试制作一个表格,简单吧?不完全的。

我目前有两个选择框的表单设置,当使用 onchange 函数更改时第一个选择运行一个生成第二个选择框的 php 页面。

然后我有另一个函数,它添加了 2 个选择框的另一个“实例”,这样我就可以一次向表中添加多行,而不必一次输入一个。

当我添加更多“实例”时出现问题,onchange 函数将第二个选择框的原始和新“实例”视为同一个。

正如我所看到的,我最好的选择是动态命名函数和包含第二个选择框的 div,这是我卡住的地方。我的问题是,我将如何更改“showDim”函数和“dimdiv”div id 以使它们匹配?

js函数调用Dim选择框;

<script>
    function showDim(str)
    {
    if (str=="")
      {
      document.getElementById("dimdiv").innerHTML="";
      return;
      } 
    if (window.XMLHttpRequest)
      {// code for IE7+, Firefox, Chrome, Opera, Safari
      xmlhttp=new XMLHttpRequest();
      }
    else
      {// code for IE6, IE5
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
    xmlhttp.onreadystatechange=function()
      {
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
        document.getElementById("dimdiv").innerHTML=xmlhttp.responseText;
        }
      }
    xmlhttp.open("GET","get_dim.php?id="+str,true);
    xmlhttp.send();
    }
</script>

html/php 用于第一个选择框和包含第二个选择框的 div;(其他功能根据我的需要多次复制这部分)

<label>Style:</label>
    <select name='Style' id='Style' onchange="showDim(this.value)">
        <option value='0' class='red'>Select a style...</option>            
        <?php
            include ('connect.php');

            $getsty = $db->prepare("SELECT Style_ID, Style_Type FROM style ORDER BY Style_Type ASC LIMIT 1, 18446744073709551615;"); 
            $getsty->execute();
                while($row = $getsty->fetch(PDO::FETCH_ASSOC)) {    
                    $Style_ID = $row['Style_ID'];
                    $Style_Type = $row['Style_Type'];                   
                    echo "      <option value='$Style_ID'>$Style_Type</option>";
                }                                       
        ?>                          
<br>
<div id='txtHint2'>                 
    <label>Dimensions:</label>
        <select name='Dim'>
            <option value='0' class='red'>Select the dimensions...</option> 
        </select>           
</div>
4

1 回答 1

1

我会使用完全不同的方法。我看不到您的带有 ID 的元素在哪里#dimdiv,但是在您的“实例”周围创建一个包装器来对它们进行分组,包括#dimdiv. 但是现在所有的 ID 都应该是类。

您的 HTML 应如下所示:

<div class="instance">
    <label>Style:</label>
        <select name='Style' class='style' onchange="showDim(this)">
            <option value='0' class='red'>Select a style...</option>            
            <?php
                include ('connect.php');

                $getsty = $db->prepare("SELECT Style_ID, Style_Type FROM style ORDER BY Style_Type ASC LIMIT 1, 18446744073709551615;"); 
                $getsty->execute();
                    while($row = $getsty->fetch(PDO::FETCH_ASSOC)) {    
                        $Style_ID = $row['Style_ID'];
                        $Style_Type = $row['Style_Type'];                   
                        echo "      <option value='$Style_ID'>$Style_Type</option>";
                    }                                       
            ?>                          
    <!-- Note: for proper HTML markup, a non-container tag must be self-closing like the following br -->
    <br />
    <div class='txtHint2'>
        <label>Dimensions:</label>
            <select name='Dim'>
                <option value='0' class='red'>Select the dimensions...</option> 
            </select>           
    </div>
    <div class="dimdiv"></div>
</div>

显然这会破坏你当前的代码。您不能使用它来查找要设置document.getElementById('dimdiv')innerHTML的元素。所以我们需要修改你的代码......

第一步:我们需要知道showDim调用函数的组号。这是最简单的方法,不仅将元素的值传递给函数,还传递元素本身。它允许我们使用document.getElementsByClassName('style')*1 并将每个返回的元素与当前元素进行比较。

第一个匹配是实例组的索引,我们现在可以以类似的方法使用它来提取.dimdiv同一组的对应项。所以现在我们已经找到了我们的目标元素,而无需创建单个函数的多个实例,在我看来这是有缺陷的设计......它会浪费内存。

您更改的代码可能如下所示:

HTML

<select name="Style" class="style" onchange="showDim(this)">
    ...
</select>

JavaScript(已编辑)

function showDim(elem)
{
    // Best would be to pack this code into a separate function.
    var elems = document.getElementsByClassName('style'),
        groupIndex = -1,
        targetDimDiv,
        i;
    for( i = 0; i < elems.length; ++i ) {
        if( elems[i] == elem ) {
            groupIndex = i;
            break;
        }
    }

    // This can only happen if somebody plays around with your function
    // manually calling it and providing an unexpected parameter.
    if( groupIndex == -1 )
    {
        return;
    }

    targetDimDiv = document.getElementsByClassName('dimdiv')[groupIndex];

    if (elem.value == "")
    {
        targetDimDiv.innerHTML="";
        return;
    }
    // ...XMLHttpRequest...
    xmlhttp.onreadystatechange = function( ) {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200 ) {
            targetDimDiv.innerHTML = xmlhttp.responseText;
        }
    };
    // ...send AJAX...
}

最后,我要指出最后一个关键点:我认为为每个值的变化创建一个 ajax 并不是一个好主意。我认为已经通过网站提供响应并从那里检索您需要的信息是一个更好的主意。毕竟这样可以节省更多的流量...

很抱歉回答冗长,但我相信真正理解为什么代码以它的工作方式工作很重要。而且我怀疑您可能没有那么有经验……;)

*1:我相信document.getElementsByClassName在旧版本的 IE 中不存在。document.getElementsByTagName如果您必须支持这些版本,您可以手动使用匹配的类编写补丁。

PS:没有测试代码。它只是为您提供一个通用指南。剩下的就看你了。摆弄它以适应您的需求。

于 2013-10-08T18:19:30.907 回答