javascript - 基于使用 php 的另一个选择进行选择不工作

标签 javascript php jquery

Select 基于使用 PHP 的另一个 select,仅在添加新行时不起作用。

如需演示,请访问here (参见演示步骤)

  1. 页面加载时有两行,它们按需要工作。 (服务选项按照项目选项)
  2. 点击“添加行”按钮,将添加另一行
  3. 新插入的行不起作用。 (服务选择没有给出任何选项,因为前两个给出)

我尝试过的:

<?php require_once '../home.php' ?>
<?php


    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['action'], $_POST['id'] ) && $_POST['action']=='get_dependant_menu' ){
        ob_clean();

        $action=filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING );
        $id=filter_input( INPUT_POST, 'id', FILTER_SANITIZE_STRING );
        if( $action && $id && !is_nan( $id ) ){

            $stmt=$user_home->runQuery("SELECT * FROM service WHERE IRN=:irn ORDER BY Sr ASC ");
            $stmt->bindParam(':irn',$id);
            $stmt->execute();
            $stmtin=$user_home->runQuery("SELECT * FROM item WHERE IRN=:irn ORDER BY Sr ASC ");
            $stmtin->bindParam(':irn',$id);
            $stmtin->execute();
            $rowin=$stmtin->fetch( PDO::FETCH_ASSOC );

            if( $stmt->rowCount() > 0 ){
                echo "<option value='Select Service'>Select Service ({$rowin['Name']})</option>";
                 while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){
                    echo "<option value='{$row['SRN']}'>{$row['Name']}</option>";
                 }
            }
        }
        exit();
    }
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type='text/javascript' charset='utf-8'>
            function ajax(m,u,p,c,o){
                var xhr=new XMLHttpRequest();
                xhr.onreadystatechange=function(){
                    if( xhr.readyState==4 && xhr.status==200 )c.call( this, xhr.response, o, xhr.getAllResponseHeaders() );
                };

                var params=[];
                for( var n in p )params.push(n+'='+p[n]);

                switch( m.toLowerCase() ){
                    case 'post': p=params.join('&'); break;
                    case 'get': u+='?'+params.join('&'); p=null; break;
                }

                xhr.open( m.toUpperCase(), u, true );
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send( p );
            }
            function createmenu(r,o,h){
                o.menu.innerHTML=r;
            }



            function bindEvents(){
                var oSelItem=document.querySelector('select[name="item1"]');
                var oSelService=document.querySelector('select[name="service1"]');
                oSelItem.onchange=function(e){

                    var method='post';
                    var url=location.href;
                    var params={
                        'action':'get_dependant_menu',
                        'id':this.options[ this.options.selectedIndex ].value
                    };
                    var opts={
                        menu:oSelService
                    };
                    ajax.call( this, method, url, params, createmenu, opts );
                }.bind( oSelItem );
            }
            document.addEventListener( 'DOMContentLoaded', bindEvents,false );
        </script> 
</head>
<body>
<form method="post" action="invoice_form.php" id="item_sel">

    <table id="chiru_inv" class="table table-striped table-hover table-bordered table-responsive">
   <tr>
    <td colspan="3">
      <input type="text" name="customer" value="" placeholder="Customer Name">
    </td>
  </tr>
  <tr>
    <th>Item</th>
    <th>Service</th>
    <th>Qty</th>

  </tr>

    <tr>
      <td>
      <select name='item1' class='country'>
            <option value="Select Item">Select Item</option>
            <?php

                //$sql='select * from `item` order by `Sr` asc;';
                $stmt=$user_home->runQuery("SELECT * FROM item ORDER BY Sr ASC ");
                $stmt->execute();

                if( $stmt->rowCount() > 0 ){
                    while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){
                        echo "<option value='{$row['IRN']}'>{$row['Name']}</option>";
                    }
                }

            ?>
</select></td>

      <td><select class="country" name="service1">
</select></td>
<td><input type="text" name="qty1" value="" placeholder="Quantity"></td>
    </tr>
    <tr>
      <td>
      <select name='item2' class='country'>
            <option>Select Item</option>
            <?php


                $stmt=$user_home->runQuery("SELECT * FROM item ORDER BY Sr ASC ");
                $stmt->execute();

                if( $stmt->rowCount() > 0 ){
                    while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){
                        echo "<option value='{$row['IRN']}'>{$row['Name']}</option>";
                    }
                }

            ?>
