У меня такой тип формы:
<?php
namespace Myproject\App\ErpBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormEvent;
use Myproject\OrderBundle\Entity\OrderProductType;
use Myproject\OrderBundle\Entity\OrderOrder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\HttpFoundation\RequestStack;
class OrderSearchType extends AbstractType
{
protected $em;
protected $container;
protected $requestStack;
public function __construct(ObjectManager $em, ContainerInterface $container, RequestStack $requestStack)
{
$this->em = $em;
$this->container = $container;
$this->requestStack = $requestStack;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$data = $builder->getData();
$currentRequest = $this->requestStack->getCurrentRequest();
$pt = [
'class' => OrderProductType::class,
'choices' => [],
'required' => false
];
if ($productType = $currentRequest->query->get('ProductType', null)) {
$pt["data"] = $productType;
}
$id = [
'label' => 'id',
'required' => false
];
if ($idValue = $currentRequest->query->get('id', null)) {
$id["data"] = $idValue;
}
$name = [
'label' => 'név',
'required' => false
];
if ($nm = $currentRequest->query->get('name', null)) {
$name["data"] = $nm;
}
$builder
->add('productType', EntityType::class, $pt)
->add('id', IntegerType::class, $id)
->add('name', TextType::class, $name)
->add('status', ChoiceType::class, [
'choices' => [ 'Bármilyen',
OrderOrder::$ORDER_STATUS_TEXT[OrderOrder::$ORDER_STATUS_ORDERED],
OrderOrder::$ORDER_STATUS_TEXT[OrderOrder::$ORDER_STATUS_ACCEPTED],
OrderOrder::$ORDER_STATUS_TEXT[OrderOrder::$ORDER_STATUS_REFUSED]
],
'data' => $currentRequest->query->get('status', "1")
])
->add('search', SubmitType::class, [
'label' => 'Keresés',
'attr' => ['class' => 'btn btn-primary btn-sm']
]);
$builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPresubmit'));
$builder->addEventListener(FormEvents::POST_SET_DATA, array($this, 'onPostSetData'));
}
public function onPostSetData(FormEvent $event)
{
$form = $event->getForm();
$data = $form->getData();
$event->getForm()
->add('productType', EntityType::class, [
'class' => OrderProductType::class,
'choices' => $this->em->getRepository(OrderProductType::class)->findAll(),
'choice_label' => function($orderProductType = null) {
return sprintf($orderProductType ? $orderProductType->getTitle() : "Kérem válasszon");
},
'label' => 'Termékfajta',
'required' => false,
'attr' => [
'class' => 'selectpicker',
'data-live-search' => 'true'
]
]);
}
public function onPresubmit(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
$event->getForm()
->add('productType', EntityType::class, [
'class' => OrderProductType::class,
'choices' => $this->em->getRepository(OrderProductType::class)->findAll(),
'choice_label' => function($orderProductType = null) {
return sprintf($orderProductType ? $orderProductType->getTitle() : "Kérem válasszon");
},
'label' => 'Termékfajta',
'required' => false,
'attr' => [
'class' => 'selectpicker',
'data-live-search' => 'true'
]
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => null,
'em' => $this->em,
]);
parent::configureOptions($resolver);
}
public function getBlockPrefix()
{
return 'route';
}
}
Он отображается в пользовательском интерфейсе следующим образом:
{{ form_start(form, { 'attr': {'class': 'myprojectAdminForm pull-right', 'id': form.vars.name } }) }}
Szűrés:
{{ form_widget(form.productType) }}
{{ form_widget(form.id, {'attr': {'placeholder': form.id.vars.label, 'class':'form-control'}}) }}
{{ form_widget(form.name, {'attr': {'placeholder': form.name.vars.label, 'class':'form-control' }}) }}
{{ form_widget(form.status, {'attr': {'class':'form-control'}}) }}
{{ form_widget(form.search) }}
{{ form_widget(form._token) }}
{{ form_errors(form) }}
{{ form_end(form, {'render_rest': false}) }}
и всякий раз, когда пользователь нажимает на поиск, выполняется следующий Javascript:
$("#erpordersearch_search").click(function(e) {
e.preventDefault();
var productTypeID = document.querySelector("#erpordersearch_productType").value;
var ID = document.getElementById("erpordersearch_id").value;
var name = document.getElementById("erpordersearch_name").value;
var status = document.getElementById("erpordersearch_status").value;
var url = window.location.href.substring(0, window.location.href.lastIndexOf("/page"));
url = url + "/page1";
window.location.href = url + "[ProductTypeID = " + productTypeID + "&id = " + ID + "&name = " + name + "&status = " + status + "]";
});
Это работает, но проблема в том, что я отслеживаю историю действий пользователя в пользовательском интерфейсе, и если система загружает полную страницу, я теряю всю историю действий пользователя, поскольку история сохраняется в Javascript. Я знаю, что могу сохранить историю в базе данных или localStorage, но в моем случае любой из этих вариантов не является жизнеспособным, поскольку они нарушают политику проекта. Меня попросили внести изменения, которые будут включать следующие функции:
[queryString=somevalue] после ответа на запрос, даже если он не содержал его до запроса GETvar foo = 'bar';, то после запроса должна быть определена переменнаяМне дали расплывчатое описание того, как этого можно достичь с помощью комбинации Symfony и конкретного проекта, над которым я работаю, но оно неясно и содержит информацию о конкретном проекте, которой я не могу здесь поделиться.
Итак, мой вопрос: есть ли способ с помощью PHP и Symfony изменить URL-адрес при отправке запроса и при этом сохранить все переменные, которые были определены в Javascript?






