Ergebnis 1 bis 18 von 18

Thema: seltsames Verhalten des Select Widgets?

  1. #1
    Contao-Nutzer
    Registriert seit
    13.07.2013.
    Ort
    Nordsachsen
    Beiträge
    130

    Standard seltsames Verhalten des Select Widgets?

    Hallo in die Runde,

    schon seit längerem stoße ich wiederholt auf ein seltsames bzw. inkonsistentes Verhalten des Select-Widgets. Dies äußert sich so, dass bei ids (in der DB) bzw. values (in der options-List), die zwischen 0 und 9 liegen, das Widget aus solchen Daten wie

    tl_source_table
    id tstamp name
    0 1500 Option0
    1 1500 Option1
    2 1500 Option2

    eine option-List generiert, die wie folgt aussieht (der Schwerpunkt liegt hier auf dem string-value)

    HTML-Code:
    <option value="0 Option0">0 Option0</option>
    <option value="1 Option1">1 Option1</option>
    <option value="2 Option2">2 Option2</option>
    ...
    Fügt man nun der table eine id oberhalb von 10 hinzu,

    id tstamp name
    0 1500 Option0
    1 1500 Option1
    1000 1500 Option1000

    so wird die option-List bzw. das option-Array nicht mehr mit einem string-value generiert, sondern mit einem int-value

    HTML-Code:
    <option value="0">0 Option0</option>
    <option value="1">1 Option1</option>
    <option value="1000">1000 Option1000</option>
    Dieses Verhalten scheint immer aufzutreten, egal ob die Optionen mit oder ohne Callback generiert werden. Mir ist es bisher nicht gelungen einen einheitlichen integer value zu erzwingen. Auch nicht unter Verwendung der verschiedenen eval-keys, wie findInSet, includeBlankOption oder isAssociative etc.

    Ist das ein Bug oder ein Feature? Kennt jemand eine Möglichkeit, die Erzeugung von integer-values in der option-List zu erzwingen?

    Beste Grüße.
    Theo

  2. #2
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.109
    Partner-ID
    10107

    Standard

    Wie fügst du diese Options denn zum Widget hinzu?
    » sponsor me via GitHub or PayPal or Revolut

  3. #3
    Contao-Nutzer
    Registriert seit
    13.07.2013.
    Ort
    Nordsachsen
    Beiträge
    130

    Standard

    Entweder ich lasse es Contao selbst machen oder ich verwende einen options.callback.

  4. #4
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.109
    Partner-ID
    10107

    Standard

    Zitat Zitat von theobald Beitrag anzeigen
    Entweder ich lasse es Contao selbst machen
    Wie lässt du das Contao selbst machen? Contao kann ja keine solchen kombinierten Werte erzeugen?


    Zitat Zitat von theobald Beitrag anzeigen
    oder ich verwende einen options.callback.
    Poste deinen options_callback - oder überhaupt mal deinen gesamten Code inkl. DCA (falls es um ein DCA geht).
    » sponsor me via GitHub or PayPal or Revolut

  5. #5
    Contao-Nutzer
    Registriert seit
    13.07.2013.
    Ort
    Nordsachsen
    Beiträge
    130

    Standard

    Hallo Spooky,

    danke für Deine Antwort.

    sicher kann das Contao selber machen. Dazu ist das Widget ja entwickelt worden. Folgendes genügt in einem DCA, um ein komplettes select chosen von Contao selbst generieren zu lassen:

    PHP-Code:
            'type_id' => [
                
    'search'    => true,
                
    'filter'    => true,
                
    'inputType' => 'select',
                
    'foreignKey'=> 'tl_foreign_table.name',
                
    'relation'  => ['type'  => 'hasOne''load'  => 'lazy'],
                
    'eval'      => ['chosen' => true'tl_class' => 'w50'],
            ], 
    Bereits dieses Konstruckt liefert beide o.g. Varianten. Also unter einer id=10 mit string-value und über einer id=10 mit int-value.

    Ein typischer options-Callback sieht bei mir so aus:

    PHP-Code:
        #[AsCallback(table: 'tl_parent_table', target: 'fields.foreign_id.options')]
        
    public function foreignIdOptions(DataContainer $dc): array
        {
            
    $options = [];

            
    $collection MyModel::findAll();

            if (
    $collection) {
                foreach (
    $collection as $item) {
                    
    $options[$item->id] = sprintf("%'.04d "$item->id) . $item->name;
                }
            }

            
    asort($options); // optional

            
    return $options;
        } 

  6. #6
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.109
    Partner-ID
    10107

    Standard

    Zitat Zitat von theobald Beitrag anzeigen
    sicher kann das Contao selber machen. Dazu ist das Widget ja entwickelt worden. Folgendes genügt in einem DCA, um ein komplettes select chosen von Contao selbst generieren zu lassen:

    PHP-Code:
            'type_id' => [
                
    'search'    => true,
                
    'filter'    => true,
                
    'inputType' => 'select',
                
    'foreignKey'=> 'tl_foreign_table.name',
                
    'relation'  => ['type'  => 'hasOne''load'  => 'lazy'],
                
    'eval'      => ['chosen' => true'tl_class' => 'w50'],
            ], 
    Bereits dieses Konstruckt liefert beide o.g. Varianten. Also unter einer id=10 mit string-value und über einer id=10 mit int-value.
    Achso, also du meinst
    HTML-Code:
    <select>
      <option value="1">Lorem</option>
      <option value="2">Ipsum</option></select>
    So wie du es oben beschrieben hattest sah es so aus als hättest du gerne für value und label eine Kombination aus mehreren Tabellenspalten. Das geht von Haus aus nicht.

    Und was genau ist nun das Problem?
    Geändert von Spooky (09.02.2024 um 09:13 Uhr)
    » sponsor me via GitHub or PayPal or Revolut

  7. #7
    Contao-Urgestein Avatar von do_while
    Registriert seit
    15.06.2009.
    Ort
    Berlin | Deutschland
    Beiträge
    3.613
    Partner-ID
    1081
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Was mir dabei auffällt:
    In Contao war es noch nie gut, in Selects einen Wert "0" zu haben, da der Default in der Datenbank auch Null ist (keine Option gewählt).
    Tritt der Effekt auch auf, wenn Du keine 0-Wert-Option hast und trotzdem nur 1 Ziffer?

  8. #8
    Contao-Nutzer
    Registriert seit
    13.07.2013.
    Ort
    Nordsachsen
    Beiträge
    130

    Standard

    @do_while,

    ja danke, das ist mir bewusst, ich nehme das als Workaround, um meine "undefined" oder blankLabels über die Datenhaltung konfigurieren zu können. Aber auch ohne 0 tritt das Problem auf.
    Ich habe mal gelesen, dass es ein php kernel bug sein soll, der seit php 5.1 besteht. Ist das ein Gerücht, oder könnt Ihr das bestätigen?

    @Spookie
    Und was genau ist nun das Problem?
    Nunja, ich weiss nicht, ob ich das alles noch einmal auschreiben soll. Es ist alles in meinem ersten Posting erklärt. Ich versuche mich nochmal kürzer und möglw. klarer zu fassen:

    1. fordere ich ein select-Widget vom System an und fülle es, egal ob mit options-callback oder ohne weitere Hilfe (ich meine damit, ich lasse den DC_TABLE mit dem Widget alles selbst machen), so erhalte ich bei einfachen Daten-Paaren wie (int)id => 1, (string)name => 'option1' eine options-list der Form
    2. <option value="option1">option1</option>
    3. auch dann, wenn ich die $options explizit mit einem Callback erstelle: $options[$record->id] = $record->name;
    4. das geschieht solange die id < 10
    5. wird die id >10 so wechselt die option-Generierung auf <option value="1">option1</option>

    Was ich meine, ist der Unterschied zwischen Punkt. 2 (value ist vom Typ string) und Punkt 5. (value wird zum Typ int). Das habe ich jetz von Contao 4.3 bis 5.3-RC3 so beobachtet.

    Meine Frage ist: Kennit Ihr das auch? Oder ist es möglw. mein Fehler? oder möglw. ein Seiteneffekt oder ein Konfigurationsfehler etc.?

  9. #9
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.109
    Partner-ID
    10107

    Standard

    Zitat Zitat von theobald Beitrag anzeigen
    1. fordere ich ein select-Widget vom System an und fülle es, egal ob mit options-callback oder ohne weitere Hilfe (ich meine damit, ich lasse den DC_TABLE mit dem Widget alles selbst machen), so erhalte ich bei einfachen Daten-Paaren wie (int)id => 1, (string)name => 'option1' eine options-list der Form <option value="option1">option1</option>
    Nein, wenn dann muss es
    HTML-Code:
    <option value="1">option1</option>
    sein.
    » sponsor me via GitHub or PayPal or Revolut

  10. #10
    Contao-Nutzer
    Registriert seit
    13.07.2013.
    Ort
    Nordsachsen
    Beiträge
    130

    Standard

    ok, das denke ich auch, aber Contao generiert bei einer id <10 immer <option value="option1">option1</option>.

    Ich habs in etlichen Projekten von 4.13 bis 5.3 gesehen und sehe es auch gerade vor mir auf dem Bildschirm. Es würde mich auch nicht stören, wenn es nicht eine Exception provoziert. Denn ein value 'option1' lässt sich nicht in das DB-Feld (int)id schreiben. Da knallts dann... Erfasse ich nur einen Datensatz mit id > 10 so läuft das System einwandfrei.

    Das ist strange.

    - - - Aktualisiert - - -

    na vielleicht sollte ich die id = 0 doch weglassen...

  11. #11
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.109
    Partner-ID
    10107

    Standard

    Ja, das wäre seltsam. Ich kann das jedenfalls nicht nachvollziehen. Bei einem DCA Feld mit foreignKey bzw. relation wird immer die Primary Key ID der anderen Tabelle als value benutzt.


    Zitat Zitat von theobald Beitrag anzeigen
    na vielleicht sollte ich die id = 0 doch weglassen...
    Warum hast du überhaupt eine ID mit 0 in der Datenbank? Normale Primary Keys in MySQL Tabellen starten immer mit 1.
    » sponsor me via GitHub or PayPal or Revolut

  12. #12
    Contao-Nutzer
    Registriert seit
    13.07.2013.
    Ort
    Nordsachsen
    Beiträge
    130

    Standard

    Danke! das ist schon mal was. Das deutet auf einen lokalen Fehler bei mir hier hin. Ich teste mal weiter.
    Danke @Spooky!
    Warum hast du überhaupt eine ID mit 0 in der Datenbank? Normale Primary Keys in MySQL Tabellen starten immer mit 1.
    Da hast Du recht. Es ist zumindest nicht ganz "sauber".

  13. #13
    Contao-Nutzer
    Registriert seit
    13.07.2013.
    Ort
    Nordsachsen
    Beiträge
    130

    Standard

    ich bins nochmal. Ich habe jetzt versucht, auf die "saubere" Arbeitsweise umzustellen, indem ich 'includeBlankOption' => true gesetzt habe. Damit generiert Contao selbst folgendes Markup

    HTML-Code:
    <option value="">-</option>
    <option value="1" selected="">Option1</option>
    <option value="2" selected="">Option2</option>
    <option value="3" selected="">Option3</option>
    Sende ich diese Daten mit Formular Speichern an Contao, dann erhalte ich folgende Exception (weswegen ich diese Lösung auch bisher gemieden habe)

    Code:
    An exception occurred while executing a query: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'foreign_id' at row 1
    Das dürfte richtig sein, da ein value="" nicht in ein int() umgewandelt werden kann.

    Warum funktioniert dieses Standardverhalten des DCA nicht?

    Meine Felddefinition sieht so aus:
    Code:
            'foreign_id' => [
                'search'    => true,
                'filter'    => true,
                'inputType' => 'select',
                'foreignKey'=> 'tl_foreign_table.name',
                'relation'  => ['type'  => 'hasOne', 'load'  => 'lazy'],
                'eval'      => ['chosen' => true, 'includeBlankOption' => true, 'blankOptionLabel' => '-', 'tl_class' => 'w50'],
            ],
    Ich verwende kein SQL Key sondern Entities...
    Code:
         #[ManyToOne(targetEntity: ForeignEntity::class)]
         #[JoinColumn(name: 'foreign_id', referencedColumnName: 'id')]
         #[Column(type: 'integer', nullable: false, options: ['unsigned' => true, 'default' => 0])]
         private ForeignEntity $foreign_id;
    Oder muss das Feld vom Typ string sein? Das wäre für eine Fremdschlüssel-Id aber strange...

  14. #14
    Contao-Nutzer
    Registriert seit
    13.07.2013.
    Ort
    Nordsachsen
    Beiträge
    130

    Standard

    Ja tatsächlich! Die Fremdschlüssel-Id muss als varchar abgelegt werden. Dann funktioniert die Select-Box. Es ist erstaunlich!

    Danke!

  15. #15
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.109
    Partner-ID
    10107

    Standard

    Das Problem ist, dass du Entities nutzt, dadurch kann Contao die SQL Definition nicht mehr auslesen und daher auch nicht den korrekten "Leer-Wert" für das jeweilige Feld ermitteln (siehe Widget::getEmptyValueByFieldType()).
    » sponsor me via GitHub or PayPal or Revolut

  16. #16
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.109
    Partner-ID
    10107

    Standard

    Den Foreign Key als String anzulegen wäre falsch. Ich denke du solltest die SQL Definition in das DCA schreiben, wenn du DCAs verwenden willst.
    » sponsor me via GitHub or PayPal or Revolut

  17. #17
    Contao-Nutzer
    Registriert seit
    13.07.2013.
    Ort
    Nordsachsen
    Beiträge
    130

    Standard

    OK! Das ist gut zu wissen. Ich hatte mich bisher darauf ausgerichtet, ab C5 nur noch Entities zu verwenden, da das zukünftig so kommt und die SQL im DCA zeitnah wegfällt...

  18. #18
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.109
    Partner-ID
    10107

    Standard

    Nein, die Verbindung zwischen DCAs und Entities wird aktuell noch nicht unterstützt (wenngleich es auch einige Entwickler so verwenden - mit eben Workarounds aufgrund solcher Probleme). Hier gibt es noch keinerlei Pläne und insofern ist SQL im DCA auch state-of-the-art.
    » sponsor me via GitHub or PayPal or Revolut

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •