Automatically conceal a div or flash message after a short period of time by utilizing CSS3 in a React

I am relatively new to the React environment and recently created a basic component for a bookmarking feature.

Essentially, when the favourite icon is clicked,

an ajax call is sent > a record is created in the database > on ajax success, a flash message displays "Page added to favourites."

It's a toggle button, so clicking on it again will,

send another ajax call > delete the record in the database > show a flash message on successful deletion "Page removed from favourites."

Here is the component I wrote, which functions perfectly. However, I am not fond of using the setTimeout function to hide the flash message. I believe there may be an alternative way (possibly using CSS) to achieve the same result in a more React-oriented manner.

import React, {
  PropTypes
} from 'react';
import {
  Component
} from 'aplus-base';
import axios from 'axios';

const API = "http://localhost:3000/favourites/toggle"
const API2 = "http://localhost:3000/favourites/current_bookmark_status"

@Component
export default class Bookmark extends React.Component {
  static styles = require('./bookmark.sass')

  state = {
    bookmarked: '',
    message: "",
    alert: false
  }

  componentDidMount() {
    this.fetchData();
  }

  toggle() {
    const querystring = require('querystring')
    axios.post(API, querystring.stringify({
        current_page_key: '/marketing'
      }), {
        headers: {
          "Content-Type": "application/x-www-form-urlencoded"
        }
      })
      .then(response => {
        this.setState({
          bookmarked: response.data.bookmarked,
          alert: true
        });
        const message = response.data.bookmarked ? "Added to Favourites" : "Removed from Favourites"
        this.setState({
          message
        })
        setTimeout(() => {
          this.setState({
            alert: false
          });
        }, 2000);
      })

  }
  fetchData = () => {
    const querystring = require('querystring')
    axios.post(API2, querystring.stringify({
        current_page_key: '/marketing'
      }), {
        headers: {
          "Content-Type": "application/x-www-form-urlencoded"
        }
      })
      .then(response => {
        this.setState({
          bookmarked: response.data.bookmarked
        });
      })
  }

  render() {
    return ( <
      div >
      <
      i className = {
        this.state.bookmarked ? "icon icon-bookmarked" : "icon icon-bookmark"
      }
      onClick = {
        this.toggle.bind(this)
      }
      /> <
      div styleName = {
        `result ${this.state.alert ? "alert-shown": "alert-hidden"}`
      } > {
        this.state.message
      } <
      /div>     <
      /div>
    )
  }
}
.icon display: inline-block width: 30px height: 30px background: no-repeat center background-size: contain vertical-align: middle &.icon-bookmark background-image: url(../assets/bookmark.png) transition: all 1s linear &.icon-bookmarked background-image: url(../assets/bookmarked.png) transition: all 1s linear .result position: fixed top: 0 left: 40% width: 20% box-sizing: border-box padding: 4px text-align: center font-weight: bold .alert-shown opacity: 1;
transition: all 250ms linear;
.alert-hidden opacity: 0;
transition: all 250ms linear;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Answer №1

To hide your element after a certain time, you can utilize CSS3 animations. Without being able to test your code output myself, I cannot provide the exact snippet for you. However, one way to achieve this is by adding classes dynamically upon request success. You can use the same method you are currently using or consider using a npm package like "classnames" to apply animations for showing and fading your element.

For instance, you can implement the following animation:

animation: FadeAnimation 1s ease-in .2s forwards;

In this example, the FadeAnimation will run for 1 second with an ease-in effect, starting 0.2 seconds after the class is attached.

@keyframes FadeAnimation {
  0% {
    opacity: 1;
    visibility: visible;
  }

  100% {
    opacity: 0;
    visibility: hidden;
  }
}

This keyframe rule will transition the element from a visible state to a hidden state. By incorporating additional properties at different percentage points, you can introduce intermediate stages in your animation sequence. This approach can also be applied for removing elements.

For more information on CSS3 Animations, refer to W3Schools' guide.

Answer №2

I came across a challenge where I needed to create an overlay using React and hide it with CSS after a brief period of time. Thankfully, I stumbled upon this question and found the solution provided by @jefree-sujit incredibly helpful.

The final outcome involves initially displaying a hidden overlay, transitioning its visibility through a CSS animation, and then concealing it once again.

Within my render method, I implemented my component like so:

{isPostFulfilled && <SuccessDisplay />}

(Note: The implementation may vary based on how API calls are handled. In my case, I utilize react-redux-fetch to manage pending/fulfilled/rejected states for my calls.)

The SuccessDisplay component utilizes styled-components to act as the overlay:

// @flow
import React from 'react';
import styled from 'styled-components';
import { BootstrapIcon } from 'skin';

export const Styling = styled.div`
  .success {
    animation: hide-animation 0.6s ease-in 0s;
    visibility: hidden;
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    height: 100vh;
    width: 100vw;
    background-color: rgba(0, 0, 0, 0.3);
    z-index: 100000;

    .ok-icon {
      font-size: 50px;
      cursor: default;
      opacity: 0.9;
      position: absolute;
      top: 48%;
      left: 48%;
      color: green;
      margin: 0 auto;
    }

    @keyframes hide-animation {
      0% {
        opacity: 1;
        visibility: visible;
      }

      100% {
        opacity: 0;
        visibility: hidden;
      }
    }
  }
`;

const SuccessDisplay = () => (
  <Styling>
    <div className="success">
      <BootstrapIcon icon="ok" className="ok-icon" />
    </div>
  </Styling>
);

export default SuccessDisplay;

