Kalle_Worms: Idee gefragt für Massen- Eingabefelder

Hallöle,

ich habe eine Liste mit Artikeln (Spalten) und deren Eigenschaften (Zeilen), etwa so:

Handy 1 Handy 2
            ------- -------
Preis          1,00   49,90
Kamera            J       N
Speicher MB       5       -
...

Nun möchte ich sämtliche Eigenschaften editieren können, es können hunderte von input- Feldern sein. Wie könnte ich die auswerten?

Hatte mal einen ähnlichen Fall, allerdings mit Checkboxen:
echo "<input type='checkbox' name='chkbox[]' value='".$x."-".$y."'>";

Wenn sie aktiviert wurden, wurde im Array chkbox[] z.B. der Wert "10-12" zurückgegeben, Zeile 10, Spalte 12 war dann ausgewählt.

Doch jetzt brauche ich das Value- Feld ja für Inhalte.

Habe im Moment keine Idee, wie der Lösungsansatz aussehen könnte.

Lieben Gruß, Kalle

  1. Hello,

    ich habe eine Liste mit Artikeln (Spalten) und deren Eigenschaften (Zeilen), etwa so:

    Handy 1 Handy 2
                ------- -------
    Preis          1,00   49,90
    Kamera            J       N
    Speicher MB       5       -
    ...

    Nun möchte ich sämtliche Eigenschaften editieren können, es können hunderte von input- Feldern sein. Wie könnte ich die auswerten?

    Willst Du ein Grid aufbauen?
    Leider hat HTML ja kein Dirty-Flag, sodass Du tatsächlich alle Zeilen auf Veränderung prüfen musst.

    1. Regel: nicht ohne Session
    2. Regel: nach Möglichkeit mit Formular-Zertifikat (gegen Doppel-POST)

    Woher kommen die Daten?

    Harzliche Grüße aus http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
    1. Hi, Tom,

      Willst Du ein Grid aufbauen?

      Was ist das? Ein speicherinternes Abbild der Tabelle?

      Leider hat HTML ja kein Dirty-Flag, sodass Du tatsächlich alle Zeilen auf Veränderung prüfen musst.

      Ja, wenn ein Eingabefeld gelöscht wird, fehlt ja dieses Feld in der Rückgabeliste.

      1. Regel: nicht ohne Session

      Ja, brauche ich später, im Moment erstmal die Technik lösen.

      1. Regel: nach Möglichkeit mit Formular-Zertifikat (gegen Doppel-POST)

      ???

      Woher kommen die Daten?

      aus MySQL

      LG, Kalle

  2. Hi,

    Habe im Moment keine Idee, wie der Lösungsansatz aussehen könnte.

    ich habe solche data grids auf verschiedene Art und Weisen realisiert.

    1.) Du kannst es ohne JavaScript machen mit n <form/> Elementen, allerdings kriegst Dus dann nicht XHTML faehig (zumindest schien sich das irgendwie zu beissen)
    2.) Du kommst mit einer <form> und JavaScript
    3.) Du sendest an den Client xml und ein xsl, dann kannst Du auch groessere grids mit vielen dropdownlisten ohne Redundanz (also wenig traffic) darstellen

    Gruss,
    Ludger

    1. Hello,

      3.) Du sendest an den Client xml und ein xsl, dann kannst Du auch groessere grids mit vielen dropdownlisten ohne Redundanz (also wenig traffic) darstellen

      Wenn man mit einem <form> und vielen <input>-Feldern arbeitet, geht das aber auch mit vertretbarem Traffic, wenn man konsquent CSS einsetzt und Klassen verwendet.

      Allerdings finde ich die Variante mit JavaScript hier auch nicht schlecht, wenn man es vorschreiben kann. Man sendet einfach einen dicken Datenblock mit den Feldern, lässt split einmal kreuz und einmal quer drüberlaufen und schon hat man das Javascriptarray mit den Daten. Daraus kann man dann (ggf. in einem Frame) das Input-Grid erzeugen.

      Über ein Dummy-Frame kann man hier sogar die ganze Kommunikation mit dem Server zeitnah betreiben.

      Harzliche Grüße aus http://www.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau
      1. Hi,

        Wenn man mit einem <form> und vielen <input>-Feldern arbeitet, geht das aber auch mit vertretbarem Traffic, wenn man konsquent CSS einsetzt und Klassen verwendet.

        was ist "das"?

        Allerdings finde ich die Variante mit JavaScript hier auch nicht schlecht, wenn man es vorschreiben kann. Man sendet einfach einen dicken Datenblock mit den Feldern, lässt split einmal kreuz und einmal quer drüberlaufen und schon hat man das Javascriptarray mit den Daten. Daraus kann man dann (ggf. in einem Frame) das Input-Grid erzeugen.

        redundanzvermeidend, aber superlangsam und praxisuntauglich.

        Über ein Dummy-Frame kann man hier sogar die ganze Kommunikation mit dem Server zeitnah betreiben.

        Aeeh, roechel, echt, aeeh, ernstgemeint?

        Gruss,
        Ludger

        --
        "Bio ist doof."
  3. wie wäre es, wenn ich den Feldern Namen gebe:
    <input type='text' name='56-40' maxlength=50 size=5 value='99,90'>

    Die Eigenschaft 56 (der Preis) zu Artikel 40 hat den Wert 99,90

    Aber wie kann man in PHP in einer Schleife die zurückgegebenen Namen herausbekommen?

    1. Hello,

      wie wäre es, wenn ich den Feldern Namen gebe:
      <input type='text' name='56-40' maxlength=50 size=5 value='99,90'>

      Das wäre dumm, Daten und Feldbezeichner zu vermischen.

      Schreib Dir eine Funktion, die die Daten entweder in einem Zeilenarray

      $_data = array;

      $_data[1]['vorname'] = 'Thomas';
        $_data[1]['nachname'] = 'Schmieder';
        $_data[1]['wohnort'] = 'Sankt Andreasberg';

      $_data[2]['vorname'] = 'Hans';
        $_data[2]['nachname'] = 'Hinterhuber';
        $_data[2]['wohnort'] = 'Hohenbergen';

      oder besser noch in einem Spaltenarray zur Verfügung stellt.

      $_data = array;

      $_data['vorname'][1] = 'Thomas';
        $_data['vorname'][2] = 'Hans';

      $_data['nachname'][1] = 'Schmieder';
        $_data['nachname'][2] = 'Hinterhuber';

      $_data['wohnort'][1] = 'Sankt Andreasberg';
        $_data[2]['wohnort'][2] = 'Hohenbergen';

      Die Variante mit dem Spaltenarray hat u.a. für HTML den Vorteil, dass man sofort sieht, wieviele Spalten im Grid vorhanden sein müssen. Die <td>'s müssen nämlich, soweit ich ermitteln konnte, für jedes <tr> immer dieselbe Anzahl haben.

      Wenn Du es alleine nicht hinbekommst, schreiben wir gerne zusammen eine Funktion für die Erzeugung des Grids und auch für die Auswertung nach dem POST.

      Harzliche Grüße aus http://www.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau
      1. Hallo, Tom.

        erstmal vielen Dank für deine Mühe.

        Beispiel: Ich habe 2 Spalten mit jeweils 48 Zeilen, macht 96 input- Felder. Zuzüglich submit- Button also 97.

        Die ZAHL 97 kann ich sehen mit
        echo "<p>Anzahl Felder =[".count($_POST)."]</p>";

        Aber
          for ( $i=0; $i<count($art_mrk); $i++ ) {
            echo "<br>".$i.": ".$_POST[$i];
          }
        bringt NICHTS, auch $_POST[$i][0] nicht.

        Wenn ich einen Feldnamen kenne, klappt's aber:
        echo $_POST['56-40'];

        Wenn das SYSTEM den Namen 56-40 kennt, muss ich da doch drankommen ...

        LG, Kalle

        1. Hello,

          Beispiel: Ich habe 2 Spalten mit jeweils 48 Zeilen, macht 96 input- Felder. Zuzüglich submit- Button also 97.

          Die ZAHL 97 kann ich sehen mit
          echo "<p>Anzahl Felder =[".count($_POST)."]</p>";

          Das nützt aber nicht viel.
          Du solltest die Feldnamen bereits auf ein zweidimensionales Array anlegen und außerdem durch Wahl der Namen die Daten von den Steuerfunktionen und von den Controls trennen.

          Daten sind alle Felder, die direkt an die Datenhaltung gebunden sind
          Steuerfunktionen sind z.B. Buttons
          Controls sind alle Felder, die erst noch eine Umsetzung erfordern, um an den Datenwert zu gelangen, der dann wieder an die Datenhaltung gebunden ist.

          Mehr als diese drei Typen konnte ich bisher nicht bestimmen.

          Diese Strukturierung vereinfacht einem aber die Arbeit.
          PHP unterstuützt das durch die Umsetzung der Namen in Strukturen.

          for ( $i=0; $i<count($art_mrk); $i++ ) {
              echo "<br>".$i.": ".$_POST[$i];
            }

          die for-Schleife ist bei Arrays (für diese Aufgabe) schon alnge nicht mehr aktuell.
          Nimm foreach(). das führt zu wesentlich weniger Fehlern. Kein Element wird vergessen und es sit sehr viel schneller.

          Die Felder sollten z.B. lauten:

          <input type="text" name="data[$recno][$field]">

          Ich habe da eine Funktion erstellt, die aus der DB ein Spaltenarray erzeugt:

          <?php    ### fetch_data.php ###

          #------------------------------------------------------------------------------

          function fetch_data_grid
          ( &$error,         # Fehlernummer, 0 für kein Fehler
            $con,            # Connection-Number
            $table,          # Tabellen-Name
            $fieldlist,      # String mit kommaseparierten Feldnamen
            $primary = 'ID', # Name der Spalte mit dem Primary Key (hierfür habe ich auch eine Funktion erstellt)
            $filter = true,  # Filterbedingung
            $offset = 0,     # Offset in der Resultmenge
            $limit = 30      # Anzahl der Datensätze
          )
          {
            if ($error) return $error + 2048;  ## Wenn bereits ein Fehler vorlag, abbrechen

          $sql = "select $fieldlist,$primary from $table where $filter";

          $res = mysql_query($sql, $con);
            if (($error = mysql_errno($con)) > 0) return false;

          $_grid = array();

          while ($_rec = mysql_fetch_assoc($res))
            {
              $id = $_rec[$primary];
              foreach($_rec as $fieldname => $value)
              {
                $_grid[$fieldname][$id] = $value;
              }
            }

          return $_grid;

          }
          #------------------------------------------------------------------------------

          $con = mysql_connect('localhost','thomas','thomas') or die('DB-Server nicht erreichbar');
          $db  = mysql_select_db('thomass',$con) or die('Datenbank nicht erreichbar');

          $error = 0;

          $_grid = fetch_data_grid($error, $con, 'ADRESSE', '*', 'ID_ADRESSE');

          if ($error !==0) echo "<p>Abfragefehler: ".mysql_error($con)."</p>\n";

          echo "<pre>\n";
          echo(htmlentities(print_r($_grid,true)));
          echo "</pre>\n";

          ?>

          Gleich als Testprogramm verpackt. Dum usst nur die relevanten Daten anpassen und kannst Dir angucken, was daraus wird bei Dir.

          Nun kannst Du eine Funktion erstellen, die das Grid erstellt:

          Ich denek noch einen Moment drüber nach und dann poste ich Dir das auch.

          Du könntest ja inzwischen die fetch_data_grid() eigensicher machen. Da fehlen nämlich noch diverse Prüfungen.

          Harzliche Grüße aus http://www.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau
          1. Hello,

            So, hier nun Deine Grid-Funktion:

            function make_grid($_data,$primary,$class='grid')
            {
              if (!is_array($_data)) return false;
              if (!isset($_data[$primary])) return false;

            $grid = '';

            foreach($_data[$primary] as $key => $id)
              {
                foreach($_data as $field => $value)
                {
                  if ($field != $primary)
                  {
                    $grid .= "<input class="$class"\n".
                             "       type="text"\n".
                             "       name="data[$field][$id]"\n".
                             "       size="20"\n".
                             "       value="".htmlentities($_data[$field][$id])."">\n";
                  }
                }
                $grid .= "<br />\n";
              }
              return $grid;
            }

            Nur so als Denkansatz.
            Die passt zu fetch_data_grid.
            $_data ist das Datenarray, dass Du damit aus der Tabelle holst
            $primary ist der Name der Primärschlüsselspalte
            $class ist der Name der CSS-Klasse für Deine Grid-Elemente

            Ggf. musst Du das "\n" hinter dem Input wegnehmen, oder zumindest optional machen, denn sonst bekommst Du den Abstand zwischen den Input-Elementen nicht weg.

            Bau Dir das Ganze in ein <form> und schau Dir an, was nach dem POST auf dem Server ankommt. Das kannst Du leicht, wenn Du als form-action entweder "http://selfhtml.bitworks.de/debug/kontrolle.php" eingibst, oder Dir selber eine Datei aufbaust, in der Du z.B. einfach nur phpinfo(); drinstehen hast.

            Der nächste Schritt wäre dann ja der Aufbau des Update-Statements für die DB.
            Nach Erzeugung des Datengrids aus der Tabelle wird dies in der Session gespeichert und dann erst das Input-Grid an den Client gesandt.

            Wenn jetzt ein Post vom Formular zurückkommt, prüfst Du, ob unter der von Dir mitgesandten Formular-ID Daten in der Session vorhanden sind. Wenn nein, ist es entweder ein Doppelpost (schon abgearbeitet) oder ein Fake.

            Nun gehst Du das Datenarray in der Session Element für Element durch und prüfst, ob die Daten im Post vorhanden sind und ob sie sich geändert haben. Das musst Du für jede Zeile tun. Wenn sich in der Zeile irgendwas geändert hat, wird sie ins Updatestatement aufgenommen, wenn sich nichts geändert hat, lässt Du die Zeile fürs Update unter den Tisch fallen.

            Vergiss nicht, auf magic_quotes_gpc() zu achten (also die Masklierungen ggf. vor dem Vergleich wieder zu entfernen) und den Update-Value mit mysql_[real_]escape_string() zu escapen.

            Harzliche Grüße aus http://www.annerschbarrich.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau
            1. Hi, Tom,

              ich war einen ganzen Tag nicht online. Danke für deine Mühe, ich hab es nicht auf Anhieb verstanden, werde das durcharbeiten und melde mich wieder.

              Lieben Gruß, Kalle

              1. Hi, Tom,

                habe über deiner Lösung gebrütet und im Gefühl gehabt, dass es einfacher gehen muss. Und ich habe es gefunden. Für jedes Feld kann man in der <form> mit einem kleinen Trick doch beliebig viele Werte übergeben. Für jeden zusätzlichen Wert baut man einfach ein <input type='hiddden' ..> dazu:

                echo "<input type='hidden' name='fld[]' value='".$row['mrk_id']."-".$row['art_id']."'>";
                  echo "<input type='hidden' name='vla[]' value='".$row['masz']."'>";  // value alt
                  echo "<input type='text'   name='vln[]' maxlength=50 size=5 value='".$row['masz']."'>";  // value neu

                Nun habe ich ein Array fld[] mit den Feldnamen, ein Array vla[] mit den alten values und ein Array vln[] mit den eventuell neuen values.

                Die Auswertung ist simpel:

                echo "<pre>";
                  for ( $i=0; $i<count($_POST['fld']); $i++ ) {
                    if ( $_POST['vla'][$i] !== $_POST['vln'][$i] ) echo "* "; else echo "  ";
                    echo $i.": ".$_POST['fld'][$i]." / ".$_POST['vla'][$i]." / ".$_POST['vln'][$i]."\n";
                  }
                  echo "</pre>";

                Was hälst du davon ? Immer da, wo der alte und neue Wert differiert und bei obiger Anzeige ein * erscheint, muss ich die Datenbank ändern.

                Dein Vorschlag, die alten Daten in Session- Variablen zu speichern, brachte mich drauf. Also danke nochmal.

                LG, Kalle

                1. Hello,

                  Was hälst du davon ? Immer da, wo der alte und neue Wert differiert und bei obiger Anzeige ein * erscheint, muss ich die Datenbank ändern.

                  Nichts.
                  Denn wenn Deine Applikation vernünftig werden soll, müssen die Daten sowieso in der Sessiondatei gespeichert werden.

                  Harzliche Grüße aus http://www.annerschbarrich.de

                  Tom

                  --
                  Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                  Nur selber lernen macht schlau