0

I try to create js obj form a table. like following and I want a json object form it using jquery.

First row tr should be consider as header and rest of tr as body. The order should be as row index of table tr.

<table class='table-out'>
   <tr class='header'>
          <td>title</td>
          <td>name</td>
          <td>address</td>
   </tr>
   <tr>
          <td>Mr.</td>
          <td>John Doe</td>
          <td>St. Michael Rd.</td>
   </tr>
   <tr>
          <td>Mr.</td>
          <td>Daniel Kautman</td>
          <td>St. Michael Rd.</td>
   </tr>
</table>

JSON Obj I need:

tableObj =
[
     head:
        {
           txttitle: title,
           txtName: Name,
           txtAddrs: Address,
           order: 1
        }
     body:
        [{
            txttitle: Mr,
            txtName: John Doe,
            txtAddrs: St. Michael Rd
            order: 1
        },
        {
            txttitle: Mr,
            txtName: Mrak Doe,
            txtAddrs: 3 Z, Moyed Park
            order: 2
        },
        {
            txttitle: Mr,
            txtName: Meghan Slattery,
            txtAddrs: address here
            order: 3
        }]
]

Something i try like-

$('.table-out>tbody>tr').each(function (index, elem){
  if($(this).hasClass(header)){
    ......
  }else{
    ......
 }
});
2

5 Answers 5

1

You're almost there. Fetch the cells for each row and get the text based on the column index. Your tableObj needs to be an object btw, not an array.

e.g.

var tableObj = {
  head: {},
  body: []
};

$(".table-out tr").each(function(index, value) {
  var $cols = $(this).children("td");

  var item = {
    txttitle: $cols.eq(0).text(),
    txtName: $cols.eq(1).text(),
    txtAddrs: $cols.eq(2).text()
  };

  if ($(this).hasClass("header")) {
    item.order = 1;
    tableObj.head = item;
  } else {
    item.order = index;
    tableObj.body.push(item);
  }

});

console.log(tableObj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class='table-out'>
  <tr class='header'>
    <td>title</td>
    <td>name</td>
    <td>address</td>
  </tr>
  <tr>
    <td>Mr.</td>
    <td>John Doe</td>
    <td>St. Michael Rd.</td>
  </tr>
  <tr>
    <td>Mr.</td>
    <td>Daniel Kautman</td>
    <td>St. Michael Rd.</td>
  </tr>
</table>

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

1 Comment

I have an another JS question, It would be helpfull if you could take a look there stackoverflow.com/questions/68737245/…
1

You could iterate through each row and add the properties like so:

var tableObj = {
    head: {},
    body: [{}]
};

function ObjectTemplate(title, name, address) {
    this.txttitle = title;
    this.txtName = name;
    this.txtAddrs = address;
}

$(".table-out tbody tr").each(function(rowIndex, row) {
    var title, name, address, bodyObj;
    if (row.className == "header") {
        bodyObj = true;
    } else {
        bodyObj = false;
    }
    $(row + " td").each(function(index, cell) {
        switch (index) {
            case 0:
                title = cell.text();
            case 1:
                name = cell.text();
            case 2:
                address = cell.text();
        }
    });
    var newObject = new ObjectTemplate(title, name, address);
    if (bodyObj) {
        tableObj[body].push(newObject);
    } else {
        tableObj[head] = newObject;
    }
});

Comments

0

Although, in your desired output, you've shown JSON array with string keys which is not correct syntax. I hope that is typo and you want a JSON object.

Yes, you're in right way to iterate through tr using jQuery .each. The following with a helper function to parse tr should do the work:

function parseTr(tr) {
  const keyMap = ['txttitle', 'txtName', 'txtAddrs'];
  let trObj = {};
  tr.find('td').each(function(i, td) {
    trObj[keyMap[i]] = $(this).text();
  });
  return trObj;
}

let tableObj = { 'head': {}, 'body': [] };
$(document).ready(function() {
  $('.table-out tr').each(function(i, tr) {
     if($(this).hasClass('header')) {
       tableObj['head'] = parseTr($(this));
       tableObj['head']['order'] = i;
     } else {
       let parsedTr = parseTr($(this));
       parsedTr['order'] = i;
       tableObj['body'].push(parsedTr);
     }
  });
  console.log(tableObj);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class='table-out'>
   <tr class='header'>
      <td>title</td>
      <td>name</td>
      <td>address</td>
   </tr>
   <tr>
      <td>Mr.</td>
      <td>John Doe</td>
      <td>St. Michael Rd.</td>
   </tr>
   <tr>
      <td>Mr.</td>
      <td>Daniel Kautman</td>
      <td>St. Michael Rd.</td>
   </tr>
</table>

You should see JavaScript object as console output, however if you want JSON string, you could use JSON.stringify on that object:

JSON.stringify(tableObj);

1 Comment

I have an another JS question, It would be helpfull if you could take a look there stackoverflow.com/questions/68737245/…
0

Please add class or some attr so that your data will remain safe

Here is the Live DEMO https://jsfiddle.net/shoesheill/od8ry0nc/47/

<table class='table-out'>
   <tr class='header'>
          <td class="title">title</td>
          <td class="name">name</td>
          <td class="address">address</td>
   </tr>
   <tr>
          <td class="title">Mr.</td>
          <td class="name">John Doe</td>
          <td class="address">St. Michael Rd.</td>
   </tr>
   <tr>
          <td class="title">Mr.</td>
          <td class="name">Daniel Kautman</td>
          <td class="address">St. Michael Rd.</td>
   </tr>
</table>
var tableObj = {
    head: {},
    body: []
}

$('tr:not(".header")').each(function(i,v) {
var $this=$(this);
    var body = { 
       txttitle: $this.find('.title').text(), 
       txtName:$this.find('.name').text(),
       txtAddrs: $this.find('.address').text(),
       order:Number(i+1)
   };
   tableObj.body.push(body);
});

$('tr[class="header"]').each(function(i,v) {
var $this=$(this);
     tableObj.head = { 
       txttitle: $this.find('.title').text(), 
       txtName:$this.find('.name').text(),
       txtAddrs: $this.find('.address').text(),
       order:Number(i+1)
   };
});

console.log(tableObj);

3 Comments

How adding class attribute makes data safe? Also you could use tr.header instead of tr[class="header"].
@rmalviya extracting data would be easier else there may be conflict while getting values
yeah, you can use tr.header too.
0

Try not to hardcode it, whatever you put in you header it will be used then:

var tableObj = {head: {}, body:[]};
var order_number = 0;

$('.table-out tr').each(function (index, elem){
  if($(this).hasClass('header')){
     construct_header(this);
  }else{
     append_body(this);
  }
});

console.log(tableObj);

function construct_header(thisObj){
   $(thisObj).find("td").each(function (index, elem){
      tableObj.head[$(this).text()]=$(this).text();
   });
   tableObj.head.order=1;
}

function append_body(thisObj){
   var row = [],colno=0;
   order_number++;
   var fields = $(thisObj).find("td");
   Object.keys(tableObj.head).forEach(function(key_){
      var field = {};
      if(key_=="order"){
        field[key_] = order_number;
      }else{
        field[key_] = $(fields[colno]).text();
      }
      row.push(field);
      colno++;
   });

   tableObj.body.push(row);
}

Comments

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.