简体   繁体   中英

Tabular/nested(?) JSON collection and then accessing it on the server-side

I have a HTML table that gets generated dynamically, it looks like this:

<table>
    <thead>
        <tr>
            <th>First name</th>
            <th>Last name</th>
            <th>Tel</th>
        </tr>
    </thead>
    <tbody>
        <tr id="11">
            <td><input id="txt1" name="txt1" class="gridinput" type="text" field="FirstName" value="A" /></td>
            <td><input id="txt2" name="txt2" class="gridinput" type="text" field="LastName" value="B" /></td>
            <td><input id="txt3" name="txt3" class="gridinput" type="text" field="Tel" value="C" /></td>
        </tr>
    </tbody>
</table>

I want to iterate and store each table row as an item in a JSON object, and then pass that to the server with AJAX. I've gotten as far as being able to store and pass each individual input. (Sorry, the following is as concise as I can make it):

JavaScript function:

function SaveData() {
    var gridInputs = {
        items: [
            { field: "", val: "" }
        ]
    };

    $('.gridinput').each(function () {
        gridInputs.items.push({
            field: $(this).attr('field'),
            val: $(this).val()
        });
    });

    // send 'JSON.stringify(gridInputs)' to the server
}

Model:

public class GridInputRoot
{
    public List<GridInput> items { get; set; }
}

public class GridInput
{
    public string field { get; set; }
    public string val { get; set; }
}

Web Service method:

[WebMethod(true)]
public void SaveData(string gridInputsJson)
{
    GridInputRoot gridInputs = JsonConvert.DeserializeObject<GridInputRoot>(gridInputsJson);

    foreach (var item in gridInputs.items)
    {
        string field = item.field;
        string val = item.val;
         // etc
    }
}

How can I change this solution so that I'm looping through each row rather than each cell on the server side? The key in whatever collection I end up with will be unique obviously - it will be the tr 's 'id' attribute

(I have thought of using LINQ to group the items etc but there are reasons why this isn't ideal)

Ok, create your array better, like this:

var result=new Array();
$('tr:has(input[field])').each(function () {
    var row={};
    $('input[field]',this).each(function(){
      row[$(this).attr('field')]=$(this).val();
    });
    result.push(row);
});

C# would look something like this:

[WebMethod(true)]
public void SaveData(string gridInputsJson)
{
    GridInputRoot grid = JsonConvert.DeserializeObject<GridInputRoot>(gridInputsJson);

    foreach (var row in grid)
    {
        // Your row.
        Console.Write("First Name:{0}",row.FirstName);
        Console.Write("Last Name:{0}",row.LastName);
        Console.Write("Telephone:{0}",row.Tel);
    }
}

My approach is to simply work row-by-row:

/**
 * Approach: Resulting Data structure.
 */
var example = [
  {
    id: 11, // The row ID
    columns: [
      {field: 'FirstName', value: 'A'} // A column in the row.
    ]
  }
];

/**
 * Approach: Implementation.
 */
var rows = $('tr');
var table = [];

rows.each(function () {
  var columns = this.children('td');
  table.push({
    id: this.id,
    columns: columns.map(function () {
      return {field: this.attr('field'), value: this.attr('value')};
    })
  });
});

Now, in your backend code:

[WebMethod(true)]
public void SaveData(string gridInputsJson)
{
    GridInputRoot grid = JsonConvert.DeserializeObject<GridInputRoot>(gridInputsJson);

    foreach (var item in grid)
    {
        // Your row.

        foreach (var column in item.columns) {
          // Your column.

          string field = column.field;
          string val = column.val;
        }
    }
}

My C# is rusty, but let's hope that gets you enough of the way there.

This is just an addendum to Trey Cordova's nice solution, which appears to work fine. I was just curious to if the jQuery part might be written in another way. The example below groups by row and also uses the "attributes" object to serialize all the inputs.

This is the interesting bit here:

 $.each(this.attributes, function() { /* do stuff */ }); 

Run code snippet to view json ouput to server:

 <html> <body> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script> <table> <tr> <td><input data-field="keyA1" value="A1"></td> <td><input data-field="keyB2" value="B2"></td> <td><input data-field="keyC3" value="C3"></td> <td><input data-field="keyD4" value="D4"></td> <td><input data-field="keyE5" value="E5"></td> </tr> <tr> <td><input data-field="keyF1" value="F1"></td> <td><input data-field="keyG2" value="G2"></td> <td><input data-field="keyH3" value="H3"></td> <td><input data-field="keyI4" value="I4"></td> <td><input data-field="keyJ5" value="J5"></td> </tr> </table> json output: <xmp id="stdout"></xmp> <script type="text/javascript"> var rows = []; $('TR').each( function() { var cells = []; $('TD INPUT', this).each( function() { var attr = {}; $.each(this.attributes, function() { attr[this.name] = this.value; }); cells.push( attr ); }); rows.push( cells ); }); // send to server here (not shown) document.getElementById('stdout').innerHTML = JSON.stringify( rows, null, ' '); </script> </body> </html> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM