Search code examples
jqueryhtmlinvoice

fetching value from database in Invoice


I am trying to make an invoice where in product i have used autocomplete to fetch the product name and price from the database.

It's coming easily for the first row, but for the second row it's not working at all.

index.php

<!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 src="js/jquery-1.10.2.min.js"></script>
<script src="js/jquery-ui-1.10.4.custom.min.js" type="text/livescript"></script>
<link rel="stylesheet" href="syle/style.css" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"   type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js" type="text/javascript"></script>
 <script type="text/javascript" src="js/main.js"></script>
<title>Untitled Document</title>
  <script>
  $(document).ready(function(){
var ac_config = {
    source: "autosuggest.php",
    select: function(event, ui){
        $(".menu_name").val(ui.item.menu_name);
        $(".menu_code").val(ui.item.menu_code);
        $(".menu_price").val(ui.item.menu_price);

        },
        minLength:1
        };
        $(".street").autocomplete(ac_config);
});

</script>
</head>

<body>
<form action="action.php" method="POST">

<table>
<tr>
<td>Invoice Number</td>
<td><input type="text" name="inv_no" id="inv_no" /></td>
</tr>
<tr>
<td>Invoice Date </td>
<td><input type="date" name="inv_date" id="inv_date" /></td>
</tr>
</table>

<table border="1" style="border-collapse:collapse">
<thead>
<tr>
<th>No</th>
<th>Product Name</th>
<th>Quantity</th>
<th>Price</th>
<th>Amount</th>
</tr>
</thead>
<tbody id="inv_detail">
<tr>
<th><b class="no">1</b></th>
<td><input type="text" class="street" class="menu_name"  name="p_name[]"  /></td>
<td><input type="text" name="qty[]" class="qty" /></td>
<td><input type="text" name="price[]" class="menu_price"  /></td>
<td align="right"><b class="amt"> </b></td>

</tr>
</tbody>
<tfoot>
<th colspan="6"><b class="total" value="add">0</b></th>
</tfoot>

</table>

</form>
<input type="button" id="click"  value="add"/>
</body>
</html>
<script type="text/javascript">
$.datepicker.setDefaults({
    changeMonth:true,
    changeYear:true,
    dateFormat:'yy/mm//dd'

    });
    $(function(){

    $('#click').click(function(){
       addnewrow();

    });

    $('#inv_detail').delegate('.p_name','change',function(){
        var p_name = $('.p_name:last').val();
        if(p_name !='')
        {
            addnewrow();
            }
            if($(this).val()== '' && $('.p_name').length > 1 && p_name == '')
            {
                $('.p_name:last').parent().parent().remove();   
                total();
            }

        });

        $('#inv_detail').delegate('.qty,.menu_price',function(){
            var tr = $(this).parent().parent();
            var qty = tr.find('.qty').val()-0;
            var menu_price = tr.find('.menu_price').val()-0;
            var amt = qty * menu_price;
            tr.find('.amt').html(amt);
            total();
            });

    $('input[type=date]').datepicker(); 
    $('body').delegate('input[type=date]',click,function(e)
    {
        $(this).datepicker();

        });



        function addnewrow()
        {
            var n = ($('#inv_detail tr').length-0)+1;
            var row ='<tr>'+
            '<th><b class="no">'+ n +'</b></th>'+   
            '<td><input type="text" name="p_name[]" class="menu_name"/></td>'+  
            '<td><input type="text" name="qty[]" class="qty"/></td>'+
            '<td><input type="text" name="price[]" class="menu_price"/></td>'+
            '<td allign="right"><b class="amt"></b></td>'+
            '</tr>';
            $('#inv_detail').append(row);
            }


    });
    function total(){

             var gg=0;
             $('.amt').each(function(i,el){
                 var amt = $(this).html()-0;
                 gg += amt;

            });
        $('.total').html(gg);
        }
</script>

action.php

<?php

$cn = mysql_connect('localhost','root','');
mysql_select_db('phpinvoice',$cn);
//if(isset($_post['submit']))
//{
    echo $sql="INSERT INTO inv (inv_no,inv_date)VALUES('{$_POST['inv_no']}','{$_POST['inv_date']}')";

