Select
基于另一个select
使用PHP
仅在添加新行时才起作用。
对于演示访问here (请参阅演示步骤)
我尝试了什么:
<?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> 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>
答案 0 :(得分:0)
您的问题是由于此错误 - 未捕获的TypeError:无法在第243行的HTMLDocument.bindEvents中设置null的属性'onchange'。您可以在inspect元素中看到相同的内容。这是因为您正在为item3定义函数bindEvents,该函数尚未添加。此外,这仅在添加单行的情况下才有效。改变了你的逻辑并经常使用jquery。我已经在你的代码中注释掉了php部分并对其进行了硬编码。还创建了一个php文件,在选择框更改时发送ajax响应。
<?php // require_once '../home.php' ?>
<?php
foreach($_POST as $key => $val) {
echo "$key => $val <br>";
}
if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['action'], $_POST['id'] ) && $_POST['action']=='get_dependant_menu' ){
echo "here <br>";
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>";
// }
// }
// }
echo "<option value='Select Service'>Select Service (Pant)</option>";
echo "<option value='12121211'>Iron</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>
</head>
<body>
<div class="container">
<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>";
// }
// }
?>
<option value='ZZ2017TF11A1'>Shirt</option>
<option value='ZZ2017TF11A2'>Pant</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>";
// }
// }
?>
<option value='ZZ2017TF11A1'>Shirt</option>
<option value='ZZ2017TF11A2'>Pant</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> 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>";
// }
// }
?>
<option value='ZZ2017TF11A1'>Shirt</option>
<option value='ZZ2017TF11A2'>Pant</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="js/jquery-2.1.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++;
});
$('.container').on( 'change', '.country', function () {
//console.log($(this).attr('name'));
var oSelItem = $(this).attr('name');
var lastChar = oSelItem.substr(oSelItem.length -1);
var prevChar = oSelItem.substr(0, oSelItem.length-1);
//console.log(prevChar);
if(prevChar === "item") {
var oSelService = "service" + lastChar;
console.log(oSelItem + " " + oSelService);
console.log($(this).val());
var thisId = $(this).val();
$.ajax({
type: 'post',
url: 'ajax.php',
data: {
'id':thisId,
'action':'get_dependent_menu'
},
success: function (response) {
//alert(response);
console.log(oSelService);
$('select[name="'+ oSelService +'"]').html(response);
}
});
}
});
});
</script>
</body>
</html>
和ajax.php
<?php
echo "<option value='Select Service'>Select Service (Pant)</option>";
echo "<option value='12121211'>Iron</option>";
?>
答案 1 :(得分:0)
在上面的代码中,您运行相同的查询两次,我认为这是一个复制/粘贴错误?
以下内容基于之前提出的问题和帮助。
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
〜ie:{{ 1}}
<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> 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)>
然后以通常的方式在PHP中访问适当的值。应该提到的是,如果您决定使用该方法(即数组语法),那么您需要查看javascript中使用的各种选择器并适当地编辑名称。
我相信,通过对<input type='number' name='qty[]' />
的使用的新见解,你应该能够解决你所遇到的问题 - 你可以通过对这段代码的一点点修改,自己运行它来看看应用程序正常工作您应该编辑表名称(inline event handlers
- &gt; irn_item
,item
- &gt; irn_service
)并添加合适的db / pwd详细信息...祝你好运
答案 2 :(得分:0)
你真的要改变这里的逻辑,对不起,但静态处理动态内容在这种情况下不起作用......如果我们有第4行,第5行和第10行...你需要真正给所有一组公共类然后使用事件委托on()
附加事件,因此动态添加的新元素也将绑定。
示例,在项目列中将country
类更改为item
,在服务列中将country
类更改为service
:
$('body').on('change', '.item', function(){
//You're ajax logic here
//Try to use `$.post()` instead
//Target the related service list like
var related_service_select = $(this).closest('tr').find('.service');
//Now you can fill it with the server side response
});
希望这有帮助。