Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Form Questions /

[ SOLVED ]Forms and a many_many relationship


Go to End
Reply


17 Posts   4322 Views

Avatar
cumquat

Community Member, 198 Posts

18 March 2011 at 10:52pm

Hi there,

I have a dataobject that contains information about training areas, i have created a frontend form for the team to add info, all works fine. code below.

function locationaddForm() {
   
      $fields = singleton('Locations')->getFrontEndFields();
            
      $actions = new FieldSet(
         new FormAction('dolocationadd', 'Submit')
      );
      
      return new Form($this, 'locationaddForm', $fields, $actions);
      
      }
   
   function dolocationadd($data, $form) {
      $Locations = new Locations();
      $form->saveInto($Locations);
      $Locations->write();
      
      
      Director::redirectBack();
      }
The Locations dataobject has 'has_one' links to other dataobjects and they are displayed and save fine but it also has a 'many_many' link to LocationFacilities which contains items like parking, water, toilet, etc.
I can't seem to get that to show. This is a little bit out of my comfort zone so any help would be appreciated. This all works fine in the backend with ModelAdmin but i need a front end solution.

Cheers

Mick

Avatar
cumquat

Community Member, 198 Posts

23 March 2011 at 12:31am

Bump.

I'm still stuck, the code so far,

   
function locationaddForm() {
      
      $fac = DataObject::get("LocationFacilities",""); // getting all the facilities
   $map = $fac->toDropDownMap();
                  
      $fields = new FieldSet(
         new TextField('Name'),
         new TextField('GridRef'),
         new TextField('Postcode'),
         new TextField('HeightRst'),
         new CheckboxField('Training', 'Training Location'),
         new TextareaField('Notes', 'Notes'),
         new CheckboxSetField('LocationFacilities','Location Facilities',$map)
         );
               
      $actions = new FieldSet(
         new FormAction('dolocationadd', 'Submit')
      );
      
      return new Form($this, 'locationaddForm', $fields, $actions);
      }
   
   function dolocationadd($data, $form) {
      $Locations = new Locations();
      $form->saveInto($Locations);
      $Locations->write();
      
      /***sure a loop needs to go here but don't know the code *****/
}
      Director::redirectBack();
      }
   


I have the fields from the many_many table appearing but they don't save so i'm guessing a loop of some sort is needed but i'm not 100% on if this is the case or how to code it.

Any help or pointers please?

Mick

Avatar
katja

Community Member, 46 Posts

23 March 2011 at 1:19am

Hi Mick,

I think toDropDownMap() is not the right method here, as you are using the result then in a CheckboxSetfield .

Try map() instead, like $map = $fac->map('ID','Name') .

This worked for me.

Katja

Avatar
cumquat

Community Member, 198 Posts

23 March 2011 at 4:08am

Hi ya,

Thanks for the response, i have tried that and they display fine cheers, i just can't seem to get the data to save, i'm sure i need to add a loop to cycle through the selected check boxes in the dolocationadd() but i'm just a bit stuck on how write that (still learning PHP) and i've looked at a couple of examples that people have had in the forum but i can't seem to get the code to work, mostly because i don't fully understand it yet.

Mick

Avatar
katja

Community Member, 46 Posts

23 March 2011 at 9:01am

There should be no need for you to write any loops, silverstripe does the looping for you. One other thing, have you put $belongs_many_many in your LocationFacilities class?

Katja

Avatar
cumquat

Community Member, 198 Posts

23 March 2011 at 9:08am

Yea got the LocationFacilities page,

<?php
class LocationFacilities extends DataObject {

   static $db = array(
'Name' => 'Varchar(30)'

);
static $belongs_many_many = array(
'Locations' => 'Locations'
);
}

Locations page,

<?php
class Locations extends DataObject {

   static $db = array(
'Name' => 'Varchar(255)',
'GridRef' => 'Varchar(15)',
      'Postcode' => 'Varchar(10)',
      'Notes' => 'Text',
      'HeightRst' => 'Decimal',
      'Training' => 'Boolean',
      'Fundraising' => 'Boolean'

);
   static $has_one =array (
      'Vet' => 'Vet',
      'Hospital' => 'Hospital',
      'OSMaps' =>'OSMaps',
      'LocationsPage' => 'LocationsPage'
      );

