nextjs and bootstrap5 modal - reactjs

Hello I would like to use bootstrap 5 without react-bootstrap and reactstrap when I create my modal I end up with this error:
TypeError: undefined is not an object (evaluating 'this._element.classList')
Do you have any idea because all the examples I am viewing are still with reactstrap or react-bootstrap, do you have any idea how to do this, thanks for your help.
import Document, { Html, Head, Main, NextScript } from "next/document";
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
<div id="modal-root"></div>
</body>
</Html>
);
}
}
export default MyDocument;
My modal
import { useState, useEffect } from "react";
import ReactDom from "react-dom";
const Modal = ({ show, onClose, children, title, targetModal }) => {
const [isBrowser, setIsBrowser] = useState(false);
useEffect(() => setIsBrowser(true));
const handleCloseModal = (e) => {
e.preventDefault();
let myModalEl = document.getElementById(targetModal);
console.log(myModalEl);
onClose();
};
const modalContent = show ? (
<div
className="modal fade py-3"
tabIndex="-1"
role="dialog"
id={targetModal}
>
<div className="modal-dialog" role="document">
<div className="modal-content border-0 rounded-6 shadow-blue-sm">
<div className="modal-header p-4 pb-4 border-bottom-0">
<h4 className="fw-bold mb-0 hstack text-secondary">
{title && (
<span>
<i className="ri-user-search-line me-2"></i> {title}
</span>
)}
</h4>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
onClick={handleCloseModal}
aria-label="Close"
></button>
</div>
<div className="modal-body p-4 pt-0">{children}</div>
</div>
</div>
</div>
) : null;
if (isBrowser) {
return ReactDom.createPortal(
modalContent,
document.getElementById("modal-root")
);
} else {
return null;
}
};
export default Modal;
My Page
import { useState } from "react";
import Layouts from "#/components/Layouts";
import Modal from "#/components/Modal";
const EditEventsPage = () => {
const [showModal, setShowModal] = useState(false);
return (
<Layouts title="Edit event.">
<button
type="submit"
className="btn btn-secondary mt-4 hstack"
data-bs-toggle="modal"
data-bs-target="#uploadImage"
onClick={() => setShowModal(true)}
>
<i className="ri-image-line "></i> Ajouter image{" "}
</button>
<Modal
show={showModal}
onClose={() => setShowModal(false)}
targetModal="uploadImage"
></Modal>
</Layouts>
);
};
export default EditEventsPage;
Thansk for your helps.

I have not been able to achieve this using your method.
However, this works for me, and you could expand on the example.
in your _app.js file add this line of code, you should wrap it in the useEffect function as so
useEffect(() => {
typeof document !== undefined
? require("bootstrap/dist/js/bootstrap")
: null;
},[]);
This will make bootstrap available across your project. So where ever you want to trigger your modal.
just do this instead
<button type="button" data-bs-toggle="modal" data-bs-target="#myModal">Launch modal</button>
Your Bootstrap modal
<div
className="modal modal-alert bg-secondary py-5"
tabIndex="-1"
role="dialog"
id="myModal"
>
<div className="modal-dialog modal-dialog-centered" role="document">
<div className="modal-content rounded-4 shadow">
<div className="modal-body p-4 text-center">
<h5 className="mb-0">Enable this setting?</h5>
<p className="mb-0">
You can always change your mind in your account settings.
</p>
</div>
<div className="modal-footer flex-nowrap p-0">
<button
type="button"
className="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0 border-right"
>
<strong>Yes, enable</strong>
</button>
<button
type="button"
className="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0"
data-bs-dismiss="modal"
>
No thanks
</button>
</div>
</div>
</div>
</div>
Hope this helps.

Related

How to connect react js voice text to speech into search bar?

