Having trouble animating a collapse element in Bootstrap 5 that was dynamically created using JavaScript

My objective is to develop a collapsible element that notifies the user about the success or error of sending form data to the server. This will provide clear feedback to the user after form submission.

function sendForm(event, form) {
    const notification=document.createElement('div');
    notification.setAttribute('role', 'alert');
    notification.classList.add('alert', 'alert-dismissible', 'alert-success');
    notification.innerHTML='<span>Success!</span><button type="button" class="btn-close" data-bs-dismiss="alert"></button>';
    form.prepend(notification);

    const bsNotificationCollapse = bootstrap.Collapse.getOrCreateInstance(notification);
    bsNotificationCollapse.show();
    setTimeout(() => {
        bsNotificationCollapse.hide();
    }, 4000);
    setTimeout(() => {
        notification.remove();
    }, 7000);
    form.reset();

    event.preventDefault();
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ed8f8282999e999f8c9dadd8c3dec3ddc08c819d858cdc">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
</head>
<body>
    <main class="container-fluid my-5" style="max-width:300px">
        <form action="#" method="post" onsubmit="sendForm(event, this)"> 
            <button type="submit" class="btn btn-primary">Submit Form</button>
        </form>

        <button class="btn btn-primary" data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
            Button with data-bs-target
        </button>

        <div class="collapse" id="collapseExample">
            <div class="alert alert-dismissible alert-success" role="alert">
                <span>Success!</span>
                <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
            </div>
        </div>
    </main>
    <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="187a77776c6b6c6a7968582d362b362835797468707929">[email protected]</a>/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
</body>
</html>

I have included two variations in the test HTML - the first button triggers my custom implementation within the form, which shows jerky animation when processing the data. The second button, inspired by Bootstrap documentation, showcases smooth and desired animation effects. My aim is to achieve similar animations for successful form submissions using javascript.

Answer №1

It appears that the issue lies in the JavaScript code where the created element is missing the 'collapse' class. The transition effect is only applied to elements with the 'collapse' class. I made some modifications by adding the 'collapse' class to the wrapper and assigning the alert classes to a div inside the wrapper. Now, the animation seems to be working properly.

function sendForm(event, form) {
    const wrapper=document.createElement('div');
    wrapper.setAttribute('role', 'alert');
wrapper.classList.add("collapse");
    wrapper.innerHTML='<div class="alert alert-dismissible alert-success"><span>Success!</span><button type="button" class="btn-close" data-bs-dismiss="alert"></button> </div>';
    form.prepend(wrapper);

    const bsWrapperCollapse = bootstrap.Collapse.getOrCreateInstance(wrapper);
    bsWrapperCollapse.show();
    setTimeout(() => {
        bsWrapperCollapse.hide();
    }, 4000);
    setTimeout(() => {
        wrapper.remove();
    }, 7000);
    form.reset();

    event.preventDefault();
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c6a4a9a9b2b5b2b4a7b686f3e8f5e8f6eba7aab6aea7f7">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
</head>
<body>
    <main class="container-fluid my-5" style="max-width:300px">
        <form action="#" method="post" onsubmit="sendForm(event, this)"> 
            <button type="submit" class="btn btn-primary">My form submit btn</button>
        </form>

        <button class="btn btn-primary" data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
            Button with data-bs-target
        </button>

        <div class="collapse" id="collapseExample">
            <div class="alert alert-dismissible alert-success" role="alert">
                <span>Success!</span>
                <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
            </div>
        </div>
    </main>
    <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e4868b8b909790968594a4d1cad7cad4c98588948c85d5">[email protected]</a>/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
</body>
</html>

Answer №2

After a bit of trial and error, I discovered a solution to make the animation normalize without requiring assistance from this forum. It turns out that the alert container in the HTML code was enclosed within another container, which I failed to replicate when creating the alert using JavaScript. Once I wrapped this element appropriately, the animation functioned as intended. Special thanks to @Nick for suggesting the inclusion of a collapse class to fix the issue. However, upon testing his code variation without the class, the animation persisted smoothly. Ultimately, the success of the animation came down to encapsulating my code within a container via innerHTML – much like what I ended up implementing.

function sendForm(event, form) {
    const alert=document.createElement('div');
    alert.setAttribute('role', 'alert');
    alert.classList.add('alert', 'alert-dismissible', 'alert-success');
    alert.innerHTML='<span>Success!</span><button type="button" class="btn-close" data-bs-dismiss="alert"></button>';

    const alertWrapper=document.createElement('div');
    alertWrapper.append(alert);
    form.prepend(alertWrapper);

    const alertWrapperCollapse = bootstrap.Collapse.getOrCreateInstance(alertWrapper);
    alertWrapperCollapse.show();
    setTimeout(() => {
        alertWrapperCollapse.hide();
    }, 4000);
    setTimeout(() => {
        alertWrapper.remove();
    }, 7000);
    form.reset();
    event.preventDefault();
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f1939e9e858285839081b1c4dfc2dfc1dc909d819990c0">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
</head>
<body>
    <main class="container-fluid my-5" style="max-width:300px">
        <form action="#" method="post" onsubmit="sendForm(event, this)"> 
            <button type="submit" class="btn btn-primary">My form submit btn</button>
        </form>

        <button class="btn btn-primary" data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
            Button with data-bs-target
        </button>

        <div class="collapse" id="collapseExample">
            <div class="alert alert-dismissible alert-success" role="alert">
                <span>Success!</span>
                <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
            </div>
        </div>
    </main>
    <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3e5c51514a4d4a4c5f4e7e0b100d100e135f524e565f0f">[email protected]</a>/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
</body>
</html>

I've noted @Nick's response as constructive.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble grasping the inner workings of code while iterating through a JSON array in ReactJS

Currently, I am immersed in a school project that requires me to develop a simple CRUD web application. After weighing my options, I decided to utilize Spring Boot + ReactJS for this endeavor. The progress has been smooth so far, but I must admit that part ...

jquery for quick search

<form method="post" action="search.php"> Commence search: <input id="search" type="text" size="30" > <div id="search_results"></div> <script src="//code.jquery.com/jquery-1.12.0.min.js"></script> <script src="//code. ...

The functionality of Dnd-kit nested is functioning properly, however, one specific component is unfortunately

Currently, I am dealing with a two-dimensional array that results in two nested dnd-kit drag and drop fields. The nested dnd functions correctly; however, the first one sorts items when moved without any animations (even when moving my div). Below is the ...

The carousel spun around, each section moving to the side on its own

One issue I'm facing is that on my page, I have multiple carousel rows. However, when I click on the "next" or "prev" button to navigate through the items in the carousel, it affects all carousels instead of just the one I clicked on. I've attem ...

Creating obstacles in a canvas can add an extra layer of challenges and

I am working on creating a basic platformer game using the code displayed below. window.onload = function(){ var canvas = document.getElementById('game'); var ctx = canvas.getContext("2d"); var rightKeyPress = false; var leftKeyPress = false; ...

ASP updatepanel textbox focusing - Working only with breakpoints, not without them

I've encountered a bizarre problem where my code functions perfectly with a breakpoint set, but when I remove the breakpoint, certain parts of the code fail to work. My goal is to have a textbox automatically select all text upon focus; it should foc ...

Phaser 3 game app on iOS generated with Capacitor lacks audio functionality

I have developed a basic test app using Phaser 3 (written in Typescript and transpiled with rollup) and am utilizing Capacitor to convert it into an iOS application on my Mac. This excerpt highlights the key functionality of the app: function preload () { ...

issues with jquery functionality on user control page

For searching through dropdown lists in my project, I have implemented the Chosen jQuery plugin. In the Master page before the closing body tag, ensure to include the necessary CSS and jQuery script files. <link href="/assets/css/chosen.css" rel=" ...

Executing a controller method in AngularJS when redirecting a page

I am currently working on an app using Cordova/Phonegap, Ionic, and AngularJS. One challenge I am facing is trying to call a method from a controller inside my app when redirecting to another HTML page (secondPage.html). This particular method (secondMetho ...

Certain mobile devices experiencing issues with AngularJS filters

Currently, I am attempting to filter an AngularJS array by utilizing custom filters within a controller. The filters are functioning correctly on certain mobile devices, yet they are not working on others. Here is the code snippet that I am using: var a ...

Adding npm packages to your Vue.js application

My Vue app is structured like this (auto created by vue init webpack myProject): index.html components/ -main.js -App.vue I am trying to include npm packages, such as https://github.com/ACollectionOfAtoms/atomic-bohr-model. Following the instructions, I ...

Why isn't my function being triggered by the Click event?

I can't figure out why the click event isn't triggering the btn() function. function btn() { var radio = document.getElementsByTagName("input"); for (var i = 0; i > radio.length; i++){ if (radio[i].checked){ alert(radio[i].value); } ...

Adding a background image in javascript using data from a MySQL database

My current tech stack includes CodeIgniter, vanilla JavaScript, AJAX, CSS, and MySQL. I am trying to figure out how to set the background of an image that is stored in a MySQL database. While the following code is error-free and working perfectly, my cha ...

Embedding HTML Tags within an array element

The task at hand involves adding an HTML element from Array Value to the Document Object Model template: { 0: { h1: '<h1>Hi</h1>' }, 1: { h2: '<h2>Hi</h2>' }, 2: { h3: &a ...

Sending data to a React component from regular HTML

I have a question about implementing a method to pass custom attributes from HTML elements as props to React components. Here's an example: function someFunction(props) { return <h1>props.something</h1> } HTML: <div id="someEl ...

bind a class property dynamically in real-time

I need to dynamically generate a TypeScript class and then add a property to it on the go. The property could be of any type like a function, Promise, etc., and should use this with the intention that it refers to the class itself. let MyClass = class{ ...

When Axios is disconnected, the sequence of events following a user's action is no longer dependent on when it is called after a button

I am working on a script that performs the following actions: Upon clicking a button, an encoded text is sent to an API for decoding. The decoded text is then used as a query for a Google search link that opens in a new tab. JAVASCRIPT // Summary: // ...

Challenges with asynchronous problems related to importing models utilizing promises in conjunction with the three.js

I'm currently struggling to resolve a promise in my script. The promise needs to be resolved when a function containing 3D file imports finishes importing, but I'm unsure how to make this happen. Is there a way to receive a signal or data from t ...

What is the best way to create a dynamic URL linking to an external site in Angular 5?

When attempting to create a link like this: <a [href]="getUrl()">click me</a> getUrl() { return this.domSanitizer.bypassSecurityTrustUrl('http://sampleUrl.com'); } The link is not clickable. When hovering over the ...

Triggering a function without the presence of an actual event

I need to come up with a solution for reusing a function triggered by an event binding. This problem stems from browsers remembering checkbox states, which is why I have to call the function on document load. One approach could involve wrapping setGrid() ...