Formular mit zwei Submit-Buttons

TRex87

Grünschnabel
Hallo,
ich habe ein Formular mit zwei Datumsfeldern und zwei Submit-Buttons. Der eine Button soll eine SQL Abfrage als HTML Tabelle anzeigen, der andere Button soll die SQL Abfrage in eine CSV-Datei schreiben und dem User zum Download anbieten. Über die Datumsfelder wird ein Filter in die SQL Abfrage eingebaut. Es funktioniert alles soweit auch gut, bis auf einen kleinen Fehler. Wenn ich zuerst den "Show" Button klicke, wird die Tabelle angezeigt. Wenn ich danach den Zeitraum ändere und den Download-Button klicke, dann bleibt die vorherige Ausgabe stehen. Kann mir jemand sagen woran das liegt?
Danke!

Hier mein Code:
PHP:
<?php
require_once 'includes/database.class.php';
require_once 'includes/export_functions.php';

$conn = database::getInstance();
$conn->connect();

if (isset($_POST['formData']))    {
    $data = $_POST['formData'];
    $datefrom = $data['datefrom'];
    $dateto = $data['dateto'];

} else {
    //calculate last quarter
    $date = date_create('today'); //oder hier Datum rein zum testen
    $month = $date->format('m'); $year = $date->format('Y');
    $month_q = $month - ($month-1) % 3;  //Monat des akt.Quartals
    $str_curr_q = $year.'-'.$month_q.'-01';  //akt.Quartal Anfang als string
   
    //letztes. Quartal Anfang = akt.Quartal Anfang - 3 Monate
    $datefrom = date_format(date_create('-3 month '.$str_curr_q),"Y-m-d");
   
    // letztes. Quartal Ende = akt.Quartal Anfang - 1 Tag
    $dateto = date_format(date_create('-1 day '.$str_curr_q),"Y-m-d");
}

?>
<div class="page-header">
        <h1>Report of entered Data</h1>
      </div>

<form>
<label>Please select timeframe</label><br />
<input type="date" name="formData[datefrom]" value="<?php echo $datefrom; ?>" required /> to
<input type="date" name="formData[dateto]" value="<?php echo $dateto; ?>" required />
<button name="formData[submit]" value="show" formaction="index.php?page=report" formmethod="post">Show</button>
<button name="formData[submit]" value="download" formaction="index.php?page=report" formmethod="post">Download</button><br />
</form>

<?php if (isset($_POST['formData'])) {

        if ($data['submit']=="show")    {   /* Ergebnisausgabe nur wenn Show-Button gedrückt wurde */?>
   
    <div class="col-md-6">
    <table class="table table-striped">
    <thead>
        <tr>
            <th>Spalte 1</th>
            <th>Spalte 2</th>
        </tr>
    </thead>
    <tbody>
   
<?php
// SQL-Befehl ausführen
    if($results = $conn->doQuery("SELECT spalte1, spalte2 FROM table1 WHERE enddate BETWEEN '".$datefrom."' AND '".$dateto."' ORDER BY spalte1")) {
   
        while ($list = $results->fetch_object()){
        echo "<tr>";
        echo "<td>".$list->spalte1."</td>";       
        echo "<td>".$list->spalte2."</td>";
        echo"</tr>";
        }
    }
?>   
    </tbody>
    </table>   
    </div>
<?php

    $results->close();


}     elseif ($data['submit']=="download")    {
            $headers = array('spalte1', 'spalte2');
            $sql = "SELECT spalte1, spalte2 FROM table1 WHERE enddate BETWEEN '".$datefrom."' AND '".$dateto."' ORDER BY spalte1";
            export_csv($headers, $sql);  /* Funktion in export_functions.php */
            exit();
    }
    // Verbindung zum Datenbankserver beenden
    $conn->close();
}
?>
 
Von meinen if-Schachtelungen her, sollte das so passen. Beim Klick auf "Download", springt er auch nicht in die "show" Ausgabe. Aber der Seiteninhalt vom Seitenaufruf zuvor bleibt stehen. Hat jemand einen Tipp wie ich den leeren kann?
 
Hallo TRex87,

ich muss das kurz für mich elaborieren.

