Динамическое изменение содержимого формы в Symfony 4 - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть 3 объекта, которые я хочу использовать в форме: пользователь, адрес и тег. Тег ссылается на пользователя и адрес через их идентификаторы:

mysql> describe user;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| name  | longtext | NO   |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> describe address;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| name  | longtext | NO   |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> describe tag;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| user_id    | int(11)  | YES  | MUL | NULL    |                |
| address_id | int(11)  | YES  | MUL | NULL    |                |
| text       | longtext | NO   |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

Мой конструктор форм:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('user',EntityType::class, [
            'class' => User::class
        ])
        ->add('address', EntityType::class, [
            'class' => Address::class
        ])
        ->add('text')
        ->add('save', SubmitType::class)
    ;
}

Теперь я добавил несколько JS, чтобы форма отправлялась, когда пользователь из выпадающего списка меняет либо выбранного пользователя, либо адрес. Но если существует соответствующий тег с выбранным пользователем и адресом, я хочу предварительно заполнить текстовое поле в форме, чтобы пользователь мог его редактировать. Кто-нибудь знает, как я могу сделать это в Symfony?

Пожалуйста, проверьте это изображение

В случае изменения, отправьте форму с JS. Если в БД существует тег с соответствующим пользователем и адресом, предварительно загрузите текст из БД в текстовое поле, чтобы пользователь мог видеть, что он уже существует и его можно редактировать. В противном случае просто отобразите пустое поле, и при нажатии Сохранить будет создан новый тег.

1 Ответ

0 голосов
/ 04 сентября 2018

Во-первых, вам нужно привязать вашу форму к вашему классу тегов. Итак, в TagType.php у вас будет:

public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults([
        'data_class' => Tag::class,
        'csrf_token_id' => 'tag_form'
    ]);
}

Есть много способов реализовать желаемую функциональность. Например, вы можете найти все теги в вашей базе данных, перечислить их и с помощью кнопок редактирования отредактировать каждый нужный тег. Тогда у вас также будет кнопка «Создать» для создания новых тегов.

Но так, как вы решили его реализовать, вам не нужно отправлять форму при смене пользователя или адреса. Все, что вам нужно, это создать функцию javascript следующим образом:

function onChange(){
    var userId = $('input#user_input').val();
    var addressId = $('input#address_input').val();
    $.post( "check-tag", { user: userId, address: addressId }).done(function( data ) {
        if (data.tagText !== ""){
            $( "input#text_input" ).val( data.tagText );
        }
    });
}

Затем привяжите ваши обработчики событий следующим образом:

$('input#user_input, input#address_input').on('change', function() {
    onChange();
});

Ваш контроллер для маршрута 'check-tag' должен выглядеть следующим образом:

/**
 * @Route("/check-tag", name="check-tag", options={ "expose" = true })
 */
public function checkTag(Request $request, EntityManagerInterface $em) {
    $userId = $request->request->get('user');
    $addressId = $request->request->get('address');
    $tagRepository = $em->getRepository(Tag::class);
    $tag = $tagRepository->findBy(['user' => $userId, 'address' => $addressId]);

    $tagText = $tag ? $tag->getText() : '';

    return $this->json(['tagText' => $tagText]);
}

Наконец, вы можете правильно заполнить форму, когда будете готовы. Нет необходимости в проверке и т. Д., Когда вам просто нужно проверить, существует ли тег, и получить его текст.

ПРИМЕЧАНИЯ:

  • Код выше предполагает, что вы используете доктрину для обработки вашего соединения с базой данных. В противном случае просто измените код правильно.
  • Вы должны использовать FOSJsRoutingBundle для генерации маршрутов в javascript вместо их жесткого кодирования, как в моем примере. Вот где в моей конфигурации маршрута используется опция expose = true.
  • Вам придется еще раз проверить, существует ли тег в вашем контроллере, где вы обрабатываете отправку формы, в противном случае вы получите сообщение об ошибке доктрины для повторной вставки при попытке сохранить уже существующий тег.
  • Конечно, вам придется немного изменить мой код, особенно если вы не используете jQuery.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...