Connecting Tech Pros Worldwide Forums | Help | Site Map

Ajax Pop-Up

Member
 
Join Date: Aug 2008
Posts: 40
#1: Jan 7 '09
I am doing an inventory project in which i need to do sales and rentals.As the starting point,there will be text box where the customer id is entered.If the customer id is valid another text box will appear in which the product id should be entered.If that particular product is for rentals, a popup will appear which is done using ajax.In that popup i need to add some data and submit it in the database.My problem is,if i click on the submit button,nothing is getting submitted.what may be the problem?????help me please....

Dormilich's Avatar
Moderator
 
Join Date: Aug 2008
Location: Leipzig, Germany
Posts: 3,664
#2: Jan 7 '09

re: Ajax Pop-Up


If you can show us the code, we can maybe spot the problem.

regards
Member
 
Join Date: Aug 2008
Posts: 40
#3: Jan 8 '09

re: Ajax Pop-Up


The code is bit bigger...
Still i have to work on some functionalities and that too only after submitting.Now my sole aim is to submit...Here is the code for returns.php

Expand|Select|Wrap|Line Numbers
  1. <?php
  2. include "includes/user.php";
  3.  
  4. if(isset($_GET['customerID'])&& $_GET['customerID']!='' && isset($_GET['productID'])&& $_GET['productID']!='' )
  5. {
  6. $totalUser=mysql_num_rows(mysql_query("SELECT Customers.customerID, Products.productID FROM pri_master_sales_rental SaleAndRental, pri_master_products Products, pri_master_customers Customers WHERE SaleAndRental.customerID=Customers.customerID AND SaleAndRental.productID=Products.productID HAVING customerID='$_GET[customerID]' AND productID ='$_GET[productID]' "));
  7.  
  8. $query="SELECT Customers.Name, Customers.customerID, Products.productID, Products.productName, SaleAndRental.rentalPrice, SaleAndRental.rentedDate, SaleAndRental.dueDate, SaleAndRental.lateCharges FROM pri_master_sales_rental SaleAndRental, pri_master_products Products, pri_master_customers Customers WHERE SaleAndRental.customerID=Customers.customerID AND SaleAndRental.productID=Products.productID HAVING customerID='$_GET[customerID]' ORDER BY SaleAndRental.rentedDate DESC LIMIT $set_limit, $limit";
  9.  
  10. $result=mysql_query($query);
  11. $count=mysql_num_rows($result);
  12. }
  13.  
  14. if(isset($_GET['sendCR']))
  15. {
  16. $productUpdate=mysql_query("update pri_master_products set stockInHand=stockInHand+1 where productID ='$_GET[productID]'");
  17. $customerUpdate=mysql_query("update pri_master_customers set totalAmount=totalAmount+'$_GET[lateCharges]',
  18.                                                                amountPaid=amountPaid+'$_GET[amountPaid]', 
  19.                                                                balanceAmount='$_GET[balanceAmount]' where customerID='$_GET[customerID]'") or die("Query failed : " . mysql_error());
  20.         //header('location:returns.php?success=1');                                   
  21. }
  22.  
  23.  
  24. if(isset($_GET['sendCS']))
  25. {
  26. $tempInsert=mysql_query("insert into pri_temp_returns(productID)VALUES('$_GET[productID]')");
  27. $productUpdate=mysql_query("update pri_master_products set stockInHand=stockInHand-1,stockInStores=stockInStores-1 where productID ='$_GET[productID]'");
  28. $customerUpdate=mysql_query("update pri_master_customers set totalAmount=totalAmount+'$_GET[convCharges]',
  29.                                                              amountPaid=amountPaid+'$_GET[amountPaid]', 
  30.                                                              balanceAmount='$_GET[balanceAmount]' where customerID='$_GET[customerID]'") or die("Query failed : " . mysql_error());
  31.         //header('location:returns.php?success=2');                                   
  32. }
  33.  
  34. if(isset($_GET['sendMoreCR']))
  35. {
  36. $insert=mysql_query("INSERT INTO pri_temp_returns(productID)VALUES('$_GET[productID]')");
  37. $productUpdate=mysql_query("update pri_master_products set stockInHand=stockInHand+1 where productID ='$_GET[productID]'");
  38. $customerUpdate=mysql_query("update pri_master_customers set totalAmount=totalAmount+'$_GET[lateCharges]',
  39.                                                                amountPaid=amountPaid+'$_GET[amountPaid]', 
  40.                                                                balanceAmount='$_GET[balanceAmount]' where customerID='$_GET[customerID]'") or die("Query failed : " . mysql_error());
  41. }
  42.  
  43. if(isset($_GET['sendMoreCS']))
  44. {
  45. $insert=mysql_query("INSERT INTO pri_temp_returns(productID)VALUES('$_GET[productID]')");
  46. $productUpdate=mysql_query("update pri_master_products set stockInHand=stockInHand-1,
  47.                                                            stockInStores=stockInStores-1 where productID ='$_GET[productID]'");
  48. $customerUpdate=mysql_query("update pri_master_customers set totalAmount=totalAmount+'$_GET[convCharges]',
  49.                                                              amountPaid=amountPaid+'$_GET[amountPaid]', 
  50.                                                              balanceAmount='$_GET[balanceAmount]' where customerID='$_GET[customerID]'") or die("Query failed : " . mysql_error());
  51. }
  52.  
  53. ?>
  54. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  55. <html xmlns="http://www.w3.org/1999/xhtml">
  56. <head>
  57. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  58. <title>SALES AND RENTALS MANAGEMENT SYSTEM</title>
  59. <link rel="stylesheet" href="styled.css" type="text/css">
  60. <link rel="stylesheet" href="style.css" type="text/css">
  61. <script src="javascripts/popup.js"></script>
  62.  
  63. </head>
  64. <body onload="javascript:document.getElementById('customerID').focus();">
  65.     <div>
  66.     <div>
  67.         <? include_once "includes/header.php" ?>
  68.         <? include_once "includes/menu.php" ?>
  69.     </div>
  70.     <div class="container">
  71.     <div><h2>Home</h2></div>
  72. <div style="min-height:400px;">
  73.  
  74. <h3 style="margin: 0px 50px 25px 50px; border-bottom: #999999 2px solid">Returns</h3><a href="home.php"><h5 align="right" style="margin-right:50px;">Back to Home</h5></a>
  75. <div align="center" style="font-size:12px; color:#FF0000;"><strong>
  76. <?
  77. if($_GET['success']==1)
  78. {echo 'Product Returned successfully';}
  79. if($_GET['success']==2)
  80. {echo 'Converted to sales successfully';}
  81.  
  82. ?>
  83. </strong>
  84. </div><div style="padding-left:250px">
  85.  
  86. <div class='divStyle'>
  87. <div class='divLabel'><label class='text'>Customer ID</label></div>
  88. <div><input type='text' onkeyup="keyPress(this.value,event)" name="customerID" id="customerID" value="<?=isset($_GET['customerID'])&& $_GET['customerID']!=''? $_GET['customerID'] :''?>"/></div>
  89.  
  90. </div>
  91. </div>
  92. <div style="padding-left:250px">
  93. <div id="placeHolder" class="text"></div></div>
  94. <div style="display:none; width:440px;" id="popupForm"></div>
  95.  
  96. <div id="product"></div>
  97.  
  98. <div id="productDetails"></div>
  99.       <br />
  100.         <div align="center">
  101.            <input type="button" name="history" id="history" value="Customer History" onclick="getHistory();"/>
  102.            <input type="button" name="details" id="details" value="Customer Details" onclick="getDetails();"/>
  103.            <input type="button" name="Reset" id="Reset" value="Reset" onclick="javascript:window.location='returns.php'"/>
  104.         <input type="submit" name="view" id="view" value="View Last Transaction" onclick="viewTrans();formSubmit('salesRentals')"/>
  105. </div>
  106.  
  107.         </div>
  108.       </div>
  109.       </div>
  110.     </div>
  111.     </div>
  112.  <div align="right" style="padding:10px 16px 0px 0px; font-size:12px; font-weight:bold;"></div>
  113. </body>
  114. </html>
and the one below is popup.js
Expand|Select|Wrap|Line Numbers
  1. var xmlHttp
  2. var globalString
  3. var returnPopup=0
  4. var x=0
  5. var y=0
  6.  
  7. function showUser(str)
  8.  
  9. customerxmlHttp=GetXmlHttpObject()
  10. if (customerxmlHttp==null)
  11.  {
  12.  alert ("Browser does not support HTTP Request")
  13.  return
  14.  }
  15. var url="product.php?customerID="+str+"&custid="+Math.random()
  16. customerxmlHttp.onreadystatechange=stateChanged
  17. customerxmlHttp.open("GET",url,true)
  18. customerxmlHttp.send(null)
  19.  
  20. }
  21.  
  22. function stateChanged() 
  23. if (customerxmlHttp.readyState==4 || customerxmlHttp.readyState=="complete")
  24.  { 
  25.      //document.getElementById("txtHint").innerHTML=xmlHttp.responseText 
  26.      var placeHolder=document.getElementById("placeHolder");
  27.      //alert(xmlHttp.responseText)
  28.      if(customerxmlHttp.responseText==1)
  29.      {
  30.             placeHolder.innerHTML='<div class="divStyle" id="product"><div class="divLabel"><label class="text">Product ID</label></div><div><input type="text" name="productID" id="productID" onKeyup="productPress(\'popupForm\',event)" onblur="returnForm(\'popupForm\')"></div></div>';
  31.             document.getElementById('productID').focus();
  32.             var rate=document.getElementById("salesPrice").value
  33.             var val=document.getElementById("rentalPrice").value
  34.             document.getElementById("balanceAmount").value=rate-val
  35.  
  36.      }else{
  37.          placeHolder.innerHTML=''
  38.          document.getElementById('customerID').value=''
  39.          document.getElementById('customerID').focus(); 
  40.          alert('Invalid customer')
  41.      }
  42.   }
  43. }
  44.  
  45. function returnForm(elementId)
  46. {
  47.     var customerId=document.getElementById('customerID').value
  48.     var productID=document.getElementById('productID').value
  49.     var popup=document.getElementById('popupForm')
  50.         popxmlHttp=GetXmlHttpObject()
  51.             if (popxmlHttp==null)
  52.              {
  53.              alert ("Browser does not support HTTP Request")
  54.              return
  55.              }
  56.  
  57.     if(popup.style.display=='none')
  58.     {
  59.  
  60.         var url="returnsDetails.php?customerID="+customerId+"&productID="+productID+"&cid="+Math.random()
  61.         //call the ajax function
  62.         popxmlHttp.onreadystatechange=popUpControl
  63.         popxmlHttp.open("GET",url,true)
  64.         popxmlHttp.send(null)
  65.     }
  66. }
  67. function popUpControl(){
  68.     var control=document.getElementById("popupForm")
  69.     if (popxmlHttp.readyState==4 || popxmlHttp.readyState=="complete"){ 
  70.     if(popxmlHttp.responseText!=0){
  71.         control.style.display='block';
  72.         control.innerHTML=popxmlHttp.responseText
  73.             var rate=document.getElementById("salesPrice").value
  74.             var val=document.getElementById("rentalPrice").value
  75.             document.getElementById("convCharges").value=rate-val
  76.             var num = new Number(document.getElementById('convCharges').value);
  77.             document.getElementById('convCharges').value=num.toFixed(2);
  78.  
  79.     }
  80.     else
  81.     {
  82.         var placeHolder=document.getElementById("placeHolder");
  83.         placeHolder.innerHTML='<div class="divStyle" id="product"><div class="divLabel"><label class="text">Product ID</label></div><div><input type="text" name="productID" id="productID" onKeyup="productPress(\'popupForm\',event)" onblur="returnForm(\'popupForm\')">&nbsp;&nbsp;<font color="#FF0000">This Product is not for Rentals</font></div></div>';
  84.         document.getElementById('productID').focus(); 
  85.  
  86.     }
  87.  
  88.     }
  89.     ajaxPopup(control)
  90. }
  91.  
  92. function ajaxPopup(htmlElement){
  93.     htmlElement.style.zIndex="100";
  94.     htmlElement.style.position="absolute";
  95.     htmlElement.style.width="450px";
  96.     htmlElement.style.margin='0px 0px 0px 0px';
  97.     htmlElement.style.backgroundColor="#FFFFFF";
  98.     htmlElement.style.borderColor="#000000";
  99.     htmlElement.style.left=((window.screen.width/2)-250)+'px';
  100.     //htmlElement.style.top=((window.screen.height/2)-80)+'px';
  101.     htmlElement.style.top='330px';
  102. }
  103.  
  104. function keyPress(str,e){
  105.     var keycode = e.keyCode || window.event.keyCode;
  106.     if(keycode == 13){
  107.         showUser(str)
  108.     }
  109. }
  110.  
  111. function productPress(str,e){
  112.     var keycode = e.keyCode || window.event.keyCode;
  113.     if(keycode == 13){
  114.         returnForm(str)
  115.     }
  116. }
  117.  
  118.  
  119. function afterpopup(popupElement)
  120. {
  121.   var con=document.getElementById(popupElement);
  122.   con.style.zIndex="50";
  123.   con.innerHTML="";
  124.   con.style.display='none';
  125.  
  126. }
  127.  
  128. /*function to get the details of the customer*/
  129. function getDetails(){
  130.     var customerId=document.getElementById('customerID').value
  131.     //create ajax object
  132.     getDetailxmlHttp=GetXmlHttpObject()
  133.             if (getDetailxmlHttp==null)
  134.              {
  135.              alert ("Browser does not support HTTP Request")
  136.              return
  137.              }
  138.  
  139.         var url="customerDetails.php?customerID="+customerId+"&cid="+Math.random()
  140.         //call the ajax function
  141.         getDetailxmlHttp.onreadystatechange=getCustomerDetails
  142.         getDetailxmlHttp.open("GET",url,true)
  143.         getDetailxmlHttp.send(null)
  144.  
  145. }
  146.  
  147. function getCustomerDetails(){
  148.              var place=document.getElementById("productDetails");
  149.  
  150.     if (getDetailxmlHttp.readyState==4 || getDetailxmlHttp.readyState=="complete"){ 
  151.             place.innerHTML=getDetailxmlHttp.responseText
  152.       }
  153. }
  154.  
  155. //end of the function
  156.  
  157. /* function to get the history of the customer*/
  158. function getHistory(){    
  159.     var customerId=document.getElementById('customerID').value
  160.     //create ajax object
  161.     getHistoryxmlHttp=GetXmlHttpObject()
  162.             if (getHistoryxmlHttp==null)
  163.              {
  164.              alert ("Browser does not support HTTP Request")
  165.              return
  166.              }
  167.  
  168.         var url="customerHistory.php?customerID="+customerId+"&cid="+Math.random()
  169.         //call the ajax function
  170.         getHistoryxmlHttp.onreadystatechange=getCustomerHistory
  171.         getHistoryxmlHttp.open("GET",url,true)
  172.         getHistoryxmlHttp.send(null)
  173. }
  174.  
  175. function getCustomerHistory(){
  176.              var placeHolder=document.getElementById("productDetails");
  177.  
  178.     if (getHistoryxmlHttp.readyState==4 || getHistoryxmlHttp.readyState=="complete"){ 
  179.             placeHolder.innerHTML=getHistoryxmlHttp.responseText
  180.       }
  181. }
  182. //end of the function
  183.  
  184.  
  185.  
  186. function lateBalance(){
  187.  
  188. if(x==0){
  189.  var latefees=document.getElementById("lateCharges").value
  190.  var balanceamount=document.getElementById("balanceAmount").value
  191.  document.getElementById("balanceAmount").value=parseFloat(latefees)+parseFloat(balanceamount)
  192. x++;
  193. }
  194. }
  195.  
  196. function returnBalance(){
  197.  
  198. if(y==0){
  199.  
  200.  var conversioncharges=document.getElementById("convCharges").value
  201.  var balanceamount=document.getElementById("balanceAmount").value
  202.      document.getElementById("balanceAmount").value=parseFloat(conversioncharges)+parseFloat(balanceamount)
  203.     y++
  204. }
  205. }
  206.  
  207. /*function caldueAmount(val){
  208.  var rPrice=document.getElementById("rentalPrice").value
  209.   var rprice=document.getElementById('rentalPrice').value
  210.  var sprice=document.getElementById('salesPrice').value
  211.  var latefees=document.getElementById("lateCharges").value
  212.  var conversioncharges=document.getElementById("convCharges").value
  213.  var balanceamount=document.getElementById("balanceAmount").value
  214.  
  215.  if(conversioncharges==sprice){
  216.      document.getElementById("balanceAmount").value=(parseFloat(balanceamount) + parseFloat(sprice))-rprice
  217.     //alert "parseInt(balanceamount) + parseInt(sprice)-rprice"
  218.  }
  219.  else if(conversioncharges==latefees){
  220.      document.getElementById("balanceAmount").value=parseFloat(balanceamount) + parseFloat(latefees)
  221.  }
  222.  else{
  223.      document.getElementById("balanceAmount").value=balanceamount
  224.  }
  225. }
  226. */
  227. function discountAmount(val){
  228.     var rate=document.getElementById("balanceAmount").value
  229.     document.getElementById("balanceAmount").value=rate-val
  230. }
  231.  
  232. function paymentAmount(val){
  233.     var balanceamount=document.getElementById("balanceAmount").value
  234.     document.getElementById("newBalance").value=balanceamount-val
  235.     var num = document.getElementById('newBalance').value;
  236.     document.getElementById('newBalance').value=num.toFixed(2);
  237. }
  238.  
  239. function GetXmlHttpObject()
  240. {
  241. var xmlHttp=null;
  242. try
  243.  {
  244.      // Firefox, Opera 8.0+, Safari
  245.      xmlHttp=new XMLHttpRequest();
  246.  }
  247. catch (e)
  248.  {
  249.  //Internet Explorer
  250.  try
  251.   {
  252.       xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
  253.   }
  254.  catch (e)
  255.   {
  256.       xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
  257.   }
  258.  }
  259. return xmlHttp;
  260. }// JavaScript Document// JavaScript Document// JavaScript Document
  261.  
and the other one is returnDetails.php and this is the file where the submit buttons are present..
Expand|Select|Wrap|Line Numbers
  1. <?
  2. include_once('includes/connection.php');
  3.  
  4. if(isset($_GET['customerID'])&&($_GET['customerID']!='') && isset($_GET['productID'])&&($_GET['productID']!='')) {
  5.  
  6. $select=mysql_query("select (DATEDIFF(curdate(),salesrental.dueDate)* products.lateFees) as lateCharges,products.lateFees from pri_master_sales_rental salesrental,pri_master_products products where products.productID=salesrental.productID and products.productID='$_GET[productID]' and salesrental.customerID='$_GET[customerID]'");
  7. $selectResultset=mysql_fetch_array($select);
  8.  
  9. $result=mysql_query("SELECT Customers.firstName, Customers.customerID, Products.productID, Products.productName, SaleAndRental.rentalPrice, DATE_FORMAT(SaleAndRental.rentedDate, '%m-%d-%X') AS rentedDate,DATE_FORMAT(SaleAndRental.dueDate, '%m-%d-%X') AS dueDate , SaleAndRental.lateFees, SaleAndRental.Discounts, SaleAndRental.paymentMode, Products.salesPrice,Customers.balanceAmount FROM pri_master_sales_rental SaleAndRental, pri_master_products Products, pri_master_customers Customers WHERE SaleAndRental.customerID=Customers.customerID AND SaleAndRental.productID=Products.productID AND SaleAndRental.type='rented' HAVING customerID='$_GET[customerID]' AND productID ='$_GET[productID]' ORDER BY SaleAndRental.rentedDate");
  10.  
  11. if(mysql_num_rows($result)>0){
  12. $detailsresultset=mysql_fetch_array($result);
  13.  
  14. ?>
  15. <div style="background:url(images/bg.gif); margin:0px 0px 0px 0px;  padding:0px 0px 0px 0px;">
  16. <div style="float:right; line-height:36px;">
  17. <a href="javascript:void(0)" onclick="afterpopup('popupForm')"><img src="images/close.png" style="border:none" title="Close"/></a>&nbsp;&nbsp;</div>
  18. <div style=" line-height:36px; text-align:center; font-family:Verdana, Arial, Helvetica, sans-serif;">Returns</div>
  19. </div>
  20. <form name="returnDetails" id="returnDetails">
  21.  
  22. <div style="padding:10px 10px 0px 15px;" >
  23. <div class='divStyle'><div class='divLabel'><label class='text'>Rented Date </label> </div><div><input size="30" name="rentedDate" id="rentedDate" type="text" value="<?= $detailsresultset['rentedDate']; ?>" readonly="readonly"/></div></div>
  24. <div class='divStyle'><div class='divLabel'><label class='text'>Rental Charges </label></div><div><input size="30" name="rentalPrice" id="rentalPrice" type="text" value="<?= $detailsresultset['rentalPrice']; ?>" readonly="readonly" /></div></div>
  25. <div class='divStyle'><div class='divLabel'><label class='text'>Sales Price </label></div><div><input size="30" name="salesPrice" type="text" value="<?= $detailsresultset['salesPrice']; ?>" readonly="readonly" id="salesPrice"/></div></div>
  26. <div class='divStyle'><div class='divLabel'><label class='text'>Due Date</label></div><div><input size="30" name="dueDate" id="dueDate" type="text" value="<?= $detailsresultset['dueDate']; ?>" readonly="readonly" /></div></div>
  27. <div class='divStyle'><div class='divLabel'><label class='text'>Late fees </label></div><div><input size="30" name="lateCharges" id="lateCharges" type="text" value="<? if($selectResultset['dueDate'] < $selectResultset['curdate()']) { 
  28.                       echo $selectResultset['lateCharges'];
  29.                       } else {
  30.                       echo '0';
  31.                       } ?>" readonly="readonly"/>
  32. <input type="radio" id="radioLateCharges" name="radioLateCharges" onclick="lateBalance()"/></div>
  33. </div>
  34. <div class='divStyle'><div class='divLabel'><label class='text'>Current Charges</label></div><div><input size="30" name="convCharges" type="text" id="convCharges" readonly="readonly"/>&nbsp;<input type="radio" id="radioConvCharges" name="radioLateCharges" onclick="returnBalance()"/></div></div>
  35. <div class='divStyle'><div class='divLabel'><label class='text'>Discount </label></div><div><input size="30" name="Discount" id="Discount" type="text" value="0" onchange='discountAmount(this.value)'/></div></div>
  36. <div class='divStyle'><div class='divLabel'><label class='text'>Amount Due</label></div><div><input size="30" name="balanceAmount" id="balanceAmount" type="text" value="<?= $detailsresultset['balanceAmount']; ?>" readonly="readonly"/></div></div>
  37. <div class='divStyle'><div class='divLabel'><label class='text'></label>
  38. </div>
  39.   <div></div>
  40. </div>
  41. </div>
  42. <div class="divStyle"><div class="divLabel"><label class="text" style="padding: 0px 0px 0px 0px;"></label></div>        
  43. <div>
  44. <input type="submit" name="sendCR" id="sendCR" value="Submit-CR" style="border:double #000000 2px;" onclick="javascript:document.getElementById(\'returnDetails\').submit();"/>
  45. <input type="submit" name="sendCS" id="sendCS" value="Submit-CS" style="border:double #000000 2px;" onclick="javascript:document.getElementById(\'returnDetails\').submit();"/>
  46. <input type="submit" name="sendMoreCR" id="sendMoreCR" value="More Returns" style="border:double #000000 2px;" onclick="javascript:document.getElementById(\'returnDetails\').submit();"/>
  47. <input type="submit" name="sendMoreCS" id="sendMoreCS" value="More Conversions" style="border:double #000000 2px;" onclick="javascript:document.getElementById(\'returnDetails\').submit();"/>
  48. </div></div>
  49. </form>
  50. <!--<label class="text" style="padding:0px 0px 0px 30px;"></label>-->
  51.  
  52. <div class="divStyle"><div class="divLabel"><label class="text"></label></div> 
  53.   <label class="text" style="padding:0px 0px 0px 46px;"></label>
  54. </div>
  55. </div>
  56. <? } }?>
  57.  
Dormilich's Avatar
Moderator
 
Join Date: Aug 2008
Location: Leipzig, Germany
Posts: 3,664
#4: Jan 8 '09

re: Ajax Pop-Up


Quote:

Originally Posted by divyac View Post

My problem is,if i click on the submit button,nothing is getting submitted.

technically speaking, you do not have a form here, i.e. you are missing the <form> tags.

regards
Reply