[FLOW3-general] How to set/get/show M:N relations using checkboxes instead of selectbox?

Jan Greth jan at greth.me
Thu Mar 7 12:41:41 CET 2013


Hello everybody!

I've got a question, no "googleing" could answer to me, so i'm asking 
you. :)

I have two models - Event and Person. They have a m:n relation, cause 
many Persons can participate on a event and a person can visit many 
events. When I'm creating (~editing) a new event I made it working that 
I can select the participating persons by a multi selectbox. 
(<f:form.select ... multiple="multiple" size="3"/>). Inside the 
editAction of the event the participating persons are also preselected. 
Everything fine. But now i want checkboxes instead of a selectbox. It's 
no Problem to output persons already set inside the event by a
Fluid Code like:

<f:for each="{event.persons}" as="person">
     <f:form.checkbox property="persons" value="{person}" 
/><label>{person.name}</label><br />
</f:for>

Or output all available persons by writing:

<f:for each="{persons}" as="person">
     <label class="checkbox">
         <f:form.checkbox property="persons" value="person" />
         {person.name}<br />
     </label>
</f:for>

using the editAction:

     public function editAction(\Jpg\Events\Domain\Model\Event $event) {
         $this->view->assign('event', $event);
         $this->view->assign('locations', 
$this->locationRepository->findAll());
         $this->view->assign('persons', $this->personRepository->findAll());
     }

But how can make it work like the select box? I mean, showing all 
availible persons but preselecting the already
participating persons and after editing, saving them in my event?

I hope for your help,
Jan






PS: Here the according parts of my Code & Websites i found so far, but 
didn't help me further:

##### EventModel: #####
     /**
      * The title
      * @var string
      * @Flow\Validate(type="NotEmpty")
      * @Flow\Validate(type="String")
      * @Flow\Validate(type="StringLength", options={ "minimum"=5, 
"maximum"=100 })
      */
     protected $title;

     /**
     * @var 
\Doctrine\Common\Collections\Collection<\Jpg\Events\Domain\Model\Person>
     * @ORM\ManyToMany(inversedBy="events")
     */
     protected $persons;

     /**
      * Constructs this event
      */
     public function __construct() {
         $this->persons = new 
\Doctrine\Common\Collections\ArrayCollection();
     }

     /**
      * Get/Set the Event's title
      * ...
      */

     /**
      * Setter for person
      *
      * @param 
\Doctrine\Common\Collections\Collection<\Jpg\Events\Domain\Model\Person> 
$persons The attending persons
      * @return void
      */
     public function setPersons(\Doctrine\Common\Collections\Collection 
$persons) {
         $this->persons = clone $persons;
     }

     /**
      * Adds a person to this event
      *
      * @param \Jpg\Events\Domain\Model\Person $person
      * @return void
      */
     public function addPerson(\Jpg\Events\Domain\Model\Person $person) {
         $this->persons->add($person);
     }

     /**
      * Removes a person to this event
      *
      * @param \Jpg\Events\Domain\Model\Person $person
      * @return void
      */
     public function removePerson(\Jpg\Events\Domain\Model\Person $person) {
         $this->persons->remove($person);
     }

     /**
      * Getter for persons
      *
      * @return 
\Doctrine\Common\Collections\Collection<\Jpg\Events\Domain\Model\Person> 
The attending persons
      */
     public function getPersons() {
         return clone $this->persons;
     }

##### PersonModel: #####

     /**
      * The name
      * @var string
      */
     protected $name;

     /**
     * The events the person is attending
     * @var 
\Doctrine\Common\Collections\Collection<\Jpg\Events\Domain\Model\Event>
     * @ORM\ManyToMany(mappedBy="persons")
     */
     protected $events;


     /**
      * Constructs this tag
      */
     public function __construct() {
         $this->events = new \Doctrine\Common\Collections\ArrayCollection();
     }

     /**
      * Getters/Setters Person's name
      *
      * ...
      */

##### Repositories #####

The "standard" / blank ones... No extra functions.

##### EventController #####


     /**
     * Inject Repositories
     */


     /**
      * @return void
      */
     public function listAction() {
         $eventList = $this->eventRepository->findAll();
         $this->view->assign('events', $eventList);
     }

     /**
      * newAction
      * this action will only load the template and display the
      * form for adding a new event
      *
      * @return void
      */
     public function newAction() {

         $newEvent = new \Jpg\Events\Domain\Model\Event();
         $this->view->assign('newEvent', $newEvent);
         $this->view->assign('locations', 
$this->locationRepository->findAll());
         $this->view->assign('persons', $this->personRepository->findAll());
     }

     /**
      * @param \Jpg\Events\Domain\Model\Event $events
      * @return void
      */
     public function createAction(\Jpg\Events\Domain\Model\Event $event) {
         $this->eventRepository->add($event);
             $this->redirect('list');
     }

     /**
      * Shows a form for editing an existing location object
      *
      * @param \Jpg\Events\Domain\Model\Event $event The event to edit
      * @return void
      */
     public function editAction(\Jpg\Events\Domain\Model\Event $event) {
         $this->view->assign('event', $event);
         $this->view->assign('locations', 
$this->locationRepository->findAll());
         $this->view->assign('persons', $this->personRepository->findAll());
     }

     /**
      * Updates the given location object
      *
      * @param \Jpg\Events\Domain\Model\Event $event The event to update
      * @return void
      */
     public function updateAction(\Jpg\Events\Domain\Model\Event $event) {
         $this->eventRepository->update($event);
         $this->addFlashMessage('Updated the event.');
         $this->redirect('list');
     }

##### Fluid Event New #####

...
     <div id="content">
         <f:form action="create" controller="Event" package="Jpg.Events" 
name="event" object="{event}">
             <label for="title">Title:</label><f:form.textfield 
id="title" property="title" />
             <br />
             <label>Location:</label>
             <f:form.select property="location" name="location" 
options="{locations}" optionLabelField="name"/>
             <br />
             <f:form.select property="persons" name="persons" 
options="{persons}" optionLabelField="name" multiple="multiple" size="3"/>
             <br />
             <f:form.submit value="Speichern" />
         </f:form>
     </div>
...

##### Fluid Event Edit #####

     <f:form action="update" controller="Event" package="Jpg.Events" 
name="event" object="{event}">
         <label for="title">Title:</label><f:form.textfield id="title" 
property="title" />
         <br />

         <label for="location">Location:</label>
             <f:form.select property="location" id="location" 
options="{locations}" optionLabelField="name" />
         <br />

         <label for="persons">Persons:</label>
             <f:form.select property="persons" id="persons" 
options="{persons}" optionLabelField="name" multiple="multiple" size="3"/>
         <br />

         <f:form.submit value="Speichern" />
     </f:form>

##### Websites found so far... #####

http://www.typo3.net/forum/beitraege/extbase_und_fluid/107372/
http://docs.typo3.org/flow/TYPO3FlowDocumentation/TheDefinitiveGuide/PartV/FluidViewHelperReference.html
http://wiki.typo3.org/Fluid#f:form.checkbox
http://www.typo3lexikon.de/typo3-tutorials/extensions/fluid/fluid-variablen-und-arrays.html
http://forge.typo3.org/issues/9037
https://gist.github.com/benjaminrau/4674180
http://michelalbers.tumblr.com/post/23689244334/multiple-checkboxes-with-flow3-fluid
http://docs.typo3.org/flow/TYPO3FlowDocumentation/TheDefinitiveGuide/PartIII/Persistence.html


More information about the FLOW3-general mailing list