how to set onChange handler to change the language in react i18next - reactjs

-the select form that allow the user to change the language don't work with onclick how can I use onChange handler
am using react i18next.
*keep in mind that am not getting any errors or warnings.
this is my code
import i18n from 'i18next';
export default function Footer() {
const languages = [
{
code: "fr",
name: "francais",
countryCode:"fr"
},
{
code: "en",
name: "english",
countryCode:"gb"
},
{
code: "ar",
name: "العربية",
countryCode:"sa"
}
]
return <Form.Select aria-label="Default select example" >
{languages.map(({code,name, countryCode})=>{
return(
<option key={countryCode} onClick={()=> i18n.changeLanguage(code)}>{name}</option>
)
})}
</Form.Select>
}

The onChange handler to change the language needs to be set on the Form.Select component, like this: https://codesandbox.io/s/react-code-works-on-mozilla-but-but-dont-on-chrome-forked-1lkvw?file=/src/Footer.js:579-657
import { useTranslation } from "react-i18next";
import { Container, Form } from "react-bootstrap";
export default function Footer() {
const { i18n } = useTranslation();
const languages = [
{
code: "fr",
name: "francais",
countryCode: "fr"
},
{
code: "en",
name: "english",
countryCode: "gb"
},
{
code: "ar",
name: "العربية",
countryCode: "sa"
}
];
return (
<div className="section footer">
<Container>
<Form.Select
defaultValue={i18n.resolvedLanguage}
onChange={e => {
i18n.changeLanguage(e.target.value);
}}
>
{languages.map(({ code, name, countryCode }) => {
return (
<option
key={countryCode}
value={code}
>
{name}
</option>
);
})}
</Form.Select>
</Container>
</div>
);
}

Related

How to link fullcalendar and google api in react js

