Open momocode-de opened 6 months ago
I did it with an event, listened by the ModalComponent which itselfs change its model and trigger an event leading to the re-render and the opening of the modal there:
There is a controller which use event delegation to handle the "clicks" but if you have a compenent for every item it's event better
const customEvent = new CustomEvent('Icon:Clicked', { detail: { icon: iconCard.title }, bubbles: true });
window.dispatchEvent(customEvent);
Then the modal controller listen to this and
connect() {
window.addEventListener('Icon:Clicked', this.onIconClick.bind(this));
}
// ...
onIconClick(event) {
const input = this.element.querySelector('input');
input.value = event.detail.icon;
input.dispatchEvent(new Event('change', {bubbles: true}));
this.show();
}
Now the ModalController, beeing a LiveController, has got the "id" and can render a form with the correct entity
The event part could be improved but you got the idea
@smnandre Thank you for your approach! I have now done it with an extra controller for this type of modal. I have added this to the template of the general bootstrap modal component:
<div {{ attributes.defaults(stimulus_controller('bootstrap-modal')) }} ...
And where the modal is added to the template, I now add an extra controller:
{% component BootstrapModal with {id: 'my-item-modal', 'data-controller': 'my-item-modal'} %}
This is the "my-item-modal-controller" for this specific type of modals:
import { Controller } from '@hotwired/stimulus';
import { getComponent } from '@symfony/ux-live-component';
/* stimulusFetch: 'lazy' */
export default class extends Controller {
async initialize() {
// The inner component of the modal
this.formComponent = await getComponent(this.element.querySelector('[data-live-name-value="MyItemForm"]'));
}
connect() {
this.element.addEventListener('show.bs.modal', (event) => {
this.formComponent.set('item', event.relatedTarget.dataset.itemId);
});
}
}
I then added the data attribute for the ID to the buttons that open the modal: data-item-id="{{ item.id }}"
Please let me know if there are any better approaches.
It seems very clean & reusable 👍
Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?
I tried the following demo for a bootstrap modal: https://ux.symfony.com/demos/live-component/product-form
It works quite well, but I have a question. I have a list of items on my page and each item has a button that should open the modal. In the modal there should be a form that contains a hidden input with the ID of the item. There are also two text fields. If I render the modal in every item, this is not a problem. But that wouldn't be so nice if the modal is rendered in every item just because it has to contain the ID of the item in the hidden input. So my idea would be to include the modal in the template once under the list. Is there a smart way to set the value of the input field when the button is clicked, i.e. when the modal is opened?