-1

I have a dynamic html table, in which I want the rows in the first column only to be merged together if the values are same.Image of table. In the first column, the first two row values are same, so they should be merged but the row values of third column should not be merged.

<table id="example1" class="table table-bordered">
  <thead>
    <th class="hidden"></th>
    <th>Area</th>
    <th>Name</th>
    <th>Party</th>
    <th>Symbol</th>
    <th>Total Number of Votes</th>
  </thead>
  <tbody>
    <?php
                    $query="SELECT * FROM `candidates` ";
                    $result=mysqli_query($con,$query);
                    
                    while($row = mysqli_fetch_array($result)){
                      $sql1 = "SELECT `Name`,`Symbol` FROM `party` WHERE `Party_ID` = '".$row["Party_ID"]."' " ;
                      $query1 = $con->query($sql1);
                      $row1 = $query1->fetch_assoc();
                      $sql2 = "SELECT `Name` FROM `part` WHERE `Part_No` = '".$row["Part_No"]."' " ;
                      $query2 = $con->query($sql2);
                      $row2 = $query2->fetch_assoc();
                      $time1 = filemtime("../party/".$row['Symbol']);
                      echo "
                        <tr>
                          <td class='hidden'></td>
                          <td>".$row2['Name']."</td>
                          <td>".$row['Name']."</td>
                          <td>".$row1['Name']."</td>
                          <td><img src='../party/".$row1['Symbol']."?".$time1."' alt='".$row1['Symbol']."' role='button' width='30px' height='30px' onclick='window.open(this.src)'></td>
                          <td>".$row['Total_Votes']."</td>
                        </tr>
                      ";
                    }
                  ?>
  </tbody>
</table>
  • your question, at least to me, doesn't make any sense. Please show how the table should look after you merge the first two rows. Presumably you would also merge rows 3 and 4 of the first column too – DCR Oct 03 '20 at 19:59
  • You should look into using `rowspan` Your image implies that the table is sortable, which indicates that you will have to recheck this every time the table is sorted. – ATD Oct 03 '20 at 20:03
  • **Warning:** You are wide open to [SQL Injections](https://stackoverflow.com/a/60496/1839439) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/5741187) – Dharman Oct 03 '20 at 22:30
  • @DCR Yes you are right, I want to combine the rows of the first column and for the image provided, it would be 1st & 2nd rows combined, and 3rd & 4th rows combined. But the for 3rd column also the values are same but it's not required to combine those. Only for first column. – Farhan Khan Oct 05 '20 at 09:33
  • @ATD Yes my table is sorted, i.e. for 1st column the same values will be always consecutive. But I cannot use static rowspan as I don't know how many consecutive rows will have same value. – Farhan Khan Oct 05 '20 at 09:36
  • I have understood the logic, i.e. I need to compare the value of first column with the previous value in the same column, and if it is the same I need to increment the rowspan value. But I need help in the coding part. If any other logic can do the same, that also will be appreciable. – Farhan Khan Oct 05 '20 at 09:42
  • @Dharman Thank for pointing out the vulnerabilities. I'll do the recommended amendments. But I need help in the dynamic rowspan for first column if consecutive values are same. Please help...!!! – Farhan Khan Oct 05 '20 at 09:44
  • It's not just incrementing the rowspan - you also have to hide the `td` items that are not required for display. – ATD Oct 05 '20 at 09:45
  • @ATD That's true but can't figure out how do I implement that as a code. I suppose after the table is created, I need to recreate the table 'onload' event using js. But if there can be a way only to recreate the first column of table, that would be best approach. – Farhan Khan Oct 05 '20 at 09:58
  • You don't need to recreate the first column at all. I've given an Answer that shows how you can merge cells and hide unneeded ones. That should be run on first load and after every sort (though I haven't included any sort functionality, so I can't test that part) – ATD Oct 05 '20 at 10:34

1 Answers1

1

Ok, have a look at this as an example:

function mergeCells() {
  let db = document.getElementById("databody");
  let dbRows = db.rows;
  let lastValue = "";
  let lastCounter = 1;
  let lastRow = 0;
  for (let i = 0; i < dbRows.length; i++) {
    let thisValue = dbRows[i].cells[0].innerHTML;
    if (thisValue == lastValue) {
      lastCounter++;
      dbRows[lastRow].cells[0].rowSpan = lastCounter;
      dbRows[i].cells[0].style.display = "none";
    } else {
      dbRows[i].cells[0].style.display = "table-cell";
      lastValue = thisValue;
      lastCounter = 1;
      lastRow = i;
    }
  }
}

window.onload = mergeCells;
table {border-collapse: collapse;}
td {border:1px solid black; vertical-align: top;}
<table id="datatable">
  <tbody id="databody">
    <tr><td>1</td><td>Text item 1</td></tr>
    <tr><td>1</td><td>Text item 10</td></tr>
    <tr><td>2</td><td>Text item 3</td></tr>
    <tr><td>2</td><td>Text item 9</td></tr>
    <tr><td>3</td><td>Text item 7</td></tr>
    <tr><td>4</td><td>Text item 6</td></tr>
    <tr><td>5</td><td>Text item 2</td></tr>
    <tr><td>5</td><td>Text item 4</td></tr>
    <tr><td>5</td><td>Text item 5</td></tr>
    <tr><td>5</td><td>Text item 8</td></tr>
  </tbody>
</table>

I've just added enough to show how the functionality could work.

ATD
  • 1,344
  • 1
  • 4
  • 8
  • It says, "Cannot read property 'rows' of null " at line number 2 of the js. – Farhan Khan Oct 05 '20 at 16:57
  • I have included the id="databody" to the tag. But I have my own id for tag which I'm using to make it a datatable using bower components, that's why I didn't change it and also I didn't see any relevance of
    id being used in the script.
    – Farhan Khan Oct 05 '20 at 16:59
  • The issue is resolved now, had to call the function after the element. As my table is dynamic, calling the function at onload event was executing before the table was loaded. Thank You for your help.
    – Farhan Khan Oct 05 '20 at 17:18
  • np - I tend to use the ID on the tbody tag for most of the stuff I do. But, I left an ID on the table tag as well, in case you used that instead. As long as you can get to the TR tags, then all's well. – ATD Oct 05 '20 at 17:32