Anu
Anu

Reputation: 630

Why table id is not identified by getElementById()

Hi I am trying to get the id of my table and calculate the number of rows in my table. I used this code

var table =document.getElementById("test");
var i = table.rows.length;

This doesnot work for me when I use window.onload It works. This my working function

window.onload = function() {
var table =document.getElementById("test");
var i = table.rows.length;

}

Now I need this i variable used in another function. How to make this i variable global. Any problem with my code? Can some one help me code? Edit 01

<table id="test">
    <thead>
        <tr>
            <td style="width:80px;"><img src="http://localhost/elfanto/elfanto_billing/assets/img/ticket_page/employee.svg"></td>
            <td style="width:35px;"><img src="http://localhost/elfanto/elfanto_billing/assets/img/ticket_page/start_time.svg"></td>
            <td style="width:35px;"><img src="http://localhost/elfanto/elfanto_billing/assets/img/ticket_page/id.svg"></td>
            <td style="width:145px;"><img src="http://localhost/elfanto/elfanto_billing/assets/img/ticket_page/Description.svg"></td>
            <td style="width:45px;"><img src="http://localhost/elfanto/elfanto_billing/assets/img/ticket_page/Type.svg"></td>
            <td style="width:45px;"> <img src="http://localhost/elfanto/elfanto_billing/assets/img/ticket_page/qty_prch.svg"></td>
            <td style="width:45px;"> <img src="http://localhost/elfanto/elfanto_billing/assets/img/ticket_page/qty_used.svg"></td>
            <td style="width:70px;"> <img src="http://localhost/elfanto/elfanto_billing/assets/img/ticket_page/Price.svg"></td>
            <td style="width:70px;"> <img src="http://localhost/elfanto/elfanto_billing/assets/img/ticket_page/discount.svg"></td>
            <td style="width:70px;"> <img src="http://localhost/elfanto/elfanto_billing/assets/img/ticket_page/Tax.svg"></td>
            <td style="width:70px;"> <img src="http://localhost/elfanto/elfanto_billing/assets/img/ticket_page/Total_01.svg"></td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <input type="text" name="employee[]" value="" style="width:80px;" />
            </td>
            <td>
                <input type="text" name="start_time[]" value="" style="width:35px;" />
            </td>
            <td>
                <input type="text" name="pid[]" onChange="get_values(this.value)" value="" style="width:35px;" />
            </td>
            <td>
                <input type="text" name="description[]" id="description1" value="" style="width:145px;" />
            </td>
            <td>
                <input type="text" name="type[]" id="type1" style="width:45px;" />
            </td>
            <td>
                <input type="text" name="qty_prch[]" id="qty_prch1" style="width:45px;" />
            </td>
            <td>
                <input type="text" name="qty_used[]" id="qty_used1" style="width:45px;" />
            </td>
            <td>
                <input type="text" name="price[]" id="price1" style="width:70px;" />
            </td>
            <td>
                <input type="text" name="discount[]" id="discount1" style="width:70px;" />
            </td>
            <td>
                <input type="text" name="tax[]" id="tax1" style="width:70px;" />
            </td>
            <td>
                <input type="text" name="total[]" id="total1" style="width:70px;" />
            </td>

        </tr>
    </tbody>
</table>

I need to use that variable i in this following javascript

 function displayResult()
        {


            document.getElementById("test").insertRow(-1).innerHTML = '<td><input type="text" name="employee[]" value="" style="width:80px;"/></td><td><input type="text" name="start_time[]" value="" style="width:35px;"/></td><td><input type="text" name="pid[]" onChange="get_values(this.value)" style="width:35px;"/></td><td><input type="text" name="description[]" id="description[x]" value="" style="width:145px;"/></td><td><input type="text" id="type[x]" value="" style="width:45px;"/></td><td><input type="text" id="qty_used[x]" value="" style="width:45px;"/></td><td><input type="text" value="" style="width:45px;"/></td><td><input type="text" value=""  style="width:70px;"/></td><td><input type="text" value=""  style="width:70px;"/></td><td><input type="text" value=""  style="width:70px;"/></td><td><input type="text" value=""  style="width:70px;"/></td>';
        }
