Checkboxen in eigener EXT

  • ÁndreMansfeld ÁndreMan...
    Jedi-Meister
    0 x
    341 Beiträge
    0 Hilfreiche Beiträge
    21. 07. 2006, 10:59

    Hallo liebe Helfer,
    hab da ein Problem mit Checkboxen und den Einträgen in der DB. In meiner eigenen EXT. gibts eine Auswahl per Checkboxen. ich habe mich für:
    "Checkbox, 10 boxes in two rows (max) 10 checkboxes" entschieden. Die darin enthaltenen Daten sollten eigentlich als Zahlen in die DB geschrieben werden, damit ich später in einem Formular eine Suche starten kann. Was aber passiert ist folgendes: Wenn ich nur eine Auswahl treffe, dann erhalte ich in der DB je nach Eingabe folgende Werte:
    Checkbox 1 = 0
    Checkbox 2 = 2
    Checkbox 3 = 4
    Checkbox 4 = 8
    Checkbox 5 = 16
    Checkbox 6 = 32
    Ok, das alleine wäre nicht so tragisch, weil ich ja mein Formular dementsprechend anpassen könnte. ABER
    Wenn ich im BE [b]zwei[/b] Auswahlen treffe z.B. Checkbox 2 und die 5, dann erhalte ich in der DB die Zahl 18 (also die beiden wurden addiert).
    Das sollte nicht so sein ;-), weil ich ja jetzt keine spezifische Suche mehr machen kann.

    Also meine Frage: Wie "erkläre" ich dem Kickstarter
    das er die Einträge getrennt (z.b. ; oder , ) in die DB schreibt?
    Oder ist die Wahl der Checkboxen nicht die richtige. Leider funktionieren alle Anderen nur mit einer Auswahl. Ich benötige aber eine mehrfach Auswahl.

    Hier mal der Code des TCA

    1. "art" => Array (
    2. "exclude" => 1,
    3. "label" => "LLL:EXT:as_locations/locallang_db.xml:tx_aslocations_main.art",
    4. "config" => Array (
    5. "type" => "check",
    6. "cols" => 4,
    7. "items" => Array (
    8. Array("LLL:EXT:as_locations/locallang_db.xml:tx_aslocations_main.art.I.0", ""),
    9. Array("LLL:EXT:as_locations/locallang_db.xml:tx_aslocations_main.art.I.1", ""),
    10. Array("LLL:EXT:as_locations/locallang_db.xml:tx_aslocations_main.art.I.2", ""),
    11. Array("LLL:EXT:as_locations/locallang_db.xml:tx_aslocations_main.art.I.3", ""),
    12. Array("LLL:EXT:as_locations/locallang_db.xml:tx_aslocations_main.art.I.4", ""),
    13. Array("LLL:EXT:as_locations/locallang_db.xml:tx_aslocations_main.art.I.5", ""),
    14. Array("LLL:EXT:as_locations/locallang_db.xml:tx_aslocations_main.art.I.6", ""),
    15. Array("LLL:EXT:as_locations/locallang_db.xml:tx_aslocations_main.art.I.7", ""),
    16. Array("LLL:EXT:as_locations/locallang_db.xml:tx_aslocations_main.art.I.8", ""),
    17. Array("LLL:EXT:as_locations/locallang_db.xml:tx_aslocations_main.art.I.9", ""),
    18. ),
    19. )
    20. ),
    21. ),

    Und hier die Abfrage in der EXT. die zur Ausgabe führt:
    1. Die Funktion von hier
    2. ---------------------------
    3. function getItems($uid=false,$searchParams=array(),$limit=false,$start=0){
    4. /*
    5. $this->config["pid_list"] = trim($this->cObj->stdWrap($this->conf["pid_list"],$this->conf["pid_list."]));
    6. $this->config["pid_list"] = $this->config["pid_list"] ? implode(t3lib_div::intExplode(",",$this->config["pid_list"]),",") : $this->cObj->data["pages"];
    7. list($pid) = explode(",",$this->config["pid_list"]);
    8. $this->pid = $pid;
    9. */
    10. $singleStr = '';
    11. if($uid){
    12. $sqlAd = "WHERE uid='$uid' ";
    13. } else if(count($searchParams)>0) {
    14. $sqlAds = array();
    15.  
    16. while(list($i,$w)=each($searchParams)){
    17. if($w){
    18. --------------------------
    19. Hier kommen andere Abfragen
    20. --------------------------
    21. }
    22. -------------
    23. bis hier ist nicht so wichtig (da funktioniert alles
    24. aber ab hier
    25. ------------------------------------------------
    26.  
    27. } else if($i=='art'){
    28. switch($w){
    29.  
    30. case 1:
    31. $sqlAds[] = "$i ='1' ";(würde ich gegebenfalls durch 2,4,8,16,32 austauschen)
    32. break;
    33. case 2:
    34. $sqlAds[] = "$i ='2' ";
    35. break;
    36. u.s.w.
    37. u.s.w.
    38. ------------------------------
    39. }
    40. } else {
    41. $sqlAds[] = " $i = '$w' ";
    42. }
    43. }
    44. }
    45. if(count($sqlAds)>0){
    46. $sqlAd = "WHERE ".join(" AND ", $sqlAds);
    47. }
    48. }
    49. if($limit){
    50. if(!$start){
    51. $start=0;
    52. }
    53. $sqlAd .= "LIMIT $start,".$this->CONFIG['maxRows'];
    54. }
    55. $query = "SELECT * FROM tx_aslocations_main $sqlAd ";
    56. // echo $query.'<hr />';
    57.  
    58. $res = mysql(TYPO3_db,$query);
    59. $out = array();
    60. while( $row = mysql_fetch_assoc($res) ){
    61. $out[]=$row;
    62. }
    63. return $out;
    64. }

    Nochmal zur Erklärung des obigen Codes der pi:
    In der Extension sind mehrere Auswahlkriterien (alle aber mit Selectorbox)
    den Code habe ich hier weggelassen, weil das alles funktioniert.
    Nur bei der Mehrfachauswahl der Tabelle 'art' klappts natürlich nicht.

    Hat einer einer Tipp dazu??

    Andreas


  • 1
  • steffenk steffenk
    Obi-Wan Kenobi
    0 x
    4666 Beiträge
    0 Hilfreiche Beiträge
    21. 07. 2006, 11:09

    Du brauchst das Rad nicht neu erfinden - das Bit-Schreiben reicht ja aus, auch bei Mehrfachauswahl.
    Du musst nur die entsprechende Routine zum Auslesen schreiben.

    Ein kleiner Ansatz:

    1. function Array2Dual($v) {
    2. $res=0;
    3. if(count($v)>0) {
    4. foreach($v as $key=>$val) {
    5. $res+=pow(2,$key);
    6. }
    7. }
    8. return $res;
    9. }
    10. function Dual2Array($d) {
    11. $ret=array();
    12. for($i=0;$i<16;$i++) {
    13. $ret[$i]= ($d & pow(2,$i)) ? 1 : 0;
    14. }
    15. return $ret;
    16. }

  • ÁndreMansfeld ÁndreMan...
    Jedi-Meister
    0 x
    341 Beiträge
    0 Hilfreiche Beiträge
    21. 07. 2006, 11:20

    Danke, :o
    jetzt weiß ich was ich am WE mache!!!!!
    Ich werde mich damit auseinandersetzen.
    Gebe dir Bescheid
    Andreas

  • ÁndreMansfeld ÁndreMan...
    Jedi-Meister
    0 x
    341 Beiträge
    0 Hilfreiche Beiträge
    25. 01. 2009, 20:59

    Hallo Freunde,
    der Post ist zwar schon fast 3 Jahre alt, aber ich möchte ihn doch nochmal anschubsten.
    Danke steffenk für deinen Ansatz. Ich habs damals nicht hinbekommen und behalf mir mit Single Checkboxen.
    Ich habe es am diesem WE nochmal aufgegriffen, weil ich jetzt schon mehr Erfahrung (leider noch nicht genug) mit PHP/SQL habe.
    Mit dem nachfolgenden Code konnte ich meine Extension dazu überreden, mir ein Array zu erzeugen, in dem die einzelnen Bits dargestellt werden. Ich habe mir das durch einen debug ausgeben lassen. Mein Array $ret ist also schon vorhanden.
    Ich habe das mit dem etwas abgewandelten Dual2Array von steffenk erzeugt.
    Dieses Array möchte ich jetzt gerne wieder den Eingaben zuweisen.
    Also BIT 1 = 1 oder 0 (true or false)
    Also BIT 2 = 1 oder 0 (true or false)
    ect.
    Auf meinen Markern sollen dann die Ausgaben weiterverarbeitet werden.
    Ich habe es aber leider nicht hinbekommen, dass ich die Bitwerte meinen Markern zuweisen konnte, Irgend etwas mache ich da völlig falsch o.O .

    Hier mein Code (welcher innerhalb einer Whileschleife die Marker ansprechen soll.

    1. // Den addierten Wert der Checkboxen aus der DB Tabelle->Spalte holen
    2. $cbwert = $row['tx_feuserext_dienstleistungen']; // <- ist die Spalte mit dem Wert
    3.  
    4. $ret=array(); // Ein Array für die Werte erzeugen
    5. for($i=0;$i<7;$i++) { // Die Bits durchgehen und für jedes Bit den Wert (0 oder 1) ermitteln
    6. $ret[$i]= ($cbwert & pow(2,$i)) ? 1 : 0; // Das Array ausgeben
    7. }
    8. t3lib_div::debug($ret,'RET'); //<- Der Debug liefert eine genaue Ausgabe des Arrays ($ret)
    9.  
    10. // Bis hier ist alles OK (DEBUG liefert ein richtig gefülltes Array)
    11.  
    12. // Das will noch nicht so richtig!!!!!
    13. $ausgabe = array($ret); // Hier hole ich erneut die Werte aus dem Array ($ret) von oben!
    14. foreach($v as $key=>$val) {
    15. $res+=pow(2,$key);
    16.  
    17.  
    18.  
    19. ###'MARKERBIT1'### =
    20. ###'MARKERBIT2'### =

    Anbei die DEBUG Ausgabe (Checkboxen 2 und 3 wurden im BE angehakt)
    [img]http://typo3.stadelmann-webservice.de/fileadmin/ret.jpg[/img]

    Hat jemand vielleicht nochmal so einen kleinen Schubser,
    wie ich die Einzelteile des Arrays als Marker ansprechen kann. #paralyzed#

  • ÁndreMansfeld ÁndreMan...
    Jedi-Meister
    0 x
    341 Beiträge
    0 Hilfreiche Beiträge
    26. 01. 2009, 13:10

    BINGO!
    Ich habs ... und für Alle die es interessiert!
    Ich bekomme eine Ausgabe von Mehrfach-Checkboxen folgendermaßen ausgegeben.

    1. // Den addierten Wert der Checkboxen aus der DB Tabelle->Spalte holen
    2. $cbwert = $row['tx_feuserext_dienstleistungen']; // <- ist die Spalte mit dem Wert
    3.  
    4. $ret=array(); // Ein Array für die Werte erzeugen
    5. for($i=0;$i<7;$i++) { // Die Bits durchgehen und für jedes Bit den Wert (0 oder 1) ermitteln
    6. $ret[$i]= ($cbwert & pow(2,$i)) ? 1 : 0; // Das Array ausgeben
    7. }
    8. $ausgabe = $ret;
    9.  
    10. $markerArray['###BIT1###']= $ret[0];
    11. $markerArray['###BIT2###']= $ret[1];
    12. $markerArray['###BIT3###']= $ret[2];
    13. $markerArray['###BIT4###']= $ret[3];
    14. $markerArray['###BIT5###']= $ret[4];
    15. $markerArray['###BIT6###']= $ret[5];
    16. $markerArray['###BIT7###']= $ret[6];
    17. //t3lib_div::debug($ausgabe);

    Zur Erklärung:
    Zuerst hole ich mir den Wert der Summe aus dem Checkboxfeld mit dem Code aus der Zeile 2.
    Dann (Danke steffenk) wandele ich diesen Wert wieder in die einzelnen BITWERTE (0 oder 1) zurück und erhalte somit ein Array in dem jeder BIT (also 0,1,2,4,8,16 ect.) mit 1 oder 0 drinsteht(je nach dem was man eben angehakt hat). Schön im DEBUG zusehen, wenn man das Array debug t :p

    Und jetzt das was mich die ganze Zeit aufgehalten hat!!!
    Ich habe in einem Array immer die Möglichkeit auf einzelne Reihen des Arrays zuzugreifen, also kam mir dann der Geistesblitz.
    Weise doch einfach jeder Reihe einen Marker zu! indem ich an die Ausgabe das[] dranhänge mit der entsprechenden Zeile.
    Wichtig ist noch! (Denke ich zumindest)
    In Zeile 5 steht $i<7 . Die 7 steht für die Gesamtzahl der Checkboxen
    Wahrscheinlich kann man das auch mit einem Count vorher als Variabele aufrufen.

    Und der Code steht innerhalb der Whileschleife der Ausgabe. Man kann ihn also einfach vor den MARKER der Checkboxen schreiben.
    Voila!

    Ich werde das noch etwas verfeinern, denn wir wollen ja reele Werte haben.
    Ich denke da entweder an ein IF vor jedem Marker mit einen reelen Wert als Ausgabe, wenn die Zahl 1 ist, oder an eine CASE Funktion.
    Ich werde es dann noch posten, denn dieses Thema wird nicht so oft behandelt(sonst hätte ich nicht so lange gebraucht).

    Soweit erstmal...

    Lieben Gruß Andreas

  • ÁndreMansfeld ÁndreMan...
    Jedi-Meister
    0 x
    341 Beiträge
    0 Hilfreiche Beiträge
    26. 01. 2009, 13:51

    Also das ist nicht die eleganteste Lösung, aber ich habe es jetzt so gemacht!

    1. if(($ret[1])==1){ // <- Wenn die Checkbox aktiviert
    2. $markerArray['###DEIN_MARKER###']= 'Dein_TEXT/'; //<- ersetze den Marker mit 'Deinem Text'
    3. } else { // <- wenn nicht ( also 0)
    4.  
    5. $markerArray['###DEIN_MARKER###']= ''; // <- lasse den Marker leer.
    6.  
    7. }

    auch könnte man das dann grafisch lösen (also ein Bildchen für eine Checkbox o.ä) mit
    1. if(($ret[1])==1){ // <- Wenn die Checkbox aktiviert
    2.  
    3. $markerArray['###DEIN_MARKER###']= $this->cObj->fileResource("fileadmin/checkboxyes.gif"); //<- ersetze den Marker mit dem YES GIF
    4.  
    5. } else { // <- wenn nicht ( also 0)
    6.  
    7. $markerArray['###DEIN_MARKER###']= $this->cObj->fileResource("fileadmin/checkboxno.gif"); // <- ersetze den Marker mit dem NO GIF
    8.  
    9. }

    Wenn ichs komplett fertig habe, dann werde ich nach einer "kürzeren" Variante suchen.

    Bis dann..
    Andreas


  • 0 x
    19. 08. 2009, 14:32

    Hi!

    Ich hänge da an demselben Problem.

    Mein Stand:
    -Eigene FE Extension
    -Formular im FE welches drei Checkboxen (value= 0,1,2) enthält

    Wenn ich nun z.B. Box 1 & 2 (value 0 + 2 = 2 in der DB) anklicke,
    wird im BE, wenn ich mir den Datensatz anschaue die Checkbox Nummer zwei (eigentlich value 1) angekreuzt.

    Was ist da los?

    Und wo muss ich die hier beschriebenen Ansätze integrieren? In der tca.php? in meiner ...pi1.php???

    LG

    Jafix

  • ÁndreMansfeld ÁndreMan...
    Jedi-Meister
    0 x
    341 Beiträge
    0 Hilfreiche Beiträge
    18. 09. 2009, 13:42

    Sorry, wurde nicht per Mail informiert, das du was geschrieben hast!
    Hast du es lösen können?


  • 0 x
    18. 09. 2009, 14:54

    Hat sich leider noch nicht erledigt... Hättest du denn einen Ansatz für mich???

  • ÁndreMansfeld ÁndreMan...
    Jedi-Meister
    0 x
    341 Beiträge
    0 Hilfreiche Beiträge
    18. 09. 2009, 18:53

    Ich hänge heute selber wieder an diesem Thema und beim Googlen bin ich da eben auf meinen eigenen Post gestoßen :-)
    Deswegen konnte ich auch erst heute antworten :-)

    Ok, zurück zum Thema. Wie ich es gemacht habe steht ausführlich in den Posts, also code ich es nicht nochmal komplett, aber nochmal zum Verständnis.
    Nach dem Eintragen von Einem oder mehreren Werten steht ja eine Zahl in der DB.

    Was ich mache ist folgendes:
    In der _pi meiner eigenen Extension hole ich mir diese Zahl und gebe ihr die Variable ($cbwert).

    Das Script

    1. #
    2. $ret=array(); // Ein Array für die Werte erzeugen
    3. #
    4. for($i=0;$i<7;$i++) { // Die Bits durchgehen und für jedes Bit den Wert (0 oder 1) ermitteln
    5. #
    6. $ret[$i]= ($cbwert & pow(2,$i)) ? 1 : 0; // Das Array ausgeben
    7. #
    8. }
    9. #
    10. $ausgabe = $ret;

    nimmt diese Zahl und erzeugt mir ein ARRAY , in dem für jede Checkboxvariante ein eigenes array[] erzeugt wird.

    Somit steht als Ausgabe dann z.B.

    1. $markerArray['###BIT1###']= $ret[0];
    2. $markerArray['###BIT2###']= $ret[1];
    3. ...

    Genau gesagt ersetze ich den Marker mit dem Wert, welcher in $ret[0]steht.

    Weil wir das Array oben ja aufgelöst haben, steht dort entweder eine 0 oder eine 1.
    Das wiederum sagt mir dann ob diese Checkbox angeklickt ist (also 1) oder nicht (also 0).

    Mit den Codes aus dem anderen Post habe ich dann nur die FE Ausgabe etwas verschönert.

    Also wenn $ret[o]= 1 dann Marker durch (irgendetwas) ersetzen.
    Das irgendetwas ist zum Beispiel 'JA' oder ein IMG oder eben nur die Zahl 1.

    Wie die Formel oben funktioniert ist reine Mathematik :-)
    Den ersten Teil verstehe ich so ziemlich.

    1. $ret[$i]= ($cbwert & pow(2,$i))

    $ret[$i] erzeugt eine Ausgabe für ein Array.
    Das erste $i ist 0 und wird potenziert. Danach geht das Script automatisch zum zweiten Value u.s.w..
    Das macht das

    1. for($i=0;$i<7;$i++)

    Somit liefert
    $ret[0]FALSE ergibt sich aus $cbwert(0) und $i hoch 2 = 0
    $ret[0]TRUE ergibt sich aus $cbwert(1) und $i hoch 2 = 2

    $ret[1]FALSE ergibt sich aus $cbwert(0) und $i hoch 2 = 0
    $ret[1]TRUE ergibt sich aus $cbwert(2) und $i hoch 2 = 6

    $ret[2]FALSE ergibt sich aus $cbwert(0) und $i hoch 2 = 0
    $ret[2]TRUE ergibt sich aus $cbwert(4) und $i hoch 2 = 20

    $ret[3]FALSE ergibt sich aus $cbwert(0) und $i hoch 2 = 0
    $ret[3]TRUE ergibt sich aus $cbwert(8-) und $i hoch 2 = 72

    und so weiter ....
    Somit erhalte ich immer ein True oder False und die frage ich halt ab.

    Es gibt auch die umgekehrte Sache mit dem Auslesen aus dem $cbwert in das Array, so das dann dort die Ausgabe aufgrund der Zahl erfolgt.
    Das ist das was mich gerade beschäftigt!
    Vielleicht kann mir da jemand auf die Sprünge helfen.

    Folgendes Szenario:
    Ich habe z.B. [0]auf 1 gecheckt und [1]auf 1 gecheckt und 2 auf[1]gecheckt, dann steht in der DB 7( also 1 + 2 + 4 )
    Nun muß ich in einem Formular auf eines der Felder suchen, also schreibe ich folgendes.
    Grundsätzlich gibts ein Suchresultat, wenn $suche mit $eintrag übereinstimmt.
    Also

    1. if($suche == $eintrag){
    2. $ausgabe = ......

    Ich möchte nun nach Checkbox 3 ist angeklickt suchen!

    Ich vergebe also zunächst eine Variable für den Suchwert und für die Spalte aus der Tabelle.
    $suchewert ist das Array mit dem Suchwert
    $eintrag ist die Tabellenspalte

    Also $suchwert = 4 ist TRUE wenn Bestandteil im $eintrag #paralyzed#

    1. if($suche=='$eintrag') {
    2.  
    3. if($suchwert==1){
    4. $ausgabe = " $suche = '1' "; // TRUE
    5. }else if ($suchwert==2){
    6. $ausgabe = " $suche = '2' "; // TRUE
    7. u.s.w .......

    Das funktioniert natürlich nur, wenn [b]nur eine[/b] Checkbox angeklickt ist.

    Jetzt müßte ich das mit den Potenzen in der Zahl aber berechnen #angry#
    Und hier setzts aus.
    Wenn ich in meinem Beispiel (Zahl 7) jetzt wissen möchte, ob Checkbox 3 angeklickt war, dann müßte ich das ja in einer Art Einschlußverfahren machen, denn die Zahl 7 ist ja nur möglich, wenn die Checkbox 3 angeklickt war. Jede andere Kombination der Checkboxen bringt ja ein anderes Ergebnis. Also ist jede Ergebniszahl ja auf eine einzige Kombination zurückzuführen ( Ok, dass ist der Sinn :-) ).
    Aber wie lautet denn dafür die Berechnung der Suche auf eine Zahl (hier die Checkbox 3 also Wert -> 4?
    Wörtlich gecoded würde ich sowas wie:

    Checkbox 3 muß wohl angeklickt sein weil,
    $suchwert (BERECHNUNG/FORMEL) == In der KOMBINATION für 7 enthalten.

    Sorry für die banale Ausführung, aber anders weiß ich nicht, wie ich das erklären kann.
    Geht das überhaupt mit einer einzigen Zeile, oder muß ich tatsächlich erst das Array auslesen und dann auf Wahrheit prüfen?

    Würde mich auch über einen Anstoß freuen...

    Andreas

    [/code]

  • 1