Home > front end >  Use jQuery to group JSON data coming from Ajax
Use jQuery to group JSON data coming from Ajax

Time:12-31

I have the following array, which is extracted to from MySQL database using PDO.

[{
      "tbl":"1",
      "orid":"915",
      "date":"2021-12-30 12:46:48",
      "flag":0
   },
   {
      "tbl":"2",
      "orid":"914",
      "date":"2021-12-30 12:46:21",
      "flag":0
   },
   {
      "tbl":"3",
      "orid":"913",
      "date":"2021-12-30 12:45:00",
      "flag":0
   },
   {
      "tbl":"1",
      "orid":"911",
      "date":"2021-12-30 12:27:17",
      "flag":1
   }]

I am trying to retrieve this data via Ajax and build/attach div's accordingly. It doesn't work as I am failing at even displaying the data parameters and keys. This is the success(data) function:

$.each(data,function(i,j){
    content ='<span>' j[i] '<br /></span>';
    $('.timeline').append(content);
    });

I want to place the data in the following format:

<div tbl="1">
<span >Ref 1</span>
<div orid="915" >...</div>
<div orid="911" >...</div>
</div>
<div tbl="2">
<span >Ref 2</span>
<div orid="914" >...</div>
</div>
<div tbl="3">
<span >Ref 3</span>
<div orid="913" >...</div>
</div>

The tricky part is to attach each order/orid to an existing tbl div or create a new tbl div if it doesn't exist yet because of recurring ajax calls (each time loading 10 rows).

CodePudding user response:

Here is an example by your sample data, instead of tbl, orid I've used data-tbl and data-orid attributes.

const data = [{
    "tbl": "1",
    "orid": "915",
    "date": "2021-12-30 12:46:48",
    "flag": 0
  },
  {
    "tbl": "2",
    "orid": "914",
    "date": "2021-12-30 12:46:21",
    "flag": 0
  },
  {
    "tbl": "3",
    "orid": "913",
    "date": "2021-12-30 12:45:00",
    "flag": 0
  },
  {
    "tbl": "1",
    "orid": "911",
    "date": "2021-12-30 12:27:17",
    "flag": 1
  }
]


$.each(data, function(i, data) {
  let target = $(`div[data-tbl=${data.tbl}]`)
  if (target.length == 0) {
    target = $(`<div data-tbl="${data.tbl}"><span >Ref ${data.tbl}</span></div>`);
    $('.timeline').append(target)
  }
  const content = `<div data-orid="${data.orid}" >${data.orid}</div>`;
  target.append(content);
});
.header{
  color: green;
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div ></div>

CodePudding user response:

Consider the following.

$(function() {
  var resultData = [{
      "tbl": "1",
      "orid": "915",
      "date": "2021-12-30 12:46:48",
      "flag": 0
    },
    {
      "tbl": "2",
      "orid": "914",
      "date": "2021-12-30 12:46:21",
      "flag": 0
    },
    {
      "tbl": "3",
      "orid": "913",
      "date": "2021-12-30 12:45:00",
      "flag": 0
    },
    {
      "tbl": "1",
      "orid": "911",
      "date": "2021-12-30 12:27:17",
      "flag": 1
    }
  ];

  function makeNewTable(tableData, target) {
    if (tableData == undefined || target == undefined) {
      return false;
    }
    var tableId = tableData.tbl;
    var table = $("<div>", {
      id: "table-"   tableId,
      class: "table"
    }).appendTo(target);
    $("<div>", {
      class: "header"
    }).html("Ref "   tableId).appendTo(table);
    $("<div>", {
      class: "order"
    }).data("orid", tableData.orid).html(tableData.date).appendTo(table);
    $("<input>", {
      type: "checkbox",
    }).prop({
      checked: tableData.flag == 1 ? true : false,
      disabled: true
    }).appendTo(table);
  };

  function updateTable(newData, target) {
    if (newData == undefined || target == undefined) {
      return false;
    }
    $("<div>", {
      class: "order"
    }).data("orid", newData.orid).html(newData.date).appendTo(target);
    $("<input>", {
      type: "checkbox",
    }).prop({
      checked: newData.flag == 1 ? true : false,
      disabled: true
    }).appendTo(target);
  }

  function showData(data, target) {
    if (data == undefined || target == undefined) {
      return false;
    }
    var tbl;
    $.each(data, function(index, row) {
      if ($("#table-"   row.tbl).length == 0) {
        makeNewTable(row, $("#results-table"));
      } else {
        updateTable(row, $("#table-"   row.tbl));
      }
    });
  }

  showData(resultData, $("#results-table"));
});
.header {
  font-weight: bold;
  padding: 0.2em 0.4em;
}

.order {
  display: inline-block;
  padding: 0.2em 0.4em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="results-table">
</div>

You can see here how it might be easier to break up the different scenarios with Functions. This way you can make a new Table or update an existing table as needed.

Update

You may consider using DataTables. Example: https://jsfiddle.net/Twisty/u6bdcsqz/51/

Primary Code:

function makeTable(keys, data, parent) {
    var table = $("<table>").appendTo(parent);
    $("<thead>").appendTo(table);
    $("<tr>").appendTo($("thead", table));
    $.each(keys, function(i, k) {
      $("<th>").html(k).appendTo($("thead tr", table));
    });
    $("<tbody>").appendTo(table);
    var row;
    $.each(data, function(i, r) {
      row = $("<tr>").appendTo($("tbody", table));
      $("<td>").html("Table "   r.tbl).appendTo(row);
      $("<td>", {
        class: "order"
      }).html(r.orid).appendTo(row);
      $("<td>", {
        class: "date"
      }).html(r.date).appendTo(row);
      $("<td>", {
        class: "flag"
      }).html(r.flag == 1 ? "X" : "&nbsp;").appendTo(row);
    });
    var groupColumn = 0;
    dataTable = table.DataTable({
      "paging": false,
      "columnDefs": [{
        "visible": false,
        "targets": groupColumn
      }],
      "order": [
        [groupColumn, 'asc']
      ],
      "drawCallback": function(settings) {
        var api = this.api();
        var rows = api.rows({
          page: 'current'
        }).nodes();
        var last = null;

        api.column(groupColumn, {
          page: 'current'
        }).data().each(function(group, i) {
          if (last !== group) {
            $(rows).eq(i).before(
              '<tr ><td colspan="3">'   group   '</td></tr>'
            );
            last = group;
          }
        });
      }
    });
    table.on('click', 'tr.group', function() {
      var currentOrder = table.order()[0];
      if (currentOrder[0] === groupColumn && currentOrder[1] === 'asc') {
        table.order([groupColumn, 'desc']).draw();
      } else {
        table.order([groupColumn, 'asc']).draw();
      }
    });
    console.log("Table created, "   data.length   " rows.");
  }

  function updateTable(data) {
    $.each(data, function(i, r) {
      dataTable.row.add(["Table "   r.tbl, r.orid, r.date, r.flag]).draw(false);
    });
    console.log("Table updated, added "   data.length   " rows.");
  }

  function showData(tableData, target) {
    if (tableData == undefined || target == undefined) {
      return false;
    }
    if ($("table", target).length > 0) {
      console.log("Table Found, updating");
      updateTable(tableData, $("table", target));
    } else {
      console.log("No Table, creating.");
      makeTable(["Table", "Order", "Date", "Flag"], tableData, target);
    }
  }

It's more than you may want yet it give you all the features you are asking about.

  • Related