Reputation: 1
i've a class "Product" and a class "MaterialOrder". They share a many_many relation where Products in MaterialOrder has the extrafields "PriceSum" and "Quantity". So in theory someone should be able to order something where he sees a list of all active products with an inputfield on every entry to define how many of the item he wants. After hitting create it should create a new materialorder entry with the current price sum and the defined quantity.
Now i can't find anything how to access these extra fields correctly and i've no clue how to add the inputfield in the gridfield to then safe the new materialorder object with the information...
MaterialOrder.php
<?php
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Forms\CurrencyField;
use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TabSet;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\GridField\GridField;
class MaterialOrder extends DataObject
{
private static $db = [
"LastReminder" => "Date",
"IsOrdered" => "Boolean",
"IsPaid" => "Boolean"
];
private static $has_one = [
"Member" => Member::class
];
private static $many_many = [
"Products" => Product::class
];
private static $many_many_extraFields = [
"Products" => [
"PriceSum" => "Currency",
"Quantity" => "Int"
]
];
public function getCMSfields()
{
$fields = FieldList::create(TabSet::create("Root"));
$fields->addFieldsToTab("Root.Main", [
$grid = GridField::create("Products", "Products", Product::getAllProducts(true))
]);
// GridField configuration
$config = $grid->getConfig();
return $fields;
}
}
Product.php
<?php
use SilverStripe\AssetAdmin\Forms\UploadField;
use SilverStripe\Assets\Image;
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\CurrencyField;
use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TabSet;
use SilverStripe\Forms\TextField;
use SilverStripe\ORM\DataObject;
class Product extends DataObject
{
private static $db = [
"Name" => "Varchar",
"Price" => "Currency",
"IsActive" => "Boolean",
];
private static $has_one = [
"Category" => Category::class,
"Image" => Image::class,
];
private static $belongs_many_many = [
"MaterialOrders" => MaterialOrder::class,
];
private static $summary_fields = array(
"IsActive" => "Is active?",
"Name" => "Name",
"Category.Title" => "Category",
"Price" => "Price",
);
public function getCMSfields()
{
$fields = FieldList::create(TabSet::create("Root"));
$fields->addFieldsToTab("Root.Main", [
CheckboxField::create("IsActive", "Is active?"),
TextField::create("Name"),
CurrencyField::create("Price", "Price (per piece)"),
DropdownField::create("CategoryID", "Category")
->setSource(Category::get()->map("ID", "Title")),
$upload = UploadField::create(
"Image",
"Product image"
),
]);
$upload->getValidator()->setAllowedExtensions(array(
"png", "jpeg", "jpg", "gif",
));
$upload->setFolderName("product-images");
return $fields;
}
public static function getAllProducts($filterValue = null)
{
$products = Product::get();
if (!is_null($filterValue)) {
$products = $products->filter(["IsActive" => $filterValue]);
}
return $products->sort("Name");
}
}
Upvotes: 0
Views: 456
Reputation: 4626
I had this problem a while ago and wrote about it in my blog.
In your case you have to add in MaterialOrder::getCMSields()
something like
$detailFormComponent = $grid->getConfig()->getComponentByType(GridFieldDetailForm::class);
$detailFormComponent->setItemEditFormCallback(function ($form, $itemrequest) {
$record = $itemrequest->record;
$priceField = CurrencyField::create('ManyMany[Price]', 'Price (per piece)', $record->Price);
$form->Fields()->add($priceField);
});
to edit the manymany fields in the deatail form.
We get the GridFieldDetailForm component of the grid field's config and modify it by adding a field to MaterialOrder's CMSFields. With the method setItemEditFormCallback() we can add an anonymous function to add the needed field(s). Manymany extraFields are saved using the ManyMany[FieldName] syntax, so we need ManyMany[Price] as the FieldName; we also need to grab the current value from $itemrequest->record.
Upvotes: 1