Thank you for opening this question in advance.
The thing I want to make(and understood)is time input feature, that allows user to see the expected time; by comparing two (given) input value provided by user.
For example, (1) user will input any starting time to first time input section.
(2) user will input any ending time to set.
(3) By substracting ending value with starting value, it should print the outcome.
(start) 10:00
(end) 14:00
And this is goal:
End - start = 4 hours (expected time; to accomplish its task)
So far, I have attmpted searching for useState, getTime method as a clue to make the feature I described above.
But something is missing...for example:
var diffTime = (end.getTime() - start.getTime()) / (1000);
But I have no idea how to expand this idea further than this point.
How should I print the (expected time) value by comparing the input values received from two different time input values?
import React from "react";
import styled from "styled-components";
function App() {
return (
<div className="App">
<h3>Section</h3>
<div className="time">
<label for="due">Set your time to compare it</label>
<p></p>
Start
<input id="due" type="datetime-local" name="duedate" />
End
<input id="due" type="datetime-local" name="duedate" />
<p>
<label for="due">Time you spent</label>
<StylingBox>
<div className="square-box">
<div className="sqaure-content">
<p>(place to display the calculated value here)</p>
</div>
</div>
</StylingBox>
</p>
</div>
</div>
);
}
export default App;
This is a minimal setup that can help you get started:
import { useEffect, useState } from "react";
export default function App() {
// This state variable will hold the starting date:
const [start, setStart ] = useState(null);
// This state variable will hold the ending date:
const [end, setEnd ] = useState(null);
// This state variable will hold the difference between the starting and ending date:
const [ final, setFinal ] = useState(null);
// Update starting date on input change event:
function handleStartChange(e){
setStart(new Date(e.target.value).getTime());
}
// Update ending date on input change event:
function handleEndChange(e){
setEnd(new Date(e.target.value).getTime());
}
useEffect(function runWhenStartOrEndChange(){
// Calculate difference only if both starting and ending dates are present and not null
if ( end && start){
const diffTime = ((new Date(end).getTime() - new Date(start).getTime()) / (1000)) / 60;
setFinal( diffTime );
}
}, [start, end])
return (
<>
<label htmlFor="due">Set your time to compare it</label>
Start:
<input onChange={handleStartChange} id="due" type="datetime-local" name="duedate" />
End:
<input onChange={handleEndChange} id="due" type="datetime-local" name="duedate" />
<label htmlFor="due">Time you spent</label>
<div>{final} minutes</div>
</>
);
}
You can even approach this using just a single state variable, but I'll leave this up to you as a practice.
Working demo:
<script crossorigin src="https://unpkg.com/react#18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#18/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel">
const useEffect = React.useEffect;
const useState = React.useState;
function App() {
// This state variable will hold the starting date:
const [start, setStart ] = useState(null);
// This state variable will hold the ending date:
const [end, setEnd ] = useState(null);
// This state variable will hold the difference between the starting and ending date:
const [ final, setFinal ] = useState(null);
// Update starting date on input change event:
function handleStartChange(e){
setStart(new Date(e.target.value).getTime());
}
// Update ending date on input change event:
function handleEndChange(e){
setEnd(new Date(e.target.value).getTime());
}
useEffect(function runWhenStartOrEndChange(){
// Calculate difference only if both starting and ending dates are present and not null
if ( end && start){
const diffTime = ((new Date(end).getTime() - new Date(start).getTime()) / (1000)) / 60;
setFinal( diffTime );
}
}, [start, end])
return (
<React.Fragment>
<label htmlFor="due">Set your time to compare it</label>
<br /> Start:
<input onChange={handleStartChange} id="due" type="datetime-local" name="duedate" />
<br/> End:
<input onChange={handleEndChange} id="due" type="datetime-local" name="duedate" />
<br /><label htmlFor="due">Time you spent: {final} minutes</label>
</React.Fragment>
);
}
const el = document.querySelector("#root");
const rootEl = ReactDOM.createRoot(el);
rootEl.render(<App />);
</script>
Related
i'm creating a simple react website that's supposed to do some calculations and find out Joules of my input values after the calculations...right now the input values are already preset but i will remove the value="" from my <input> later.
here is the .JSX component file that's the issue...one of the components.
import React, { Component } from 'react';
import Atom_icon from './cartridges.png';
class Joule_calc extends Component {
render(){
return (
<div className='Joule_div'>
<h3 style={{color:"white", textAlign:"center"}}>JOULE CALCULATOR</h3>
<label className='lab1'>WEIGHT=/GRAMS</label><br></br>
<input className='weight_inp' type='text' value="2" />
<label className='lab2'>SPEED=M/S</label><br></br>
<input className='speed_inp' type='text' value="5" />
<button className='count_button' onClick={this.Create_response}>CALCULATE</button>
<h1 className='Result_joule'></h1>
</div>
)
}
Create_response(){
console.log("creating response...")
let sum = document.createElement("h1")
sum.className = 'Result_joule'
sum.textContent = "678"
let div_panel = document.getElementsByClassName("Joule_div")
div_panel.append('Result_joule')
}
Returned_values(){
let weight_val = document.getElementsByClassName("weight_inp")[0].value;
let speed_val = document.getElementsByClassName("speed_inp")[0].value;
let final_calculation = weight_val * speed_val
return final_calculation
}
}
export default Joule_calc
so when i run my code i get
Uncaught TypeError: div_panel.append is not a function
at Create_response (Joule_calc_window.jsx:31:1)
i don't get why i can't append my new element to the div. it says it's not a function so what's the solution then? i'm new to React and web so probably it's just a noobie thing.
also i tried directly creating a h1 inside the 'Joule_div' like this.
<h1 className='Result_joule'>{"((try returning here from one of these methods))"}</h1>
but that of course failed as well. So would appreciate some help to get what's going on. i'm trying to add a number after the button click that's in h1 and in future going to be a returned number after calculating together the input values in a method.i imagine that something like
MyMethod(){
value = values calculated
return value
}
and later grab it with this.MyMethod
example
<h1>{this.MyMethod}</h1>
this is a example that of course didn't work otherwise i wouldn't be here but at least gives you a clue on what i'm trying to do.
Thank you.
You don't leverage the full power of react. You can write UI with only js world thanks to JSX. State changes triggering UI update.
I may miss some specificaiton, but fundamental code goes like the below. You should start with function component.
// Function component
const Joule_calc = () =>{
// React hooks, useState
const [weight, setWeight] = useState(0)
const [speed, setSpeed] = useState(0)
const [result,setResult] = useState(0)
const handleCalculate = () =>{
setResult(weight*speed)
}
return (
<div className="Joule_div">
<h3 style={{ color: 'white', textAlign: 'center' }}>JOULE CALCULATOR</h3>
<label className="lab1">WEIGHT=/GRAMS</label>
<br></br>
<input className="weight_inp" type="text" value={weight} onChange={(e)=>setWeight(parseFloat(e.target.value))} />
<label className="lab2">SPEED=M/S</label>
<br></br>
<input className="speed_inp" type="text" value={speed} onChange={(e)=>setSpeed(parseFloat(e.target.value))} />
<button className="count_button" onClick={handleCalculate}>
CALCULATE
</button>
<h1 className='Result_joule'>{result}</h1>
</div>
)
}
export default Joule_calc;
div_panel is an collection of array which contains the classname ["Joule_div"]. so first access that value by using indexing . and you should append a node only and your node is "sum" not 'Result_joule' and you should not use textcontent attribute because you will be gonna definitely change the value of your result as user's input value
Create_response(){
console.log("creating response...")
let sum = document.createElement("h1")
sum.className = 'Result_joule'
//sum.textContent = "678"
let div_panel = document.getElementsByClassName("Joule_div")
div_panel[0].append('sum')
}
if any problem persists , comment below
I'm developing with React.js and below is a simplified version of my component. As you can see, when I click the button state(number) would get a number. And here is what I want, make div tags as much as a number in state(number) in the form tag(which its class name is 'b').
Could you tell me how to make this possible? Thanks for reading. Your help will be appreciated.
//state
const[number,setNumber] = useState('')
//function
const appendChilddiv =(e)=>{
e.preventDefault()
setNumber('')
}
<div>
<form className="a" onSubmit={appendChilddiv}>
<input
value={number}
onChange={(e)=>setNumber(e.target.value)}
type="number"/>
<button type="submit">submit</button>
</form>
<div>
<form className="b">
</form>
</div>
</div>
I've created a codesandbox which includes the following code, previously you were storing the value as a string, it'd be best to store it as number so you can use that to map out, which I do via the Array() constructor (this creates an array of a fixed length, in this case the size of the divCount state - when we update the state by changing the input value this creates a re-render and thats why the mapping is updated with the new value)
import "./styles.css";
import * as React from "react";
export default function App() {
//state
const [divCount, setDivCount] = React.useState(0);
//function
const appendChilddiv = (e) => {
e.preventDefault();
// Submit your form info etc.
setDivCount(0);
};
return (
<div>
<form className="a" onSubmit={appendChilddiv}>
<input
value={divCount}
onChange={(e) => setDivCount(Number(e.target.value))}
type="number"
/>
<button type="submit">submit</button>
</form>
<div>
<form className="b">
{Array(divCount)
.fill(0)
.map((x, idx) => (
<div key={idx}>Div: {idx + 1}</div>
))}
</form>
</div>
</div>
);
}
You can map over an array whose length is same as that entered in input & create divs (if number entered is valid):
{!isNaN(number) &&
parseInt(number, 10) > 0 &&
Array(parseInt(number, 10))
.fill(0)
.map((_, idx) => <div key={idx}>Hey!</div>)
}
isNaN checks is number is valid
parseInt(number, 10) converts string into number,
Array(n) creates a new array with n elements (all empty) (try console logging Array(5)) - so you need to fill it
.fill(n) fill the array (make each element n)
and map is used to render different elements from existing things
So, in this way, you can achieve the mentioned result.
Here's a link to working Code Sandbox for your reference
You can do the following.
First thing it does is creates a new array of some length number.
Next, it fills that array with undefined, because creating new arrays like this doesn't really create an array of that length.
Lastly, we map over this array, we use the index as our key.
We return an empty div for each item in the array.
Note, using an index as a key isn't the best idea. In general it should be something as unique as possible. If you have data you can use that is unique, then you should use that as a key.
return new Array(number).fill(undefined).map((_, key) => <div key={key}></div>);
You can even do it without 'Submit' button. See the codesandbox link and the code snippet below:
import "./styles.css";
import * as React from 'react';
import { useState } from 'react';
export default function App() {
const [divTags, setDivTags] = useState([])
const appendChilddiv = (e) => {
const numberAsString = e.target.value;
let numberDivTags;
if (numberAsString.length === 0) {
numberDivTags = 0
} else {
numberDivTags = parseInt(numberAsString, 10)
}
setDivTags([...Array(numberDivTags)])
console.log(divTags)
}
return (
<>
<form className="a">
<input type="number" onChange={appendChilddiv}/>
</form>
<form className="b">
{divTags.map((e, i) => {
return <p key={i}>Div number {i}</p>
})}
</form>
</>
);
}
my code:
import "./styles.css";
export default function App() {
getUserValue = (e) => {
let value = e.target.value;
console.log(value)
return value
}
let userInputValue = getUserValue
return (
<div>
<div>
<h4>Sign Up</h4>
</div>
<div>
<div>
<p>Username</p>
<input onChange = {getUserValue}/>
</div>
<div >
<p>Password</p>
<input/>
</div>
</div>
<div>
<button onClick = {console.log(userInputValue)}>Submit</button>
</div>
<div>
<button>
Close
</button>
</div>
</div>
);
}
code sandbox: https://codesandbox.io/s/dazzling-sea-my5qm?file=/src/App.js:0-720
I'm trying to store the returned value of "getUserValue" function to "userInputValue" variable so I can log the input the user made and use it in different functions. I can't get it to work though, when I console log the variable hoping to get the returned result after I made an input I don't get anything, as if the button doesn't work.
I'm trying to store the returned value of "getUserValue" function to "userInputValue" variable so I can log the input the user made and use it in different functions.
You'd do that by making the input state in your component. In a function component like yours, that means using the useState hook (or various libraries like Redux that have alternative ways of doing it).
Here's a simple example, but you can find lots of more complex ones by searching:
const { useState } = React;
function Example() {
// Call the hook to get the current value and to
// get a setter function to change it. The default
// value ("" in this example) is only used the first
// time you call the hook in this component's lifecycle
const [userInput, setUserInput] = useState("");
// Handle changes in the input by setting state.
// Note that this function is recreated every time your
// component function is called to update. That's mostly
// fine, but there are times you might want to optimize
// that.
const onChange = (event) => {
setUserInput(event.currentTarget.value);
};
// Handle clicks on the button that show' the current input.
const onClick = () => {
console.log(`The current userInput is "${userInput}"`);
};
// Return the rendering information for React
return <div>
{/* Provide the value and hook the "change" (really "input") event */}
<input type="text" value={userInput} onChange={onChange} />
<input type="button" onClick={onClick} value="Show Current" />
</div>;
}
ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
** I fetched content from API with this code**
import React from "react";
import styles from "./Space.module.css";
import {useState,useEffect} from "react";
function Space() {
const [photoData,setPhotoData]=useState(null);
useEffect(()=>{
fetchPhoto();
async function fetchPhoto(){
const res = await fetch(`https://api.nasa.gov/planetary/apod?api_key=hETQq0FPsZJnUP9C3sUEFtwmJH3edb4I5bghfWDM`);
const data=await res.json();
setPhotoData(data);
console.log(data);
}
},[]); //empty array for running only once then empty array for that
if (!photoData) return <div />;
return (
<>
<div className={styles.space}>
{photoData.media_type === "image" ? (
<img
src={photoData.url}
alt={photoData.title}
className={styles.space}
/>
) : (
<iframe
title="space-video"
src={photoData.url}
frameBorder="0"
gesture="media"
allow="encrypted-media"
allowFullScreen
className={styles.space}
/>
)}
<div>
<h1>{photoData.title}</h1>
<p className={styles.space.date}>{photoData.date}</p>
<p className={styles.space.explanation}>{photoData.explanation}</p>
</div>
</div>
</>
);
}
export default Space;
and output of this code is like this
and I want Button here with next and then that will show previous day images
so can anyone tell me how to reverse that means after clicking on the next button by reversing the previous day images will show because NASA APOD(astronomy picture of the day )daily shown to all users like that is updated daily I know we can reverse that but can anyone tell me how to do that?
You can use date query parameter of apod api to get data for a specific date. This has default value today. Date needs to be in YYYY-MM-DD format. See apod section at https://api.nasa.gov/
If you want to request data for 2 January 2021 you'll have to send request to this :
https://api.nasa.gov/planetary/apod?date=2021-01-02&api_key=hETQq0FPsZJnUP9C3sUEFtwmJH3edb4I5bghfWDM
Note the date parameter
To get the previous day date use :
let today = new Date();
let yesterday = new Date();
yesterday.setDate(today.getDate() - 1);
console.log(yesterday.toString());
for formatting date in YYYY-MM-DD format see this question.
In onClick function of your button you'll make this http request and then change state with setPhotoData function.
I'm trying to create a random name generator where a user would input a bunch of names in a text box, and then it would output a single name from the array.
So far I have the following:
function App() {
const [firstNames, setFirstNames] = useState(['']);
const submitResults = (e) => {
e.preventDefault();
console.log(firstNames.length);
};
return (
<main>
<form onSubmit={submitResults}>
<div className="container">
<NameField
htmlFor="first-selection"
id="first-selection"
title="Selection 1"
value={firstNames}
onChange={(e) => setFirstNames(e.target.value)}
/>
</div>
</form>
</main>
);
}
But when I console.log the firstNames.length, I'm getting the character number instead. For example, if I submit [hello, there], I'll get 12 as the firstNames.length instead of 2. I tried playing around with the onChange, but I'm still not sure how to update the firstNames state so it adds the array properly.
You've entered a string of comma separated names, so when you want to process this as an array you need to convert the string into an array of strings.
Use String.prototype.split to split the firstNames state by "," to get an array.
firstNames.split(',').length
function App() {
const [firstNames, setFirstNames] = useState("");
const submitResults = (e) => {
e.preventDefault();
console.log(firstNames.split(",").length);
};
return (
<main>
<form onSubmit={submitResults}>
<div className="container">
<input
htmlFor="first-selection"
id="first-selection"
title="Selection 1"
value={firstNames}
onChange={(e) => setFirstNames(e.target.value)}
/>
<button type="submit">Check Names</button>
</div>
</form>
</main>
);
}