Wenn Du Dein Formular normal befüllst und auf "Download" klickst, wird der gewünschte Inhalt korrekt in die .csv geschrieben und zum Download bereitsgestellt.
Klickst Du allerdings vorher noch auf "show" und änderst nun noch etwas am Formular, werden diese Änderungen nicht in die .csv übertragen?

Liebe Grüße
 
Hi Splater,

nein. Im Formular sind ja zwei Eingabefelder für Datum. Ich gebe ein "Von" und "bis" Datum an und von der Datenbank wird dann selektiert was in diesem Zeitraum liegt.
Ich gebe also beispielsweise an 01.01.2016 bis 31.03.2016. Klicke auf "Show" und die richtigen Daten werden auf der Seite ausgegeben. Meine Datumseingabe bleibt in den Eingabefeldern stehen. Klicke ich nun auf Download, werden auch die richtigen Datensätze in die csv geschrieben. Gleichzeitig bleiben sie aber auf der Webseite stehen, obwohl durch die if-Verschachtelung gar nicht mehr in die Ausgabe auf der Seite gesprungen wird. Also hängt das noch irgendwo in einem Puffer oder was auch immer. In diesem Beispiel könnte ich auch damit leben.

Problem ist nur, wenn ich 01.01.2016 bis 31.03.2016 eingebe und auf "Show" klicke. Danach dann aber 01.01.2016 bis 30.04.2016 eingebe und auf Download klicke. In die CSV werden die Datensätze inklusive April geschrieben, aber auf der Seite bleiben die vorherigen Daten (nur bis März) stehen. Das ist für den User dann verwirrend und ich würde das gerne unterbinden. Am einfachsten sollte die Seite nach einem Klick auf "Download" immer leer bleiben (bis auf das Formular, das immer oben angezeigt wird)

Danke
 
Hallo TRex87,

ok, so sehe ich das auch im Code.

Durch einen Klick auf "Download" wird das Formular abgesendet.

