Short
Generating table with barcodes of items. Each item has exact quantity in database table. Fields in tables are limited: 65, if more then 65 then build a second table, then a third one...How to generate tables with this conditions?
Detailed
Let's say we want to generate a table with 65 available fields (5x13).
My plan is the following
User selects items' checkboxes
When user submits form, PHP gets values of checked checkboxes
PHP gets quantities of each item from database
Generating table
For ex. the quantity for item id 55 is 2 and for 56 is 4 then the table must look like that
My code looks like that (I know that it's wrong, but I can't figure out how it must be. There must be more than 5 counters: rows counter, columns counter, $_POST['id'] counter, items' quantity counter, table counter (if total sum is more than 65))
UPDATE
<?php
$items = array();
foreach ($_POST['checkbox'] as $id) {
$stmt = $db->prepare("SELECT `qt` FROM `items` WHERE `id`=?");
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->bind_result($qt);
$stmt->fetch();
$stmt->close();
for ($cnt = 1; $cnt <= $qt; $cnt++)
$items[] = $id;
}
$i = 0;
foreach ($items as $item) {
for ($j = 0; $j < $item['quantity']; $j++) {
// check if it's the beginning of a new table
if ($i % 65 == 0)
echo '<table>';
// check if it's the beginning of a new row
if ($i % 5 == 0)
echo '<tr>';
echo '<td><img src="bc.php?id=' . $item['id'] . '" alt="' . $item['name'] . '" /></td>';
// check if it's the end of a row
if (($i - 1) % 5 == 0)
echo '</tr>';
// check if it's the end of a table
if (($i - 1) % 65 == 0)
echo '</tr></table>';
$i++;
}
}
// if the last row wasn't closed, close it
if ($i % 5 != 0)
echo '</tr>';
// if the last table wasn't closed, close it
if ($i % 65 != 0)
echo '</table>';
?>
Any suggestion?
EDIT 4
<?php
$i = 0;
foreach ($_POST['checkbox'] as $id) {
$stmt = $db->prepare("SELECT `qt` FROM `items` WHERE `id`=?");
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->bind_result($qt);
$stmt->fetch();
$stmt->close();
for ($cnt = 1; $cnt <= $qt; $cnt++) {
// check if it's the beginning of a new table
if ($i % 65 == 0)
echo '<table>';
// check if it's the beginning of a new row
if ($i % 5 == 0)
echo '<tr>';
echo sprintf('<td><img src="bc.php?id=%1$d" alt="%1$d" /></td>', $id);
// check if it's the end of a row
if (($i + 1) % 5 == 0)
echo '</tr>';
// check if it's the end of a table
if (($i + 1) % 65 == 0)
echo '</table>';
$i++;
}
}
// if the last table isn't full, print the remaining cells
if ($i % 65 != 0) {
for ($j = $i%65; $j < 65; $j++) {
if ($j % 65 == 0) echo '<table>';
if ($j % 5 == 0) echo '<tr>';
echo '<td></td>';
if (($j + 1) % 5 == 0) echo '</tr>';
if (($j + 1) % 65 == 0) echo '</table>';
}
}
You need to just repeatedly make sheets of 65 cell tables until you're done.
I'm going to pseudo code:
data rows = resultOfMyQuery();
int index = 0;
while(index < rows.count()) {
index = createASheet(rows, index);
}
END;
int createASheet(data rows, int index) {
int availableCells = 65;
int column = 0;
print("<table>");
while (availableCells > 0) {
if (index < rows.count()) {
data row = rows.get(index);
int quantity = row.getQuantity();
if (quantity > availableCells) {
// Stay on this item with reduced quantity for next sheet.
row.setQuantity(quantity - availableCells);
rows.set(index, row);
} else {
// Move on to next item on this (or next) sheet.
index++;
}
for (i=0; i<quantity && availableCells>0; quantity--) {
column = makeACell(column, StringFormat("<TAG ATTRIB='%d'></TAG>",row.getId()));
availableCells--;
}
} else {
// fill in empty cells
column = makeACell(column, "");
availableCells--;
}
}
print("</table>");
return index;
}
int makeACell(int column, String filling) {
String cell = "";
if (column == 0) {
cell.append("<tr>");
}
cell.append("<td>").append(filling).append("</td>");
if (column == 4) {
cell.append("</tr>");
}
print cell;
return (column+1) % 5;
}
Why don't you use an existing barcode system like QR-codes? These standards offer libraries to build the codes and are readable by various devices.
If you really want to built your own barcode I strongly suggest to use the binary system to store your values. Think about check sums too.
Related
I have a loop. I need write to 1 and 8 element a button. How I can do it?
$cnt = 1;
while($r = $now->fetch_assoc()) {
if ($cnt > 6) {
break; //write only 5 elements to 1 iteration
}
if($cnt === 1 || $cnt === 8) { //not working
echo "<button>Send</button>";
}
$cnt++;
}
My condition is now working. How I can do correctly condition to 8 element, which in 2 iterations?
Example, waht I want get:
------Button-------
1) record
2) record
3) record
4) record
5) record
1) record
2) record
3) record
------Button-------
1) record
2) record
....
Maybe I understand your question wrong, but I think that this should achieve it.
$i = 1;
$j = 1;
while($r = $now->fetch_assoc()) {
if ($i > 6) {
$i = 0;
}
if($j === 1 || $j%8 === 0) {
echo "<button>Send</button>";
}
$i++;
$j++;
}
My code is below:
function portfolio_gallery() {
global $conn;
$query = $conn->query("SELECT codename, namegroup, features, title, showimage FROM portfolio ORDER BY id DESC");
if ($query->num_rows > 0) {
// output data of each row
echo '<div>';
$i = 0;
while($row = $query->fetch_assoc()) {
$i++;
if ($row["showimage"]) {
if($i % 9 == 0){
echo '</div><div>';
}
echo '<a class="imgpop" href="images/portfolio/large/'.$row["codename"].'.jpg" rel="'.$row["namegroup"].'" title="'.$row["title"].' - '.$row["features"].'"><img src="images/portfolio/thumb/'.$row["codename"].'.jpg" alt="'.$row["title"].'" width="348"/><span class="imgpop-caption">'.$row["title"].'</span></a>';
}
}
echo '</div>';
}
}
portfolio_gallery();
I wanted to echo </div><div> for every after 9th item of the loop but every time I executed the code, the first echo only happened after 8 items instead of 9, but the rest was every 9th.
You have to increment
$i
after
if($i % 9 == 0)
follow the syntax example i worked out its working
<?php
$j=0;
for($i=0;$i<=50;$i++)
{
if($j==9)
{
echo $j.'hioiiiiiii<br/>'; //echo "</div><div>";
$j=-1;
}
$j++;
}
?>
Please try this :)
<?php
function portfolio_gallery() {
global $conn;
$query = $conn->query("SELECT codename, namegroup, features, title, showimage FROM portfolio ORDER BY id DESC");
if ($query->num_rows > 0) {
// output data of each row
echo '<div>';
$i = 0;
while($row = $query->fetch_assoc()) {
if ($row["showimage"]) {
if($i % 9 == 0){
echo '</div><div>';
}
echo '<a class="imgpop" href="images/portfolio/large/'.$row["codename"].'.jpg" rel="'.$row["namegroup"].'" title="'.$row["title"].' - '.$row["features"].'"><img src="images/portfolio/thumb/'.$row["codename"].'.jpg" alt="'.$row["title"].'" width="348"/><span class="imgpop-caption">'.$row["title"].'</span></a>';
}
$i++;
}
echo '</div>';
}
}
declare $i = 1 and Write $i++ at the end of while loop.
if ($query->num_rows > 0) {
// output data of each row
echo '<div>';
$i = 1; // declare $i = 1 here
while($row = $query->fetch_assoc()) {
if ($row["showimage"]) {
if($i % 9 == 1){ // 10 , 19 ,28
echo '</div><div>';
}
echo '<a class="imgpop" href="images/portfolio/large/'.$row["codename"].'.jpg" rel="'.$row["namegroup"].'" title="'.$row["title"].' - '.$row["features"].'"><img src="images/portfolio/thumb/'.$row["codename"].'.jpg" alt="'.$row["title"].'" width="348"/><span class="imgpop-caption">'.$row["title"].'</span></a>';
}
$i++; // increment at end of the loop
}
echo '</div>';
}
I was able to solve it by modifying the condition:
So instead of: if($i % 9 == 0) {...}
I used: if($i!=0 && $i % 9 == 0) {...}
And also placing $i++ at the end of while loop.
Im creating tablerows based on the number of the array colours:
$query = mysql_query("SELECT * FROM things);
$num = mysql_num_rows($query );
$colours = array ();
if($num)
{
for ($i = 0; ($row = mysql_fetch_assoc($query)); ++$i)
{
$colours[$i] = $row["colours"];
}
}
$arrlength = count($colours);
for ($i = 0; ($i < ($arrlength)); ++$i){
echo "
<tr class='border_bottom'><td>".$colours[$i]."</td></tr>
";
}
So, if colours is, lets say, equal to 8, 8 table rows with the class border_bottom are created.
border_bottom is used by CSS to add a border to the bottom of each tablerow.
What I need is some PHP help: I need code which checks the array colours. The last element of the array has to go with an empty id since I dont want a border-bottom added to that very last tablerow. All other tablerows have to go with the border_bottom class, tho.
I was thinking of starting the code like that:
echo"
<tr class='
";
-->PHP code goes here<--
echo"
'>
<td>".$colours[$i]."</td></tr>
Try this:
<?php
$query = mysql_query("SELECT * FROM things");
$num = mysql_num_rows($query);
$colours = array();
if($num)
{
while($row = mysql_fetch_assoc($query))
{
$colours[] = $row["colours"];
}
}
$arrlength = count($colours);
for ($i = 0; $i < $arrlength; ++$i){
if($i < $arrlength - 1){
echo "<tr class='border_bottom'><td>{$colours[$i]}</td></tr>";
}else{
echo "<tr><td>{$someColor}</td></tr>";
}
}
Try the following code in your table row echo
echo "<tr"
.($i < $arrlength - 1 ? " class='border_bottom'" : "")
.">"
."<td>{$colours[$i]}</td></tr>";
You can actually do this while fetching the rows without needing to count how many there are, by reading ahead one row.
$previous_row = mysql_fetch_array(); // fetch the first row (if there is one)
while ($previous_row) {
if ($row = mysql_fetch_array()) {
// if another row is fetched, then the previous row was NOT the last row
echo '<tr class="border_bottom"><td>' . $previous_row['colours'] . '</td></tr>';
} else {
// otherwise, the previous row WAS the last row, and does not get the class
echo '<tr><td>' . $previous_row['colours'] . '</td></tr>';
}
$previous_row = $row; // Set the previous row to the current row
}
I'm working on a printing a baseball team lineup, via php. I want to print a place holder for a missing Player 6 (or any missing position)
So if Player 1 -> Player 5 is OK print, NO Player #6 print place holder, Player 7 -> Player 9 is OK print. I tried to simplify the code. I have tried solving this every which way but I keep getting stuck.
CODE:
$rot = array();
$pos = array();
$jn = array();
$x = 1;
// loads up the arrays from the db
while ( $rot[$x], $pos[$x], $jn[$x])= $r->fetch_row() ) {
$x++;
}
// counts the actual number of players in linuep
// used for validation and error display
$num_players = mysqli_num_rows($r);
// controls the lineup position
for ($i = 1; $i <= 15; $i++){
if($rot[$i] == $i) {
//prints player
$lineup .= "<div data-fp='" . $pos[$i] . "'>" .$jn[$i]. "</div>";
} else {
// prints place holder
$text = "This Position needs to be filled before the next game.";
$lineup .= "<div id='pid' data-rel='".$text."' data-fp='' data-pid='' data-jn='' title=''>x</div>";
}
}
I also tried this to iterate through the array rot[] to find the matching position and print the line but it actually prints the holder repeatedly.
// controls the lineup position
for ($x = 1; $x <= 15; $x++){
for ($i = 1; $i <= ($num_players+1); $i++) {
if ($x == $i) {
//prints player
$lineup .= "<div data-fp='" . $pos[$i] . "'>" .$jn[$i]. "</div>";
} else {
// prints place holder
$text = "This Position needs to be filled before the next game.";
$lineup .= "<div id='pid' data-rel='".$text."' data-fp='' data-pid='' data-jn='' title=''>x</div>";
}
}
}
What about:
# index all players by position while taking them from the database
$players = array();
while ( $row = $r->fetch_row() ) {
list($rot, $pos, $jn) = $row;
$players[$pos] = compact(array('rot', $pos, $jn);
}
...
# line-up players
for ($pos = 1; $pos <= 15; $pos++)
{
$playerExists = isset($players[$pos]);
if ($playerExists)
{
# do this ...
}
else
{
# do that ...
}
}
I think you are creating an array where all numerical elements are filled (i.e. you'll always have a 1 thru 15) and your mistake is in the
if($rot[$i] == $i) {
When populating the arrays from the database, add this line:
$playertoid = array_flip($pos); # pos is the player number array?
i.e.
while ( ($rot[$x], $pos[$x], $jn[$x])= $r->fetch_row() ) {
$x++;
}
$playertoid = array_flip($pos);
Now you've created a reverse lookup table where the index is the player number.
Replace the
if($rot[$i] == $i) {
line with:
if (isset($playertoid[$i])) {
I need to generate random number of divs with five items per div (and remaining items in the last div) from random number of $totalItems and also not all the items satisfy $OKItems... Hopefully the code explains better than me.
My problem is that this script generates empty divs with no content in them.
<?php
$OKItems = 0;
$totalItems = rand(2,30);
for ($i = 0; $i < $totalItems; $i++) {
echo ($OKItems == 0 || $OKItems % 5 == 0) ? 'div open<br />' : '';
$testValue = rand(0, 1);
if ($testValue != 0) {
echo '1';
$OKItems++;
}
echo ($OKItems % 5 == 0 || $i+1 == $totalItems) ? '<br />div close<br />' : '';
}
?>
This is what I might get:
div open
div close
div open
11111
div close
div open
div close
div open
div close
div open
11
div close
And this is what I would have wanted in this case:
div open
11111
div close
div open
11
div close
<?php
const N = 5;
$totalItems = rand(2,30);
$items = array() ;
for ($i = 0; $i < $totalItems; $i++) {
$testValue = rand(0, 1);
if ($testValue != 0) {
$items[] = 1 ;
}
if( N == sizeof($items) || (($i == $totalItems - 1) && 0 < sizeof($items)) ) {
echo "<div>" . join(",", $items) . "</div>";
$items = array() ;
}
}
I think you need a bit more structure to your code.
My approach would be to break it up into several stages, as opposed to trying to do all the logic in the loop that outputs data.
What I'd suggest:
Decide how many items to be tested
Test each item and only copy the ones that pass into a new array
Partition this new array into sets of 5
Output each partition as a div
Code (untested):
// Decide how many items to test
$totalItems = rand(2,30);
// Test these items and add them to an accepted array
$items = Array();
for ($i = 0; $i < $totalItems; $i++) {
$testValue = rand(0, 1);
if ($testValue != 0) { $items[] = "1" }
}
//Partition them into sections
$partitions = array_chunk($items,5);
//Output as divs
foreach($partitions as $partition):
echo 'div open <br />';
foreach($partition as $item):
echo $item . "<br />";
endforeach;
echo 'div close <br />';
endforeach;
When you split up the code into logical steps, it becomes much easier to maintain and debug.
<?php
$OKItems = 0;
$totalItems = rand(2,30);
for ($i = 0; $i < $totalItems; $i++) {
echo ($OKItems == 0 || $OKItems % 5 == 0) ? 'div open<br>' : '';
$testValue = rand(0, 1);
if ($testValue != 0) {
echo '1';
$OKItems++;
}
if($OKItems % 5 == 0 || $i+1 == $totalItems) {
echo '<br>div close<br>';
$OKItems = 0;
}
}
?>
That should be working ;)
I changed your check line for an if function that also resets your $OKItems. The problem you had (i think) was that you got a 0 as the random value and that would keep $OKitems on 5.