$query=mysql_query($sql);
$id = mysql_insert_id();
$_p_name =  $_POST['p_name'];
$_qty =  $_POST['qty'];
$_price =  $_POST['price'];

for($i = 0;$i < count($_p_name);$i++)
{
    echo $sql1="INSERT INTO inv_detail SET
 inv_id='{$id}',
 p_name='$_p_name[$i]',
 qty='$_qty[$i]',
 price='$_price[$i]',



 ";
 $qyer=mysql_query($sql1);
header('Location:http://www.pingbd.com');
}


//}


?>   

Solution

  • Javascript and therefor JQuery make use of event handlers. For the browser to know which function to execute on any user action you want to handle, you need to bind an event handler.

    The binding of events in the case of JQuery, so also in your case, is done when the javascript is executed, in this case at runtime. Any items added after the initial event binding wont have and event handler attached to them, and will therefor never execute a function.

    To fix this, you need to add the same event handlers to any new element you add to your html, from which you want to run a function.

    Example 1 (jsfiddle(DOT)net/jLrcx2q6/):

    <button class="button">Show alert</button>
    
    $(document).ready(function(){
        $(".button").click(function(){
            alert("test");
        });
    });   
    

    In this example (Example 1) when the page loads a click event is "binded" to the button, so when a user clicks it an alert pops up with the text "test".

    Example 2 (http://jsfiddle.net/ceney0jg/):

    <div id="example-wrapper">
        <button class="button">Show alert</button>
    </div> 
    
    $(document).ready(function(){
        $(".button").click(function(){
            alert("test");
            $("#example-wrapper").append('<button class="button">Show alert</button>');
        });
    });  
    

    In this example, when a user presses the button, again a popup will be shown with the text "test". However, what also happens is a new button will be added to the div (example-wrapper). After the button is added no event handler is "binded", so nothing will happen when the user presses the button.

    Example 3 - The solution (jsfiddle.net/p8q4mfmv/):

    <div id="example-wrapper">
        <button class="button">Show alert</button>
    </div> 
    
    $(document).ready(function(){
        $(".button").click(function(){
            addButton()
        });
    }); 
    
    function addButton()
    {
         alert("test");
         $("#example-wrapper").append('<button class="button">Show alert</button>');   
    
         $(".button").click(function(){
            addButton()
         });
    }
    

    In your code, you have a function addnewrow(). This function adds a new table row. When your page is loaded,

    $('#inv_detail').delegate('.p_name','change',function(){ 
    

    adds an event handler to p_name. However, after the function addnewrow() is executed, a new table row is added, but the above event handler is never bound to the new element. Therefor the browser wont execute ANY code that you would want to be executed.

    The solution would be to bind an event handler, for example like this:

    function addnewrow()
    {
        var n = ($('#inv_detail tr').length-0)+1;
        var row ='<tr>'+
        '<th><b class="no">'+ n +'</b></th>'+   
        '<td><input type="text" name="p_name[]" class="menu_name"/></td>'+  
        '<td><input type="text" name="qty[]" class="qty"/></td>'+
        '<td><input type="text" name="price[]" class="menu_price"/></td>'+
        '<td allign="right"><b class="amt"></b></td>'+
        '</tr>';
        $('#inv_detail').append(row);
    
        $('#inv_detail').delegate('.p_name','change',function(){
        var p_name = $('.p_name:last').val();
        if(p_name !='')
        {
            addnewrow();
            }
            if($(this).val()== '' && $('.p_name').length > 1 && p_name == '')
            {
                $('.p_name:last').parent().parent().remove();   
                total();
            }
    
        });
    
        $('#inv_detail').delegate('.qty,.menu_price',function(){
            var tr = $(this).parent().parent();
            var qty = tr.find('.qty').val()-0;
            var menu_price = tr.find('.menu_price').val()-0;
            var amt = qty * menu_price;
            tr.find('.amt').html(amt);
            total();
        });
    }
    

    This isn't very nice code, but I think it would work. You are better of using javascript files instead of inline javascript to make your code a bit more readable and seperate functionality from your view.

    Also when writing software, you should always try to make functions do as little things as possible. A function in the best case scenario would only have 1 task.

    To understand this a bit better, i suggest reading http://courses.cs.washington.edu/courses/cse403/96sp/coupling-cohesion.html