Die Variable $_POST['formData']['submit'] enthält nach dem Klick auf "Download" das Value "download" - entsprechend wird PHP die folgende Bedinung mit true bewerten.
PHP:
if(isset($_POST['formData'])){
    $data=$_POST['formData'];
    $datefrom=$data['datefrom'];
    $dateto=$data['dateto'];
}else{

Die Variablen $datefrom und $dateto müssen also ausgeschlossen werden.

PHP:
require_once 'includes/database.class.php';
require_once 'includes/export_functions.php';

$conn=database::getInstance();
$conn->connect();

if(isset($_POST['formData'])){
    $data=$_POST['formData'];
    if($data['submit']!="download"){
        $datefrom=$data['datefrom'];
        $dateto=$data['dateto'];
    }
}else{
    //calculate last quarter
    $date=date_create('today'); //oder hier Datum rein zum testen
    $month=$date->format('m');
    $year=$date->format('Y');
    $month_q=$month-($month-1)%3;  //Monat des akt.Quartals
    $str_curr_q=$year.'-'.$month_q.'-01';  //akt.Quartal Anfang als string
    //letztes. Quartal Anfang = akt.Quartal Anfang - 3 Monate
    $datefrom=date_format(date_create('-3 month '.$str_curr_q),"Y-m-d");
    // letztes. Quartal Ende = akt.Quartal Anfang - 1 Tag
    $dateto=date_format(date_create('-1 day '.$str_curr_q),"Y-m-d");
}
?>
<div class="page-header">
    <h1>Report of entered Data</h1>
</div>

<form>
    <label>Please select timeframe</label><br />
    <input type="date" name="formData[datefrom]" value="<?php echo $datefrom;?>" required /> to
    <input type="date" name="formData[dateto]" value="<?php echo $dateto;?>" required />
    <button name="formData[submit]" value="show" formaction="index.php?page=report" formmethod="post">Show</button>
    <button name="formData[submit]" value="download" formaction="index.php?page=report" formmethod="post">Download</button><br />
</form>

<?php
if(isset($_POST['formData'])){
    if($data['submit']=="show"){ /* Ergebnisausgabe nur wenn Show-Button gedrückt wurde */
        ?>

        <div class="col-md-6">
            <table class="table table-striped">
                <thead>
                    <tr>
                        <th>Spalte 1</th>
                        <th>Spalte 2</th>
                    </tr>
                </thead>
                <tbody>
                    <?php
// SQL-Befehl ausführen
                    if($results=$conn->doQuery("SELECT spalte1, spalte2 FROM table1 WHERE enddate BETWEEN '".$datefrom."' AND '".$dateto."' ORDER BY spalte1")){

                        while($list=$results->fetch_object()){
                            echo "<tr>";
                            echo "<td>".$list->spalte1."</td>";
                            echo "<td>".$list->spalte2."</td>";
                            echo"</tr>";
                        }
                    }
                    ?> 
                </tbody>
            </table> 
        </div>
        <?php
        $results->close();
    }elseif($data['submit']=="download"){
        $datefrom=$data['datefrom'];
        $dateto=$data['dateto'];
        $headers=array('spalte1','spalte2');
        $sql="SELECT spalte1, spalte2 FROM table1 WHERE enddate BETWEEN '".$datefrom."' AND '".$dateto."' ORDER BY spalte1";
        export_csv($headers,$sql);  /* Funktion in export_functions.php */
        exit();
    }
    // Verbindung zum Datenbankserver beenden
    $conn->close();
}
 
Hi Splater,

danke für deine Antwort. Ich verstehe nicht genau worauf die hinaus willst. Die beiden Variablen $datefrom and $dateto werden ja in zeile 32,33 (in deinem Post) und dann in der SQL Zeile 54 genutzt. Die verhindern aber nicht, dass nach einem Klick auf "Download" eine Ausgabe auf der Seite erfolgt.
 
Ach es geht um den generellen Inhalt der Seite. Ich bin davon ausgegangen es geht um die Input-Felder, in welchen das Datum für den Report steht.

Also:
Klick auf "Show" => Zeige alle Einträge in der Tabelle
Klick auf "Download" => Speichere in .csv und zeige in der Tabelle keinen Inhalt

Ich kann den Fehler lokal in der Testumgebung nicht reproduzieren.

Tritt der Fehler auch auf, wenn Du den Inhalt
PHP:
elseif($data['submit']=="download"){
        $datefrom=$data['datefrom'];
        $dateto=$data['dateto'];
        $headers=array('spalte1','spalte2');
        $sql="SELECT spalte1, spalte2 FROM table1 WHERE enddate BETWEEN '".$datefrom."' AND '".$dateto."' ORDER BY spalte1";
        export_csv($headers,$sql);  /* Funktion in export_functions.php */
        exit();
    }
testweise gegen ein echo "test"; ersetzt?

Viele Grüße
 
Du meinst alles in der elseif ersetzen?

PHP:
elseif($data['submit']=="download"){
     echo "test";
    }

Dann wird unter dem Fomular einfach "test" ausgegeben, wie ich es erwarten würde. Da in diesem Fall die Ausgabe auf der Seite ja überschrieben wird, tauscht das Problem wahrscheinlich nicht auf.


Hier vielleicht mal die Export-Funktion:
PHP:
function export_csv($headers, $sql)    {
   
    // output headers so that the file is downloaded rather than displayed
    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename=data.csv');
    // Disable caching
    header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1
    header("Pragma: no-cache"); // HTTP 1.0
    header("Expires: 0"); // Proxies
   
   
    // create a file pointer connected to the output stream
    $output = fopen('php://output', 'w');
   
    // clean the output buffer
    ob_clean();
   
    // output the column headings
    fputcsv($output, $headers, ";", '"');
   
    // Connect to database
    $conn = database::getInstance();
    $conn->connect();
   
    $count = 0;
   
    // fetch the data
    if ($rows = $conn->doQuery($sql))    {
   
        // loop over the rows, outputting them
        while ($row = $rows->fetch_assoc()) {
            fputcsv($output, $row, ";", '"');
            ++$count;
        }
       
    }
   
    fclose($output);
    return $count;
}

Ich arbeite zum ersten Mal mit einem CSV Export. Das ob_clean(); in Zeile 16 musste ich rein machen, weil ansonsten noch Teile der Seite (HTML Code) mit in die CSV gelangen und das exit(); (Zeile 7 in deinem vorherigen Post) musst rein, weil sonst der Rest der HTML Seite auch wieder in der CSV gelandet ist. Vielleicht kannst du das Problem reproduzieren, wenn du den CSV Export mit rein machst. Ich kann mir vorstellen, dass das mit irgendwelchen Puffern zusammenhängt, die ich wie beim Export mit dem ob_clean() auch leeren muss.
 
Zurück