I want to add speech recognition for the search bar and I connect it with laravel controller. By typing anything I can search for products. I want to add a microphone and when tell something, search and display results. Accually I want to when tell something , it should display in search bar text. How I do this?
import React,{useState,useEffect} from 'react';
import {Link} from 'react-router-dom';
import axios from 'axios';
import swal from 'sweetalert';
import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition';
function VoiceSearchBar() {
const [searchInput,setSearchInput] = useState({
searchtext:'',
});
const [searchResults,setSearchResults] = useState([]);
const handleInput = (e) =>{
e.persist();
setSearchInput({...searchInput,[e.target.name]:e.target.value})
}
const {
transcript,
listening,
resetTranscript,
browserSupportsSpeechRecognition
} = useSpeechRecognition();
if (!browserSupportsSpeechRecognition) {
return <span>Browser doesn't support speech recognition.</span>;
}
const submitSearch = (e) =>{
e.preventDefault();
const data = {
searchtext:searchInput.searchtext,
}
axios.post('api/store-search-text', data).then(res=>{
if(res.data.status === 200){
setSearchResults(res.data.text);
console.log(res.data.text);
}
else if(res.data.status === 404){
swal("Warning",res.data.message,"warning")
}
});
}
var results = "";
if(searchResults){
results = searchResults.map((item)=>{
return(
<div key={item.id} className="row">
<div className="col-sm-3">
<img src={`http://localhost:8000/${item.pimage}`} alt={item.name} width="50px"/>
</div>
<div className="col-sm-9">
<Link to={`/products/category/${item.category.slug}/${item.slug}`}><h6 data-bs-dismiss="modal">{item.name}</h6></Link>
<p>{item.meta_description}</p>
</div>
</div>
)
});
}
return (
<div>
<form onSubmit={submitSearch} className="d-flex">
<input className="form-control me-2" onChange={handleInput} value={searchInput.searchtext} type="search" name="searchtext" placeholder="Search" aria-label="Search" />
<div>
{/* <p>Microphone: {listening ? 'on' : 'off'}</p> */}
{/* <button onClick={SpeechRecognition.startListening}>start</button>
<button onClick={SpeechRecognition.stopListening}><button className="resetBtn" onClick={resetTranscript}></button>Stop</button>
<p>{transcript}</p> */}
</div>
<button className="btn btn-success" type="submit" data-bs-toggle="modal" data-bs-target="#staticBackdrop">Search</button>
</form>
<div class="modal fade" id="staticBackdrop" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Search Results</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{results}
</div>
</div>
</div>
</div>
</div>
);
}
export default VoiceSearchBar;

React prevent body from scrolling if popup is open

React prevent body from scrolling if popup is open.
How can i disable the background body from scrolling when the pop up div is open.
function FilterButton() {
let [isOpen, setIsOpen] = useState(false);
return (
<div className='filter-button'>
<div className="name-filter" onClick={() => setIsOpen(!isOpen)}>
<p>Filter</p>
<i class="fas fa-filter"></i>
</div>
{
isOpen ? <div className="background-blur">
<div className="filter-popup">
<p className='filter-by-name'>Filter By Type</p>
<hr />
<div className="filter-types">
<div className="filter">
<input type="checkbox" />
<p></p>
</div>
</div>
<div className="apply-cancel">
<button className="apply">Apply</button>
<button className="cancel" onClick={() => setIsOpen(!isOpen)}>Cancel</button>
</div>
</div>
</div>
: null
}
</div>
)
}
You can use the body-scroll-lock library to help you with that.
Here is how it could work on your component. I haven't tested it tho.
import { useState, useRef, useEffect } from 'react';
import {
disableBodyScroll,
enableBodyScroll,
clearAllBodyScrollLocks
} from 'body-scroll-lock';
function FilterButton() {
const [isOpen, setIsOpen] = useState(false);
const popupRef = useRef(null)
useEffect(() => {
if (isOpen) {
popupRef.current && disableBodyScroll(popupRef.current)
} else {
popupRef.current && enableBodyScroll(popupRef.current)
}
}, [isOpen])
return (
<div className="filter-button">
<div className="name-filter" onClick={() => setIsOpen(!isOpen)}>
<p>Filter</p>
<i class="fas fa-filter"></i>
</div>
{isOpen ? (
<div className="background-blur">
<div className="filter-popup" ref={popupRef}>
<p className="filter-by-name">Filter By Type</p>
<hr />
<div className="filter-types">
<div className="filter">
<input type="checkbox" />
<p></p>
</div>
</div>
<div className="apply-cancel">
<button className="apply">Apply</button>
<button className="cancel" onClick={() => setIsOpen(!isOpen)}>
Cancel
</button>
</div>
</div>
</div>
) : null}
</div>
);
}

First key press is not working by using react hook form controlled component

