-1
<html>
     <body>
         <table>
              <tbody id="tblBody">
              </tbody>
         </table>

<script>    
let t = [{a:1, b:2},{a:3, b:4}]
    populate(t)
    
    function populate(t) {
        
        let tbody = document.getElementById('tblBody')
        let tableHtml = ''
        t.forEach(obj => {
            
            tableHtml += `
            <tr>
                <td>${obj.a}</td>
                <td>${obj.b}</td>
                <td>
                    <button onclick= "editT(${JSON.stringify(obj)})">Edit</button>    
                    
                </td>
            </tr>
        `
        });
        tbody.innerHTML = tableHtml
    }
    
    const editT = (obj) => {
        let parsedObj = JSON.parse(obj)
        console.log(parsedObj)
    }
</script>

</body>
</html>

But I am unable to set obj as a parameter of function editT(). Is there any way to set object as parameter so that each object can be edited by clicking button in a dynamic table. Actual object has many key value pairs.

Satyendra
  • 14
  • 4
  • I think that editT function is not visible in the scope of populate function. Try to move editT definition inside of the populate function. – pe.kne Nov 25 '22 at 16:56
  • If the editT() function is localized it will not be accessed from a dynamic row. – Satyendra Nov 26 '22 at 02:56

1 Answers1

1

One way to do it is to pass the object (stringified) index to the onclick function.

let t = [{
  a: 1,
  b: 2
}, {
  a: 3,
  b: 4
}]
populate(t)

function populate(t) {

  let tbody = document.getElementById('tblBody')
  let tableHtml = ''
  t.forEach((obj,index) => {

    tableHtml += `
                <tr>
                    <td>${obj.a}</td>
                    <td>${obj.b}</td>
                    <td>
                        <button onclick= "editT(${+index})">Edit</button>    
                        
                    </td>
                </tr>
            `
  });
  tbody.innerHTML = tableHtml
}

const editT = (index) => {
  const obj = t[index];
  console.log(obj)
}
<body>
  <table>
    <tbody id="tblBody">
    </tbody>
  </table>
</body>

Edit

I don't love the idea of encoding the param to editT, because that makes a copy of the parameter. If editT is really going to "edit t", t must either be passed as a param or be in the enclosing scope.

Anyway, if the OP really prefers a copy of the selected object via string encoding, here's a snippet that does that. The error in the OP was caused by assigning the onclick prop to a string, rather than a function.

let t = [{
  a: 1,
  b: 2
}, {
  a: 3,
  b: 4
}]
populate(t)

function populate(t) {

  let tbody = document.getElementById('tblBody')
  let tableHtml = ''
  t.forEach((obj,index) => {
    let expr = `editT(${JSON.stringify(obj)})`;
    tableHtml += `
                <tr>
                    <td>${obj.a}</td>
                    <td>${obj.b}</td>
                    <td>
                        <button onclick=${expr}>Edit</button>    
                    </td>
                </tr>
            `
  });
  tbody.innerHTML = tableHtml
}

const editT = (obj) => {
  console.log("note, this is a copy of the object in t:", obj)
}
<body>
  <table>
    <tbody id="tblBody">
    </tbody>
  </table>
</body>
danh
  • 62,181
  • 10
  • 95
  • 136
  • Surely it would work the way I did this query. But actually 't' itself is a parameter to another function which wraps it all except the editT() function. The editT() function must be a global function to be accessed from a dynamic row. So 't' cannot be accessed as a global object in the function editT(). My problem is how to stringify each obj so that it can fit as a parameter in function editT(). – Satyendra Nov 26 '22 at 02:53
  • Hi @Satyendra - added a snippet that fixes only the problem as posed. I worry that you still won't have what you need, because, as I noted in the edit, the encoded param is a copy of the object in the array. – danh Nov 26 '22 at 17:10