• Jeder User im Forum verpflichtet sich zur Akzeptanz und zur Einhaltung dieser Regeln:
    1. Umgangston
      Ein angemessener höflicher Umgangston, ohne Beleidigungen, Beschimpfungen und aggressive Postings ist für jedes Mitglied Pflicht.
    2. Beiträge
      Jedes Mitglied sollte sich bemühen nur sinnvolle Beiträge zum Thema zu posten. Dabei ist unbedingt vorher zu prüfen, ob das Thema vorher schon einmal diskutiert wurde und daher fortgesetzt werden kann
      • Suchfunktion benutzen!
      • offizielle Doku lesen!
    3. Haftung
      Jeder Beitragsersteller übernimmt die alleinige Verantwortung seiner Inhalte.
    4. Werbung
      Wir erlauben keine Beiträge, Signaturen, Private Nachrichten oder eMails an Benutzer, die Werbung enthalten. Ausgenommen
      sind Stellengesuche /-angebote, welche ausschließlich im Forum "Stellengesuche" veröffentlicht werden dürfen.
    5. Verstöße
      Regelwidrige Beiträge sollten dem Team gemeldet werden. Nach deren Überprüfung werden wir schnellstmöglich
      entsprechend handeln.
    6. Authorität
      Den Anweisungen der Team-Mitglieder (Administratoren und Moderatoren) sind in diesem Forum Folge zu leisten.
      Bei Fragen oder Beschwerden bitte an diese wenden.
    Wir möchten Euch darauf aufmerksam machen, dass es bei Verstößen gegen einen oder mehreren der oben genannten
    Punkte dem Team frei steht entsprechend zu handeln. Dies kann z.B. das Löschen eines Beitrags, das Ausschliessen bzw.
    Sperren von Mitgliedern oder aber lediglich eine Verwarnung sein.

    In diesem Zusammenhang sollte erwähnt werden, dass das Forum automatisch die IP-Adresse jedes Beitrag-Erstellers
    speichert. Bei schweren Vergehen, behalten wir es uns vor, die IP-Adresse zur Strafverfolgung weiterzugeben.
  • Willkommen im Zend Framework Forum

    ZF1 Zend Framework 1 + ZF2 Zend Framework 2

    Das Zend Framework Forum ist seit 2006 die erste Anlaufstelle für Zend Framework Entwickler in Deutschland. Mit über 70.000 Beiträgen und einer steigenden Nutzerzahl bietet das Forum hilfreiche Themen und ZF-Tutorials für professionelle Entwickler, fortgeschrittene Programmierer sowie Zend Framework Einsteiger.
    Wenn dies Dein erster Besuch in der Zend Framework Community ist, lies bitte zuerst die Hilfe - FAQ durch. Du musst Dich registrieren, bevor Du Beiträge verfassen kannst. Klicke oben auf 'Registrieren', um die Registrierung zu starten. Du kannst auch jetzt schon Beiträge lesen. Hier im Forum findest Du die Zend Framework Hilfe, die Du suchst!

    Grüße an alle Zend Framework Entwickler. Das Team vom Zend Framework Forum!

    Drupal Agentur

Parameter für Fieldset

chicorelli

New member
Hallo,

ich arbeite mich derzeit in das Zf3 ein. Ich versuche mich gerade an den Fieldsets, da ich auch erstmals mit den FormCollections arbeite. Leider ist es mir noch ein Rätsel, wie man einem Fieldset Parameter übergeben kann (für Ein Select-Element).

Für ein normales Select-Element, welches in einer Form angelegt wird, überhaupt kein Problem (einfach mit einer FormFactory Daten mittels set...()-Funktion Daten einschleusen):

PHP:
     $this->add(
                [
                        'type'       => Select::class,
                        'name'       => 'team',
                        'attributes' => [
                                'class' => 'form-control',
                        ],
                        'options'    => [
                                'value_options' => $this->teamOptions,
                                'label'         => 'Team',
                        ],
                ]
                );
Nun möchte ich das Formular aber etwas kapseln und Fieldsets einsetzen (auch um später eine FormCollection zu erzeugen):

PHP:
class TeamFieldset extends Fieldset implements InputFilterProviderInterface
{
    public function __construct()
    {
        parent::__construct('team');

        $this->setHydrator(new ClassMethodsHydrator());
        $this->setObject(new TippTeamEntity());
    }
    
    public function init() {
        
        $this->add([
                'name' => 'team',
                'type'       => Select::class,
                'options' => [
                        'value_options' => $options, // $options soll Daten beinhalten! Wie übergeben?
                        'label' => 'Name of team',
                ],
                'attributes' => [
                        'required' => 'required',
                ],
        ]);
    }
In einem weiteren Fieldset oder auch Form möchte ich nun das Fieldset nutzen, aber es auch mit Daten füttern.
PHP:
$this->add ( [ 
                'type' => TeamFieldset::class,
                'name' => 'team',
                'options' => [ 
                        'label' => 'Team',
                ] 
        ] );
Da ich ja keine direkte Instanz erzeuge, sondern das Objekt im Zf3 durch den Eintrag 'type' => TeamFieldset::class erzeugt wird, fällt das Nutzen des Konstruktors wohl weg. Bei einer Form übergebe ich Daten in einer FormFactory mittels set.....()-Funktion. Ähnliches benötige ich jetzt für die Fieldsets. Muss man hier auch mit Fieldset-Factorys arbeiten, wenn überhaupt möglich? Praktisch wäre natürlich, wenn die Daten in dem Array der add() - Funktion übergeben werden. Damit hatte ich aber keinen Erfolg:

PHP:
$this->add ( [ 
                'type' => TeamFieldset::class,
                'name' => 'team',
                'options' => [ 
                        'label' => 'Team',
                        'teamOptions' => ['Test1','Test2'], 
                ] 
        ] );
Ich hoffe ich konnte mein Problem darstellen und freue mich auf eine Antwort.

Grüße
 

Kaiuwe

Super-Moderator
Willkommen im Forum! :)
Praktisch wäre natürlich, wenn die Daten in dem Array der add() - Funktion übergeben werden.
Warum unbedingt direkt beim Hinzufügen? Danach reicht doch bestimmt auch. ;)

Wenn du ein Element dem Formular hinzugefügt hast, dann kannst du dies auch wieder vom Formular holen. Jetzt kannst du immer noch die Methode „setValueOptions“ ausführen.
Das Gleiche gilt für das „Collection“-Element. Hier holst du nur zuerst das Zielelement („targetElement“). Ist dies ein „Fieldset“, dann muss du noch von diesem das „Select“-Element holen. Dann kannst du die Methode „setValueOptions“ ausführen.

Damit hatte ich aber keinen Erfolg:
PHP:
$this->add ( [ 
                'type' => TeamFieldset::class,
                'name' => 'team',
                'options' => [ 
                        'label' => 'Team',
                        'teamOptions' => ['Test1','Test2'], 
                ] 
        ] );
Nein, nicht raten!
 

chicorelli

New member
Vielen Dank für die Willkommensgrüße :).

...und danke für die Tipps. Die Funktion setValueOptions erfüllt ihren Zweck total...muss nicht beim Hinzufügen initialisiert werden. Ich habe nur noch das Problem mit Collections. Du meintest ich muss mir das "targetElement" holen (was ja in der Regel mehreren Objekten entspricht).

PHP:
$this->add([
                'type' => Element\Collection::class,
                'name' => 'results',
                'options' => [
                        'label' => 'Results',
                        'count' => 2,
                        'should_create_template' => true,
                        'allow_add' => true,
                        'target_element' => [
                            'type' => ResultFieldset::class,
                        ],
                ],
        ]);
Collection holen -> Hier kann ich mir dann über getOptions zwar den typ des targetElements holen, ich muss aber an die Elemente kommen. Evtl. kann es ja auch passieren, dass man nicht jedes Element der Collection mit den gleichen Werten darstellen möchte.
PHP:
$this->get('results')->getOptions());
Auch die Funktion getTargetElement(), welche die Collection bereit stellt, erscheint mir noch etwas rätselhaft. Mittels var_dump() konnte ich hier durch das Ändern von 'count' => 2 auf 'count' => 20 nicht wirklich mehr Daten feststellen. Obwohl mir getCount() anscheinend die korrekte Anzahl an Items ausgibt.

Definition ResultFieldset:
PHP:
$this->add ( [ 
                'type' => TeamFieldset::class,
                'name' => 'team',
                'options' => [ 
                        'label' => 'Team',
                ] 
        ] );
...
...
Ich muss nun also von meiner Collection auf alle Items (ResultFieldsets) zugreifen welches ein TeamFieldset beinhaltet, welches das SelectElement enthält. Ich hab da folgendes versucht:

PHP:
foreach ($this->get('results')->getTargetElement() as $resultFieldset)
{
        $resultFieldset->get('team1');
}
Funktionierte aber nicht da getTargetElement() hier nicht so funktioniert wie ich es erwarte. Ich hätte gedacht, dass die Schleife genau 2x durchlaufen wird, da meine Collection 2 Einträge besitzt. Es wird allerdings 4x durchlaufen (da das ResultFieldset 4 Elemente besitzt).

Irgendwie mache ich es mir wohl zu kompliziert?
 

Kaiuwe

Super-Moderator
Funktionierte aber nicht da getTargetElement() hier nicht so funktioniert wie ich es erwarte. Ich hätte gedacht, dass die Schleife genau 2x durchlaufen wird, da meine Collection 2 Einträge besitzt. Es wird allerdings 4x durchlaufen (da das ResultFieldset 4 Elemente besitzt).
Schau mal genau auf den Methodennamen: es heißt „getTargetElement“ – ohne „s“ am Ende – also Einzahl!

