Animating CSS styles in Vue.js based on JavaScript triggers

Within my Vue.js application, I've implemented a login form that I'd like to shake whenever a login attempt fails.

Though I have achieved the desired shaking effect, I'm not completely satisfied with my current solution. Here's a simplified version of my code:

const Home = {
    data() {
        return {
            shakeForm: false
        }
    },
    template: `
        <div>
            <form :class="{'form-shaking': shakeForm}"
                  @submit.prevent="login"
                  @animationend="shakeForm = false;"
            >
                form fields
            </form>
        </div>
    `,
    methods: {
        async login() {
            // ...
            const rawResponse = await fetchLogin();

            if (!rawResponse.ok) {
                this.shakeForm = true;
                return;
            }

            // login successful
        }
    }
};
.form-shaking {
    position: relative;
    animation: shake-horizontally .2s ease-out 2;
}

@keyframes shake-horizontally {
    from {
        left: 0;
    }

    25% {
        left: 25px;
    }

    75% {
        left: -25px;
    }

    to {
        left: 0;
    }
}

In essence, I am toggling the shakeForm boolean property to dynamically apply and remove the form-shaking class on the <form> element when needed. The class is removed upon completion of the shaking animation to enable it to play again.

I am curious if there is a specific feature within Vue.js designed to handle situations like this. I explored transition and animation capabilities but did not come across a suitable alternative.

Answer №1

If you want to add some extra flair to your form, you can manually adjust the styles.animation attribute on the go to create a shaking effect. Here's how you can do it:

function shake() {
    document.getElementsByClassName('form-shaking')[0].style.animation = 'shake-horizontally .2s ease-out 2';
    // Stop the animation once it's done
    window.setTimeout(function() {
        document.getElementsByClassName('form-shaking')[0].style.animation = 'unset';
    }, 400);
}

(Make sure that the animation is set to unset when calling the function for it to work properly.)

For demonstration purposes, here's an example of how you could use this technique with some driver code:

function shake() {
    console.log('Incorrect Login: shaking form...')
    document.getElementsByClassName('form-shaking')[0].style.animation = 'shake-horizontally .2s ease-out 2';
    // Stop the animation once it's done
    window.setTimeout(function() {
        document.getElementsByClassName('form-shaking')[0].style.animation = 'unset';
        console.log('Incorrect Login: form shake state reset.')
    }, 400);
}

window.setTimeout(shake, 1000)
window.setTimeout(shake, 2000)
window.setTimeout(shake, 3000)
.form-shaking {
    position: relative;
    /* animation: shake-horizontally .2s ease-out 2; */
}

@keyframes shake-horizontally {
    from {
        left: 0;
    }

    25% {
        left: 25px;
    }

    75% {
        left: -25px;
    }

    to {
        left: 0;
    }
}
<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
    <meta charset="utf-8">
    <title>CSS Animation on JS Event</title>
</head>

<body>
    <div class="form-shaking" style="margin: 32px; display: inline-block; background-color: black; min-width: 100px; min-height: 100px;"> </div>
</body>

</html>

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

Customize the Underline Color in MaterialUI Select Component

I'm experimenting with MaterialUI and trying to figure out how to customize the underline and text color of the Select component when an item is selected. Currently, the underline and label appear blue after selection with a gray background. Is there ...

Next-Auth: Access Session in _app.js Directly Without Using getServerSideProps

When working with React.js and React-Auth, it's important to note that calling server-side functions such as getServerSideProps can prevent you from exporting your project using next export. Below is the content of my pages/_app.js, which I structured ...

Using Promises Across Multiple Files in NodeJs

Initially, I had a file containing a promise that worked perfectly. However, realizing the need to reuse these functions frequently, I decided to create a new file to hold the function and used module.export for universal access. When I log crop_inventory ...

Cannot adjust expiration date of express-session in browser

In my current project, I am utilizing express-session. Let's say a session has been created between the web browser and the Node.js server with a default expiration time of one hour. At this point, there is a cookie named connect.sid stored in the use ...

Removing single quotes and replacing them with spaces when passing data from JavaScript to MySQL

