Home > Blockchain >  How to make Simple React Lightbox automatically open image with link in Gatsby
How to make Simple React Lightbox automatically open image with link in Gatsby

Time:02-01

I am creating a webpage with Gatsby, Gatsby Image gallery and [Simple React Lightbox][1]. My goal is to make gallery image automatically open inside if the corresponding query is entered in the URL.

For example: when "example.com/images?id=0" is selected the first image will automatically open up. When "example.com/imades?id=1" is entered the second image will automatically open etc.

I tried using Simple React Lightbox [hooks][2] but the problem right now is that the image will open only when onClick event is triggered.

I tried getElementsByClassName.click(), useEffect and useRef but so far could not find working solution.

How can I make images open automatically when URL with specific query is selected?

Here is my gallery code

import * as React from "react"
import { graphql } from "gatsby"
import { GatsbyImage } from "gatsby-plugin-image"
import SimpleReactLightbox, { SRLWrapper } from "simple-react-lightbox"
import { useLightbox } from "simple-react-lightbox"
import Layout from "../components/layout"
import Seo from "../components/seo"
import Buttons from "../components/Buttons"

function Images({ data }) {
  const { t } = useTranslation()
  const images = data.allFile.edges

  const { openLightbox } = useLightbox()
  const queryParams = new URLSearchParams(window.location.search)
  const term = queryParams.get("id")

  return (
    <Layout>
      <Seo title="Portfolio" />
      <section>
        <div className="container">
          <SimpleReactLightbox>
            <SRLWrapper>
              <div className="row">
                {images.map((image, i) => (
                  <div
                    className="img-col col-sm-12 col-md-6 col-lg-3"
                    key={image.node.id}
                  >
                    <a
                      href={image.node.publicURL}
                      target="_blank"
                      rel="noreferrer"
                    >
                      <GatsbyImage
                        className="ratio ratio-1x1"
                        image={image.node.childImageSharp.gatsbyImageData}
                        alt={`https://example.com/images/?id=${  i}`}
                      />
                    </a>
                  </div>
                ))}
              </div>
            </SRLWrapper>
            <Buttons className="shared-img" term={term} />
          </SimpleReactLightbox>
        </div>
      </section>
    </Layout>
  )
}

export default Images

Here is Buttons code

import { useLightbox } from "simple-react-lightbox"
import React from "react"

export default function Buttons({ term }) {
  const { openLightbox } = useLightbox()
  return (
    <>
      <button className="shared-img" onClick={() => openLightbox(term - 1)}>
        Open the {term} image
      </button>
    </>
  )
}

Thanks! [1]: https://github.com/michelecocuccio/simple-react-lightbox [2]: https://github.com/michelecocuccio/simple-react-lightbox#hooks

CodePudding user response:

You can simply include src field while fetching the image data like this.

query {
  blogPost(id: { eq: $Id }) {
    title
    body
    avatar {
      childImageSharp {
        gatsbyImageData(width: 200)
      }
      src
    }
  }
}

src field is the url data which you can pass to the React Lightbox.

CodePudding user response:

You need to use the useEffect hook to get the URL parameters in order to get the id. If it exists, you need to trigger the openLightbox action. This approach is much more fluent and intuitive rather than simulating a click when there isn't. You will be "faking" the action.

Something like:

import * as React from "react"
import { graphql } from "gatsby"
import { GatsbyImage } from "gatsby-plugin-image"
import SimpleReactLightbox, { SRLWrapper } from "simple-react-lightbox"
import { useLightbox } from "simple-react-lightbox"
import Layout from "../components/layout"
import Seo from "../components/seo"
import Buttons from "../components/Buttons"

function Images({ data }) {
  const { t } = useTranslation()
  const images = data.allFile.edges

  const { openLightbox } = useLightbox()
  const queryParams = new URLSearchParams(window.location.search)
  const term = queryParams.get("id")

  useEffect(()=> {
    const urlParams = new URLSearchParams(window.location.search);
    const id= urlParams.get('id')
     
    if(Number.isInteger(id)){
      openLightbox(id)
    }
  }, [])

  return (
    <Layout>
      <Seo title="Portfolio" />
      <section>
        <div className="container">
          <SimpleReactLightbox>
            <SRLWrapper>
              <div className="row">
                {images.map((image, i) => (
                  <div
                    className="img-col col-sm-12 col-md-6 col-lg-3"
                    key={image.node.id}
                  >
                    <a
                      href={image.node.publicURL}
                      target="_blank"
                      rel="noreferrer"
                    >
                      <GatsbyImage
                        className="ratio ratio-1x1"
                        image={image.node.childImageSharp.gatsbyImageData}
                        alt={`https://example.com/images/?id=${  i}`}
                      />
                    </a>
                  </div>
                ))}
              </div>
            </SRLWrapper>
            <Buttons className="shared-img" term={term} />
          </SimpleReactLightbox>
        </div>
      </section>
    </Layout>
  )
}

export default Images

The key part is:

  useEffect(()=> {
    const urlParams = new URLSearchParams(window.location.search);
    const id= urlParams.get('id')
     
    if(Number.isInteger(id)){
      openLightbox(id)
    }
  }, [])

With the first two lines you are getting the URL parameter id.

The following line:

Number.isInteger(id)

Is interesting because if you just check for the id, the id=0 will be evaluated as a falsy value, so you need to check if the id is an integer.

After that, you just need to call your lightbox function.

  •  Tags:  
  • Related