Das Zielelement existiert nur einmal und durch die Angabe von „count“ wird es zweimal ausgegeben. Also nichts mit 2 Einträgen oder zwei Elementen. Die Schleife funktioniert daher, weil das Zielelement ein „Fieldset“ ist und dort das Interface „IteratorAggregate“ Anwendung findet.
Und da es sich beim Zielelement bei dir um ein „Fieldset“ handelt, darfst du auch von diesem dein „Select“-Element holen:

PHP:
$this->get('results')->getTargetElement()->get('mySelect')->setValueOptions([…]);
(Im Quellcode einfach mal die Kommentare durchschauen: https://github.com/zendframework/zend-form/blob/master/src/Element/Collection.php)
 
Zuletzt bearbeitet:

fitti70

New member
Schau mal genau auf den Methodennamen: es heißt „getTargetElement“ – ohne „s“ am Ende – also Einzahl!

Das Zielelement existiert nur einmal und durch die Angabe von „count“ wird es zweimal ausgegeben. Also nichts mit 2 Einträgen oder zwei Elementen. Die Schleife funktioniert daher, weil das Zielelement ein „Fieldset“ ist und dort das Interface „IteratorAggregate“ Anwendung findet.
Und da es sich beim Zielelement bei dir um ein „Fieldset“ handelt, darfst du auch von diesem dein „Select“-Element holen:

PHP:
$this->get('results')->getTargetElement()->get('mySelect')->setValueOptions([…]);
(Im Quellcode einfach mal die Kommentare durchschauen: https://github.com/zendframework/zend-form/blob/master/src/Element/Collection.php)
Hallo Kaiuwe,
ich habe ein ähnliches Problem, möchte aber das Label und den Wert jedes einzelnen Elements des Fieldsets dynamisch ändern. Diese Werte werden aus der Datenbank ausgelesen.
Wenn ich dies mit setValueOptions probiere, ändere ich jedes Elements des Fieldsets.
Gibt es eine Möglichkeit, die Elemente zu iterieren und einzeln zu bearbeiten?
Hier ein paar Codeschnipsel:
PHP:
class AclPermissionsForm extends Form
{

    /**
     * AclPermissionsForm constructor.
     * @param string $name
     */
    public function __construct($name = 'acl_permissions')
    {
        parent::__construct($name);
        
        $this->setHydrator(new Reflection())
              ->setObject(new AclPermissionsEntity());

        $element = new Element\Csrf('tick');
        $this->add($element);
        
        $id = new Hidden('id');
        $id->setAttribute('id','id');
        $this->add($id);
        
        $type = new Element\Select('type');
        $type->setLabel('Typ')
             ->setValueOptions(array('allow' => 'Erlauben', 'deny' => "Verbieten"));
        $this->add($type);     
        
        
        $role = new Element\Select('role');
        $role->setLabel('Rolle');
        $this->add($role);    
                
        $ressource = new Element\Select('ressource');
        $ressource->setLabel('Ressource')
                  ->setAttribute('id','ressource')  ;
        $this->add($ressource);
       
        
        $privelegCollection = new Element\Collection('privileges');
        $privelegCollection->setOptions(array(
            'allow_remove' => true,
            'label' => "Privilegien",
            'should_create_template' => false,
            'target_element'    => array(
                'type'  => AclPrivilegesFieldset::class          
            )                  
        ));
       $this->add($privelegCollection);
        
        $element = new Element\Submit('cancel');
        $element->setValue('Abbrechen')
                ->setLabel('Abbrechen');
        $element->setAttribute('class', 'btn');
        $this->add($element);
        
        $element = new Element\Submit('submit');
        $element->setValue('Speichern')
                 ->setLabel('Speichern');
        $element->setAttribute('class', 'submit');
        $this->add($element);
    }
}
PHP:
class AclPrivilegesFieldset extends Fieldset
{

    /**
     * AclPrivilegesFieldset constructor.
     * @param string $name
     */
    public function __construct($name = 'privileg')
    {
        parent::__construct($name);       
        
        $this->setHydrator(new Reflection())
             ->setObject(new AclPrivilegesEntity()) ;  
        
        $privileg = new Element\Checkbox('id');       
        $this->add($privileg);       

       
    
    }
}
Im Controller:
PHP:
$form->bind($entity);
echo "<pre>";
var_dump($form->get('privileges')->getTargetElement()->get('id'));
echo "</pre>";
Ausgabe:
Code:
object(Zend\Form\Element\Checkbox)#524 (11) {
  ["attributes":protected]=>
  array(2) {
    ["type"]=>
    string(8) "checkbox"
    ["name"]=>
    string(2) "id"
  }
  ["validator":protected]=>
  NULL
  ["useHiddenElement":protected]=>
  bool(true)
  ["uncheckedValue":protected]=>
  string(1) "0"
  ["checkedValue":protected]=>
  string(1) "1"
  ["label":protected]=>
  NULL
  ["labelAttributes":protected]=>
  array(0) {
  }
  ["labelOptions":protected]=>
  array(0) {
  }
  ["messages":protected]=>
  array(0) {
  }
  ["options":protected]=>
  array(0) {
  }
  ["value":protected]=>
  NULL
}

Viele Grüße
fitti
 
Oben