Home > OS >  How to launch a modal window with a signal from the server
How to launch a modal window with a signal from the server

Time:06-16

Programs, languages and frameworks used: Java IntelIJIdea SpringSecurity Thymleaf Html JavaScript

I have a page product.html on which there is a product. The user clicks on the order item button. I'm sending a signal to the server. If the object is successfully added to the database, I call the same window with an additional bool parameter.

I need to make it so that if bool is true, a modal window pops up with the message the product has been added to the cart.

The problem is that if I use thymeleaf if as a condition to start the window,

<div th:if="${openModal}">
        <a href="#openModal">Открыть модальное окно</a>
 
        <div  id="openModal">
            <div>
                <a  href="#close" title="Закрыть">X</a>
                <h2>Добавлено</h2>
                <p>The product has been added to your cart, continue shopping or go to the cart?</p>
            </div>
        </div>
    </div>

then I do not know how to change the value of openModal from true to false (If at all possible) when clicking the close button.

If I use the option with my_window:target. When selecting, show the window using a pseudo-class and then when clicking on the cross to remove the selection from the window , then I do not know how to determine whether the window should be opened this time or not when starting the window using a variable from the server.

CodePudding user response:

The canonical way to do this is use redirect/flash attributes. In your controller, you would do something like this:

@PostMapping("/products")
public String doAddProduct(@ModelAttribute("product") AddProductFormData formData, RedirectAttributes redirectAttributes) {
  service.addProduct(formData);

  redirectAttributes.addFlashAttribute("productAdded", formData.productName());
  return "redirect:/products";
}

In your template, you can use productAdded:

<div th:if="${productAdded}">
  <div>The product with name [[${productAdded}]] was added.</div>
</div>

The advantage of using the flash attribute is that if the page gets refreshed, the flash attribute is gone and the message is no longer showing.

That said, if you want to give the user an option to manually dismiss the dialog, I would use something like https://alpinejs.dev/ :

The template would be:

<div th:if="${productAdded}">
        <div  id="openModal"
             x-data="{ open: true }"
             x-show="open">
            <div>
                <a  @click="open = false" title="Закрыть">X</a>
                <h2>Добавлено</h2>
                <p>The product has been added to your cart, continue shopping or go to the cart?</p>
            </div>
        </div>
</div>

CodePudding user response:

The problem was solved, however, perhaps in a rather rough way. I wrote the result in a hidden field. And then I use JavaScript to turn this window on or off.

html

    <input type="hidden" id="openModalValue" th:value="${openModalValue}">
 
    <div  id="modalWindow">
        <div>
            <h2>Added</h2>
            <p>The product has been added to your cart, continue shopping or go to the cart?</p>
            <input  type="image" src="/static/images/elements/product/product/Blue_original.png" alt="Continue shopping" onclick="PopupCloseById('modalWindow')">
enter code here
        </div>
    </div>

JavaScript

function TogglePopup()
{
    const openModal = document.getElementById("openModalValue");
    const openValue = (openModal.value === 'true');
    const popup = document.getElementById("modalWindow");
 
    if (openValue)
    {
        popup.classList.add('open');
    }
    else
    {
        popup.classList.remove('open');
    }
}

function PopupCloseById(id)
{
    const popup = document.getElementById(id);
    popup.classList.remove('open');
}

.product_modal_window
{
    position: fixed;
    font-family: Arial, Helvetica, sans-serif;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0,0,0,0.8);
    z-index: 99999;
    -webkit-transition: opacity 400ms ease-in;
    -moz-transition: opacity 400ms ease-in;
    transition: opacity 400ms ease-in;
    display: none;
    pointer-events: none;
}

CSS

.product_modal_window.open
{
    display: block;
    pointer-events: auto;
}
.product_modal_window > div
{
    width: 400px;
    height: 200px;
    position: relative;
    margin: 15% auto;
    padding: 5px 20px 13px 20px;
    border-radius: 10px;
    background: #fff;
    background: -moz-linear-gradient(#fff, #999);
    background: -webkit-linear-gradient(#fff, #999);
    background: -o-linear-gradient(#fff, #999);
}
  • Related