i have custom numpad and input box and i want that when user click any number it shows in input field.
<div class="grid-container">
<button class="grid-item" onClick={inputNumKey}>1</button>
<button class="grid-item" onClick={inputNumKey}>2</button>
<button class="grid-item" onClick={inputNumKey}>3</button>
<button class="grid-item" onClick={inputNumKey}>4</button>
<button class="grid-item" onClick={inputNumKey}>5</button>
<button class="grid-item" onClick={inputNumKey}>6</button>
<button class="grid-item" onClick={inputNumKey}>7</button>
<button class="grid-item" onClick={inputNumKey}>8</button>
<button class="grid-item" onClick={inputNumKey}>9</button>
<button class="grid-item" onClick={inputNumKey}>*</button>
<button class="grid-item" onClick={inputNumKey}>0</button>
<button class="grid-item" onClick={inputNumKey}>#</button>
</div>
this is my numpad jsx code.
<div className="input-box-ad">
<input onChange={changeTime} name="hour" value={updatedHour} />
<input onChange={changeTime} name="minute" value={updatedMinute} />
<input onChange={changeTime} name="second" value={updatedSecond} />
</div>
this is input fields i want values of this button.
for more details i have codesandbox also - https://codesandbox.io/s/fancy-frog-l5uo2
const activeInput = { "background-color": "#BBFFCC" };
const Numbers = () => {
const [hour, setHour] = useState("00");
const [minute, setMinute] = useState("00");
const [second, setSecond] = useState("00");
const [timeType, setTimeType] = useState("hour");
const press = (k) => {
const [value, setter] =
timeType === "hour"
? [hour, setHour]
: timeType === "minute"
? [minute, setMinute]
: [second, setSecond];
setter((value.charAt(value.length - 1) || "0") + k);
};
return (
<div>
<div class="grid-container">
<button onClick={() => press("1")}>1</button>
<button onClick={() => press("2")}>2</button>
<button onClick={() => press("3")}>3</button>
<button onClick={() => press("4")}>4</button>
<button onClick={() => press("5")}>5</button>
<button onClick={() => press("6")}>6</button>
<button onClick={() => press("7")}>7</button>
<button onClick={() => press("8")}>8</button>
<button onClick={() => press("9")}>9</button>
<button onClick={() => press("*")}>*</button>
<button onClick={() => press("0")}>0</button>
<button onClick={() => press("#")}>#</button>
</div>
<div className="input-box-ad">
<input name={"hour"} value={hour} size={2}
onClick={() => setTimeType("hour")}
onChange={(e) => setHour(e.target.value)}
style={timeType === "hour" ? activeInput : {}}
/>
:
<input name={"minute"} value={minute} size={2}
onClick={() => setTimeType("minute")}
onChange={(e) => setMinute(e.target.value)}
style={timeType === "minute" ? activeInput : {}}
/>
:
<input name={"second"} value={second} size={2}
onClick={() => setTimeType("second")}
onChange={(e) => setSecond(e.target.value)}
style={timeType === "second" ? activeInput : {}}
/>
</div>
</div>
);
};
This is going to be very difficult to manage. I don't know why do you need the buttons to enter input you can do it with the keyboard.
If you do it with a keyboard then it will be easy.
const[updatedHour,setUpdatedHour] = useState();
function changeHour(e){
setUpdatedHour(e.target.value)
}
<input onChange={changeHour} name="hour" value={updatedHour} />
Do the same for all input boxes.
Still, if you want to do it with buttons here is a hint.
function inputNumKey(e){
console.log(e.target.textContent)
}
Related
I have a panel with 3 buttons, i want to make onclick on every button, a different component will appear in the same place. How can this logic be done?
<AddNotification />
<EditNotification />
<DeleteNotification />
const AdminPanel = () => {
return (
<Card className={classes.input}>
<div><h1>Notification Panel</h1></div>
<form>
<div className="form-group">
<Button type="submit">Add Notification</Button>
</div>
<div className="form-group">
<Button type="submit">Edit Notification</Button>
</div>
<div className="form-group">
<Button type="submit">Delete Notification</Button>
</div>
</form>
</Card>
)
}
#MLDC No i don't have another divs, i want to replace the buttons with the crossponding component. For example: onclick on Add, then Add component will appears instead of the buttons.
In that case, create a boolean state for every Panel that you have (I created 3 so that you could open the panels simultaneously),
const [isAddPanelOpen, setIsAddPanelOpen] = useState(false);
const [isEditPanelOpen, setIsEditPanelOpen] = useState(false);
const [isDeletePanelOpen, setIsDeletePanelOpen] = useState(false);
Next, apply this to every button
<Button onClick={setIsAddPanelOpen(prevState=>!prevState)}>Add Notification</Button>
<Button onClick={setIsEditPanelOpen(prevState=>!prevState)}>Edit Notification</Button>
<Button onClick={setIsDeletePanelOpen(prevState=>!prevState)}>Delete Notification</Button>
Lastly, Refactor your html to
<div className="form-group">
{isAddPanelOpen ? <AddNotification/> : <Button type="submit">Add Notification</Button>}
</div>
<div className="form-group">
{isEditPanelOpen ? <EditNotification/> : <Button type="submit">Edit Notification</Button>}
</div>
<div className="form-group">
{isDeletePanelOpen ? <DeleteNotification/> :<Button type="submit">Delete Notification</Button>}
</div>
Try this if you want to display one component at a time and hide the others when you click a button
const AdminPanel = () => {
const [componentToDisplay, setComponentToDisplay] = useState("")
return (
<>
<Card className={classes.input}>
<div><h1>Notification Panel</h1></div>
<form>
<div className="form-group">
{componentToDisplay !== "add ? (
<Button type="submit" onCLick={() => setComponentTodisplay("add")}>Add Notification</Button>)
:(<AddNotification />)}
</div>
<div className="form-group">
{componentToDisplay !== "edit ? (
<Button type="submit" onCLick={() => setComponentTodisplay("edit")}>Edit Notification</Button>)
:(<EditNotification />)}
</div>
<div className="form-group">
{componentToDisplay !== "delete ? (
<Button type="submit" onCLick={() => setComponentTodisplay("delete")}>Delete Notification</Button>)
:(<DeleteNotification />)}
</div>
</form>
</Card>
</>
)
}
Or if you want to be able to replace every buttons, use this logic with one state per button
const AdminPanel = () => {
const [addNotif, setAddNotif] = useState(false)
const [editNotif, setEditNotif] = useState(false)
const [deleteNotif, setDeleteNotif] = useState(false)
return (
<>
<Card className={classes.input}>
<div><h1>Notification Panel</h1></div>
<form>
<div className={`form-group ${editNotif || deleteNotif ? "display: none" : "display: flex"}`}>
{!addNotif ? (
<Button type="submit" onCLick={() => setAddNotif(true)}>Add Notification</Button>)
:(<AddNotification setAddNotif={setAddNotif} />)}
</div>
<div className={`form-group ${addNotif || deleteNotif ? "display: none" : "display: flex"}`}>
{!editNotif ? (
<Button type="submit" onCLick={() => setEditNotif(true)}>Edit Notification</Button>)
:(<EditNotification setEditNotif={setEditNotif} />)}
</div>
<div className={`form-group ${addNotif || editNotif ? "display: none" : "display: flex"}`}>
{!deleteNotif ? (
<Button type="submit" onCLick={() => setDeleteNotif(true)}>Delete Notification</Button>)
:(<DeleteNotification setDeleteNotif={setDeleteNotif} />)}
</div>
</form>
</Card>
</>
)
}
Then in your component
const AddNotification = ({setAddNotif}) => {
...
return (
...
<button onCLick={() => setAddNotif(false)}>back</button>
...
)
}
Same logic for the other components
To achieve this logic you need to manage which component is displayed using a state.
This means:
Attribute an arbitrary id to each component.
Store the id of the active component in a useState hook.
Use conditional rendering to display the component that match the current state.
Update the state to the corresponding Id when clicking on each button.
A small example
const [activePanel, setActivePanel] = React.useState(0)
let currentPanel = <Panel0 />
switch(activePanel){
case 0:
currentPanel = <PanelO />
case 1:
currentPanel = <Panel1 />
// Continue as needed
}
return (
<div>
<CurrentPanel/>
<button onClick={() => setActivePanel (0)}> Panel 0 </button>
<button onClick={() => setActivePanel (1)}> Panel 1 </button>
// And so on
</div>
)
You can further refine this by extracting the switch statement into its own component that takes the activePanel as a prop.
I am trying to reverse a state to true or false when user is clicking the cancel button.
The full project is available on sandbox via the link below. I am new to react developing and struggling with state. Can someone help, please?
To see what i mean by the above, please enter some input and click add
https://codesandbox.io/s/eloquent-feather-gc88n?file=/src/header/header.js
Thank Leo
Update your handleCancelClick function to this:
handleCancelClick = (e) => {
setIsEditing((prevState) => !prevState)
console.log('Cancel edit', isEditing)
}
Few more amends that you might need:
In skillist.js:
<EditSkillsForm
inputs={inputs}
isEditing={isEditing}
setIsEditing={setISEditing}
onCancelClick={handleCancelClick}
onUpdateInput={handleUpdateInput}
onCurrentInput={currentInput}
/>
In editSkillsForm.js, we get isEditing and setIsEditing props also :
const EditSkillsForm = ({
handleUpdateInput,
inputs,
handleCancelClick,
setCurrentSkill,
isEditing,
setIsEditing
}) => {
Full file code (just in case):
editSkillsForm.js:
import React, { useState } from "react";
const EditSkillsForm = ({
handleUpdateInput,
inputs,
handleCancelClick,
setCurrentSkill,
isEditing,
setIsEditing
}) => {
//const [ currentSkill, setCurrentSkill ] = useState({});
// const [isEditing, setIsEditing] = useState(true);
// const [ onSubmitEditing, SetOnSubmitEditing ] = useState("")
function handleEditInputChange(e) {
setCurrentSkill(e.target.value);
}
handleCancelClick = (e) => {
setIsEditing(false);
console.log("Cancel edit", isEditing);
};
return (
<>
{isEditing ? (
<div>
<h4>Edit Skill</h4>
<input
className="mb-2"
size="lg"
onChange={handleEditInputChange}
type="text"
name="Update skill"
placeholder="Update skill"
value={inputs}
/>
<button className="btn btn-primary mx-2" onClick={handleUpdateInput}>
Update
</button>
<button onClick={() => handleCancelClick()}>Cancel</button>
</div>
) : null}
{/* <div>
<h4>Edit Skill</h4>
<input
className="mb-2"
size="lg"
onChange={handleEditInputChange}
type="text"
name="Update skill"
placeholder="Update skill"
value={inputs}
/>
</div> */}
{/* <input
className="mb-2"
size="lg"
onChange={handleEditInputChange}
type="text"
name="Update skill"
placeholder="Update skill"
value={inputs}
/> */}
{/* <button className="btn btn-primary mx-2">Update</button> */}
{/* <button onClick={() => handleCancelClick()}>Cancel</button> */}
</>
);
};
export default EditSkillsForm;
How to convert column toggle from button list to select dropdown? Is it possible to do this?
I am using react-bootstrap-table-next.
const CustomToggleList = ({ columns, onColumnToggle, toggles }) => (
<div
className="btn-group btn-group-toggle btn-group-vertical" data-toggle="buttons">
{columns
.map((column) => ({
...column,
toggle: toggles[column.dataField],
}))
.map((column) => (
<div>
<button
type="button"
key={column.dataField}
className={`btn btn-warning ${column.toggle ? "active" : ""}`}
data-toggle="button"
aria-pressed={column.toggle ? "true" : "false"}
onClick={() => onColumnToggle(column.dataField)}
>
{column.text}
</button>
</div>
))}
</div>
);
<CustomToggleList {...props.columnToggleProps} />
const CustomToggleList = ({ columns,onColumnToggle, toggles }) => (
<div className="text-center">
<div class="pull-left ">
<div class="btn-group pull-left ">
<button class=" btn-default dropdown-toggle custom-csv" data-toggle="dropdown">Columns</button>
<ul class="dropdown-menu customcolumn-scroll" >
{
columns.map(column => ({
...column,
toggle: toggles[column.dataField]
}))
.map((column, index) => (
<React.Fragment >
<label>
<input type="checkbox" key={column.dataField}
id={column.dataField}
checked={column.toggle}
aria-checked={column.toggle ? "true" : "false"}
onChange={() => onColumnToggle(column.dataField)} />
{column.text}
</label>
</React.Fragment>
))}
</ul>
</div>
</div>
</div>
);
as you see my form not submit i can't see where is the problem i search but all the solution i found i already made it so what else can be the problem when i try to use console it don't show like it doesn't enter the submit function at all
this is the pieces in my component that work with form
const [editMyText, setEditMyText] = useState({
editIsActive: false,
textValue: body,
});
const inputRef = useRef(null);
const handleSaveEdit = (e) => {
setEditMyText({
editIsActive: false,
textValue: inputRef.current.value,
});
// updatePost(_id, textValue);
};
const handleOnSubmit = (e) => {
e.preventDefault();
console.log('done 1');
updatePost(_id, textValue);
console.log('done 2');
};
{body !== null && !editIsActive ? (
<p
className='card-text'
onClick={(e) => auth.user._id === user && handleEditText(e)}
>
{textValue}
</p>
) : (
<form
className='edit-post-form'
onSubmit={(e) => handleOnSubmit(e)}
>
<textarea
className='edit-text'
defaultValue={textValue}
ref={inputRef}
/>
<button
className='btn btn-raised btn-danger mr-2'
onClick={(e) => handleCloseEdit(e)}
>
Close
</button>
<button
type='submit'
className='btn btn-raised btn-success'
onClick={(e) => handleSaveEdit(e)}
>
Save
</button>
</form>
)}
This is my first react project with hooks. I know the code is messy, but I just want to get the gist first, then organize the code later once it's complete. But I have a calculator app that I'm building and I need help with the state. I have two states, and I need help displaying the answer. The number buttons work, but I cant figure out the code for the functional buttons like addition, subtraction etc.
tried an example with
handleMultiplication(e){
setNumber(math(number * 2)
it works, but I want to be able in input another number and hit the equal sign, then display the answer.
function Calculator() {
const [number, setNumber] = useState('');
const [answer, setAnswer] = useState('')
return (
<div>
<div>
<input value={number} readOnly />
<input value={answer} readOnly />
</div>
<div>
<button onClick={() => setNumber([])} label="AC" value="clear">
AC
</button>
<button
onClick={() => handleClick()}
label="+-"
value="positivenegative"
>
+-
</button>
<button onClick={() => handlePercentage()} value="percentage">
%
</button>
<button onClick={() => handleDivision()} value="division">
/
</button>
</div>
<div>
<button onClick={() => setNumber(number + 7)} value="7">
7
</button>
<button onClick={() => setNumber(number + 8)} value="8">
8
</button>
<button onClick={() => setNumber(number + 9)}value="9">
9
</button>
<button onClick={() => handleMultiplication()} value="multiplication">
*
</button>
</div>
<div>
<button onClick={() => setNumber(number + 6)} value="6">
6
</button>
<button onClick={() => setNumber(number + 5)} value="5">
5
</button>
<button onClick={() => setNumber(number + 4)} value="4">
4
</button>
<button onClick={() => handleSubtraction()} value="subtraction">
-
</button>
</div>
<div>
<button onClick={() => setNumber(number + 3)} value="3">
3
</button>
<button onClick={() => setNumber(number + 2)} value="2">
2
</button>
<button onClick={() => setNumber(number + 1)} value="1">
1
</button>
<button onClick={() => handleAddition()} value="addition">
+
</button>
</div>
<div>
<button onClick={() => setNumber(number + 0)} label="0" value="0">
0
</button>
<button onClick={() => handleClick()} label="." value="decimal">
.
</button>
<button onClick={() => handleClick()} label="=" value="equal">
=
</button>
</div>
</div>
);
}
Well, I assembled a rough version of the calculator with only the addition operation, it's up to you to study it and implement the other operations, is it ok?
My working addition-only calculator is available on CodeSandbox, I started from your code and removed some buttons.
NOTE: this is just one (and not 100% the best way) to implement a calculator but it's out of my scope to give you a full tutorial about it.
That's my code
import React from "react";
function Calculator() {
// the list will be an array of numbers and operators, ex. [10, "+", 5]
const [list, setList] = React.useState([]);
// when append is set to true, a new element is pushed to the list,
// when it's set to false it means that it must change the last number
const [append, setAppend] = React.useState(true);
// the result at the last "=" button click
const [result, setResult] = React.useState();
// for the "AC" click
const reset = () => {
setList([]);
setAppend(true);
};
// every number and operator click must invoke this callback
const appendItem = item => {
// the original list isn't mutated
let newList = [...list];
// if the user clicked a number button...
if (typeof item === "number") {
let number = item;
if (append) {
// the number is appended to the list
newList.push(item);
setAppend(false);
} else {
// the last aded number must be updated
number = newList[newList.length - 1];
number = number * 10 + item;
newList[newList.length - 1] = number;
}
setList(newList);
} else {
// the operator must be appended...
setList([...list, item]);
// ... and the next number too
setAppend(true);
}
};
const calculateResult = () => {
const result = list.reduce((acc, item, i, array) => {
if (typeof item === "number") {
if (i === 0) {
return item;
} else {
const operator = array[i - 1];
switch (operator) {
case "+":
return acc + item;
default:
return acc;
}
}
}
return acc;
}, 0);
setResult(result);
};
return (
<div>
<div>
<input value={list.join("")} readOnly />
<input value={result} readOnly />
</div>
<div>
<button onClick={reset} label="AC" value="clear">
AC
</button>
</div>
<div>
<button onClick={() => appendItem(7)} value="7">
7
</button>
<button onClick={() => appendItem(8)} value="8">
8
</button>
<button onClick={() => appendItem(9)} value="9">
9
</button>
</div>
<div>
<button onClick={() => appendItem(6)} value="6">
6
</button>
<button onClick={() => appendItem(5)} value="5">
5
</button>
<button onClick={() => appendItem(4)} value="4">
4
</button>
</div>
<div>
<button onClick={() => appendItem(3)} value="3">
3
</button>
<button onClick={() => appendItem(2)} value="2">
2
</button>
<button onClick={() => appendItem(1)} value="1">
1
</button>
<button onClick={() => appendItem("+")} value="addition">
+
</button>
</div>
<div>
<button onClick={() => appendItem(0)} label="0" value="0">
0
</button>
<button onClick={() => calculateResult()} label="=" value="equal">
=
</button>
</div>
</div>
);
}
export default Calculator;
I commented on it and, as you can see, the biggest improvement is about state management, I use three states:
one for the number/operations list
one to know when or not I should append the item to the list (a "+" or a number following a "+") or when I should update the last number added (when you press 1 twice, the previous 1 should become 11)
one for the result
Most of the complexity comes from managing the list of number/operations, anyway: let me know if the comments aren't sufficient to understand how it works 😊