class ModificationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add("name", TextType::class, [
"attr" => ["class" => "form-control"],
"label" => "Наименование",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"constraints" => [
new Assert\NotBlank(),
new Assert\Length(["max" => 255]),
],
"required" => true,
])
->add("alt_name", TextType::class, [
"attr" => ["class" => "form-control"],
"label" => "Альтернативное наименование",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"constraints" => [
new Assert\NotBlank(),
new Assert\Length(["max" => 255]),
],
"required" => true,
])
->add("seo_name", TextType::class, [
"attr" => ["class" => "form-control"],
"label" => "SEO Name",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"constraints" => [
new Assert\NotBlank(),
new Assert\Length(["max" => 100]),
],
"required" => true,
])
->add("power_kwt", NumberType::class, [
"attr" => ["class" => "form-control"],
"label" => "Мощность кВт",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"constraints" => [
new Assert\NotBlank(),
new Assert\Positive(),
],
"required" => true,
])
->add("power_horse", NumberType::class, [
"attr" => ["class" => "form-control"],
"label" => "Мощность л.с.",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"constraints" => [
new Assert\NotBlank(),
new Assert\Positive()
],
"required" => true,
])
->add("year_from", ChoiceType::class, [
"attr" => ["class" => "form-control"],
"label" => "Год начала производства",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"choices" => $this->getYears(),
"constraints" => [
new Assert\NotBlank(),
new Assert\Length(["max" => 4]),
],
"required" => true,
])
->add("year_to", ChoiceType::class, [
"attr" => ["class" => "form-control"],
"label" => "Год завершения производства",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"choices" => $this->getYears(),
"empty_data" => "н.в.",
"constraints" => [
new Assert\NotBlank(),
new Assert\Length(["max" => 4]),
],
"required" => false,
])
->add("brand", EntityType::class, [
"label" => "Бренд",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"class" => Brand::class,
"choice_label" => function ($brand) {
return $brand->getName();
},
"attr" => [
"class" => "form-control select"
],
"constraints" => [
new Assert\NotBlank()
],
"mapped" => false
])
->add("model", EntityType::class, [
"label" => "Модель",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"class" => Model::class,
"choice_label" => function ($brand) {
return $brand->getName();
},
"attr" => [
"id" => "choice-model",
"class" => "form-control select"
],
"constraints" => [
new Assert\NotBlank()
]
])
->add("series", EntityType::class, [
"label" => "Серия",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"class" => Series::class,
"choice_label" => function ($brand) {
return $brand->getName();
},
"attr" => [
"class" => "form-control select"
],
"constraints" => [
new Assert\NotBlank()
]
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
"data_class" => Modification::class,
]);
}
/**
* @return array
*/
private function getYears(): array
{
$years = [];
for ($i = date("Y"); $i >= 1955; $i--) {
$years[$i] = $i;
}
return $years;
}
}
<script>
function initialize() {
const $brand = $('#modification_brand');
// Когда выбран бренд ...
$brand.change(function() {
// ... вызвать соответствуюущую форму.
var $form = $(this).closest('form');
// Симулировать данные формы, но включать только значение выбранного бренда.
var data = {};
// data[$brand.attr('name')] = $brand.val();
// Отправить данные через AJAX по пути действия формы.
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : {
brand_id: $brand.val()
},
success: function(html) {
// Заменить текущую позицию на поле ...
$('#modification_model').replaceWith(
// ... той, что вернулась из ответа AJAX.
$(html).find('#modification_model')
);
// Теперь поле позиций отображает правильные позиции.
}
});
});
}
$(document).ready(initialize);
<?php
namespace App\Form;
use App\Entity\Brand;
use App\Entity\Model;
use App\Entity\Modification;
use App\Entity\Series;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints as Assert;
class ModificationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add("name", TextType::class, [
"attr" => ["class" => "form-control"],
"label" => "Наименование",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"constraints" => [
new Assert\NotBlank(),
new Assert\Length(["max" => 255]),
],
"required" => true,
])
->add("alt_name", TextType::class, [
"attr" => ["class" => "form-control"],
"label" => "Альтернативное наименование",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"constraints" => [
new Assert\NotBlank(),
new Assert\Length(["max" => 255]),
],
"required" => true,
])
->add("seo_name", TextType::class, [
"attr" => ["class" => "form-control"],
"label" => "SEO Name",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"constraints" => [
new Assert\NotBlank(),
new Assert\Length(["max" => 100]),
],
"required" => true,
])
->add("power_kwt", NumberType::class, [
"attr" => ["class" => "form-control"],
"label" => "Мощность кВт",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"constraints" => [
new Assert\NotBlank(),
new Assert\Positive(),
],
"empty_data" => 0,
"required" => true,
])
->add("power_horse", NumberType::class, [
"attr" => ["class" => "form-control"],
"label" => "Мощность л.с.",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"constraints" => [
new Assert\NotBlank(),
new Assert\Positive()
],
"empty_data" => 0,
"required" => true,
])
->add("year_from", ChoiceType::class, [
"attr" => ["class" => "form-control"],
"label" => "Год начала производства",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"choices" => $this->getYears(),
"constraints" => [
new Assert\NotBlank(),
new Assert\Length(["max" => 4]),
],
"required" => true,
])
->add("year_to", ChoiceType::class, [
"attr" => ["class" => "form-control"],
"label" => "Год завершения производства",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"choices" => $this->getYears(),
"empty_data" => "н.в.",
"constraints" => [
new Assert\NotBlank(),
new Assert\Length(["max" => 4]),
],
"required" => false,
])
->add("brand", EntityType::class, [
"label" => "Бренд",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"class" => Brand::class,
"choice_label" => function ($brand) {
return $brand->getName();
},
"attr" => [
"class" => "form-control select"
],
"constraints" => [
new Assert\NotBlank()
]
])
->add("model", ChoiceType::class, [
"label" => "Модель",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"choices" => [],
"attr" => [
"class" => "form-control select"
],
"constraints" => [
new Assert\NotBlank()
],
"disabled" => true
])
->add("series", ChoiceType::class, [
"label" => "Серия",
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"choices" => [],
"attr" => [
"class" => "form-control select"
],
"constraints" => [
new Assert\NotBlank()
],
"disabled" => true
]);
$builder->get("brand")->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) {
$form = $event->getForm();
$brand_id = $event->getData();
$form->getParent()->add("model", EntityType::class, [
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"attr" => [
"class" => "form-control select"
],
"class" => Model::class,
"query_builder" => function (EntityRepository $er) use ($brand_id) {
return $er->createQueryBuilder("m")
->andWhere("m.brand = :brand_id")
->setParameter("brand_id", $brand_id)
->orderBy("m.name", "ASC");
},
"choice_label" => function ($entity)
{
return $entity->getName();
},
"constraints" => [
new Assert\NotBlank()
],
"required" => true
]);
$form->getParent()->add("series", EntityType::class, [
"label_attr" => [
"class" => "col-sm-2 form-control-label"
],
"attr" => [
"class" => "form-control select"
],
"class" => Series::class,
"query_builder" => function (EntityRepository $er) use ($brand_id) {
return $er->createQueryBuilder("s")
->andWhere("s.brand = :brand_id")
->setParameter("brand_id", $brand_id)
->orderBy("s.name", "ASC");
},
"choice_label" => function ($entity)
{
return $entity->getName();
},
"constraints" => [
new Assert\NotBlank()
],
"required" => true
]);
}
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
"data_class" => Modification::class,
]);
}
/**
* @return array
*/
private function getYears(): array
{
$years = [];
for ($i = date("Y"); $i >= 1955; $i--) {
$years[$i] = $i;
}
return $years;
}
}