I'm currently focused on JavaScript using Hapi.js in my role at the company. My main task involves retrieving data from MongoDB and transferring it to a MySQL database. The challenge arises when dealing with data that contains single quotes within th ...

Step-by-step guide on how to show and hide a div by clicking a button with the help of an "

Here is some code that I have written to toggle a div when clicking on a button using vue.js. Instead of using hidden data property, I am trying to achieve this by targeting the div with Id="categories" <button v-on:click="isHidden = !i ...

Is it possible to refresh text in table without clearing icons?

Is there a way to maintain icons in table rows when editing text fields from a dialog? Currently, regardless of whether I use .html() or .text(), the icons disappear. I suspect that utilizing .content() may be a solution, but I'm unsure how to impleme ...

Using DefaultSeo does not override NextSeo in every component

I am looking to dynamically change the Head tag using next-seo. While browser validation will show NEXTSeo for individual pages, Twitter, Firebase's card validation tool, and others will default to next-seo-config.js. Does anyone have a solution? S ...

The function angular.factory does not exist

Hey there! I am encountering an error in the title related to my factory. Any suggestions on how I can resolve this issue? (function (angular,namespace) { var marketplace = namespace.require('private.marketplace'); angular.factory(&apo ...

PhpStorm IDE does not recognize Cypress custom commands, although they function properly in the test runner

Utilizing JavaScript files within our Cypress testing is a common practice. Within the commands.js file, I have developed a custom command: Cypress.Commands.add('selectDropdown', (dropdown) => { cy.get('#' + dropdown).click(); } ...

Press the key to navigate to a different page

I have an input field for a search box. I want it so that when I enter my search query and press enter, the page navigates to another page with the value of the input included in the URL as a query string. How can I achieve this functionality? Thank you ...

Rendering components asynchronously in ReactJS

After completing my ajax request, I need to render my component. Here is a snippet of the code: var CategoriesSetup = React.createClass({ render: function(){ var rows = []; $.get('http://foobar.io/api/v1/listings/categories/&apo ...

Tips for incorporating a hyperlink into a Vuikit table using Vue.js

I've exhausted all my options trying to make this work, and I'm on the verge of removing Vuikit... All I want is to pass dynamic data to the component, create a new HREF with that data, and have a clickable LINK text element displayed :) Here&a ...

Obtain Information from an Ajax GET Request

My question is fairly straightforward. I have this Ajax function: function fillProductLine(obj) { $.ajax({type: "POST", url: '/orderOnline/index.php/Orders/searchProductLine', async: false, data: { cd_cpl ...

Updating a slider based on the values of two other sliders can be achieved by implementing a

I am working on a project that involves three input sliders. I need the third slider to display the product of the values from the first two sliders. Additionally, I want the value of the third slider to update dynamically whenever the values of the first ...

Issues with unresponsive links (HTML5/CSS)

As a beginner, I've encountered an issue where my previously working links are no longer functioning. Can anyone help identify what could be going wrong? Below is the HTML code: <!doctype html> <html> <head> <meta charset="UTF-8 ...

Removing the loading spinner from Ag Grid

While utilizing ag-grid with rowModelType=serverSide, I have encountered an issue where the loading overlay includes a spinner as shown in the image below. My goal is to eliminate this spinner from the overlay. I attempted using hideOverlay(), but it seems ...

Is it possible for jQuery to create a popup window displaying a specific value?

Using JavaScript, I have implemented functionality to open a child window when the user clicks on a button from the parent window. The child window contains a textbox and a button. When the user clicks on the button in the child window, I want to retrieve ...

Results not showing up

After attempting to incorporate the scores into a table, I am facing an issue where they are not displaying. Can anyone offer assistance with this problem? I am currently hosting on GitHub Pages. File: https://raw.githubusercontent.com/Eternal-Network/Ete ...

What's preventing me from utilizing Leaflet Map on Next.js despite attempting Dynamic Import?

When using Leaflet, it requires the global window object which is not available on SSR (Server-Side Rendering) and can cause an error stating "window is not defined". I have tried extensively to find a solution, and the only method I found was to use dyna ...