Sortierung eines Dropdownwidgets in Symfony ändern (Doctrine)
Geschrieben von skaldrom am 6. July 2009
Frameworks sind toll. Man kann in vielen tausend Zeilen das tun, wozu man früher nur ein paar Statements gebraucht hat… Oder war es umgekehrt? Hier etwas Symfony spezifisches, das mir ein paar gefärbte Haare gekostet hat, weil ich sie mir ausreissen musste.
Das Problem
Es sei gegeben eine dreistufige Hierarchie: Kategorien → Fächer → Kurse. Es sind ganz saubere 1:n-Beziehungen: Jedes Fach gehört zu einer Kategorie und ein Kurs ist genau ein durchgeführtes Fach.
Folgt man dem (wirklich guten) Symfony-Tutorial, so wird an Tag 3 ganz unten gezeigt, wie aus der Tabellendefinition automatisch ein Formular generiert wird. Clevererweise werden für 1:n-Beziehungen Dropdowns generiert.
Wenn ein neuer Kurs generiert wird, so soll man angeben können, was für ein Fach er unterrichtet. Standardmässig werden Fächer wie folgt angezeigt:
- Ein Kategorienkürzel (“I” für Informatik, “A” für Ausdruckstanz (haha), …)
- Einer “Nummer” (normalerweise “01″ bis “15″ oder so)
- Dem Namen des Fachs
Das Fach braucht für seine Darstellung also das Kürzel aus dem Kategorien-Model (bin ich der Einzige der bei Models immer grinsen muss?).
Das generierte Dropdown zeigt die Namen der Fächer falsch und alles Kreuz und Rüben durcheinander an. Ha, nun ist guter Rat teuer.

Lösung
Namen der Fächer
Das geht noch relativ einfach: Jedes Model besitzt eine __toString() Methode, die überschrieben werden kann:
[...]
public function __toString() {
return sprintf('%s %s %s', $this->FreifachNgKategorie->getKuerzel(), $this->getNummer(), $this->getName());
}
[...]
Und tatsächlich:

Sortierung
Ich hätte mir eigentlich gewünscht, für jedes Model eine Defaultsortierung angeben zu können. Aber da nicht Weihnachten ist, werden meine Wünsche nicht erfüllt. Da hilft nur Quellcodestudium und glückliches Zusammenpuzzeln der Doctrine Anleitung, dem Symfony-Doctrine Buch und der API-Dokumentation (scrollen bis Doctrine): Beispiele gibts leider fast keine.
Nungut: Das Formular wird automatisch generiert (lib/form/doctrine/base/), darum sollte hier nur wer was ändern, der per Stunde bezahlt wird und das nach jeder Generierung wieder neu tun kann
. Für uns Andere müssen wir das Choice in der Kinderklasse hacken und eine table_method reinbringen, die die Einträge nach unserem Gusto liefert:
[...]
public function configure() {
$this->setWidget('freifach_id', new sfWidgetFormDoctrineChoice(array('model' => 'FreifachNgFreifach', 'table_method' => 'retrieveFreifachOrderedByCategory')));
}
[...]
Diese table_method muss auch noch codiert werden. Und das in der Tabellenklasse der Fächer (dochdoch, wenn man sich das überlegt ist es ganz logisch *irres_grinsen*).
[...]
function retrieveFreifachOrderedByCategory() {
$q=Doctrine_Query::create()->from('FreifachNgFreifach f')->innerJoin('f.FreifachNgKategorie k')->orderby('k.kuerzel, f.nummer, f.name');
//echo $q->getSql();
return $q;
}
[...]
Toll, und dann klappts auch mit dem Dropdown:

Related Posts
Eingeordnet in Uncategorized | Keine Kommentare »
Jetzt habe ich schon zum X-ten male bei mir dasselbe Muster entdeckt, und da ich überzeugt von meinem absoluten Durchschnittlichkeit bin extrapoliere ich frech → Vielleicht benehmen sich ja andere Humanoide gleich wie in folgendem, öfters mal auftretenden Szenario:
Diese Kampagne hat sehr geheimnisvoll begonnen. Es wurden
Widgets are little miniapplications which show data in a clearly arranged way or perform a more or less simple task for the user. Widgets are present on Windows Vista, Mac, iPhone and also in a webbased form for