</select></td>

      <td><select class="country" name="service2">
</select></td>
<td><input type="text" name="qty2" value="" placeholder="Quantity"></td>
    </tr>
    <tr>
        <td colspan="3"><button type="submit" name="btnsave" class="btn btn-default">
        <span class="glyphicon glyphicon-save"></span> &nbsp; Save
        </button>
        </td>
    </tr>
</table>
    <input type="button" class="add-row" value="Add Row">
</form>
<div id="markup_model" class="hide">
  <table>
    <tr>
      <td>
        <select name="nameitem" class="country">
                    <option>Select Item</option>
                    <?php 
                        $stmt=$user_home->runQuery("SELECT * FROM item ORDER BY Sr ASC "); 
                        $stmt->execute();

                        if( $stmt->rowCount() > 0 ){ 
                            while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){ 
                                echo "<option value='{$row['IRN']}'>{$row['Name']}</option>";
                            }
                        }   
                    ?>
                </select>
      </td>
      <td>
        <select class="country" name="namewhat"></select>
      </td>
      <td>
        <input type="text" name="nameqty" value="" placeholder="Quantity" />
      </td>
    </tr>
  </table>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
  var cont = 3
  var qty = "qty"
  var item = "item"
  var what = "service"

  $(".add-row").click(function() {
    var nameqty = qty + cont;
    var nameitem = item + cont;
    var namewhat = what + cont;

    var markup = $('#markup_model tbody');

    $(markup).find('.country:eq(0)').attr('name', nameitem);
    $(markup).find('.country:eq(1)').attr('name', namewhat);
    $(markup).find('input').attr('name', nameqty);

    $(markup.html()).insertBefore($('button[type="submit"]').closest("tr"));

    cont++;
  });
});
</script>
<script type='text/javascript' charset='utf-8'>
            function ajax(m,u,p,c,o){
                var xhr=new XMLHttpRequest();
                xhr.onreadystatechange=function(){
                    if( xhr.readyState==4 && xhr.status==200 )c.call( this, xhr.response, o, xhr.getAllResponseHeaders() );
                };

                var params=[];
                for( var n in p )params.push(n+'='+p[n]);

                switch( m.toLowerCase() ){
                    case 'post': p=params.join('&'); break;
                    case 'get': u+='?'+params.join('&'); p=null; break;
                }

                xhr.open( m.toUpperCase(), u, true );
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send( p );
            }
            function createmenu(r,o,h){
                o.menu.innerHTML=r;
            }



            function bindEvents(){
                var oSelItem2=document.querySelector('select[name="item2"]');
                var oSelService2=document.querySelector('select[name="service2"]');
                oSelItem2.onchange=function(e){

                    var method='post';
                    var url=location.href;
                    var params={
                        'action':'get_dependant_menu',
                        'id':this.options[ this.options.selectedIndex ].value
                    };
                    var opts={
                        menu:oSelService2
                    };
                    ajax.call( this, method, url, params, createmenu, opts );
                }.bind( oSelItem2 );
            }
            document.addEventListener( 'DOMContentLoaded', bindEvents,false );
        </script>
        <script type='text/javascript' charset='utf-8'>
            function ajax(m,u,p,c,o){
                var xhr=new XMLHttpRequest();
                xhr.onreadystatechange=function(){
                    if( xhr.readyState==4 && xhr.status==200 )c.call( this, xhr.response, o, xhr.getAllResponseHeaders() );
                };

                var params=[];
                for( var n in p )params.push(n+'='+p[n]);

                switch( m.toLowerCase() ){
                    case 'post': p=params.join('&'); break;
                    case 'get': u+='?'+params.join('&'); p=null; break;
                }

                xhr.open( m.toUpperCase(), u, true );
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send( p );
            }
            function createmenu(r,o,h){
                o.menu.innerHTML=r;
            }



            function bindEvents(){
                var oSelItem3=document.querySelector('select[name="item3"]');
                var oSelService3=document.querySelector('select[name="service3"]');
                oSelItem3.onchange=function(e){

                    var method='post';
                    var url=location.href;
                    var params={
                        'action':'get_dependant_menu',
                        'id':this.options[ this.options.selectedIndex ].value
                    };
                    var opts={
                        menu:oSelService3
                    };
                    ajax.call( this, method, url, params, createmenu, opts );
                }.bind( oSelItem3 );
            }
            document.addEventListener( 'DOMContentLoaded', bindEvents,false );
        </script>

