Estoy tratando de seguir esta guía para actualizar un campo de formulario cuando el usuario cambia otro campo.
Configuré correctamente mis FormTypes, pero tengo problemas para enviar el formulario en Ajax sin JQuery .
Tengo 2 selecciones:
const blockchain = document.getElementById('strategy_farming_blockchain'); const dapp = document.getElementById('strategy_farming_dapp'); const csrf = document.getElementById('strategy_farming__token'); Se supone que el campo blockchain actualiza el campo dapp .
Si envío todo el formulario, está funcionando:
blockchain.addEventListener('change', function () { const form = this.closest('form'); const method = form.method; const url = form.action; var request = new XMLHttpRequest(); request.open(method, url, true); request.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); request.onload = function () { if (this.status >= 200 && this.status < 400) { //Success const html = new DOMParser().parseFromString(this.response, 'text/html'); dapp.innerHTML = html.querySelector('#strategy_farming_dapp').innerHTML; } else { //Error from server console.log('Server error'); } }; request.onerror = function () { //Connection error console.log('Connection error'); }; request.send(new FormData(form)); }); Pero se supone que no debo enviar el formulario completo, se supone que debo enviar solo el valor de la cadena de blockchain
Intenté muchas cosas, como
var formdata = new FormData(form); formdata.delete(dapp.name); request.send(formdata); // It's working for a new entity, but if I'm editing one, it's not updating the dapp field...o
var formdata = new FormData(); formdata.append(this.name, this.value); formdata.append(csrf.name, csrf.value); request.send(formdata); // It's working in a NEW action, but not in an EDIT action...o
var data = {}; data[this.name] = this.value; request.send(data); //or request.send(JSON.stringify(data)); //If I dump($request->request) in the controller, it seems like there's no data... //Or the request isn't parsed correctly, or there's something missing ? También probé con encodeURIComponent ...
Me quedé sin ideas... ¿Alguna idea? Gracias !
Así que elegí usar FormData y eliminé el campo dapp .
const blockchain = document.getElementById('strategy_farming_blockchain'); const dapp = document.getElementById('strategy_farming_dapp'); blockchain.addEventListener('change', function () { const form = this.closest('form'); const method = form.method; const url = form.action; var request = new XMLHttpRequest(); request.withCredentials = true; request.open(method, url, true); request.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); request.onload = function () { if (this.status >= 200 && this.status < 400) { //Success const html = new DOMParser().parseFromString(this.response, 'text/html'); dapp.innerHTML = html.querySelector('#strategy_farming_dapp').innerHTML; } else { //Error from server console.log('Server error'); } }; request.onerror = function () { //Connection error console.log('Connection error'); }; var formdata = new FormData(form); formdata.set(dapp.name, ""); request.send(formdata); });Aquí está el FormType
public function buildForm(FormBuilderInterface $builder, array $options): void { $builder //... ->add('blockchain', EntityType::class, [ 'required' => false, 'class' => Blockchain::class, 'attr' => ['class' => 'js-select2'], ]); $formModifier = function (FormInterface $form, Blockchain $blockchain = null) { $dapps = null === $blockchain ? [] : $blockchain->getDapps(); $form->add('dapp', EntityType::class, [ 'class' => Dapp::class, 'required' => true, 'choices' => $dapps, 'placeholder' => 'My placeholder', 'attr' => ['class' => 'js-select2'], ]); }; $builder->addEventListener( FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formModifier) { /** * @var StrategyFarming $data */ $data = $event->getData(); $blockchain = $data->getDapp() ? $data->getDapp()->getBlockchain() : null; $formModifier($event->getForm(), $blockchain); } ); $builder->get('blockchain')->addEventListener( FormEvents::POST_SUBMIT, function (FormEvent $event) use ($formModifier) { $blockchain = $event->getForm()->getData(); $formModifier($event->getForm()->getParent(), $blockchain); } ); }Para que esto funcione, tuve que agregar el campo blockchain a la Entidad de mi formulario, para que la Solicitud maneje el campo:
/** * Not persisted * @var Blockchain */ private $blockchain; public function getBlockchain(): ?Blockchain { if ($this->blockchain === null && $this->dapp !== null && $this->dapp->getBlockchain() !== $this->blockchain) { $this->blockchain = $this->dapp->getBlockchain(); } return $this->blockchain; } public function setBlockchain(?Blockchain $blockchain): self { $this->blockchain = $blockchain; return $this; }