function get_values(val)
{

    $.ajax({
         url: baseurl+'admin/billing/getdetails',
         type: 'post',
         data : {val:val},
         success: function (response) {    
            if(response!="")
            {
                var json=jQuery.parseJSON(response);
                $('#description1').val(json.description);
                $('#type1').val(json.type); 
                $('#qty_used1').val(json.cost);                             
            }
         },
         error: function(response){
            alert("error");
         }
    });
}

Upvotes: 0

Views: 62

Answers (3)

Andreas
Andreas

Reputation: 21881

I would slightly change the setup... :)

  1. Change all the numbered ids to unnumbered classes (also in the displayResult function)
id="description1" --> class="description"
id="type1" --> class="type"
...
function displayResult() {
    var row = document.getElementById("test").insertRow(-1);
    row.innerHTML = '<td><input type="text" name="employee[]" value="" style="width:80px;"/></td><td><input type="text" name="start_time[]" value="" style="width:35px;"/></td><td><input type="text" name="pid[]" style="width:35px;"/></td><td><input type="text" name="description[]" class="description" value="" style="width:145px;"/></td><td><input type="text" class="type" value="" style="width:45px;"/></td><td><input type="text" class="qty_used" value="" style="width:45px;"/></td><td><input type="text" value="" style="width:45px;"/></td><td><input type="text" value="" style="width:70px;"/></td><td><input type="text" value="" style="width:70px;"/></td><td><input type="text" value="" style="width:70px;"/></td><td><input type="text" value="" style="width:70px;"/></td>';
}
  1. Remove the "onChange" attribute from the newly inserted row and instead use a "global" change handler on the table using event delegation - (methods used in the change handler: .closest(), .index())
$(function() {
    $('#test').on('change', 'input[name="pid[]"]', function() {
        var indexOfTheChangedRow = $(this).closest("tr").index();
        get_values(this.value, indexOfTheChangedRow);
    });
});
  1. Change the signature of get_values() to accept an additional parameter - the index of the changed row
function get_values(val, rowIndex) {
    //...
}
  1. Change the success handler of the ajax call to use the new layout
$.ajax({
    url: baseurl + 'admin/billing/getdetails',
    type: 'post',
    data: {
        val: val
    },
    success: function (indexOfTheChangedRow, response) {
        if (response != "") {
            var json = jQuery.parseJSON(response),
                rowToUpdate = $("#test tr:nth-child(" + (indexOfTheChangedRow + 1) + ")");

            // add the changed row as the context to restrict the search for the classes to this one row only
            $('.description', rowToUpdate).val(json.description);
            $('.type', rowToUpdate).val(json.type);
            $('.qty_used', rowToUpdate).val(json.cost);
        }
    }.bind(window, rowIndex),
    error: function (response) {
        alert("error");
    }
});

I'm using .bind() to "pin" the clicked row index to this ajax request (the success handler).

Now you can add as many rows as you want and you won't have to mess around with numbered ids :)

Upvotes: 2

Andrei Nemes
Andrei Nemes

Reputation: 3122

Is there anything stopping you from having this other function inside the onload closure as well?

window.onload = function() {

    var table = document.getElementById("test"),
        i = table.rows.length,

        doStuff = function () {
            // has access to i
        },

        doMoreStuff = function () {
            // also has access to i
        },

        get_values = function () {
            // also has access to i
        };

    document.getElementsByName("pid[]")[0].addEventListener("change", get_values);
}

Edit: You can remove your onChange attribute from the HTML and add an event handler in your JavaScript

Upvotes: 2

Milind Anantwar
Milind Anantwar

Reputation: 82241

You can declare the scope of variable as global.

var i = null;
window.onload = function() {
  var table =document.getElementById("test");
  i = table.rows.length;
}

Upvotes: 1

Related Questions