Article

"Building Interactive Modal Windows with [[ Stimulus JS and Twig" ]]**]]

Topic: TravelBy Rchard MathewPublished Recently added

Legacy signals

Legacy popularity: 207 legacy views

Passing a parameter from a Stimulus JS controller to a modal window defined in a Twig template is a common use case in web development, especially when building interactive interfaces with modern JavaScript frameworks and server-side templating engines. In this comprehensive guide, we'll walk you through the steps required to achieve this functionality, from setting up your Stimulus controller to passing the purchase ID (i.e., row._id) into the modal, which will then enable you to approve a specific purchase. Table of Contents Introduction to Stimulus JS Setting up the HTML Grid (Twig Template) Creating the Stimulus JS Controller Setting up the Modal Window in Twig Passing Data from Stimulus to the Modal Finalizing the Approve Purchase Flow Handling Events in Stimulus Example Code Walkthrough Best Practices and Troubleshooting 1. Introduction to Stimulus JS Stimulus is a modest JavaScript framework that enhances static HTML by adding small pieces of interactivity. It allows you to manage client-side behavior through controllers attached to HTML elements, which means you can add interactivity without writing an entire JavaScript app. Stimulus works well in server-rendered environments like Symfony, where the backend can easily pass data into the front-end via Twig templates. 2. Setting up the HTML Grid (Twig Template) First, let's start by rendering the grid of purchases in your Twig template. Each purchase will have a "detail" link and an "approve purchase" button that triggers the modal. Here's an example of how your grid might look: twig Copy code {% for purchase in purchases %} {% endfor %}
ID Name Amount Action
{{ purchase.id }} {{ purchase.name }} {{ purchase.amount }} Approve Purchase
Approve Purchase
×

Are you sure you want to approve purchase #?

Close Approve
Explanation of the Above Code: Grid of Purchases: A table is created with a list of purchases. Each row in the table has a button labeled "Approve Purchase." Data Attributes: Each row contains a data-purchase-id attribute that stores the purchase ID, and data-controller="purchase-row" attaches the Stimulus controller to the row. Modal: A simple modal is added that will display the purchase ID when the user clicks the "Approve Purchase" button. 3. Creating the Stimulus JS Controller Now we need to create a Stimulus controller that will handle the interaction with the modal. The controller will listen for the click event on the "Approve Purchase" button, retrieve the purchase ID from the button, and pass it to the modal. Here’s an example of how the controller can be structured: javascript Copy code // assets/controllers/purchase_row_controller.js import { Controller } from "stimulus"; export default class extends Controller { static targets = ["modal", "purchaseIdField"]; connect( ) { console.log("Purchase Row Controller connected"); } openModal(event) { // Get the purchase ID from the clicked button const purchaseId = event.target.getAttribute("data-purchase-id"); // Pass the purchase ID to the modal this.purchaseIdFieldTarget.textContent = purchaseId; // Show the modal (use Bootstrap modal method) $('#approvePurchaseModal').modal('show'); // Store the purchase ID in a global variable or pass it to the backend when the modal is confirmed this.purchaseId = purchaseId; } approvePurchase( ) { // Logic to approve the purchase // This could involve making an API request to update the purchase status console.log("Approving purchase", this.purchaseId); // Close the modal $('#approvePurchaseModal').modal('hide'); } } Explanation of the Above Code: Targeting Elements: The static targets property is used to define which elements within the controller's scope we want to interact with. In this case, we’re targeting the modal and the purchase ID field. openModal(): This function is triggered when the user clicks the "Approve Purchase" button. It retrieves the purchase ID from the button's data-purchase-id attribute, passes it to the modal, and shows the modal. approvePurchase(): This function will be triggered when the user confirms the action. You can use this method to make an API request or update the purchase status on the server. 4. Setting up the Modal Window in Twig The modal window is already defined in the previous Twig template. It is important to ensure that when the modal opens, it displays the correct purchase ID. The modal contains a span with an id="purchaseId", which will be updated dynamically via the Stimulus controller. 5. Passing Data from Stimulus to the Modal This step is where the data from the grid (purchase ID) is passed to the modal. We achieve this by using the openModal function within the Stimulus controller. When the "Approve Purchase" button is clicked, the openModal method is triggered. The purchase ID is retrieved from the data-purchase-id attribute of the clicked button. The purchase ID is then inserted into the modal's content by targeting the purchaseIdField (which corresponds to the span with id="purchaseId"). The modal is shown using Bootstrap's modal methods. 6. Finalizing the Approve Purchase Flow Now that the modal is set up and the purchase ID is passed to it, the final step is to handle the approval logic when the user clicks the "Approve" button. Here’s the relevant part of the code to handle the approval process: javascript Copy code // Inside your Stimulus controller approvePurchase( ) { // Make a request to the backend to approve the purchase fetch(`/approve_purchase/${this.purchaseId}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ purchaseId: this.purchaseId, status: 'approved', }), }) .then(response => response.json()) .then(data => { if (data.success) { console.log(`Purchase #${this.purchaseId} approved!`); // Update the UI or handle further actions } else { console.error("Failed to approve the purchase."); } }) .catch(error => console.error('Error:', error)); // Close the modal $('#approvePurchaseModal').modal('hide'); } Explanation: API Request: When the user clicks "Approve," the approvePurchase function makes a POST request to the server to update the purchase status. The URL /approve_purchase/${this.purchaseId} should correspond to a route in your Symfony app that handles the approval logic. UI Update: If the request is successful, you can update the UI to reflect the new status of the purchase (e.g., change the row in the table to show that the purchase was approved). 7. Handling Events in Stimulus In Stimulus, event handlers are defined using the data-action attribute. In this example, when the user clicks the "Approve Purchase" button, it triggers the openModal method. To handle the approval action, you would need to add another data-action attribute to the modal’s "Approve" button: html Copy code Approve This links the button click event to the approvePurchase method in the controller. 8. Example Code Walkthrough Now that we have a full understanding of how the Stimulus controller works and how data flows from the grid to the modal, here’s the full example: Twig Template (HTML) twig Copy code {% for purchase in purchases %} {% endfor %}
ID Name Amount Action
{{ purchase.id }} {{ purchase.name }} {{ purchase.amount }} Approve Purchase
Approve Purchase
×

