-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Turbo & Stimulus Powered JavaScript #6051
Comments
I have a little experience having these inside EasyAdmin application. The stack feels like magic, it's very impressive! I have built a form that uses I'll provide here a little scenario, just in case someone would be brave to try this too.
{% extends '@EasyAdmin/page/content.html.twig' %}
{% block main %}
<twig:RouteTemplateSelector/>
{{ importmap() }}
<link rel="stylesheet" href="{{ asset('styles/app.css') }}">
{% endblock %}
As you can see, the scenario is not so obvious. It would be amazing to have a more "native" way to implement this. |
That's really cool @b1rdex! Inside |
@weaverryan yes, the form is completely standalone and is built using |
Thanks @b1rdex, very cool! I tried something similar, but got stuck on not being able to get |
@mozkomor05 you can try getting it from request attributes. Or just create it manually from request. Reference code for more details: |
@b1rdex Thanks for the tips. After many hours of debugging I finally had success implementing LiveComponents for Easy Admin Forms. The trick was to save the AdminContext as a LiveProp, for which I wrote my own hydrator. #[LiveProp(hydrateWith: 'hydrateAdminContext', dehydrateWith: 'dehydrateAdminContext')]
public AdminContext $context;
public function hydrateAdminContext(array $data): AdminContext
{
$request = Request::create($data['requestUri']);
$action = $data['action'];
$dashboardController = $this->controllerFactory->getDashboardControllerInstance(
$data['dashboardControllerFqcn'],
$request
);
$crudController = $this->controllerFactory->getCrudControllerInstance(
$data['crudControllerFqcn'],
$action,
$request
);
$context = $this->adminContextFactory->create($request, $dashboardController, $crudController);
// Necessary as some EasyAdmin methods load context using AdminContextProvider
$this->requestStack->getCurrentRequest()?->attributes->set(EA::CONTEXT_REQUEST_ATTRIBUTE, $context);
return $context;
}
public function dehydrateAdminContext(AdminContext $context): array
{
return [
'dashboardControllerFqcn' => $context->getDashboardControllerFqcn(),
'crudControllerFqcn' => $context->getCrud()->getControllerFqcn(),
'requestUri' => $context->getRequest()->getUri(),
'action' => $context->getCrud()->getCurrentAction(),
];
} With AdminContext it is easy to instantiate EasyAdmin form: protected function instantiateForm(): FormInterface
{
$context = $this->context;
$action = $context->getCrud()->getCurrentAction();
$entityDto = $context->getEntity();
$entityFqcn = $entityDto->getFqcn();
$crudController = $this->controllerFactory->getCrudControllerInstance(
$context->getCrud()->getControllerFqcn(),
$context->getCrud()->getCurrentAction(),
$context->getRequest()
);
switch ($action) {
case Action::NEW:
$entityDto->setInstance($crudController->createEntity($entityFqcn));
$this->preprocessEntity($context, $crudController);
return $crudController->createNewForm($entityDto, $context->getCrud()->getNewFormOptions(), $context);
case Action::EDIT:
$this->preprocessEntity($context, $crudController);
return $crudController->createEditForm($entityDto, $context->getCrud()->getEditFormOptions(), $context);
default:
throw new \RuntimeException('LiveForm only supports new and edit actions.');
}
}
private function preprocessEntity(AdminContext $context, CrudControllerInterface $crudController): void
{
$entityDto = $context->getEntity();
$action = $context->getCrud()->getCurrentAction();
$this->entityFactory->processFields($entityDto, FieldCollection::new($crudController->configureFields($action)));
$fieldAssetsDto = new AssetsDto();
$currentPageName = $context->getCrud()?->getCurrentPage();
foreach ($entityDto->getFields() as $fieldDto) {
$fieldAssetsDto = $fieldAssetsDto->mergeWith($fieldDto->getAssets()->loadedOn($currentPageName));
}
$context->getCrud()->setFieldAssets($fieldAssetsDto);
$this->entityFactory->processActions($entityDto, $context->getCrud()->getActionsConfig());
} Usage: {# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #}
{% extends '@EasyAdmin/crud/edit.html.twig' %}
{% block edit_form %}
<twig:LiveForm :form="edit_form" :context="ea"/>
{% endblock %} This can be easily combined with DynamicFormBuilder (https://ux.symfony.com/demos/live-component/dependent-form-fields) in |
@mozkomor05 I am very sorry but I am not very familar with twig-components. Could you share how the twig-component LiveForm needs to look like? |
I am using Symfony 7.2 and finally figured that the twig-component LiveForm.html.twig needs to look like
It should be called from a template like
which is registered in a CrudController by
I am very grateful to @mozkomor05 for the code pubished here! It works just great and I have integrated it in the following abstract controller
This controller requires the function validate(string $property, string $value), which is meant to be a place to react on changes in a child controller. If you need you can also override the function buildForm(FormBuilderInterface $builder, array $options =[]), which is called after building the form defined by the function configureFields(string $pageName) in the CrudController calling the aforementioned template form_edit.html.twig. This buidlForm-function is the place to add dependent fields. I would be very happy, if someone could provide a more obvious way than to call {{ importmap() }} as sugested by b1rdex above in order to invoke a child controller like the following as a LiveComponent.
|
Closing because we're working on this already. It won't be available very soon, but we've already introduced several Twig components and the end goal is to build something very dynamic using UX Turbo. Thanks! |
Dear Javier,
Thank you! Please do not hesitate to contact me if you would need me for testing somewhen.
Cordially,
Jens
Von: Javier Eguiluz ***@***.***>
Gesendet: Dienstag, 31. Dezember 2024 14:05
An: EasyCorp/EasyAdminBundle ***@***.***>
Cc: Jens Simon ***@***.***>; Comment ***@***.***>
Betreff: Re: [EasyCorp/EasyAdminBundle] Turbo & Stimulus Powered JavaScript (Issue #6051)
Closing because we're working on this already. It won't be available very soon, but we've already introduced several Twig components and the end goal is to build something very dynamic using UX Turbo. Thanks!
—
Reply to this email directly, view it on GitHub <#6051 (comment)> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/BKCSOTP6BZMXDIDA3G4CXYT2IKJAXAVCNFSM6AAAAABRHVCLMWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNRWGQZTSNZXGY> .
You are receiving this because you commented. <https://github.com/notifications/beacon/BKCSOTPMWJB4WAUHQGLZEV32IKJAXA5CNFSM6AAAAABRHVCLMWWGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTUY7DBWA.gif> Message ID: ***@***.*** ***@***.***> >
|
Short description of what this feature will allow to do:
Hi everyone!
This is not really a request as it would take a bit of work and I am very willing to help with it. But I do think it is important, and people are asking about it more and more (I answered 2 questions about this on Symfonycasts tonight).
In short, it would be wonderful if the JavaScript used by EasyAdmin were powered by Stimulus, This would then allow us to add Turbo to EasyAdmin, giving it the SPA-like experience. Once these are done, it opens up a lot of other possibilities - like allowing any forms to be opened up in a modal natively (there is a simple strategy for this using Turbo Frames that I'll talk about in our LAST stack tutorial https://symfonycasts.com/screencast/last-stack ).
@javiereguiluz WDYT about this in principle? Have you gotten other similar requests or request for an even more modern frontend for EasyAdmin?
Thanks!
The text was updated successfully, but these errors were encountered: