Тип сущности формы Symfony

Я создаю простую страницу продукта. У некоторых продуктов могут быть дополнительные опции (productOptions). Эти параметры могут быть выбраны с помощью полей выбора. Но проблема в следующем:

У меня есть следующие сущности:

Продукт

#src/appbundle/entity
<?php
/**
 * Product
 */

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity(repositoryClass = "AppBundle\Repository\ProductRepository")
 * @ORM\Table(name = "product")
 */
class Product {

    /**
     * @var string id
     * @ORM\Id
     * @ORM\GeneratedValue(strategy = "AUTO")
     * @ORM\Column(type = "integer")
     */
    protected $id;

    /**
     * @var string title
     * @ORM\Column(type = "string")
     */
    protected $title;

    /**
     * @var ArrayCollection|ProductOption[]
     * @ORM\OneToMany(targetEntity = "AppBundle\Entity\ProductOption", mappedBy = "product", fetch = "EAGER")
     */
    protected $productOptions;
    protected $tempProductOptions;

    /**
     * @return string
     */
    public function getId() {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getTitle() {
        return $this->title;
    }

    /**
     * @param string $title
     */
    public function setTitle($title) {
        $this->title = $title;
    }

    public function __construct() {
        $this->productOptions = new ArrayCollection();
    }

    public function addProductOption(ProductOption $productOption){
        if ($this->productOptions->contains($productOption)){
            return;
        }

        $productOption->setProduct($this);
        $this->productOptions->add($productOption);
    }

    public function removeProductOption(ProductOption $productOption){
        if (!$this->productOptions->contains($productOption)){
            return;
        }

        $productOption->setProduct(null);
        $this->productOptions->removeElement($productOption);
    }

    /**
     * @return ProductOption[]|ArrayCollection
     */
    public function getProductOptions() {
        return $this->productOptions->toArray();
    }

}

ProductOption

#src/appbundle/entity
<?php
/**
 * ProductOption
 */

namespace AppBundle\Entity;

use AppBundle\Repository\GenusRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * @ORM\Entity(repositoryClass = "AppBundle\Repository\ProductOptionRepository")
 * @ORM\Table(name = "product_option")
 */
class ProductOption {

    /**
     * @var int id
     * @ORM\Id
     * @ORM\GeneratedValue(strategy = "AUTO")
     * @ORM\Column(type = "integer")
     */
    protected $id;

    /**
     * @var string title
     * @ORM\Column(type = "string")
     */
    protected $title;

    /**
     * @var float price
     * @ORM\Column(type = "float", scale=2)
     */
    protected $price;

    /**
     * ProductOption connected to specific product
     * @ORM\ManyToOne(targetEntity = "Product", inversedBy = "productOptions")
     * @ORM\JoinColumn(nullable=false)
     */
    protected $product;

    /**
     * @return int
     */
    public function getId() {
        return $this->id;
    }

    /**
     * @param int $id
     */
    public function setId($id) {
        $this->id = $id;
    }

    /**
     * @return string
     */
    public function getTitle() {
        return $this->title;
    }

    /**
     * @param string $title
     */
    public function setTitle($title) {
        $this->title = $title;
    }

    /**
     * @return float
     */
    public function getPrice() {
        return $this->price;
    }

    /**
     * @param float $price
     */
    public function setPrice($price) {
        $this->price = $price;
    }

    /**
     * @return Product
     */
    public function getProduct() {
        return $this->product;
    }

    /**
     * @param Product $product
     */
    public function setProduct($product) {
        $this->product = $product;
    }

    public function __toString() {
        return (string)$this->getTitle() . '(&euro;'.$this->getPrice().')';
    }
}

Это мой ProductType (formbuilder)

#src/appbundle/form
<?php

namespace AppBundle\Form;

use AppBundle\Entity\Product;
use AppBundle\Entity\ProductOption;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ProductType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('title', TextType::class, [
            'label' => 'titel'
        ]);