</body>
</html>

最佳答案

在上面的代码中,您运行相同的查询两次,我认为这是复制/粘贴错误?

以下内容基于之前的问题和已提供的帮助。

mysql> describe irn_item;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| irn   | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(50)      | YES  |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+


mysql> select * from irn_item;
+-----+------------+
| irn | name       |
+-----+------------+
|   1 | Shirt      |
|   2 | Trousers   |
|   3 | Jacket     |
|   4 | Socks      |
|   5 | Underpants |
|   6 | Hat        |
+-----+------------+


mysql> describe irn_service;
+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| srn         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| irn         | int(10) unsigned | NO   | MUL | 1       |                |
| instruction | varchar(50)      | NO   |     | 1       |                |
+-------------+------------------+------+-----+---------+----------------+


mysql> select * from irn_service;
+-----+-----+-----------------------+
| srn | irn | instruction           |
+-----+-----+-----------------------+
|   1 |   2 | Iron                  |
|   2 |   1 | Dry Clean Only        |
|   3 |   3 | Hi-Pressure dry clean |
|   4 |   4 | Steam Clean           |
|   5 |   5 | Decontaminate         |
|   6 |   6 | Waterproof            |
+-----+-----+-----------------------+

在不知道数据库架构的情况下,我根据原始代码中 sql 中看到的一些列创建了一个快速示例数据库。下面的代码使用 mysqli而不是 PDO,只是因为对于我的测试来说,编写起来要快得多,所以请忽略它不完全遵循的事实。我认为,您遇到麻烦的重要方面是新添加的行不会复制触发 ajax 请求的事件处理程序。我昨天确实提到过,在克隆节点时,使用 addEventListener 分配的任何事件处理程序不会被复制/克隆 - 因此为了确保事件处理程序被复制/克隆,您需要使用 inline event handlers 〜即:<select onchange='evtselect(event)'>...</select>

<?php

    $dbhost =   'localhost';
    $dbuser =   'root'; 
    $dbpwd  =   'xxx'; 
    $dbname =   'xxx';
    $db =   new mysqli( $dbhost, $dbuser, $dbpwd, $dbname );



    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['action'], $_POST['id'] ) && $_POST['action']=='get_dependant_menu' ){

        ob_clean();

        try{
            $id=filter_input( INPUT_POST, 'id', FILTER_SANITIZE_STRING );

            if( $id && !empty( $id ) ){

                $html=array();

                $sql='select `srn`,`instruction` from `irn_service` where `irn` = ? order by `srn` asc';
                $stmt=$db->prepare( $sql );

                if( $stmt ){
                    $stmt->bind_param( 's', $id );
                    $stmt->execute();
                    $stmt->store_result();
                    $stmt->bind_result( $srn, $instruction );


                    while( $stmt->fetch() ){
                        $html[]="<option value='{$srn}'>{$instruction}";
                    }
                    $stmt->close();
                }

                header('Content-Type: text/html');
                echo implode( PHP_EOL, $html );
            }
        }catch( Exception $e ){
            echo $e->getMessage();
        }
        exit();
    }