I want to bring a customized full calnedar and connect it with Google canlander api, but I don't know because it's customized Help me
The full calendar site says we can apply the code below, but I don't know where to put the code.
let calendar = new Calendar(calendarEl, {
plugins: [ googleCalendarPlugin ],
googleCalendarApiKey: '<YOUR API KEY>',
events: {
googleCalendarId: 'abcd1234#group.calendar.google.com',
className: 'gcal-event' // an option!
}
});
Below is my current code.
import React, { useState, useRef } from "react";
import "./style.module.css";
import FullCalendar from "#fullcalendar/react";
import timeGridPlugin from "#fullcalendar/timegrid";
import dayGridPlugin from "#fullcalendar/daygrid";
import interactionPlugin from "#fullcalendar/interaction";
import { nanoid } from "nanoid";
import {
Row,
Col,
Button,
FormGroup,
Label,
Input,
Container
} from "reactstrap";
import Select from "react-select";
import DateRangePicker from "react-bootstrap-daterangepicker";
import googleCalendarPlugin from "#fullcalendar/google-calendar"; //google calendar api
import "./custom.module.css";
import events from "./events";
import CustomModal from "../Components/CustomModal";
let todayStr = new Date().toISOString().replace(/T.*$/, "");
export default function Calendar() {
const [weekendsVisible, setWeekendsVisible] = useState(true);
const [currentEvents, setCurrentEvents] = useState([]);
const [modal, setModal] = useState(false);
const [confirmModal, setConfirmModal] = useState(false);
const calendarRef = useRef(null);
const [title, setTitle] = useState("");
const [start, setStart] = useState(new Date());
const [end, setEnd] = useState(new Date());
const handleCloseModal = () => {
handleClose();
setModal(false);
};
function handleDateClick(arg) {
};
function handleDateSelect(selectInfo) {
if (
selectInfo.view.type === "timeGridWeek" ||
selectInfo.view.type === "timeGridDay"
) {
selectInfo.view.calendar.unselect();
setState({ selectInfo, state: "create" });
// Open modal create
console.log("open modal create");
// console.log(selectInfo);
setStart(selectInfo.start);
setEnd(selectInfo.end);
setModal(true);
}
}
function renderEventContent(eventInfo) {
return (
<div>
<i
style={{
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis"
}}
>
{eventInfo.event.title}
</i>
</div>
);
}
function handleEventClick(clickInfo) {
setState({ clickInfo, state: "update" });
setTitle(clickInfo.event.title);
setStart(clickInfo.event.start);
setEnd(clickInfo.event.end);
setModal(true);
}
function handleEvents(events) {
setCurrentEvents(events);
}
function handleEventDrop(checkInfo) {
setState({ checkInfo, state: "drop" });
setConfirmModal(true);
}
function handleEventResize(checkInfo) {
setState({ checkInfo, state: "resize" });
setConfirmModal(true);
}
function handleEdit() {
state.clickInfo.event.setStart(start);
state.clickInfo.event.setEnd(end);
state.clickInfo.event.mutate({
standardProps: { title }
});
handleClose();
}
function handleSubmit() {
const newEvent = {
id: nanoid(),
title,
start: state.selectInfo?.startStr || start.toISOString(),
end: state.selectInfo?.endStr || end.toISOString(),
allDay: state.selectInfo?.allDay || false
};
calendarApi.addEvent(newEvent);
handleClose();
}
function handleDelete() {
state.clickInfo.event.remove();
handleClose();
}
function handleClose() {
setTitle("");
setStart(new Date());
setEnd(new Date());
setState({});
setModal(false);
}
const [state, setState] = useState({});
const [departments, setDepartments] = useState([
{ value: "1", label: "All" },
{ value: "2", label: "BPA Technical" },
{ value: "3", label: "Aqua 2 Cleaning" }
]);
function onFilter(element) {
console.log(element.value);
}
return (
<div className="App">
<Container>
<Row style={{ marginTop: 150 }}>
<h1 style={{color:'white', textAlign:'center', marginBottom:50}}>Make a Booking</h1>
</Row>
<Row>
<Col md={12}>
<FullCalendar
ref={calendarRef}
plugins={[dayGridPlugin,timeGridPlugin, interactionPlugin]}
headerToolbar={{
left: "prev,today,next",
center: "title",
right: "dayGridMonth,timeGridWeek,timeGridDay"
}}
buttonText={{
today: "Today's Time Table",
month: "month",
week: "week",
day: "day",
list: "list"
}}
initialView="timeGridWeek"
editable={true}
selectable={true}
selectMirror={true}
dayMaxEvents={true}
weekends={weekendsVisible}
//
initialEvents={[
{
},
{
id: nanoid(),
title: "All-day event",
start: todayStr
},
{
id: nanoid(),
title: "Timed event",
start: todayStr + "T12:00:00",
end: todayStr + "T12:30:00"
}
]}
select={handleDateSelect}
eventContent={renderEventContent} // custom render function
eventClick={handleEventClick}
eventsSet={() => handleEvents(events)}
eventDrop={handleEventDrop}
eventResize={handleEventResize}
//
dateClick={handleDateClick}
eventAdd={(e) => {
console.log("eventAdd", e);
}}
eventChange={(e) => {
console.log("eventChange", e);
}}
eventRemove={(e) => {
console.log("eventRemove", e);
}}
/>
</Col>
</Row>
</Container>
<CustomModal
title={state.state === "update" ? "Update Booking" : "Make a Booking"}
isOpen={modal}
toggle={handleCloseModal}
onCancel={handleCloseModal}
onSubmit={state.clickInfo ? handleEdit : handleSubmit}
submitText={state.clickInfo ? "Update" : "Save"}
onDelete={state.clickInfo && handleDelete}
deleteText="Delete"
>
<FormGroup>
<Label for="#gmail.com">Trainer</Label>
<br/>
<select className="form-control" name="title"
value={title} onChange={(e) => setTitle(e.target.value)}>
<option></option>
<option></option>
<option></option>
<option></option>
</select>
</FormGroup>
<FormGroup>
<Label for="#gmail.com">Start Time - End Time</Label>
<DateRangePicker
initialSettings={{
locale: {
format: "M/DD hh:mm A"
},
startDate: start,
endDate: end,
timePicker: true
}}
onApply={(event, picker) => {
setStart(new Date(picker.startDate));
setEnd(new Date(picker.endDate));
}}
>
<input className="form-control" type="text" />
</DateRangePicker>
</FormGroup>
</CustomModal>
<CustomModal
title={state.state === "resize" ? "Resize Event" : "Drop Event"}
isOpen={confirmModal}
toggle={() => {
state.checkInfo.revert();
setConfirmModal(false);
}}
onCancel={() => {
state.checkInfo.revert();
setConfirmModal(false);
}}
cancelText="Cancel"
onSubmit={() => setConfirmModal(false)}
submitText={"OK"}
>
Do you want to {state.state} this event?
</CustomModal>
</div>
);
}
I tried to apply the code below to my code by applying calendar id and api key on Google, but I don't know.
let calendar = new Calendar(calendarEl, {
plugins: [ googleCalendarPlugin ],
googleCalendarApiKey: '<YOUR API KEY>',
events: {
googleCalendarId: 'abcd1234#group.calendar.google.com',
className: 'gcal-event' // an option!
}
});

Browser Error for React Component Seperation