        $builder->add('tempProductOptions', EntityType::class, [
            'class' => ProductOption::class,
            'multiple' => true,
            'expanded' => true,
            'mapped' => false,
            'choice_attr' => function($productOption, $key, $index) {
                /** @var ProductOption $productOption */
                return [
                    'data-price' => $productOption->getPrice(),
                ];
            },
        ]);

        $builder->add('save', SubmitType::class, array(
            'label' => 'Opslaan'
        ));
    }

    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults(array(
            'data_class' => Product::class,
        ));
    }

    public function getBlockPrefix() {
        return 'product';
    }
}

Файл Twig это очень простой пример

<!doctype html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <meta name = "viewport"
          content = "width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv = "X-UA-Compatible" content = "ie=edge">
    <title>Document</title>
</head>
<body>
<h1>test product page</h1>

{{ dump(form) }}

{{ form_start(form) }}
    {{ form_row(form.titel) }}
    {{ form_row(form.productOptions) }}
    {{ form_row(form.save) }}
{{ form_end(form) }}
</body>
</html>

Например, у продукта 1 есть два варианта:

  • вариант 1 (50 евро)
  • вариант 2 (60 евро)

В базе данных варианты 1 и 2 связаны с продуктом 1 таблица product_option

ID название цена product_id

1 вариант 1 50 1

2 вариант 2 60 1

Но в представлении параметры уже отмечены (потому что они подключены через db). Можно ли снять галочки.

Укороченная версия. У каждого продукта могут быть дополнительные опции. Эти параметры хранятся в db. При создании формы на странице продукта пользователь мог выбрать эти параметры, но они уже отмечены.

Также в мой formbuilder добавлено следующее:

public function finishView(FormView $view, FormInterface $form, array $options) {
    foreach ($view->children['productOptions']->children as $productOption) {
        $productOption->vars['checked'] = false;
    }
}

но флажки все еще проверяются

Я нашел решение:

public function buildForm(FormBuilderInterface $builder, array $options) {
        // arraycollection with productOptions
        $productOptions = $options['data']->getProductOptions();

        $builder->add('id', HiddenType::class, ['mapped' => false]);
        $builder->add('productOptions', ChoiceType::class, [
            'choices'  => $productOptions,
            'expanded' => true,
            'multiple' => true,
            'mapped' => false,
            'choice_value' => function (ProductOption $productOption) {
                return $productOption->getId();
            },
            'choice_label' => function(ProductOption $productOption, $key, $index) {
                return $productOption->__toString();
            },
            'choice_attr' => function(ProductOption $productOption, $key, $index) {
                return [
                    'data-prijs' => $productOption->getPrijs(),
                ];
            },
        ]);
   // rest here ...

Отобразите их в ветке как снятые

Mcsky 13.05.2018 13:41

Как я мог сделать это в веточке? Потому что для снятия отметки мне нужно удалить отмеченный атрибут.

Bham 13.05.2018 13:43

Не могли бы вы связать свой файл веточки, пожалуйста?

Mcsky 13.05.2018 13:59

@Mcsky Я отредактировал свой первый пост и добавил файл веточки. Файл ветки очень простой.

Bham 13.05.2018 14:01
JS - События опций формы
JS - События опций формы
В продолжение предыдущей статьи CSS - стили, связанные с вводом формы , в этой статье мы будем использовать JS для взаимодействия с формами, на этот...
CSS - Стили, связанные с вводом формы
CSS - Стили, связанные с вводом формы
Общими стилями ввода для форм являются Input (включая Text, Radio, checkbox), Select и Textarea, из которых Input относительно прост, поэтому в этой...
Создание многостраничной формы заявления о приеме на работу с помощью Angular
Создание многостраничной формы заявления о приеме на работу с помощью Angular
Наличие на корпоративном сайте форм заявлений о приеме на работу, или "трудовых анкет", экономит время и деньги как для соискателей, так и для...
0
4
492
0

Другие вопросы по теме