I used react hook form for validations purpose. but our code is implemented on controlled components. I went through few examples in google that use default value instead of value.
If I replace the value with the default value after submitting a form. The values in the form are not clearing can anyone suggest to me how to overcome this.
import React, { useState, useEffect } from 'react';
import { getIdToken } from '../Utils/Common';
import { useForm } from 'react-hook-form';
export default function Roles() {
const [roleName, setroleName] = useState('');
const { register, handleSubmit, errors } = useForm();
const handleRoleName = (event) => {
setroleName(event.target.value);
};
const handleAddRole = () => {
/* api call here after succes i have clear role name*/
setroleName('');
};
}
return (
<div className='g-pa-20'>
<h1 className='g-font-weight-300 g-font-size-28 g-color-black g-mb-28'>
{editaddLabel}
</h1>
<form noValidate onSubmit={handleSubmit(handleAddRole)}>
<div className='row'>
<div className='col-md-4 col-xs-12 col-sm-12'>
<div className='g-brd-around g-brd-gray-light-v7 g-rounded-4 g-pa-15 g-pa-20--md g-mb-30'>
<div className='mb-4'>
<div className='form-group g-mb-30'>
<label className='g-mb-10' for='inputGroup-1_1'>
Role Name
</label>
<div
className={
errors && roleName === ''
? 'g-err-brd-primary--focus'
: 'g-pos-rel'
}
>
<span className='g-pos-abs g-top-0 g-right-0 d-block g-width-40 h-100 opacity-0 g-opacity-1--success'>
<i
className='hs-admin-check g-absolute-centered g-font-size-default g-color-secondary'
on
></i>
</span>
<input
id='inputGroup-1_1'
className='form-control form-control-md g-brd-gray-light-v7 g-brd-gray-light-v3--focus g-rounded-4 g-px-14 g-py-10'
type='text'
placeholder=''
onChange={handleRoleName}
value={roleName}
name='role'
ref={register({
required: true,
})}
/>
</div>
{errors.role && errors.role.type === 'required' && (
<p className='plans-single-error'> Role name is required.</p>
)}
</div>
</div>
<div className='from-group'>
<div className='form-row pull-right'>
<div className='form-group col-xs-6'>
<button
className='btn btn-md btn-xl--md u-btn-primary g-font-size-12 g-font-size-default--md g-mr-10 g-mb-10'
disabled={loading}
>
{loading && (
<i className='fas fa-spinner fa-spin spinner'></i>
)}
Save
</button>
</div>
<div className='form-group col-xs-6'>
<button
className='btn btn-md btn-xl--md u-btn-outline-gray-dark-v6 g-font-size-12 g-font-size-default--md g-mb-10'
onClick={cancelClick}
>
Cancel
</button>
</div>
</div>
</div>
<div className='from-group'>
<label></label>
</div>
</div>
</div>
</div>
</form>
</div>
);

When conditionally exporting functions components in react I cannot access my useState variables. Any Solutions?

Here is my file with two components that are supposed to conditionally render. The problem is right before I export I cannot use my variables from isLoggedIn (u, useradmin, p, passadmin).
import React, { Fragment, useState } from "react";
import "./SignIn.css";
import { Link } from "react-router-dom";
const isLoggedIn = (user, pass) => {
let u = user.toString();
let p = pass.toString();
let useradmin = "bilal";
let passadmin = "123";
console.log(u)
console.log(p)
if (u === useradmin && p === passadmin) {
console.log("success")
return (
<Fragment>
<button type="button" className="btn btn-warning" data-toggle="modal">Head to Admin</button>
<div className="modal fade">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title text-dark">Successfully Signed In!</h4>
<button type="button" className="close" data-dismiss="modal" ></button>
</div>
<div className="modal-body">
<input type="text" className="form-control" />
</div>
<div className="modal-footer">
<Link to="/adminqueue">
<button type="button" className="btn btn-danger" data-dismiss="modal">Enter Admin Queue</button>
</Link>
</div>
</div>
</div>
</div>
</Fragment>
)
}
}
const SignIn = () => {
const [user, setUser] = useState('');
const [pass, setPass] = useState('');
return (
<Fragment>
<div className="login-box">
<h1>Admin Log In</h1>
<form>
<div className="textbox">
<i className="fas fa-user" />
<input onChange={event => setUser(event.target.value)} type="text" placeholder="Username" />
</div>
<div className="textbox">
<i className="fas fa-lock" />
<input onChange={event => setPass(event.target.value)} type="password" placeholder="Password" />
</div>
<button className="button" type="button" value="Sign in" onClick={() => isLoggedIn(user, pass)} >SignIn</button>
</form>
</div>
</Fragment>
)
}
const exp = u === useradmin && p === passadmin ? isLoggedIn : SignIn;
export default exp;
This is just text because Stack Overflow Says I have too much code (IGNORE).

How to show the content and hide the content conditionally in react using hooks

