我想要做什么。我有帖子,类别和属性。我可以在我的帖子管理页面上创建具有许多属性的类别的类别。在我的帖子中,我可以选择一个类别。当我选择类别(选择字段)时,在此之后我将所选的属性显示为(输入字段)。
我的表单上的下拉列表和文本字段:
当我保存所选类别的帖子时,我会在提交属性输入字段后看到。这很有效。
这是必要但不好。好的,我需要一个带有ajax的解决方案。没有Symfony没有问题,但有一个大的^^
我谷歌这看,我需要一个CRUD控制器和我的Form TypeClass中的一个事件。
我的TypeClass:
class PropertiesType extends AbstractType
{
public $em;
private $session;
public function __construct(EntityManagerInterface $em,Session $session)
{
$this->em = $em;
$this->session = $session;
}
protected function generateFormInputs(FormEvent $event){
$form = null;
if(!is_array($event->getData()) && ($event->getData() === null || !$event->getData()->getCategory())){
return false;
}
if(!is_array($event->getData())){
$furniture = $event->getData();
$form = $event->getForm();
}else{
$pp = $this->em->getRepository('ProductBundle:Furniture')->findOneBy(array('id' => $event->getData()['furniture_id']));
$pp->setCategory($this->em->getRepository('ProductBundle:Category')->findOneBy(array('id' => $event->getData()['category_id'])));
$event->setData($pp);
$furniture = $event->getData();
$form = $event->getForm();
}
if($furniture !== null){
foreach($furniture->getCategory()->getProperties() as $val){
$repo = $this->em->getRepository('ProductBundle:FurnitureProperties')->findOneBy(array('furniture' => $furniture->getId(), 'property' => $val->getId()));
if($repo === null){
$repo = new FurnitureProperties();
$repo->addProperty($val);
$repo->addFurniture($furniture);
$repo->setPropertyId($val->getId());
$repo->setCurrentLocale($this->session->get('_locale'));
}
$form->add('properties_'.$val->getId(), 'text', array(
'mapped' => false,
'label' => $val->getName(),
'data' => $repo,
'required' => false
));
}
}
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
if($event->getData() !== null){
foreach($event->getData() as $key => $val){
$obj = '';
$obj = $event->getForm()->get($key)->getData();
if($val !== ''){
$obj->setText($val);
$this->em->persist($obj);
$obj->mergeNewTranslations();
$this->em->flush();
}else{
$this->em->remove($obj);
$this->em->flush();
}
}
}
});
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$this->generateFormInputs($event);
});
}
/**
* @param OptionsResolverInterface $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'ProductBundle\Entity\Furniture',
'empty_data' => new FurnitureProperties(),
));
}
}
我的CRUD控制器:
<?php
namespace ProductBundle\Controller;
use ProductBundle\Form\Type\PropertiesType;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
class FurnitureCRUDController extends Controller
{
public function ajaxAction($furniture_id, $category_id, Request $request)
{
$form = $this->createForm(PropertiesType::class, array(
'furniture_id' => $furniture_id,
'category_id' => $category_id
));
$form->handleRequest($request);
return $this->render('form/fields.html.twig',
array(
'form' => $form->createView()
)
);
}
}
我的树枝模板:
{% block properties_widget %}
{% if id is defined %}
{% set token = id|split('_')[0] %}
<script type="text/javascript">
jQuery(document).ready(function($){
$('#{{ token }}'+'_category').change(function(){
var current_element = this;
jQuery.ajax({
url : '/admin/product/furniture/ajax/{{ form.vars.value.id }}/'+jQuery(current_element).val()+'?uniqid={{ token }}',
type: 'post',
data: $("form").serialize(),
success: function(html) {
jQuery('.category_replacement').html(html);
}
});
});
});
</script>
{% endif %}
<div class="category_replacement">
{% for fields in form.children %}
{% set attr = fields.vars %}
<div id="sonata-ba-field-container-{{ attr.id }}" class="form-group">
<label for="{{ attr.id }}" class="control-label {{ attr.required == true ? 'required' : '' }}">{{ attr.label }}</label>
<div class="sonata-ba-field sonata-ba-field-standard-natural">
<input class="form-control" name="{{ attr.full_name }}" id="{{ attr.id }}" value="{{ attr.value }}" {{ attr.required == true ? 'required="required"' : '' }}>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
如果我这样做的话。我得到了这个结果(浏览器)。
<div class="category_replacement">
<div id="sonata-ba-field-container-properties_properties_1" class="form-group">
<label for="properties_properties_1" class="control-label ">höhe</label>
<div class="sonata-ba-field sonata-ba-field-standard-natural">
<input class="form-control" name="properties[properties_1]" id="properties_properties_1" value="">
</div>
</div>
<div id="sonata-ba-field-container-properties__token" class="form-group">
<label for="properties__token" class="control-label "></label>
<div class="sonata-ba-field sonata-ba-field-standard-natural">
<input class="form-control" name="properties[_token]" id="properties__token" value="AhNHvQrq_8f6ObAOTB1MmbX7Nv_FBmFsgQe3z_sH7qg">
</div>
</div>
</div>
My Original但看起来如此(浏览器):
<div class="category_replacement">
<div id="sonata-ba-field-container-s594d9b1861e8e_furniture_properties_1" class="form-group">
<label for="s594d9b1861e8e_furniture_properties_1" class="control-label ">height</label>
<div class="sonata-ba-field sonata-ba-field-standard-natural">
<input class="form-control" name="s594d9b1861e8e[furniture][properties_1]" id="s594d9b1861e8e_furniture_properties_1" value="">
</div>
</div>
</div>
有什么问题? Ajax请求没有唯一的ID?我想,没问题,我会用JavaScript改变它。
但提交表格后。 Symfony不知道我的输入字段。为什么呢?
当我使用没有此Ajax解决方案的表单时。我可以在表单中添加实体,并在提交后使用它们。但是当我使用ajax解决方案时,我无法与实体合作,我认为这很糟糕。
唯一的选择是将Property ID添加到输入字段的name属性,并从db加载它。
如果有帮助的话。我的作曲家要求:
"php": ">=5.5.9",
"doctrine/doctrine-bundle": "^1.6",
"doctrine/orm": "^2.5",
"friendsofsymfony/rest-bundle": "^2.2",
"incenteev/composer-parameter-handler": "^2.0",
"knplabs/doctrine-behaviors": "^1.4",
"nelmio/api-doc-bundle": "^2.13",
"sensio/distribution-bundle": "^5.0.20",
"sensio/framework-extra-bundle": "^3.0.2",
"sonata-project/admin-bundle": "3.19.0",
"sonata-project/doctrine-orm-admin-bundle": "^3.1",
"sonata-project/google-authenticator": "^2.0",
"sonata-project/media-bundle": "^3.5",
"sonata-project/translation-bundle": "^2.1",
"sonata-project/user-bundle": "dev-master",
"stof/doctrine-extensions-bundle": "^1.2",
"symfony/assetic-bundle": "^2.8",
"symfony/monolog-bundle": "^3.1.0",
"symfony/polyfill-apcu": "^1.0",
"symfony/swiftmailer-bundle": "^2.3.10",
"symfony/symfony": "3.3.*",
"twig/twig": "1.34.3"
是的,我知道。带有ID的解决方案不是最好的:
'properties_'.$val->getId()
但这是另一个问题:)