tera_789
tera_789

Reputation: 529

Display different HTML elements based on array's index

I am using Python to scrape through a webpage and then download its table data, <td> elements, and store them in file as JSON. Afterwards, I use PHP to process that data and display it in a table:

<?php
    $file_content = file_get_contents("./file.txt");
    $decoded_json = json_decode($file_content); // $decoded_json becomes an array with 72 elements (each of the elements is a string)
?>

Each row of the table where I got data from has 24 columns. Basically I have 3 rows now (72 elements in an array). I need to create 3<tr> and 24 <td> for each row - dynamically because each time number of rows I scrape may change. Also, I need to add <input type="checkbox"> next to 18th, 21st, and 24th column in my table. Here is what I have so far (it looks at least somewhat close to what I want to achieve):

<table>
    <?php
        $i = 0;
        while ($i <= count($decoded_json)) {
            if ($i % 24 === 0) {
                echo "<tr><td>$decoded_json[$i]</td></tr>";
                $i++;
            } else {
                if ($i % 18 === 0 || $i % 21 === 0 || $i % 24 === 0) {
                    echo "<td>$decoded_json[$i]</td>";
                    echo '<td><input type="checkbox"></td>'; // It does not echo checkboxes correctly because of $i. 
                    $i++;
                } else {
                    echo "<td>$decoded_json[$i]</td>";
                    $i++;
                }  
            }
        }
    ?>
</table>

Questions:

If yes:

  1. How can I make sure only 1 row is created for each 24 elements in an array (even if my array consists of thousands of elements)? Right now 1 row is created for each 23 elements, and 1st element of 24 is always left out.
  2. How can I add a checkbox next to 18th, 21st, and 24th column of each row? Because I increment $i on every iteration, number is growing, but I guess I have to keep it between 1-24 for every row.

If no:

  1. Which approach would you recommend to use? I prefer PHP.

P.S. I hope I was clear. If not, please ask for clarification. My title may look vague but I did not know how to specify my question in 1 sentence.

Edit (replying to @ggorlen comment): Here is the file content:

["first", "768.51", "4,680", "0", "0%", "0", "0", "0%", "0", "0", "0%", "0", "0.00", "0.00%", "2", "0", "0%", "0", "0.00", "0.00%", "1", "768.51", "100.00%", "4,677", "second", "547.80", "27,392", "0", "0%", "0", "0", "0%", "0", "0", "0%", "0", "44.30", "8.09%", "138", "503.50", "91.91%", "27,254", "0", "0%", "0", "0", "0%", "0", "third", "509.41", "59,777", "0", "0%", "0", "0", "0%", "0", "0", "0%", "0", "0.00", "0.00%", "1", "412.94", "81.06%", "9,972", "22.15", "4.35%", "6,118", "74.32", "14.59%", "43,686"]

Here is what I want to get (sort of; I just need checkboxes next to the 18th, 21st, and 24th columns of each row):

<html><head><title>The Website Title</title></head>
<body>

<table border="1">

<td>first</td><td align="right">768.51</td> <td align="right">4,680</td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td><td align="right">0.00</td> <td align="right">0.00%</td> <td align="right"></td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td><td align="right">0.00</td> <td align="right">0.00%</td> <td align="right"><a >1</a></td><td align="right">768.51</td> <td align="right">100.00%</td> <td align="right"><a >4,677</a></td></tr>

<tr>
<td>second</td><td align="right">547.80</td> <td align="right">27,392</td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td><td align="right">44.30</td> <td align="right">8.09%</td> <td align="right"><a >138</a></td><td align="right">503.50</td> <td align="right">91.91%</td> <td align="right"><a >27,254</a></td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td></tr>

<tr>
<td>third</td><td align="right">509.41</td> <td align="right">59,777</td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td><td align="right">0</td> <td align="right">0%</td> <td align="right">0</td><td align="right">0.00</td> <td align="right">0.00%</td> <td align="right"><a>1</a></td><td align="right">412.94</td> <td align="right">81.06%</td> <td align="right"><a >9,972</a></td><td align="right">22.15</td> <td align="right">4.35%</td> <td align="right"><a>6,118</a></td><td align="right">74.32</td> <td align="right">14.59%</td> <td align="right">43,686<</td></tr>

</table>


</body></html>

Upvotes: 2

Views: 482

Answers (1)

ggorlen
ggorlen

Reputation: 57195

Your code is close. The idea is to formulate the 1d array in terms of rows and columns somehow. My approach was to increment the outer row loop by the number of desired columns (24).

For each row, I echo the opening <tr> tag, then iterate over all the columns in an inner loop and place cells and checkboxes as appropriate. Each cell's index is $row + $col ($col + $row < count($decoded_json) is a safety check). Finally, I close the row's </tr> and move on to the next row, which begins 24 indices further in the array.

$columns = 24;
$checkboxes = array_flip([17, 20, 23]);

for ($row = 0; $row < count($decoded_json); $row += $columns) {
    echo '<tr>';

    for ($col = 0; $col < $columns && $col + $row < count($decoded_json); $col++) {
        echo '<td>' . $decoded_json[$row+$col] . '</td>';
        
        if (array_key_exists($col, $checkboxes)) {
            echo '<td><input type="checkbox"></td>';
        }
    }

    echo '</tr>';
}

Here's the tidied HTML output:

table {
  border-collapse: collapse;
  font-family: monospace;
}

tr,
td {
  padding: 0.6em;
  border: 1px solid black;
}
<table>
  <tr>
    <td>first</td>
    <td>768.51</td>
    <td>4,680</td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td>0.00</td>
    <td>0.00%</td>
    <td>2</td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td><input type="checkbox"></td>
    <td>0.00</td>
    <td>0.00%</td>
    <td>1</td>
    <td><input type="checkbox"></td>
    <td>768.51</td>
    <td>100.00%</td>
    <td>4,677</td>
    <td><input type="checkbox"></td>
  </tr>
  <tr>
    <td>second</td>
    <td>547.80</td>
    <td>27,392</td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td>44.30</td>
    <td>8.09%</td>
    <td>138</td>
    <td>503.50</td>
    <td>91.91%</td>
    <td>27,254</td>
    <td><input type="checkbox"></td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td><input type="checkbox"></td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td><input type="checkbox"></td>
  </tr>
  <tr>
    <td>third</td>
    <td>509.41</td>
    <td>59,777</td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td>0</td>
    <td>0%</td>
    <td>0</td>
    <td>0.00</td>
    <td>0.00%</td>
    <td>1</td>
    <td>412.94</td>
    <td>81.06%</td>
    <td>9,972</td>
    <td><input type="checkbox"></td>
    <td>22.15</td>
    <td>4.35%</td>
    <td>6,118</td>
    <td><input type="checkbox"></td>
    <td>74.32</td>
    <td>14.59%</td>
    <td>43,686</td>
    <td><input type="checkbox"></td>
  </tr>
</table>

Upvotes: 1

Related Questions