I am working on a React project that I have to show content and hide the content conditionally when I click the button. For example, I have four buttons, First Button is Frontend, Second Button is Middleware, Third Button is Database, and Fourth Button is Apps.
By Default when I landed on the Home Page Frontend Button should be Highlighted remaining button should be normal. At that time I have to show only Frontend-related frameworks or libraries.
Now when I click Middleware Button then the Middleware Button should be Highlighted At that time I have to show Middleware Frameworks like Node Express etc.
Now when I click Database Button then the Database Button should be Highlighted At that time I have to show Database like Mongo Db, Casandra.
Now when I click Apps Button then the App Button should be Highlighted At that time I have to show Apps like React native, Flutter.
Please help me to achieve this task
This is Home.js
import React, { useState } from 'react';
import './Home.css'
const Home = () => {
return (
<div className='container'>
<div className='row'>
<div className='col-3'>
<button className='btn btn-primary mt-3'>Frontend</button>
</div>
<div className='col-3'>
<button className='btn btn-danger mt-3'>Middleware</button>
</div>
<div className='col-3'>
<button className='btn btn-secondary mt-3'>Database</button>
</div>
<div className='col-3'>
<button className='btn btn-info mt-3'>Apps</button>
</div>
</div>
<div className='row mt-3'>
<div className='col-3'>
<h3>React</h3>
</div>
<div className='col-3'>
<h3>Angular</h3>
</div>
<div className='col-3'>
<h3>Vue</h3>
</div>
<div className='col-3'>
<h3>Ember</h3>
</div>
</div>
</div>
)
}
export default Home
const Home = () => {
const [selected, setSelected] = useState('frontend')
const frontends = ['React', 'Angular', 'Vue']
const middlewares = ['Node', 'Express', 'Hapi']
const databases = ['MongoDB', 'MySQL', 'Casandra']
const apps = ['React Native', 'Flutter']
let showingArr = []
if (selected === 'frontend') {
showingArr = frontends
} else if (selected === 'middleware') {
showingArr = middlewares
} else if (selected === 'database') {
showingArr = databases
} else if (selected === 'apps') {
showingArr = apps
}
return (
<div className='container'>
<div className='row'>
<div className='col-3'>
<button
className='btn btn-primary mt-3'
onClick={() => setSelected('frontend')}
>Frontend</button>
</div>
<div className='col-3'>
<button
className='btn btn-danger mt-3'
onClick={() => setSelected('middleware')}
>Middleware</button>
</div>
<div className='col-3'>
<button
className='btn btn-secondary mt-3'
onClick={() => setSelected('database')}
>Database</button>
</div>
<div className='col-3'>
<button
className='btn btn-info mt-3'
onClick={() => setSelected('apps')}
>Apps</button>
</div>
</div>
<div className='row mt-3'>
{
showingArr.map(item => (
<div className='col-3'>
<h3>{item}</h3>
</div>
))
}
</div>
</div>
)
}
const [show, setShow] = useState(false);
return(
{show ? <content to show when state is true /> : null}
)
here is a more scale able way of doing this . in the future if you want to add new topics of different types for example Pythonwhich can be of type AI , you want have to add an other condition check you can just add your AI toggle button and set onClick as toggleListType('AI')
import React, { useState ,useEffect} from 'react';
import './Home.css'
const Home = () => {
const [listOFtopics,setlistOFtopics]=useState([
{type:'FRONTEND',title:'react'},
{type:'FRONTEND',title:'angular'},
{type:'MIDDLEWEAR',title:'node'},
{type:'MIDDLEWEAR',title:'express'},
])
const [listOFtopicsToDisplay,setlistOFtopicsToDisplay]=useState([])
useEffect(()=>{
//initializing listOFtopicsToDisplay to show FRONEND related topics
setlistOFtopicsToDisplay(listOFtopics.filter(t=> t.type =="FRONTEND"))
},[])
const toggleListType=(type)=>{
setlistOFtopicsToDisplay(listOFtopics.filter(t=> t.type ==type))
}
return (
<div className='container'>
<div className='row'>
<div className='col-6'>
<button onClick={e=>toggleListType('FRONTEND')} className='btn btn-primary mt-3'>Frontend</button>
</div>
<div className='col-6'>
<button onClick={e=>toggleListType('MIDDLEWEAR')} className='btn btn-danger mt-3'>Middleware</button>
</div>
</div>
<div className='row mt-3'>
{
listOFtopicsToDisplay.map(t=><div className='col-3'><h3>Vue</h3</div>)
}
</div>
</div>
)
}
export default Home

Resources