Единственный способ, которым я бы сказал, что это возможно (приготовьтесь к более расплывчатым объяснениям), - это хранить ваши переменные JavaScript в невидимых элементах формы, которые отправляются при нажатии кнопки поиска.
Затем они должны быть отправлены контроллеру Symfony через почтовые данные, сформируйте здесь, затем вы можете использовать описанный здесь метод для отправки переменных в JavaScript из PHP (но изменен для синтаксиса ветки) - Как я могу сохранить вывод переменной JavaScript в переменной PHP?
Если в файле сценария, вы можете попробовать передать аргументы таким образом - https://www.gun.io/blog/pass-arguments-to-embedded-javascript-tutorial-example
Прочитав все это еще раз (и обсудив это в комментариях ниже), я думаю, что я лучше понимаю вопрос.
Я лично согласен с вами, похоже, это невозможно сделать в чистом Symfony через GET-запросы.
Даже если бы существовал «хакерский» метод, он не был бы масштабируемым или динамичным, и поэтому не стоил бы его.
В этом проекте Symfony есть хлебная крошка, и всякий раз, когда мы щелкаем ссылку, она раскрывается. Однако, если мы нажмем на ссылку хлебных крошек, данная страница должна загрузиться без полной загрузки страницы. Если URL-адрес не содержит того, что мне нужно, история будет потеряна. Я могу реализовать хаки, но они не будут приняты, пока я не докажу, что первоначальная идея невозможна.
@LajosArpad думали ли вы о том, чтобы просто изменить URL-адрес в Javascript и использовать что-то вроде vue.js для отображения результатов с помощью JSON? Связанный вопрос об изменении URL - stackoverflow.com/questions/824349/…
Меня не интересует VueJS в контексте этого вопроса, однако предоставленная вами ссылка отвечает на суть этого вопроса. Поскольку это вопрос Symfony, нам нужно знать, есть ли в Symfony что-то, что отвечает за такое поведение.
@LajosArpad, насколько я понимаю PHP и Java, это не проблема Symfony, а просто фундаментальный способ работы сети (если я правильно понимаю ваш вопрос), поскольку Java является клиентской, а Symfony - серверной, нет ничего вы можете изменить любой из них, чтобы удалить это поведение, поскольку оно не вызвано ни тем, ни другим. Вам понадобится «хакерское» решение или взгляните на JSON-фреймворки, чтобы решить эту проблему.
Под «Java», я полагаю, вы имели в виду Javascript. Symfony - это большой набор инструментов, который предоставляет множество инструментов. Если я начну использовать инструмент вне Symfony, тогда как Symfony предоставляет эквивалентный инструмент для того же, тогда мое решение не будет принято. Вы указали, что эта функция возможна, и рекомендовали VueJS, однако VueJS не подходит, если для этого нет решения на основе Symfony. Symfony предоставляет фреймворк на стороне сервера, но это не исключает возможности предоставления функций на стороне клиента.
Подробнее о клиентских функциях Symfony читайте здесь: symfony.com/doc/current/frontend.html
@lajosarpad, однако, даже те функции, с которыми вы связались, технически не являются «клиентской стороной», поскольку они всего лишь оболочки для обслуживания контента клиенту и управления активами. Прочитав все это еще раз, я думаю, что лучше понимаю вопрос. Я лично согласен с вами, похоже, это невозможно сделать в чистом Symfony через GET-запросы. Даже если бы существовал «хакерский» метод, он не был бы масштабируемым или динамичным.
Пожалуйста, отредактируйте свой ответ, указав эту информацию, чтобы я мог принять ее и сообщить мне об этом в разделе комментариев. Спасибо.
Я понимаю ваш ответ, но если я это реализую, он не будет принят. Ожидается, что при поиске будет получен запрос GET, который изменит URL-адрес и изменит содержимое страницы без полной перезагрузки. Насколько мне известно, URL-адрес не может быть изменен без перезагрузки страницы (за исключением изменения хэша, что здесь не вариант). Если я прав в том, что это невозможно, то я могу сказать другим, что их идея невозможна. Если есть возможность, я должен это реализовать.