Asset(Image/Video) Picker with javascript(react/nextjs) on button click

asset(image/video)-picker-with-javascript(react/nextjs)-on-button-click

Before we start i am going to put my social media links if you would like to follow me there
Instagram
Twitter

and also my upwork profile if you want to work with me

In this blog post i am going to demonstrate how to create an asset picker on button click.
Below is how the the ui of the picker looks like and how it works

First of all we are going to create our app with next js a react framework

npx create-next-app assetpicker

make sure all the characters are in small letters because next js does not allow capital letters
and during the creation of the app select yes for typescript on the terminal pop up because we are going to use typescript in this app
After app creation we are going to install 3 npm packages which are react-icons, classnames and sass

npm i react-icons classnames sass

After installation go to pages and delete index.tsx content but not the file itself and we are going to start from scratch

we are going to have 4 items in our setState which are image, selecta, current and names

 const [image, setImage] = useState([])
 const [selecta, setSelecta] = useState([])
 const [current, setCurrent] = useState(0)
 const [names, setNames] = useState([])

image this is the actual image **which is going to be displayed inside a div known as **selecta and current is the current selected image which by default is the first one and names contains an array of names of all selected images this is going to help us to check if the image is already selected or not

Apart from those we are going to have 3 functions addSelecta, onChange and deleteData

 const addSelecta = () => {
    let image1 = selecta.length
    if(selecta.length > image.length){
      alert('not allowed')
      return 
    }else if( selecta.length >= 5){
      alert('maximum images 5 reached')
      return 
    }else{
      selecta.push(`image${image1+1}`)
      setSelecta(selecta.map((item:any)=> item))
    }
  }

in this function we are adding a button to select image and that div is going to display a plus icon if there is no image selected and and image otherwise.
Every Time we click a button we are going to add an item named image plus selecta.length icreament so selecta item is going to be image0, image1 etc in an array

 const onChange = (e: React.ChangeEvent) => {
    const one:any = e.target.files
    const two = URL.createObjectURL(one[0])
    if(names.includes(one[0].name)){
      alert('asset available')
      return 
    }else{
      image.push(two)
      names.push(one[0].name)
      setImage(image.map((item:any)=> item))
      setNames(names.map((item:any)=> item))
    }
  }

in in onchange function this is all about selecting assets but there is more to that.
we are going to have a constant value named one **which is simply an array assignment of assets.
and the second constant value is **two
which is simply a url creation for selected files number one.
we are using URL.createObjectURL(one[0]) because we cannot display files as files files on the web unless they are BLOB so this method is simply a creation of a BLOB url

const deleteData = (image1:any, selecta1:any) => {
    const imageIndex = image.indexOf(image1)
    const selectaIndex = selecta.indexOf(selecta1)

    if(selecta.includes(selecta1)){
      selecta.splice(selectaIndex,1)
      image.splice(imageIndex,1)
      names.splice(image1.name,1)
      setSelecta(selecta.map((item:any)=> item))
      setImage(image.map((item:any)=> item))
      setNames(names.map((item:any)=> item))
    }
  }

The third function deleteData we are going to pass 2 items along with it the first one is *image **which is the image index of that selected image plus the selecta index of the selecta array.
Then we are going to get indexes of those two **imageIndex **and **selectaIndex *

and then we are going to check if the selecta array includes the selected selecta if true we are going to delete the selecta, image and name and after that we are going to set them with new array so as to update the ui because if we do not do that the changes will not be reflected on the ui

return (
    
{ image.map((item:any, index:number)=> (
setCurrent(index)}>
)) }
{ image.length < 1 ? null : }
{ selecta.map((item:any, index:number)=> (
{ index+1 > image.length ?
onChange(e)} />
: deleteData(image[index], item)}/> }
)) }
addSelecta()}>
)

After all that we need to write our code we are going to have home as our main div and inside it there is item and inside item we are having hero section which is the big image.

 
{ image.map((item:any, index:number)=> (
setCurrent(index)}>
)) }
{ image.length < 1 ? null : }

Inside the hero section we have thumbs which are the small dots indicating the selected image and unselected ones.

and then we have the action div with left and right divs the left is an array of selectas and the right one is the button to add selectas.
inside the selecta we are going to check if selecta has an image or not if not we are going to show a button to select the image

here is the full code

Index.tsx

import React, { useState } from 'react'
import styles from './home.module.scss'
import { BiPlus } from 'react-icons/bi'
import cx from 'classnames'

function Home() {
  const [image, setImage] = useState([])
  const [selecta, setSelecta] = useState([])
  const [current, setCurrent] = useState(0)
  const [names, setNames] = useState([])

  const addSelecta = () => {
    let image1 = selecta.length
    if(selecta.length > image.length){
      alert('not allowed')
      return 
    }else if( selecta.length >= 5){
      alert('maximum images 5 reached')
      return 
    }else{
      selecta.push(`image${image1+1}`)
      setSelecta(selecta.map((item:any)=> item))
    }
  }

  const onChange = (e: React.ChangeEvent) => {
    const one:any = e.target.files
    const two = URL.createObjectURL(one[0])
    if(names.includes(one[0].name)){
      alert('asset available')
      return 
    }else{
      image.push(two)
      names.push(one[0].name)
      setImage(image.map((item:any)=> item))
      setNames(names.map((item:any)=> item))
    }
  }

  const deleteData = (image1:any, selecta1:any) => {
    const imageIndex = image.indexOf(image1)
    const selectaIndex = selecta.indexOf(selecta1)

    if(selecta.includes(selecta1)){
      selecta.splice(selectaIndex,1)
      image.splice(imageIndex,1)
      names.splice(image1.name,1)
      setSelecta(selecta.map((item:any)=> item))
      setImage(image.map((item:any)=> item))
      setNames(names.map((item:any)=> item))
    }
  }
  return (
    
{ image.map((item:any, index:number)=> (
setCurrent(index)}>
)) }
{ image.length < 1 ? null : }
{ selecta.map((item:any, index:number)=> (
{ index+1 > image.length ?
onChange(e)} />
: deleteData(image[index], item)}/> }
)) }
addSelecta()}>
) } export default Home

home.module.scss

.home{
    width: 100vw;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;

    .item{
        width: 50%;

        .hero{
            width: 100%;
            height: 400px;
            background: black;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;

            img{
                width: 90%;
                height: 90%;
                object-fit: cover;
            }
            .thumbs{
                position: absolute;
                bottom: 0;
                display: flex;
                align-items: center;
                justify-content: center;

                .dot{
                    width: 10px;
                    height: 10px;
                    margin: 5px;
                    background: white;
                    cursor: pointer;

                    &.active{
                        background: crimson;
                    }
                }
            }
        }

        .action{
            width: 100%;
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin: 10px 0;

            .left{
                width: 90%;
                display: flex;
                align-items: center;
                justify-content: flex-start;

                .item{
                    width: 100px;
                    height: 100px;
                    background: crimson;
                    margin-right: 10px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    cursor: pointer;

                    img{
                        width: 100%;
                        height: 100%;
                        object-fit: cover;
                    }
                }
            }
            .right{
                width: 10%;

                .add{
                    background: crimson;
                    border-radius: 50%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    width: 40px;
                    height: 40px;
                    cursor: pointer;

                    .icon{
                        color: white;
                    }
                }
            }
        }
    }
}
Total
0
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post
print()funksiyasi-haqida

Print()funksiyasi haqida

Next Post
microsoft-launched-its-ai-powered-bing-image-creator-–-what-that-means-for-marketers

Microsoft Launched Its AI-Powered Bing Image Creator – What That Means for Marketers

Related Posts