?>
<!doctype html>
<html>
    <head>
        <title>Dependent / Chained SELECT menus</title>
        <script>
            /* AJAX FUNCTION */
            function ajax(m,u,p,c,o){
                var xhr=new XMLHttpRequest();
                xhr.onreadystatechange=function(){
                    if( xhr.readyState==4 && xhr.status==200 )c.call( this, xhr.response, o, xhr.getAllResponseHeaders() );
                };

                var params=[];
                for( var n in p )params.push(n+'='+p[n]);

                switch( m.toLowerCase() ){
                    case 'post': p=params.join('&'); break;
                    case 'get': u+='?'+params.join('&'); p=null; break;
                }

                xhr.open( m.toUpperCase(), u, true );
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send( p );
            }


            /* AJAX CALLBACK */
            function createmenu(r,o,h){
                o.menu.innerHTML=r;
            }

            /* UTILITY TO FIND NEXT SIBLING ELEMENT NODE */
            function get_nextsibling(n){
                x=n.nextSibling;
                while ( x.nodeType!==1 ) x=x.nextSibling;
                return x;
            }

            /* INLINE EVENT HANDLER */
            function evtselect(e){
                try{
                    var el=e.target;
                    if( el.value=='null' || el.value==null )return false;

                    var method='post';
                    var url=location.href;
                    var params={
                        'action':'get_dependant_menu',
                        'id':el.value
                    };
                    var td=get_nextsibling( el.parentNode );
                    var oSelect=td.querySelector('select');

                    var opts={
                        menu:oSelect
                    };
                    ajax.call( this, method, url, params, createmenu, opts );
                }catch( err ){
                    console.log( err );
                }
            }


            function bindEvents(){

                var bttn=document.querySelector('input[name="add"]');
                var tbl=document.querySelector('form#item_sel > table');

                if( bttn && tbl ){
                    bttn.addEventListener('click',function(e){
                        /* get a reference to the first & last row, of class "item", in table */
                        var tr=tbl.querySelectorAll( 'tr.items' )[0];
                        var ref=tbl.querySelector( 'tr.save' );

                        /* Create a clone of the entire row - which includes the inline event handlers */
                        var clone=tr.cloneNode( true );

                        /* Insert the new row after the last row */
                        tr.parentNode.insertBefore( clone, ref );

                        /* Ensure that newly added "service" select menu is empty */
                        clone.querySelector('select[name="item[]"]').value='null';
                        clone.querySelector('select[name="service[]"]').innerHTML='';
                        clone.querySelector('input[name="qty[]"]').value='';

                    },{ capture:false, passive:true, once:false } );                    
                }
            }
            document.addEventListener( 'DOMContentLoaded', bindEvents, false );
        </script>
        <style type='text/css' charset='utf-8'>
            select {padding:1rem;width:300px;}
        </style>
    </head>
    <body>
        <h1>Chained select menus using basic ajax</h1>
        <form method='post' id='item_sel'>
            <table>
                <tr class='headers'>
                    <th scope='col'>Item</th>
                    <th scope='col'>Service</th>
                    <th scope='col'>Qty</th>
                </tr>
                <tr class='items'>
                    <td>
                        <select name='item' class='country' onchange='evtselect(event)'>
                            <option value=null>Please Select
                        <?php
                            $sql='select * from `irn_item` order by `irn`;';
                            $result=$db->query( $sql );
                            $html=array();
                            if( $result ){
                                while( $rs=$result->fetch_object() ){
                                    $html[]="<option value='{$rs->irn}'>{$rs->name}";
                                }
                                echo implode( PHP_EOL, $html );
                            }
                        ?>
                        </select>                       
                    </td>
                    <td><select name='service' class='country'></select></td>
                    <td><input type='number' name='qty' min=0 max=1000 /></td>
                </tr>
                <tr class='save'>
                    <td colspan='3'>
                        <button type='submit' name='btnsave' class='btn btn-default'>
                            <span class='glyphicon glyphicon-save'></span> &nbsp; Save
                        </button>
                    </td>
                </tr>
            </table>
            <input name='add' type='button' class='add-row' value='Add Row' />
        </form>
    </body>
</html>

使用此代码,我不厌其烦地重命名了新添加的元素 - 这可能并不是绝对必要的,因为您可以改为使用 array syntax对于元素名称 - 即:<select name='item[]' onchange='evtselect(event)><input type='number' name='qty[]' />等然后以通常的方式访问 PHP 中的适当值。应该提到的是,如果您决定采用这种方法(即数组语法),那么您将需要查看 JavaScript 中使用的各种选择器并适本地编辑名称。

我相信有了对 inline event handlers 的使用的新见解您应该能够解决您遇到的问题 - 您可以通过对此代码进行一些小的编辑,自己运行它以查看应用程序是否正常工作。您应该编辑表名称( irn_item -> itemirn_service -> service )并添加合适的 db/pwd 详细信息...祝你好运

关于javascript - 基于使用 php 的另一个选择进行选择不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47321918/

相关文章:

javascript - 检查按钮单击时输入字段值是否已更改

javascript - &lt;script&gt; 标签是否受到与 javascript/fetch 调用相同的 CORS 限制?

javascript - 如何使用jquery在选择框选项中显示数据

javascript - 在文件中设置 Harmony 标志

javascript - 对其中包含可选斜杠的字符串求和

php/ajax-{"success": {"title" :"Message Sent"}}

PHP:这安全吗?

php - vs 代码 - 引号内的 php intellisense

javascript - jQuery 词频计数器

javascript - jQuery:查找 div 中的所有表并重置类和属性