1

I have table with dynamic Rows and columns,i was trying to convert HTML table to Json by looping through each tr and td and finding values inside textbox but with no luck.Here is my js code.

 $("#btn_Table2Json").click(function () {
        var rows = [];
        $('table.dynatable tbody tr').each(function (i, n) {
            var $row = $(n);
            if (n.className.toUpperCase() != "Prototype".toUpperCase() && n.className.toUpperCase() != "Header".toUpperCase()) {
                $('table.dynatable tbody td').each(function (j, d) {
                    rows.push({
                        //Here id,Name,Address,Contact are dynamic.so need to find it inside of 'th' of table.
                        //but i am not being able to find it, so i just hard coded it :(
                        Id: $row.find('td:eq(0)').text(),
                        Name: $row.find('td:eq(1)').text(),
                        Address: $row.find('td:eq(2)').text(),
                        Contact: $row.find('td:eq(2)').text()
                    });
                });
            }
        });
        //debugger;
        alert(JSON.stringify(rows));
        //alert(table.toString());
    });

TableJson

For above table JSON output should be:

[{ID:"1",Name:"Bibek",Address:"lubhoo",Contact:"98411"},{ID:"4",Name:"Suraj",Address:"Sanagaun",Contact:"984511"}]

My Html is (columns and rows are dynamic)

<table class="dynatable">
        <thead>
            <tr class="Header">
                <th id="AddRowTh"><button class="add">Add Row</button></th>
                <th>ID &nbsp;&nbsp;<a href="#" class="RemoveColumn">Remove</a></th>
                <th>Name&nbsp;&nbsp;<a href="#" class="RemoveColumn">Remove</a></th>
                <th>Address&nbsp;&nbsp;<a href="#" class="RemoveColumn">Remove</a></th>
                <th>Contact&nbsp;&nbsp;<a href="#" class="RemoveColumn">Remove</a></th>
                <th id="AddColumnTh"><button style="width: 100px; height: 25px" class="addColumn">Add Column</button></th>
            </tr>
        </thead>
        <tbody>
            <tr class="prototype">
                <td><p class="RowName"></p><a href="#" class="RemoveRow">Remove</a><!--<button class="remove">Remove</button>--></td>
                <td><input type="text" name="id[]" value="0" class="id" /></td>
                <td><input type="text" name="name[]" value="" /></td>
                <td><input type="text" name="col4[]" value="" /></td>
                <td><input type="text" name="col3[]" value="" /></td>
            </tr>
    </table>
Bibek Gautam
  • 581
  • 8
  • 30

3 Answers3

4

Try this

$('table.dynatable tr').each(function(){
    rows.push({
        Id: $(this).find('td:eq(1) input').val(),
        Name: $(this).find('td:eq(2) input').val(),
        Address: $(this).find('td:eq(3) input').val(),
        Contact: $(this).find('td:eq(4) input').val()
    });
});

DEMO

Jeemusu
  • 10,415
  • 3
  • 42
  • 64
Anton
  • 32,245
  • 5
  • 44
  • 54
  • my column are also dynamic so can't hardcode Id,Name,Address,Contact..i have to find column name from `th` for respective `td` in `$('table.dynatable tr').each(function(){}` loop.. – Bibek Gautam Aug 01 '13 at 11:38
2

There is a library which converts table to json format: link: https://github.com/lightswitch05/table-to-json

maverickosama92
  • 2,685
  • 2
  • 21
  • 35
  • This is a great tool! (I might be bias since I'm the author). But it doesn't work all that great when getting values from `` fields. It is more useful for extracting plain text. Although it wouldn't be hard to modify to work with `` fields... – lightswitch05 Aug 08 '13 at 20:40
2

Basic Solution - Demo

Because you are using actual input fields, all you really need to do is wrap it in a form. Once you have it as a form, you can select it using jQuery and call serializeArray() to create a name-value array of your inputs.

var table = $('#my_form').serializeArray();
console.log(table);
alert(JSON.stringify(table)); 

The result isn't going to be 100% like you want it. As you can see, all the inputs are in order, but there isn't a really reliable way to know the difference between the rows. Also, I don't think order is guaranteed.

[{"name":"id[]","value":"1"},
 {"name":"name[]","value":"Billy"},
 {"name":"col4[]","value":"Home"},
 {"name":"col3[]","value":"Phone"},
 {"name":"id[]","value":"2"},
 {"name":"name[]","value":"Bob"},
 {"name":"col4[]","value":"work"},
 {"name":"col3[]","value":"Cell"}]

Maintain row groupings - Demo

If you edit your <input name="something[]"> named arrays to have the row number, then you'll be able to know which values belong together. For example, if you had two rows, the input names would look like this:

<tr class="prototype">
    <td><input type="text" name="id[0]" value="1" class="id" /></td>
     <td><input type="text" name="name[0]" value="Billy" /></td>
     <td><input type="text" name="col4[0]" value="Home" /></td>
     <td><input type="text" name="col3[0]" value="Phone" /></td>
 </tr>
 <tr class="prototype">
     <td><input type="text" name="id[1]" value="2" class="id" /></td>
     <td><input type="text" name="name[1]" value="Bob" /></td>
     <td><input type="text" name="col4[1]" value="work" /></td>
     <td><input type="text" name="col3[1]" value="Cell" /></td>
 </tr>

(notice the name arrays have the row number in it) and the returning results would looks like this:

[{"name":"id[0]","value":"1"},
 {"name":"name[0]","value":"Billy"},
 {"name":"col4[0]","value":"Home"},
 {"name":"col3[0]","value":"Phone"},
 {"name":"id[1]","value":"2"},
 {"name":"name[1]","value":"Bob"},
 {"name":"col4[1]","value":"work"},
 {"name":"col3[1]","value":"Cell"}]

Massage results into desired output - Demo

Obviously the results still don't match what you are looking for, but that can be fixed too. We know the name of the field, we know the field's value, and now we know its row number too. Using some regular expressions, we can separate out the name from the row number. Using a loop we can move things around to a format that we like:

var table = $('#my_form').serializeArray();
var final_results = [];
var row_patt = /\[(\d+)\]$/; // Gets the row number inside []
var name_patt = /^[^\[]+/; // Gets the name without the [0]
$(table).each( function(index, ele){
    // Get the name of input and row number
    var rowNum = parseInt(row_patt.exec(ele.name)[1]);
    var name = name_patt.exec(ele.name);

    // Add the name and value to the correct spot in results
    if( final_results[rowNum] === undefined ){
        final_results[rowNum] = {};
    }
    final_results[rowNum][name] = ele.value;
});

Now we have a nicely formatted array of hashes that list each value per row:

[{"id":"1","name":"Billy","col4":"Home","col3":"Phone"},
 {"id":"2","name":"Bob",  "col4":"work","col3":"Cell"}]
lightswitch05
  • 9,058
  • 7
  • 52
  • 75