im having a slight problem with my react code, im trying to create a simple react appplication that has seperated components, as im still currently learning. Can someone look at this code and let me know whats going wrong? My dropdown component when added makes the browser load forever, so its something to do with that component, as when removed from app.js, it loads fine
import * as React from "react";
function Dropdown() {
const [food, setFood] = React.useState("fruit");
const [drink, setDrink] = React.useState("water");
const handleFoodChange = (event) => {
setFood(event.target.value);
};
const handleDrinkChange = (event) => {
setDrink(event.target.value);
};
return (
<div>
<Dropdown
label="What do we eat?"
options={[
{ label: "Fruit", value: "fruit" },
{ label: "Vegetable", value: "vegetable" },
{ label: "Meat", value: "meat" },
]}
value={food}
onChange={handleFoodChange}
/>
<Dropdown
label="What do we drink?"
options={[
{ label: "Water", value: "water" },
{ label: "Beer", value: "beer" },
{ label: "Wine", value: "wine" },
]}
value={drink}
onChange={handleDrinkChange}
/>
<p>We eat {food}!</p>
<p>We drink {drink}!</p>
</div>
);
}
export default Dropdown;
Below is how its being imported
import "./App.css";
import Checkbox from "./components/Checkbox";
import Dropdown from "./components/Dropdown";
function App() {
return (
<div>
<Checkbox />
<Dropdown />
<h1>test</h1>
</div>
);
}
export default App;
This is happening because you are importing Dropdown inside Dropdown component.
I updated your code to show you another way to create a Dropdown.
function DropdownContainer() {
const [food, setFood] = React.useState("fruit");
const [drink, setDrink] = React.useState("water");
const handleFoodChange = (event) => {
setFood(event.target.value);
};
const handleDrinkChange = (event) => {
setDrink(event.target.value);
};
return (
<div>
<Dropdown
label="What do we eat?"
selectedOption={food}
options={[
{ label: "Fruit", value: "fruit" },
{ label: "Vegetable", value: "vegetable" },
{ label: "Meat", value: "meat" },
]}
onHandleChange={handleFoodChange}
/>
<Dropdown
label="What do we drink?"
selectedOption={drink}
options={[
{ label: "Water", value: "water" },
{ label: "Beer", value: "beer" },
{ label: "Wine", value: "wine" },
]}
onHandleChange={handleDrinkChange}
/>
<p>We eat {food}!</p>
<p>We drink {drink}!</p>
</div>
);
}
function Dropdown({ selectedOption = "", label = "", options = [], onHandleChange }) {
return (
<select
label={label}
onChange={onHandleChange}
>
{options.map(opt => <option selected={selectedOption === opt.value} value={opt.value}>{opt.label}</option>)}
</ select>
);
}
export function App(props) {
return (
<DropdownContainer />
);
}
Why do you put <Dropdown ...> inside Dropdown function? It causes recursive call and results in infinite loading.
You should use <select ..> like below.
<select>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option selected value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>

React: Why is one of my prop variable undefined?

Hey I'm new to React and I'm having a problem with my prop which I'm passing to my ChildComponent. I am using "react-select" and have two multiselects. Originally I wanted to show in each select the value for the corresponding select I get from the state.
value={optionsColor.filter(item => ( myTest.color.includes(item.value)))}
But this is not possible because one of my calls is always "undefined". For example "myTest.Color" and "myTest.Car" one of them is "undefined" but I don't know why?
In my code (ChildComponent) I have two console.logs which illustrate this.
For example, if I select Color and have previously selected a car in Car, the console.log output looks like this.
undefined
blue
But I want it to output both.
import {useState} from "react";
import ChildComponent from "./ChildComponent";
const ParentComponent = () => {
const [step, setStep] = useState(0)
const [myTest, setMyTest] = useState(
{
color: ['defaultColor'],
car: ['defaultCar'],
}
)
const handleChange = (e, action) => {
setMyTest({ [action.name]: e ? e.map(x => x.value) : [] })
}
return (
<div>
<div className="card-body container mt-3">
<h2>Product data input Intended Use</h2>
<div className="card p-2 mt-5">
<form className="mb-4">
<div className="form"></div>
<ChildComponent myTest={myTest} handleChange={handleChange}/>
</form>
</div>
</div>
</div>
)
}
export default ParentComponent;
import React, { useState } from 'react';
import Select from 'react-select';
const optionsColor = [
{ value: 'blue', label: 'Blue' },
{ value: 'red', label: 'Red' },
{ value: 'yellow', label: 'Yellow' }
]
const optionsCar = [
{ value: 'bmw', label: 'BMW' },
{ value: 'ford', label: 'Ford' },
{ value: 'vw', label: 'VW' },
]
const ChildComponent = ({ handleChange, myTest}) => {
return (
<div>
<h4>Car {console.log(myTest.car)}</h4>
<Select
name="car"
options={optionsCar}
className="mb-3"
onChange={handleChange}
//value={intendedUse.sex === undefined ? '' : optionsSex.filter(item => (intendedUse.sex.includes(item.value)))}
isMulti
autoFocus
isSearchable
/>
<h4>Color {console.log(myTest.color)}</h4>
<Select
name="color"
options={optionsColor}
className="mb-3"
onChange={handleChange}
//value={intendedUse.age === undefined ? '': optionsAge.filter(item => ( intendedUse.age.includes(item.value)))}
isMulti
autoFocus
isSearchable
/>
</div>
)
}
export default ChildComponent;
the problem lies here.
setMyTest({ [action.name]: e ? e.map(x => x.value) : [] })
When you're updating your myTest state you're actually replacing both of the fields with the field you're setting.
Try something like this:
setMyTest(myTest => ({...myTest, { [action.name]: e ? e.map(x => x.value) : [] }}));
In that way, you have a new object with both the field that changed and the one that didn't.