The BootstrapIcon component is utilized to render glyphicons from react-bootstrap.

The key aspect of the animation in the CSS snippet is that: it triggers the hide-animation lasting for 0.6 seconds, utilizing the ease-in transition style within that duration, beginning instantly (0 seconds) after loading the styles.

It's crucial to include visibility: hidden in the initial styles as well, as the starting point and endpoint of the animation. Once the animation concludes (after 0.6 seconds), the styles revert back to their original state.

I hope this explanation proves useful to someone facing a similar issue in the future!

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

Utilize AngularJS ng-repeat directive to refine JSON objects

I'm working on an angular js controller with a json array that organizes countries by continents. Each continent consists of its own array of countries. //CONTROLLER app.controller('CountryController', function(){ this.continents = ...

FixPermissions not working properly | Discord.js EXPERT

I am currently in the process of updating my bot to be compatible with the latest version of discord.js. I have successfully made various changes, but I am facing an issue with the overwritePermissions section within my ticket command. For some reason, the ...

performing an AJAX call utilizing both a file and post data

I'm reaching out for help because I'm having trouble sending an ajax request with a data file and two posts included Here is the code snippet: $('#image--1').change(function (e) { e.preventDefault(); var img = new FormData(); ...

Employing [style.something.px]="2" in Angular to specify the thickness of the border

Presently, I am setting the width of the element using this code format: <div [style.width.px]="size" [style.height.px]="size"></div> What I am aiming for is to utilize a comparable format but to define the border-width css attribute, such as ...

Specify the versions of packages in your package.json file

My package.json file contains many dependencies with "*" as the version, which I have learned is not recommended. I want to update them all to their latest versions. Despite using npm-check-updates tool, it indicates that all packages are up-to-date. Can ...

The sticky navbar fails to stay in place when the content becomes too lengthy

This is my current state of code (minified, for explanation only) index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-w ...

Having trouble positioning a specific element at the top right of the header navbar in Laravel Bootstrap 5

Is there a way to create a top navbar with the project name and menu on the left, and user management on the right? Currently, both options are aligned to the left. Here is an example of what I have: top navbar This navbar is placed in the header, and her ...

Using the https module in Node.js to transfer a file to a PHP server

What is the best method to send an HTTP post request that includes a jpg file to a php server using the node https module? I attempted to use the request module, but it is unreliable (timing out most of the time) and already deprecated. Here is the functi ...

An easy guide on inserting a new row or footer in the rc-table component using React JS

I am looking to insert a new row at the end of an rc-table in order to display the total value of a particular column. const columns = [ { title: "Name", className: "cursor-pointer", dataIndex: "name", key: ...

Step by step guide on serializing two forms and an entire table

I have been attempting to serialize data from two forms and the entire table simultaneously. While the form data is successfully serialized, I am encountering difficulty in serializing the table records as well. Below is the code snippet of what I have att ...

The form is refusing to submit even after using the "return false

Even after adding validation to the form, it still submits when the script returns false. The Form Submission <form action=payment.php method=POST name=UserForm id=UserForm onsubmit="return check(this); return false;"> Javascript Code function ch ...

Main page cluttered with irrelevant data from PHPExcel

I am facing an issue where, upon generating a PDF file with information obtained from a database using PHPExcel and clicking the 'report' button to transfer this data into the PDF, my page is flooded with unreadable symbols resembling random garb ...

Dynamic Navbar that Adapts to Your Scroll

I'm experiencing an issue with my navbar. I want it to stay at the top of the page when I scroll, but whenever I apply the "position: fixed;" property, the navbar disappears. Below is my HTML and CSS code: <nav> <div class="navbar"> <b ...

Tips for adjusting the default selection in a second dropdown menu

I have a dilemma with my two dropdown lists, "optionone" and "optiontwo". I am trying to alter the default selected value from "option value=3>3" to option value=3 selected>3 when the user selects 2 from the first dropdown list ("optionone"). <sc ...

The operation failed because the property 'dasherize' is inaccessible on an undefined object

While attempting to execute the following command: ng generate component <component-name> An error occurred saying: Error: Cannot read property 'dasherize' of undefined Cannot read property 'dasherize' of undefined The confi ...

What is the process of using the split() method to extract specific text from a string in JavaScript?

Working with AngularJS and facing a requirement to extract a specific text from a scope value. Here's my scope value: $scope.myLogMsg = '1111 order is placed by Sukumar Ms(User)'; //output: by Sukumar Ms(User) Desired output: by Sukumar Ms ...

Is it possible to transfer a massive number of files using node.js?

I need to asynchronously copy a large number of files, about 25000 in total. I am currently using the library found at this link: https://github.com/stephenmathieson/node-cp. Below is the code snippet I am using: for(var i = 0; i < 25000; i++ ...

Trouble with the functionality of the Bootstrap collapse button

I am facing an issue where clicking on the collapse button does not trigger any action. I have tested it on both of my laptops, ruling out any problems with the web browser. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

Guide to incorporating animated material icons in vuetify

in Vuetify makes it easy to utilize mainstream material design icons through the use of the v-icon component. An example of this would be: <v-icon>home</v-icon> I am curious if animated material icons are supported and can be integrated in ...

Difficulty encountered while implementing mouseover event listener for an SVG component

I'm having trouble triggering an event for an svg element. Here's the link to my jsfiddle example: https://jsfiddle.net/r1ahq5sa/ Here's the HTML code: <div class="row"> <div class="col-md-8"> <svg class="video-nav-bar ...