How do I show some elements of an array following this criterion?

Asked

Viewed 469 times

0

I have to make a php form that at the end shows the price of each product purchased, showing only the prices of the products that in the other column of the table, were marked in the checkbox:

FORM:

**<!DOCTYPE html>
<html>
<head>
    <title>Pag</title>
</head>
<style>
table{
    margin-top:10%;
    width:50%;
}
.comprar{
margin-left:49%;
}
#qtd{
        width:40px;
    }
.linha1{
    text-align:center;
}
.preco{
    width: 50px;
}
</style>
<body>
<form action="cupom.php" method="post" name="compras">
<table cellspacing="5" align='center' border='1'>
<tr class="linha1"><td>Produtos</td><td>Valor Unitário</td><td>Quantidade</td></tr>

<?php
$prod['Arroz']=1.2;
$prod['Macarrão']=2.6;
$prod['Biscoito Cream']=4.1;
$prod['Margarina']=4.89;
foreach($prod as $key => $value){
   ?>
   <tr>
   <td><input type="checkbox" name="produtos[]" value="<?php echo $key; ?>"><?php echo $key; ?></td>

   <td><input type="text" name="preco[]" class="preco" readonly value="<?php echo 'R$ '.$value; ?>"></td>

   <td><input type="number" name="qtd[]" id="qtd" min="0" max="100">
   </tr>
<?php 
}
?>
</table>
<input type="submit" value="Comprar" class="comprar">
</form>
</body>
</html>**

INVOICE:

<?php
require "pag1.php";
$prod_comp = $_POST['produtos'];
$qtd_prod = $_POST['qtd'];
$precos = $_POST['preco'];
foreach($prod_comp as $value){
     echo '<p align="center">'.$value."</p>";
}
foreach($qtd_prod as $value){
     echo '<p align="center">'.$value."</p>";
}
foreach($precos as $key => $value){
     echo '<p align="center">'.$value."</p>";
}
?>
  • Not already being done?

  • But it shows all prices in the price array, it should show only the prices of the products that were purchased

  • what field do you keep that product has already been purchased ?

  • provides the code, where brands the product as purchased.

1 answer

0

It is important to remember that in a form submission only the <checkbox> those that are marked/selected, those that are not even sent. If none is marked this key will not exist in $_POST['produtos'], soon this:

foreach($prod_comp as $value){
     echo '<p align="center">'.$value."</p>";
}
foreach($qtd_prod as $value){
     echo '<p align="center">'.$value."</p>";
}
foreach($precos as $key => $value){
     echo '<p align="center">'.$value."</p>";
}

It is not correct because it assumes that everyone always exists and $prod_comp will not always exist and will have size dependent on what was selected. Moreover the $qtd_prod and the $precos do not depend on what was chosen in $prod_comp.

Instead we can change the html of <checkbox> to have a sequential numerical value:

$prod['Margarina']=4.89;
$num = 0; //numero do produto
foreach($prod as $key => $value){
   ?>
   <tr>
   <td><input type="checkbox" name="produtos[]" value="<?=$num++?>"><?php echo $key; ?></td>

   ...
<?php 
}

What will make the generated html for the <checkbox> looks like the following:

<td><input type="checkbox" name="produtos[]" value="0">Arroz</td>
<td><input type="checkbox" name="produtos[]" value="1">Macarrão</td>
<td><input type="checkbox" name="produtos[]" value="2">Biscoito Cream</td>
<td><input type="checkbox" name="produtos[]" value="3">Margarina</td>

In this way when submitted by value we know which lines we need to go read to the other arrays. We can then interpret it as follows:

if ($_SERVER["REQUEST_METHOD"] == "POST"){ //se foi submetido em post

    if (isset($_POST["produtos"])){ //se existem produtos escolhidos

        //criar os nomes num array
        $nomesProdutos = array('Arroz','Macarrão','Biscoito Cream','Margarina'); 

        //obter todos os arrays que vem de $_POST como já era feito
        $prod_comp = $_POST['produtos'];
        $qtd_prod = $_POST['qtd'];
        $precos = $_POST['preco'];

        echo "Produtos escolhidos:";

        //for apenas sobre os que foram escolhidos
        for ($i = 0; $i < count($prod_comp);++$i){
            $pos = $prod_comp[$i]; //obter a posição do elemento escolhido (0,1,2 ...)
            //ir buscar as informações aos outros arrays com base nessa posição
            echo "Nome:  $nomesProdutos[$pos]  Quantidade: $qtd_prod[$pos] Preço: $precos[$pos]<br>";
        }
    }
    else {
        echo "Não escolheu nenhum produto";
    }
}

This solution already works for the intended purpose. A more organized solution would be to use classes because we have 3 distinct arrays that refer to the same thing, a product. For that reason we could create a class Produto and create objects of that class within the for:

class Produto{
    var $nome;
    var $quantidade;
    var $preco;

    //construtor de Produto que recebe nome, quantidade e preço
    function __construct($nome, $quantidade, $preco){
        $this->nome = $nome;
        $this->quantidade = $quantidade;
        $this->preco = $preco;
    }
}


if ($_SERVER["REQUEST_METHOD"] == "POST"){

    if (isset($_POST["produtos"])){

        $nomesProdutos = array('Arroz','Macarrão','Biscoito Cream','Margarina');

        $prod_comp = $_POST['produtos'];
        $qtd_prod = $_POST['qtd'];
        $precos = $_POST['preco'];

        echo "Produtos escolhidos:";

        //Array de objetos produto
        $produtos = array();

        for ($i = 0; $i < count($prod_comp);++$i){
            $pos = $prod_comp[$i];
            //acrescentar um novo objeto produto ao array
            $produtos[] = new Produto($nomesProdutos[$pos], $qtd_prod[$pos], $precos[$pos]);
        }

        //mostrar todos
        print_r($produtos);
    }
    else {
        echo "Não escolheu nenhum produto";
    }
}

However, it would make sense to create a specific method to show the Produto html in a more beautiful and organized way, so that the visualization is identical to code without classes. This method could look like this:

class Produto{
    ...
    //método para obter o html do produto de forma mais organizada
    function obterHtml(){
        return "Nome:  {$this->nome}  Quantidade: {$this->quantidade} Preço: {$this->preco}<br>";
    }
}

And now we show where it is necessary to call only the method:

//mostrar todos
foreach ($produtos as $prod){
    echo ($prod->obterHtml());
}

As an additional note there is a small flaw in html that has a close tag </td> missing in:

<td><input type="number" name="qtd[]" id="qtd" min="0" max="100">
   </tr>

Which should be corrected to

<td><input type="number" name="qtd[]" id="qtd" min="0" max="100"></td>
   </tr>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.