Встроенная форма и сохранение (многие ко многим)
У меня есть ошибка при создании скрипта в JQuery, который позволил бы мне добавить несколько пар навыков / уровня в форму рекламы. На самом деле, я хотел бы добавить тезисные пары благодаря кнопке JS и иметь возможность видеть навыки / уровни, добавленные в пользовательском интерфейсе.
Конечно, данные должны храниться в базе данных, когда мы отправим форму.
Мне действительно нужна твоя помощь, потому что я пытаюсь улучшить себя с Symfony, но я только начинаю с этим, и я застрял в течение нескольких недель...
Вот несколько кодов моего приложения:
*** ADVERT ENTITY ***
/**
* Advert
*
* @ORM\Table(name="oc_advert")
@ORM\Entity(repositoryClass="OC\PlatformBundle\Repository\AdvertRepository")
* @ORM\HasLifecycleCallbacks()
*/
class Advert
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var \DateTime
*
* @ORM\Column(name="date", type="datetime")
* @Assert\DateTime()
*/
private $date;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=255)
* @Assert\Length(min=10)
*/
private $title;
/**
* @var string
*
* @ORM\Column(name="author", type="string", length=255)
* @Assert\Length(min=2)
*/
private $author;
/**
* @var string
*
* @ORM\Column(name="content", type="text")
* @Assert\NotBlank()
* @Antiflood()
*/
private $content;
/**
* @ORM\Column(name="published", type="boolean")
*/
private $published = true;
/**
* @ORM\OneToOne(targetEntity="OC\PlatformBundle\Entity\Image", cascade=
{"persist", "remove"})
* @Assert\Valid()
*/
private $image;
/**
* @ORM\ManyToMany(targetEntity="OC\PlatformBundle\Entity\Category",
cascade={"persist"})
* @ORM\JoinTable(name="oc_advert_category")
*/
private $categories;
/**
* @ORM\OneToMany(targetEntity="OC\PlatformBundle\Entity\Application",
mappedBy="advert")
*/
private $applications;
/**
* @ORM\Column(name="updated_at", type="datetime", nullable=true)
*/
private $updatedAt;
/**
* @ORM\Column(name="nb_applications", type="integer")
*/
private $nbApplications = 0;
/**
* @ORM\Column(name="email", type="text", length=255)
*/
private $email;
/**
* @Gedmo\Slug(fields={"title"})
* @ORM\Column(name="slug", type="string", length=255, unique=true)
*/
private $slug;
/**
* @ORM\Column(name="ip", type="text", length=255)
*/
private $ip;
/**
* @ORM\ManyToOne(targetEntity="OC\UserBundle\Entity\User",
inversedBy="advert")
*/
private $user;
/**
* @ORM\OneToMany(targetEntity="OC\PlatformBundle\Entity\AdvertSkill",
mappedBy="advert")
*/
private $advertSkills;
public function __construct()
{
//Par défaut, la date de l'annonce est la date d'aujourd'hui
$this->date = new \DateTime();
$this->categories = new ArrayCollection();
$this->applications = new ArrayCollection();
$this->advertSkills = new ArrayCollection();
}
*** SKILL ENTITY ***
/**
* @ORM\Entity
* @ORM\Table(name="oc_skill")
*/
class Skill
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="OC\PlatformBundle\Entity\AdvertSkill",
mappedBy="skill")
*/
private $advertSkills;
public function getId()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
public function setAdvertSkills(\OC\PlatformBundle\Entity\advertSkills
$advertSkill)
{
$this->advertSkills[] = $advertSkill;
}
public function getAdvertSkills()
{
return $this->advertSkills;
}
}
*** ADVERT SKILL ENTITY ***
/**
* @ORM\Entity
* @ORM\Table(name="oc_advert_skill")
*/
class AdvertSkill
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="level", type="string", length=255)
*/
private $level;
/**
* @ORM\ManyToOne(targetEntity="OC\PlatformBundle\Entity\Advert",
inversedBy="advertSkills")
* @ORM\JoinColumn(nullable=false)
*/
private $advert;
/**
* @ORM\ManyToOne(targetEntity="OC\PlatformBundle\Entity\Skill",
inversedBy="advertSkills")
* @ORM\JoinColumn(nullable=false)
*/
private $skill;
public function getId()
{
return $this->id;
}
public function setLevel($level)
{
$this->level = $level;
}
public function getLevel()
{
return $this->level;
}
public function setAdvert(\OC\PlatformBundle\Entity\Advert $advert)
{
$this->advert = $advert;
}
public function getAdvert()
{
return $this->advert;
}
public function setSkill()
{
$this->skill = $skill;
}
public function getSkill()
{
return $this->skill;
}
}
*** ADVERT TYPE FORM ***
class AdvertType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('date', DateTimeType::class, array(
'view_timezone' => 'Europe/Paris',
'with_seconds' => true
))
->add('title', TextType::class)
->add('content', TextareaType::class)
->add('author', TextType::class)
->add('email', TextType::class)
->add('image', ImageType::class)
->add('categories', EntityType::class, array(
'class' => 'OCPlatformBundle:Category',
'choice_label' => 'name',
'multiple' => true
))
->add('advertSkills', CollectionType::class, array(
'entry_type' => AdvertSkillType::class,
'allow_add' => true,
'prototype' => true
))
->add('save', SubmitType::class);
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) {
$advert = $event->getData();
if (null == $advert) {
return;
}
if (!$advert->getPublished() || null == $advert->getId()) {
$event->getForm()->add('published', CheckboxType::class,
array('required' => false));
} else {
$event->getForm()->remove('published');
}
}
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'OC\PlatformBundle\Entity\Advert'
));
}
}
*** ADVERT SKILL TYPE FORM ***
class AdvertSkillType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array
$options)
{
$builder
->add('skill', EntityType::class, array(
'class' => 'OCPlatformBundle:Skill',
'choice_label' => 'name',
))
->add('level', ChoiceType::class, array(
'choices' => array(
'Débutant' => 'Débutant',
'Intermédiaire' => 'Intermédiaire',
'Expert' => 'Expert',
),
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'OC\PlatformBundle\Entity\AdvertSkill'
));
}
}
*** ADVERT TWIG FORM ***
<div class="well">
{{ form_start(form_advert) }}
{{ form_errors(form_advert) }}
<div id="advert">
<div class="form-group">
{{ form_label(form_advert.date, "Date", {'label_attr': {'class':
'control-label required'}}) }}
{{ form_errors(form_advert.date) }}
{{ form_widget(form_advert.date) }}
</div>
<div class="form-group">
{{ form_label(form_advert.title, "Title", {'label_attr': {'class':
'control-label required'}}) }}
{{ form_errors(form_advert.title) }}
{{ form_widget(form_advert.title, {'attr': {'class': 'form-control'}}) }}
</div>
<div class="form-group">
{{ form_label(form_advert.content, "Contenu", {'label_attr': {'class':
'control-label required'}}) }}
{{ form_errors(form_advert.content) }}
{{ form_widget(form_advert.content, {'attr': {'class': 'form-control'}})}}
</div>
<div class="form-group">
{{ form_label(form_advert.author, "Auteur", {'label_attr': {'class':
'control-label required'}}) }}
{{ form_errors(form_advert.author) }}
{{ form_widget(form_advert.author, {'attr': {'class': 'form-control'}}) }}
</div>
<div class="form-group">
{{ form_label(form_advert.email, "Email", {'label_attr': {'class':
'control-label required'}}) }}
{{ form_errors(form_advert.email) }}
{{ form_widget(form_advert.email, {'attr': {'class': 'form-control'}}) }}
</div>
<div class="form-group">
{{ form_label(form_advert.image, "Image", {'label_attr': {'class':
'control-label required'}}) }}
{{ form_errors(form_advert.image) }}
<div id="advert_image">
<div class="form-group">
{{ form_widget(form_advert.image, {'attr': {'class': 'control-label
required'}}) }}
</div>
</div>
</div>
<div class="form-group">
{{ form_label(form_advert.categories, "Catégories", {'label_attr':
{'class': 'control-label required'}}) }}
{{ form_errors(form_advert.categories) }}
{{ form_widget(form_advert.categories, {'attr': {'class': 'form-
control'}}) }}
</div>
<div id="oc_platformbundle_advert_skill" class="form-group">
{{ form_label(form_advert.advertSkills.vars.prototype.skill,
"Compétences", {'label_attr': {'class': 'control-label required'}}) }}
{{ form_errors(form_advert.advertSkills.vars.prototype.skill) }}
{{ form_widget(form_advert.advertSkills.vars.prototype.skill, {'attr':
{'class': 'form-control'}}) }}
</div>
<div class="form-group">
{{ form_label(form_advert.advertSkills.vars.prototype.level, "Niveau",
{'label_attr': {'class': 'control-label required'}}) }}
{{ form_errors(form_advert.advertSkills.vars.prototype.level) }}
{{ form_widget(form_advert.advertSkills.vars.prototype.level, {'attr':
{'class': 'form-control'}}) }}
</div>
{{ form_widget(form_advert.save, {'attr': {'class': 'btn btn-primary'}}) }}
{{ form_rest(form_advert) }}
</div>
{{ form_end(form_advert) }}
</div>