Are you sure you want to approve purchase #?

Close Approve
Stimulus Controller (JavaScript) javascript Copy code import { Controller } from "stimulus"; export default class extends Controller { static targets = ["modal", "purchaseIdField"]; openModal(event) { const purchaseId = event.target.getAttribute("data-purchase-id"); this.purchaseIdFieldTarget.textContent = purchaseId; this.purchaseId = purchaseId; $('#approvePurchaseModal').modal('show'); } approvePurchase( ) { fetch(`/approve_purchase/${this.purchaseId}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ purchaseId: this.purchaseId, status: 'approved', }), }) .then(response => response.json()) .then(data => { if (data.success) { console.log(`Purchase #${this.purchaseId} approved!`); } else { console.error("Failed to approve the purchase."); } }) .catch(error => console.error('Error:', error)); $('#approvePurchaseModal').modal('hide'); } } 9. Best Practices and Troubleshooting Event Handling: Always ensure that event handlers are correctly linked to the actions defined in the controller. Use data-action properly to trigger methods in the Stimulus controller. Modal Visibility: Make sure that the modal is properly hidden before it is shown again. Sometimes modals may not display correctly if they are already visible or not reset between usages. Testing: Test the purchase approval flow thoroughly, especially the API request to approve purchases. Ensure that the modal data is correctly updated, and make sure the server-side logic is working as expected. This guide should give you a solid understanding of how to pass data (in this case, a purchase ID) from a Stimulus JS controller to a modal window defined in a Twig template. By following these steps, you can create interactive, dynamic UIs that leverage both the power of Stimulus JS for interactivity and Twig for rendering server-side templates.

Article author

About the Author

Rchard Mathew is a passionate writer, blogger, and editor with 36+ years of experience in writing. He can usually be found reading a book, and that book will more likely than not be non-fictional.