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>
2
  • 1
    Can you post your HTML for the table? Commented Aug 1, 2013 at 8:26
  • @Jeemusu Question is edited Commented Aug 1, 2013 at 8:29

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

1 Comment

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..
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"}]

Comments

2

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

1 Comment

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 <input> fields. It is more useful for extracting plain text. Although it wouldn't be hard to modify to work with <input> fields...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.