0

I'm trying to get all values of my table by doing this:

var table = $('#myTableId').DataTable();

data = table.rows().data().toArray();

console.log( data );

for each row that I get, I get this:

id: "1"
fixedBalance: 345
balanceEditable1: "<div class='input-group'><span class='input-group-addon'>$</span><input value='75.0' type='number' min='0' class='form-control'/></div>"
balanceEditable2: "<div class='input-group'><span class='input-group-addon'>$</span><input value='7.00' type='number' min='0' class='form-control'/></div>"
description: "EXAMPLE 1"

id: "2"
fixedBalance: 147
balanceEditable1: "<div class='input-group'><span class='input-group-addon'>$</span><input value='2.30' type='number' min='0' class='form-control'/></div>"
balanceEditable2: "<div class='input-group'><span class='input-group-addon'>$</span><input value='12.20' type='number' min='0' class='form-control'/></div>"
description: "EXAMPLE 1"

As you see, I had to add an <input> to make the Datatable cell editable for the balanceEditable1 and balanceEditable2 columns. But It is being hard to retrieve the value of it.

How could I get all the values of those inputs using de rows().data() function and get the data like this?

id: "1"
fixedBalance: 345
balanceEditable1: 75.0
balanceEditable2: 7.00
description: "EXAMPLE 1"

id: "2"
fixedBalance: 147
balanceEditable1: 2.30
balanceEditable2: 12.20
description: "EXAMPLE 2"
Jonatan Lavado
  • 954
  • 2
  • 15
  • 26
  • cells().every() and make a loop condition if the cell contains an input element, get the value of the input element. Usually tag names are used, especially on input elements. – drtechno Nov 20 '19 at 23:32
  • you can use a regex. `var regex = /value='\s*(.*?)\s*'/; var value = regex.exec(balanceEditable1String)` – Mattia Nov 20 '19 at 23:37

1 Answers1

1

rows().data() gives you the text of the underlying td elements. You will have to manually get the value of the input element yourself:

let data = [];
rows().every(function(){
  //`this` will be the row()
  let rowData = this.data();
  //this.node() gets the underly DOM node
  //then we use jQuery's find() to get the actual input element
  rowData[2] = $(this.node()).find("input").val();
  data.push(rowData);
});
console.log(data);

Note the rowData[2] refers to the third column, change the index to match your actual column index.

Demo

$(document).ready(function() {
  var dataSet = [
    ["1", `<input>`, "3"],
    ["2", `<input>`, "2"],
    ["3", `<input>`, "1"],
  ];

  var columnDefs = [{
    title: "first"
  }, {
    title: "second"
  }, {
    title: "third"
  }];

  var myTable;

  myTable = $('#example').DataTable({
    data: dataSet,
    columns: columnDefs
  });
  $("button").click(function(){
    let data = [];
    myTable.rows().every(function(e,d,b){
      let rowData = this.data()
      rowData[1] = parseInt($(this.node()).find('input').val(),10);
      data.push(rowData);
    });
    console.log(JSON.stringify(data));
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.11/js/jquery.dataTables.min.js"></script>

<div class="container">
  <table cellpadding="0" cellspacing="0" border="0" id="example">

  </table>
</div>

<button>Get values</button>
Patrick Evans
  • 41,991
  • 6
  • 74
  • 87
  • I mean, even writting the value into the input, writting like `347`, the `value` attribute doesn't update his value, it keeps setting `0.00` itself. What am I doing wrong? – Jonatan Lavado Nov 21 '19 at 14:56
  • 1
    That is why you need to get the `value` property off the DOM element object. Writing in input and textarea elements does not update their `value` attribute in the html [q&a about attributes vs properties](https://stackoverflow.com/questions/6003819/what-is-the-difference-between-properties-and-attributes-in-html/6004028) – Patrick Evans Nov 21 '19 at 15:01
  • I'm doing it. I'm using the same as you told me: `...find("input").val()` but that would not make sense if the value of the input is not updated itself after writting a new value. I'm confused about what change should I do – Jonatan Lavado Nov 21 '19 at 15:08
  • can you link to an example of your implementation of it (ie on jsfiddle or similar js playground) – Patrick Evans Nov 21 '19 at 15:09
  • http://jsfiddle.net/f0pqnu9g/ Change the value of the input and you will see in the **alert** that the value doesn't change – Jonatan Lavado Nov 21 '19 at 15:23
  • Because you are alerting the unchanged `rowData` which just holds the text from the elements. You need the `rowData[1] = ...` assignment line to get the value into `rowData`, see here: http://jsfiddle.net/kfvo5bd9/ all i did was add the `rowData[1] = ...` line – Patrick Evans Nov 21 '19 at 15:27
  • Actually, what I'm doing to get the value is `$(this.node().cells[2].innerHTML).find("input").val();` because I have 5 cells actually. And to access to the `rowData["fixedBalance"]` because doing `rowData[1]`returns `undefined` – Jonatan Lavado Nov 21 '19 at 15:37
  • Don't use `$(this.node().cells[2].innerHTML)` this is getting the html string and creating new DOM elements it is equivalent to `$('')` that input and the input that is in the page will not be the same element – Patrick Evans Nov 21 '19 at 15:38
  • 1 was just an example, use whatever index your input is in for instance `rowData[2]` if your element is in the 3rd column, `rowData[4]` if it is in the fifth column. If `rowData` has named keys like `fixedBalance` then use that instead of the numerical keys, ie `rowData["fixedBalance"] = ...` – Patrick Evans Nov 21 '19 at 15:40
  • I get it. Could I use something like `$(this.node())[0].find("input").val()`because, as I told you, I have more than 1 column – Jonatan Lavado Nov 21 '19 at 15:46
  • 1
    `$(this.node())[0]` gets the underlying DOM element, changing it to like `[1]` wont give you anything as that jQuery object is only holding 1 item (the tr element). You can use different selectors for different inputs. For instance if each of your inputs have different names (for example one two and three) you can select them by using an attribute selector, eg `find('input[name=one]')` or `find('input[name=two]')` and so on – Patrick Evans Nov 21 '19 at 15:49