Monatliches Archiv: Januar 2014

Joomla 3 Form Field aus Datenbank

Öfters hat man bei der Entwicklung einer Joomla Komponente das Problem dass man eine Benutzerdefinierte Auswalliste (Select-Box) machen möchte. Das folgende Vorgehen was ich beschreiben werde geht sowohl im Backend als auch im Frontend. Als Basis nehme ich an dass eine Komponente schon besteht und diese nun um ein Auswahlfeld erweitert werden soll. Dabei werden wir einen Index haben also einen Value der dann den Wert den wir auswählen darstellt, sowie eine Darstellbare Option für jeden Punkt der Auswahlliste.

Um ein neues Form field unserer Komponente hinzufügen zu können müssen wir im „model“ Verzeichnis unserer Joomla Komponente ein neues Verzeichnis „fields“ erstellen. In dieses Verzeichnis packen wir eine PHP-Datei mit dem namen unseres form Field typs. Für unser Beispiel Feld benutzen wir hier eine Benutzerdefinierte Länderliste. Da Umlaute hier natürlich nicht so Ideal sind nehmen wir als Feld-Typ „laender“. Im ersten Schritt erstellen wir erst ein mal einen Manuellen Listen-Typ.
Also erstellen wir /models/fields/laender.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
// No direct access to this file
defined('_JEXEC') or die;

// import the list field type
jimport('joomla.form.helper');
JFormHelper::loadFieldClass('list');

/**
 * Klasse für das Form Field Länder
 */

class JFormFieldLaender extends JFormFieldList
{

  /**
   * @var string - Feld Typ
   */

  protected $type = 'Laender';

  /**
   * @return array Bezirke
   */

  protected function getOptions() {
    $options[] = JHTML::_('select.option', 1, 'Deutschland');
    $options[] = JHTML::_('select.option', 2, 'Österreich');
    $options[] = JHTML::_('select.option', 3, 'Schweiz');
    # Setze Array zusammen
    $options = array_merge(parent::getOptions(), $options);

    # Gib die fertigen Select optionen zurück
    return $options;
  }
}

In der ersten Zeile finden wir wie gewohnt die Abfrage ob die Datei innerhalb von Joomla aufgerufen wurde. So dass diese Datei Standalone nicht lauffähig ist. Im Anschluss importieren wir die notwendigen Libraries bzw. Klassen.

Um unseren eigenen Feldtyp zu erstellen benötigen wir eine Klasse die sich JFormFieldType (Type durch den eigenen Namen ersetzen) nennt und von JFormFieldList erbt. Dies ist wichtig damit wir das gesamte notwendige Gerüst drum herum automatisch haben. Anschließend legen wir noch die Eigenschaft $type fest. Dabei müssen wir den Namen unseres Feldes nochmals angeben. Hinweis: Der Name den wir hier immer als Type verwenden ist hinterher auch der Feld-Typ im XML-Formular.
In der Funktion getOptions findet nun unsere gesamte Listenzusammensetzung statt. Hier erstellen wir das Array $options noch manuell. Mir geht es nur darum ein Lauffähiges Beispiel zu haben, wir werden dies nachher noch mit der Datenbank koppeln.

Damit unser Feld-Typ auch im Formular eingelesen wird müssen wir in unserer Formular-Beschreibung einen Hinweis auf die Felder einbauen. Das Formular befindet sich für gewöhnlich unter component/models/forms/ und beginnt mit Folgendem code

1
2
3
<?xml version="1.0" encoding="utf-8"?>
<form>
        <fieldset addfieldpath="/components/com_example/models/fields"                >

Hier ersetzen wir addfieldpath durch unseren Pfad, in diesem Fall müssen wir nur den Component-Name auswechseln. Haben wir das getan, können wir dem Formular ganz einfach unser eigenes Feld hinzufügen.

1
2
3
4
5
6
7
8
9
10
<field
  name="datenbankfeld"
  type="laender"
  label="Label"
  description="Form Field Beschreibung"
  message="Form Field, Beschreibung bei Fehlerfall z.B. bei Required"
  class="inputbox"
  required="false"
  default=""
  />

Nun haben wir unser erstes Formularfeld in unsere Komponente integriert. Wenn wir die Komponente jetzt installieren sollte das natürlich jetzt schon funktionieren. Um die Daten von einer Datenbanktabelle auszulesen, gehe ich von einer Tabelle mit dem namen #__example_laender aus in der zwei Spalten definiert sind, einmal die ID und einmal Title für den Ländernamen. Im folgenden müssen wir unsere Klasse die wir als erstes eingefügt haben wie folgt überarbeiten:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php
// No direct access to this file
defined('_JEXEC') or die;

// import the list field type
jimport('joomla.form.helper');
JFormHelper::loadFieldClass('list');

/**
 * Klasse für das Form Field Länder
 */

class JFormFieldLaender extends JFormFieldList
{
  /**
   * @var string - Feld Typ
   */

  protected $type = 'Laender';

  /**
   * Methode um die Bezirke aus der Datenbank auszulesen
   *
   * @return array Bezirke
   */

  protected function getOptions()
  {
    # Hole Datenbankdaten
    $db = JFactory::getDBO();
    # Erstelle einen neuen Query
    $query = $db->getQuery(true);
    # Von welcher Datenbank soll ausgelesen werden
    $query->from('#__example_laender');
    # Welche Spalten sollen ausgelesen werden.
    $query->select('id,title');
    # Den Query als nächstes Abfrageobjekt setzen
    $db->setQuery((string)$query);
    # Objektliste laden
    $messages = $db->loadObjectList();

    # Erstelle ein Array mit Optionen fürs
    # Selectfeld aus der Datenbankabfrage
    $options = array();
    if ($messages)
    {
      foreach($messages as $message)
      {
        # Erstelle die Optionen fürs Selectfeld
        $options[] = JHtml::_('select.option', $message->id, $message->title);
      }
    }
    # Setze Array zusammen
    $options = array_merge(parent::getOptions(), $options);
    # Gib die fertigen Select optionen zurück
    return $options;
  }
}

Ich gehe davon aus dass wir uns schon mit Datenbankabfragen auskennen und ich diese hier nicht erläutern muss. Mit $db->loadObjectList() hole ich eine Objektliste verpackt in einem Array, über dieses ich mi einer foreach iteriere. Als Letzten Punkt fügen wir noch ein entsprechendes Element wie „Bitte wählen“ mit parent::getOptions in das Array ein und verwendenn dieses nun als eigenen Feld-Typ.