Cascade Dropdown using react Hooks

Hi Guys I'm new to React. I am trying to create a cascade drop down list using react hooks and the way I did it works well but I feel something wrong in the way I did it. Please check this code and tell me there is a way that I can improve my code.Thanks in advance
import React, { useState } from 'react';
import './App.css';
function App() {
const[data, setName] = useState({
countrie:"",
state:""
});
let state;
const countrie =['Germany','India','France']
const gstate = ['Duesseldorf', 'Leinfelden-Echterdingen', 'Eschborn']
const istate = ['Delhi', 'Kolkata', 'Mumbai', 'Bangalore']
const fstate =['Auvergne','Bretagne','Corse','Centre']
if(data.countrie==="Germany"){
state = gstate.map((gstate,key)=> <option key={key} value={gstate}>{gstate}</option>)
}else if(data.countrie==="India"){
state = istate.map((istate,key)=> <option key={key} value={istate}>{istate}</option>)
}else{
state = fstate.map((fstate,key)=> <option key={key} value={fstate}>{fstate}</option>)
}
const countries = countrie.map((countrie,key)=> <option key={key} value={countrie}>{countrie}</option>)
function handleCountry(e){
setName({...data,countrie:e.target.value});
}
function handleStateChange(e){
setName({...data,state:e.target.value});
}
return (
<form onSubmit={handleSubmit}>
<div>
<select value={data.countrie} onChange={handleCountry}>
{countries}
</select>
</div>
<div>
<select value={data.state} onChange={handleStateChange}>
{state}
</select>
</div>
<input type="submit" />
</form>
);
}
export default App;
The best suggestion I have is to change the data structure which combines the country and states. Doing so makes it a lot easier to map over each country and getting the states without having to map variables. This makes it also more scalable.
Here is an example using the country data as a collection:
Codesandbox
import React, { useState } from "react";
const countriesData = [
{
name: "Germany",
states: ["Duesseldorf", "Leinfelden-Echterdingen", "Eschborn"]
},
{
name: "India",
states: ["Delhi", "Kolkata", "Mumbai", "Bangalore"]
},
{
name: "France",
states: ["Auvergne", "Bretagne", "Corse", "Centre"]
}
];
function Form() {
const [{ country, state }, setData] = useState({
country: "Germany",
state: ""
});
const countries = countriesData.map((country) => (
<option key={country.name} value={country.name}>
{country.name}
</option>
));
const states = countriesData.find(item => item.name === country)?.states.map((state) => (
<option key={state} value={state}>
{state}
</option>
));
function handleCountryChange(event) {
setData(data => ({ state: '', country: event.target.value }));
}
function handleStateChange(event) {
setData(data => ({ ...data, state: event.target.value }));
}
return (
<form onSubmit={() => console.log("Submitted")}>
<div>
<select value={country} onChange={handleCountryChange}>
{countries}
</select>
</div>
<div>
<select value={state} onChange={handleStateChange}>
{states}
</select>
</div>
<input type="submit" />
</form>
);
}
export default Form;

How can I set HTML code inside select <option> in React?

I'm trying to output pretty fractions inside my options, ¼ ½ ¾ but it's displaying the "&frac 14;" as strings.
How can I get the JSX to interpret my optionContent and render the HTML, not as a string?
optionValue = "4.25"
optionContent = "4 ¾"
{optionContent}
You can do it using the html-react-parser;
Example:
https://codesandbox.io/s/parsing-html-react-zlmwj
import React, { useState } from "react";
import Parser from "html-react-parser";
import "./styles.css";
export default function App() {
const [options, setOption] = useState(1);
const [listOptions] = useState([
{ id: 1, desc: "4 ¼" },
{ id: 2, desc: "4 ½" },
{ id: 3, desc: "4 ¾" }
]);
function handleSelect(e) {
const selected = e.target.value;
setOption(selected);
}
return (
<div className="App">
<h1>Example parsing html in React</h1>
<select value={options} onChange={e => handleSelect(e)}>
{listOptions.map(option => (
<option key={option.id} value={option.id}>
{Parser(option.desc)}
</option>
))}
</select>
</div>
);
}

Resources