Php Symfony 3-编辑表单-使用db数据填充字段(数组)
我需要一个带有3个动态选择框(choicetypes)的表单,表单提交后,这些框将保存为数据库中的序列化数组 我最终成功地让它工作了,但现在我正在努力在编辑项目时用数据库值填充下拉列表 项目实体Php Symfony 3-编辑表单-使用db数据填充字段(数组),php,forms,symfony,symfony-forms,Php,Forms,Symfony,Symfony Forms,我需要一个带有3个动态选择框(choicetypes)的表单,表单提交后,这些框将保存为数据库中的序列化数组 我最终成功地让它工作了,但现在我正在努力在编辑项目时用数据库值填充下拉列表 项目实体 <?php namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @ORM\Table(name="projects") */ class Projects {
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="projects")
*/
class Projects
{
/**
* @ORM\Column(type="string", length=255)
*/
protected $projectName;
/**
* @ORM\Column(type="array")
*/
protected $frequency;
/**
* No database fields for these.
* They are used just to populate the form fileds
* and the serialized values are stored in the frequency field
*/
protected $update;
protected $every;
protected $on;
/*
* Project Name
*/
public function getProjectName()
{
return $this->projectName;
}
public function setProjectName($projectName)
{
$this->projectName = $projectName;
}
/*
* Frequency
*/
public function getFrequency()
{
return $this->frequency;
}
public function setFrequency($frequency)
{
$this->frequency = $frequency;
}
/*
* Update
*/
public function getUpdate()
{
return $this->update;
}
public function setUpdate($update)
{
$this->update = $update;
}
/*
* Every
*/
public function getEvery()
{
return $this->every;
}
public function setEvery($every)
{
$this->every = $every;
}
/*
* On
*/
public function getOn()
{
return $this->on;
}
public function setOn($on)
{
$this->on = $on;
}
}
我不确定这是否会对你有帮助,因为我没有足够的时间阅读你所有的帖子 首先(仅供参考),您可以在表单中使用3个字段(
update
、every
和on
)选项'mapped'=>false
,并从实体中删除这3个字段(这是与实体的映射,而不是DB)
然后,您可以使用在控制器中访问它们
$editForm->get('update')->getData(); //or setData( $data );
当然,如果您愿意并且更方便的话,您可以保留这些属性。
但如果您确实保留了它们,请确保它们始终反映频率属性中的数据
接下来,我在编辑控制器中看到,在创建表单之前,您没有设置3个字段的值。
由于这些字段未映射(这次与数据库一起映射),因此在获取实体时,它们将为null
(这是通过编辑控制器中的paramConverter
完成的)。
因此,在将$project
作为创建表单中的参数传递之前,必须对其进行设置(取消序列化或其他)
希望这能对你有所帮助 多谢各位。我已经按照您的建议在控制器中设置了值
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use AppBundle\Entity\Projects;
class ProjectsType extends AbstractType
{
private function setUpdateChoice(Projects $project)
{
return $project->getFrequency()['update'];
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('projectName', null, array());
$builder->add('update', ChoiceType::class, array(
'label' => 'Update',
'attr' => array(
'class' => 'update_selector',
),
'choices' => array(
'Daily' => 'Daily',
'Weekly' => 'Weekly',
'Monthly' => 'Monthly'
),
'data' => $this->setUpdateChoice($builder->getData())
)
);
$addFrequencyEveryField = function (FormInterface $form, $update_val) {
$choices = array();
switch ($update_val) {
case 'Daily':
$choices = array('1' => '1', '2' => '2');
break;
case 'Weekly':
$choices = array('Week' => 'Week', '2 Weeks' => '2 Weeks');
break;
case 'Monthly':
$choices = array('Month' => 'Month', '2 Months' => '2 Months');
break;
default:
$choices = array();
break;
}
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($addFrequencyEveryField) {
$update = $event->getData()->getUpdate();
$update_val = $update ? $update->getUpdate() : null;
$addFrequencyEveryField($event->getForm(), $update_val);
}
);
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) use ($addFrequencyEveryField) {
$data = $event->getData();
$update_val = array_key_exists('update', $data) ? $data['update'] : null;
$addFrequencyEveryField($event->getForm(), $update_val);
}
);
$addFrequencyOnField = function (FormInterface $form, $every_val) {
$choicesOn = array();
switch ($every_val) {
case 'Week':
$choicesOn = array(
'Monday' => 'Monday',
'Tuesday' => 'Tuesday',
'Wednesday' => 'Wednesday',
'Thursday' => 'Thursday',
'Friday' => 'Friday',
'Saturday' => 'Saturday',
'Sunday' => 'Sunday',
);
break;
case 'Month':
$choicesOn = array(
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5',
'6' => '6',
'7' => '7',
);
break;
default:
$choicesOn = array();
break;
}
$form->add('on', ChoiceType::class, array(
'choices' => $choicesOn,
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($addFrequencyOnField) {
$every = $event->getData()->getEvery();
$every_val = $every ? $every->getEvery() : null;
$addFrequencyOnField($event->getForm(), $every_val);
}
);
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) use ($addFrequencyOnField) {
$data = $event->getData();
$every_val = array_key_exists('every', $data) ? $data['every'] : null;
$addFrequencyOnField($event->getForm(), $every_val);
}
);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Projects'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_projects';
}
}
{% extends 'base.html.twig' %}
{% block body %}
{% block content %}
<h1>Edit Project</h1>
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
<input type="submit" value="Edit" />
{{ form_end(edit_form) }}
{% endblock content %}
{% block javascripts %}
<script>
var $update = $('#appbundle_projects_update');
var $every = $('#appbundle_projects_every');
var $on_selector = $('#appbundle_projects_on');
// When update gets selected ...
$update.change(function() {
$every.html('');
// ... retrieve the corresponding form.
var $form = $(this).closest('form');
// Simulate form data, but only include the selected update value.
var data = {};
data[$update.attr('name')] = $update.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(html) {
var options = $(html).find('#appbundle_projects_every option');
for (var i=0, total = options.length; i < total; i++) {
$every.append(options[i]);
}
}
});
});
// // When every gets selected ...
$every.change(function() {
$on_selector.html('');
// ... retrieve the corresponding form.
var $form = $(this).closest('form');
// Simulate form data, but only include the selected every value.
var data = {};
data[$every.attr('name')] = $every.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(html) {
var options = $(html).find('#appbundle_projects_on option');
for (var i=0, total = options.length; i < total; i++) {
$on_selector.append(options[i]);
}
}
});
});
</script>
{% endblock javascripts %}
{% endblock %}
public function editAction(Request $request, Projects $project)
{
$project->setUpdate($project->getFrequency()['update']);
$project->setEvery($project->getFrequency()['every']);
$project->setOn($project->getFrequency()['on']);
$editForm = $this->createForm('AppBundle\Form\ProjectsType', $project);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$frequency = array(
"update" => $project->getUpdate(),
"every" => $project->getEvery(),
"on" => $project->getOn()
);
$project->setFrequency($frequency);
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('projects_edit', array('id' => $project->getId()));
}
return $this->render('projects/edit.html.twig', array(
'project' => $project,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
$editForm->get('update')->getData(); //or setData( $data );