   static $many_many =array (
      'LocationFacilities' => 'LocationFacilities'
      );

//Set our defaults
static $defaults = array(

);
   
   function canCreate() {return true;}
   function canEdit() {return true;}
   
public function getFrontendFields() {
   
   
   
    $fields = $this->scaffoldFormFields(array(
       'restrictFields' => array(
         'Name',
         'GridRef',
         'OSMaps',
         'Postcode',
         'HeightRst',
         
         'Notes',
         'Vet',
         'Hospital',
         'LocationsPage'
         
         )
         )
         );
         
         return $fields;
         
         
         }

static $summary_fields = array(
'Name' => 'Name',
      'GridRef' => 'Grid Reference'
      
);

function getCMSFields() {
$fields = parent::getCMSFields();
$FacilityList = DataObject::get('LocationFacilities');

$Facilitytablefield = new ManyManyComplexTableField(
$this,
'LocationFacilities',
'LocationFacilities',
array(
    'Name' => 'Name'
)
      
       );
// add a checkbox set field to the 'Industry' tab in the CMS
$fields->removeFieldFromTab("Root", "Location Facilities");
$fields->addFieldToTab('Root.Facilities', $Facilitytablefield );

return $fields;
}
   function HeightWarning() {
      return ($this->HeightRst > 0 && $this->HeightRst < 3);
   }
   
   
public function Link()
   {
      if($LocationsPage = $this->LocationsPage())
      {
         return $LocationsPage->Link('/show/') . $this->ID;   
      }
   }
}

and finally the AddLocations page,

<?php

class AddLocations extends Page {
      static $db = array(
   
    );
       static $has_one = array(
   
    );
    static $many_many = array(

);
}

class AddLocations_Controller extends Page_Controller {
   
   function locationaddForm() {
         
      $fac = DataObject::get("LocationFacilities",""); // getting all facilities
   /*$map = $fac->toDropDownMap();*/
      $map = $fac->map('ID','Name');
                  
      $fields = new FieldSet(
         new TextField('Name'),
         new TextField('GridRef'),
         new TextField('Postcode'),
         new TextField('HeightRst'),
         new CheckboxField('Training', 'Training Location'),
         new TextareaField('Notes', 'Notes'),
         new CheckboxSetField('ID','Location Facilities',$map) //add 1,true to make option one ticked
         );
               
      $actions = new FieldSet(
         new FormAction('dolocationadd', 'Submit')
      );
      
      return new Form($this, 'locationaddForm', $fields, $actions);
      }
   
   function dolocationadd($data, $form) {
      $submission = new Locations();
      $form->saveInto($submission );
      $submission ->write();
      
      $data = $form->getData();
      
   
}
      Director::redirectBack();
      }
   

   
}
?>

Thanks for getting back to me, anything obvious missing?

Mick

Avatar
katja

Community Member, 46 Posts

23 March 2011 at 12:03pm

in AddLocations page:
new CheckboxSetField('ID','Location Facilities',$map)

You should leave that as you had it before: new CheckboxSetField('LocationFacilities','Location Facilities',$map)

If that doesn't help I don't know ;)

Katja

Avatar
cumquat

Community Member, 198 Posts

23 March 2011 at 8:56pm

Edited: 23/03/2011 8:58pm

Thanks for that but no that doesn't work, the form processes ok and the other data is stored just not the data for the location facilities. It all works fine in the back end just not the front end.

I found something similar in this post [url]http://silverstripe.org/form-questions/show/10854 [/url]

function doForm($data, $form) {
$submission = new EnquiryObject();

$form->saveInto($submission);

$submission->write();

$data = $form->getData();
foreach($data['Groups'] as $key => $value){
$dob = DataObject::get_one('Group',"ID = ".$value);
$submission->Groups()->add($dob);
unset($dob);
}

Director::redirectBack();
}

and this looks like it's what i'm after but i can't get it to work in my set up.

i changed it to

function dolocationadd($data, $form) {
      $submission = new Locations();
      $form->saveInto($submission );
      $submission ->write();
      
      $data = $form->getData();
      
   foreach($data['LocationFacilities'] as $key => $value){
$dob = DataObject::get_one('LocationFacilities',"ID = ".$value);
$submission ->LocationFacilities()->add($dob);
unset($dob);
}
      Director::redirectBack();
      }


when i do it i get "Invalid argument supplied for foreach()"

Mick

Go to Top