选择基于另一个选择使用PHP不工作 [英] Select based on another select using php Not working

查看:69
本文介绍了选择基于另一个选择使用PHP不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

选择基于另一个选择使用 PHP 而不是仅在添加新行时才有效。

Select based on another select using PHP not working only when a new row is added.

对于演示访问这里 (参见演示步骤)


  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>


推荐答案

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

In your code above you are running the same query twice which I presume is a copy/paste mistake?

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

What follows is based upon previous question and help already offered.

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 分配的任何事件处理程序 - 因此为了确保复制/克隆事件处理程序,您需要使用内联事件处理程序〜ie:< select onchange ='evtselect(event)'> ...< / select>

Without knowing the schema of the database I made up a quick example database based upon some of the columns seen in the sql in the original code. The code below uses mysqli rather than PDO simply because for my testing it is much quicker to write so please ignore the fact that it does not follow exactly. The important aspect that you are having troubles with, I believe, is that newly added rows do not copy the event handler which triggers the ajax request. I did make mention yesterday that when cloning nodes any event handlers assigned using addEventListener will NOT be copied/cloned - so to ensure that event handlers are copied/cloned you need to use inline event handlers ~ ie: <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>

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

With this code I took the trouble of renaming newly added elements - this is probably not strictly necessary as you could instead use array syntax for the element names - viz: <select name='item[]' onchange='evtselect(event)> or <input type='number' name='qty[]' /> etc then access the appropriate values in PHP in the usual manner. It should be mentioned that if you decide upon that approach (ie array syntax ) then you would need to look at the various selectors used in the javascript and edit the names appropriately.

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

I trust that with this new insight into the use of inline event handlers that you should be able to nail the problem you have - you can, with a little minor editing of this code, run it for yourself to see the application working correctly. You should edit the table names (irn_item -> item, irn_service -> service ) and add suitable db/pwd details... Good luck

这篇关于选择基于另一个选择使用PHP不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