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


Reply


17 Posts   4120 Views

Avatar
cumquat

Community Member, 198 Posts

25 March 2011 at 1:00am

Anyone, i'm sure this has to be close, i can't move on till i sort it and i think i have been looking at it too long to sort it.

Mick

Avatar
swaiba

Forum Moderator, 1798 Posts

25 March 2011 at 4:29am

i get "Invalid argument supplied for foreach()"
this is when the foreach isn't getting an array... are you sure that - $data['LocationFacilities'] is an array?

try this to read what exactly the $data contains

print '<pre>';print_r($data);exit();

Avatar
cumquat

Community Member, 198 Posts

25 March 2011 at 4:42am

Edited: 25/03/2011 4:42am

Hi ya,

this is the output with the print statement placed directly before the foreach statement.

Array
(
[Name] => printtest
[GridRef] => abc123
[Postcode] =>
[HeightRst] =>
[Training] => 0
[Notes] =>
[LocationFacilities] => 1,2,3,4
[SecurityID] => d11fb97bf04ae37b428be58e49fa83f37b6f711f
)

that was with all four items ticked.

Avatar
swaiba

Forum Moderator, 1798 Posts

25 March 2011 at 6:22am

so $data['LocationFacilities'] is a csv string, not an array (if it were an array, you'd see something different)

try this to get your code working...

$cos = $submission ->LocationFacilities();
$cos->addMany(explode(',',$data['LocationFacilities']));

Avatar
cumquat

Community Member, 198 Posts

25 March 2011 at 6:34am

You are a god.....

Man it worked, i don't know what that code means but will look that up, all i can say is thank you.

Mick

Avatar
swaiba

Forum Moderator, 1798 Posts

25 March 2011 at 8:32am

Edited: 25/03/2011 8:34am

you're welcome.

$cos = $submission ->LocationFacilities();


gets a ComponentSet, which is a special kind of DataObjectSet used to represent the items linked to in a 1-many or many-many join. It provides add and remove methods that will update the database.

$cos->addMany(explode(',',$data['LocationFacilities']));


addmany is one of those extra ComponentSet functions and takes an array for ids to add top the ComponentSet, the explode converts a csv sting to an array

Avatar
katja

Community Member, 46 Posts

25 March 2011 at 11:38am

Edited: 25/03/2011 11:39am

Good to see you solved it. Just for the record, I have just found out how I can make mine work as well.

(Funnily enough, it was starting to drive me crazy that it worked with my website, and I couldn't reproduce it! )

The reason it wasn't saved was that at the point of saving your Locations item does not have an ID yet! So really all you needed to do is an extra $Submission->write() before you do $form->saveInto($Submission). Then you have to have another $Submission->write() and the records in the join table will automatically get created.

On my website, at the point where I save the many_many relations, I save them into an already existing record. That's why I didn't have your problem.

Anyway, if I strip your files down to what is essential for this example, they would look like this (I used $locations instead of $Submission) :

Locations.php

<?php

class Locations extends DataObject {
static $db = array(
'Name' => 'varchar(60)'
);

static $many_many = array(
'LocationsFacilities' => 'LocationFacilities',

);
}

-----------------------------------------
LocationFacilities.php

<?php

class LocationFacilities extends DataObject {

static $db = array(
'Name' => 'VarChar(60)'
);

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

}

--------------------------------
And AddLocations.php

<?php

class AddLocations extends Page {

}

class AddLocations_Controller extends Page_Controller {

function locationaddForm()
{
$fac = DataObject::get("LocationFacilities");
$map = $fac->map('ID','Name');

$form = new Form($this,'locationaddForm',new Fieldset(
new TextField('Name','Name'),
new CheckboxSetField('LocationsFacilities','Location Facilities',$map)
),
new FieldSet(
new FormAction('dolocationadd', 'Submit')
));
return $form;
}

function dolocationadd($data,$form)
{

$locations = new Locations();
$locations->write();
$form->saveInto($locations);
$locations->write();

Director::redirectBack();
}

}

So you can get Silverstripe to do it for you!

Cheers,
Katja

Avatar
cumquat

Community Member, 198 Posts

25 March 2011 at 9:16pm

Morning,

Thanks for that as well, yep you were correct i made that change and it also worked you are a star.

Like i said thank you to both of you, i can now finally move on to the next stage of this project.

Both from Bristol i notice do you know each other?

Mick