2

First I hit the button Add then 'Show' and lastly Show Object

The problem is that when I hit the button Show Object I get only one object for the last input element instead one object for each input element.

How can I add new objects from inside a function without loosing most of them?

Here is the code:

$(document).ready(function() {
  // body...
  var tableInput = "<tr><td><input type='text'/></td><td><input type='text'/></td></tr>";
  var obj = {};
  const rowNo = 2;

  $("h1").text("Helllo Sonq");
  console.log("function called!");

  $("#add").click(function() {
    $("#table").append(tableInput)
  })

  $("#show").click(function() {
    $(":text").each(function(index) {
      console.log(index + ': ' + $(this).val());
      var rowno = "row" + parseInt(index / rowNo)
      obj[rowno] = new Object()
      obj[rowno]["element" + index.toString()] = $(this).val();
      // obj[rowno]["element" + index.toString()] = $(this).val();
    })
  })

  $("#show-object").click(function() {
    console.log(obj);
  })
})
<!DOCTYPE html>
<html>

<head>
  <title>Page Title</title>
</head>

<body>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script type="text/javascript" src="js/js.js"></script>
  <h1>Hello Riko!</h1>
  <button id="add">Add</button>
  <button id="show">Show</button>
  <button id="show-object">Show Object</button>
  <table id="table">
    <tr>
      <th>Name</th>
      <th>Age</th>
    </tr>
  </table>
</body>

</html>

Into the function :

$("#show").click(function(){
    $(":text").each(function(index) {

I want to add an object to the global obj for each iterated input type=text element.

6
  • What output do you expect? Commented Dec 16, 2017 at 15:04
  • 2
    var rowno = "row" + parseInt(index/rowNo) What are you trying to achieve here? you are trying to divide index with rowNo and assign it to rowNo? Commented Dec 16, 2017 at 15:06
  • if the input text elements are two for example I expect: {obj: {row0: {element0: "text-input2", element1: "text-input2"}}} Commented Dec 16, 2017 at 15:07
  • 1
    The expression index/rowNo will always be NaN. Commented Dec 16, 2017 at 15:08
  • There are 2 text fields per roll. I want an object that reflects the structure of the table. Row0 would have element0 and element1, then Row1 would have element0 and element1 and so on Commented Dec 16, 2017 at 15:09

3 Answers 3

2

Since you target the rows then you should loop through them first then inside every row loop throug the inputs just like :

$("tbody>tr").each(function(index) {
  var rowno = "row" + index;
  obj[rowno] = {};

  $(":text", this).each(function(index) {
    console.log(index + ': ' + $(this).val());

    obj[rowno]["element" + index] = $(this).val();
  });
});

NOTE : My suggestion adjust also the table using thead/tbody.

$(document).ready(function() {
  var tableInput = "<tr><td><input type='text'/></td><td><input type='text'/></td></tr>";
  var obj = {};
  const rowNo = 2;

  $("h1").text("Helllo Sonq");
  console.log("function called!");

  $("#add").click(function() {
    $("#table>tbody").append(tableInput)
  })

  $("#show").click(function() {
    $("tbody>tr").each(function(index) {
      var rowno = "row" + index;
      obj[rowno] = {};

      $(":text", this).each(function(index) {
        console.log(index + ': ' + $(this).val());

        obj[rowno]["element" + index] = $(this).val();
      })
    })
  })

  $("#show-object").click(function() {
    console.log(obj);
  })
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<h1>Hello Riko!</h1>
<button id="add">Add</button>
<button id="show">Show</button>
<button id="show-object">Show Object</button>
<table id="table">
  <thead>
    <tr>
      <th>Name</th>
      <th>Age</th>
    </tr>
  </thead>
  <tbody></tbody>
</table>

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

Comments

1

The first time you do var rowno = "row" + parseInt(index/rowNo) , var rowno is filled with row0. Since 0/2 is 0.

But then, the second time, the same row, var rowno = "row" + parseInt(index/rowNo) gives you also a value of 0, since 1/2 does 0.5, wich gets truncated to 0. By doing so, you are replacing the object at position 'row0', wich is what an object in javascript does.

You should not use parseInt

6 Comments

The example above is only for demonstration, If I omit this line: obj[rowno] = new Object() I get the error Cannot set property 'subSubObj0' of undefined. How on earth In javaScript one can APPEND object to an object?
So ... the other guy steals my answer and gets the answer LOL
You were first - Fixed :D
@BabaNew you mentioned, "You should not use parseInt". if parseInt() is not be used then first time row0 & second time it should row0.5 (rowno is changed)?
@SajibKhan since paraseInt is leading to this undesired behaviour, it should be avoided in favor of other approaches
|
1

Just create obj[rowno] = new Object() if it does not exist:

if (!obj[rowno]) {
  obj[rowno] = new Object()
}

because it is recreating the new instance so, the previous one has vanished.

$("#show").click(function() {
  $(":text").each(function(index) {
    console.log(index + ': ' + $(this).val());
    var rowno = "row" + parseInt(index / rowNo)
    if (!obj[rowno]) {
      obj[rowno] = new Object()
    }
    obj[rowno]["element" + index.toString()] = $(this).val();
  })
})

N.B.

parseInt(index / 2) returns 0 when index = 0
parseInt(index / 2) returns 0 when index = 1

1 Comment

The other workarounds would do the job as well, but due to my BAD example, the didn't understand that I wanted to know want happens really, not how to get the job done. Now I get what happens :O, Tricky for noobsies like me :D.

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.