I was trying to set custom display for input type=file , but htmlFor with selecting id is not working .
By default input type=file displays as
Choose file(as button) - no file selected
I am trying to change those names "Choose files" and "no file selected" to my custom display , how can i achieve this ? I trying htmlFor with selecting id of the input field , but did not work out . I tried using label attribute but the text is being places on top of "Choose file" button.
Here's my tryout so far :
<label className="form-label" htmlFor='input-file'> select.....</label>
<input
className="form-control form-control-lg form-control-solid"
type="file"
id="input-file"
name="thumbnailImg"
value={undefined}
onChange={(e) => file_choosen(e)}
/>
The output is like :
select...
[Choose File] [no file selected]
I am trying to display something like :
[select...] [***custom no file selected here***]
If you do not wish to use the default input element then you need to:
Hide the input element
Use a button that you can style to your wishes
On click then trigger the input file click
import { useRef, useState } from "react";
export default function App() {
const ref = useRef();
const [file, setFile] = useState(null);
function file_chosen() {
setFile(ref.current.files[0]);
}
return (
<div>
<div style={{ display: "flex", flexDirection: "row", gap: 4 }}>
<button onClick={() => ref.current.click()}>Select file</button>
<p>{file === null ? "No file chosen" : "1 file selected"}</p>
</div>
<input
onChange={file_chosen}
ref={ref}
type="file"
style={{ display: "none" }}
/>
</div>
);
}
codesandbox example
Related
How can I remove the focus of either input box when I press the "enter" key?
I have this code:
import React, { useState } from "react";
import "antd/dist/antd.css";
import { Form, Input, Button, Card } from "antd";
function Login() {
const [loadings, setloadings] = useState(false);
const [disabledLoading, setDisabledLoading] = useState(false);
function changeloading() {
setloadings(true);
setDisabledLoading(true);
setTimeout(() => {
setloadings(false);
}, 1630);
}
function passwordEnterPress(e) {
e.target.blur();
}
return (
<div>
<Card className="home-card">
<Form>
<Form.Item name="Username">
<Input name="username" onPressEnter={passwordEnterPress} />
</Form.Item>
<Form.Item name="Password">
<Input.Password name="password" onPressEnter={passwordEnterPress} />
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
onClick={() => changeloading()}
>
Log in
</Button>
</Form.Item>
</Form>
</Card>
</div>
);
}
export default Login;
Codesandbox
EDIT per the documentation link, there's a blur function that I could call to remove the focus, but I don't know how to trigger the function on submit and target the input fields.
If I select either input, it will be focused; however, when I pressed "enter" to submit the form, the focus won't go away. I want the focus to disappear whenever I press the "enter" key that submits the form.
It's worth mentioning that I don't want to forcibly overwrite the focus border. I only want the border to disappear whenever I click the login button (which is already working) or press the "enter" key (entire point of this question).
Thanks in advance.
inorder to lose focuse from input when enter key is pressed , you should handle
key up event of input ,as shown below
function handleKeyUp(event) {
//key code for enter
if (event.keyCode === 13) {
event.preventDefault();
event.target.blur();
}
}
now assign this function to on key up event of input box like this
<Input name="username" onKeyUp={handleKeyUp} />
now to clear focus of input on form submit ,
you can create refernce to both input as shown below
let userNameRef = React.createRef();
let passwordRef = React.createRef();
assign this to input as below
<Input ref={userNameRef} name="username" onKeyUp={handleKeyUp} />
<Input.Password ref={passwordRef} name="password" />
use these reference to clear focus whenever you want as
userNameRef.current.blur();
passwordRef.current.blur();
EDITED
What difference does createref on the two fields have compared to using handlekeyup?
both works the same,
when an event triggered ,event.target is your target element,
while React provide way to access dom element with createRef,
there is no big difference with event.target and ref.current
but its is good to use reference as using reference you can access
element any where, no matter an event is occured or not
In order to call the blur function you would need to get instance of the input tag which you can do by using ref or simply you can call the onPressEnter attribute given by and
<Input.Password name="password" onPressEnter={passwordEnterPress} />
then you can write the required functionality like bluring out
function passwordEnterPress(e) {
e.target.blur()
}
sorry for my poor editing skills below is the code which you can run in your code sandbox. Please note you have to the mouse out of the input box
import React, { useState } from "react";
import "antd/dist/antd.css";
import { Form, Input, Button, Card } from "antd";
function Login() {
const [loadings, setloadings] = useState(false);
const [disabledLoading, setDisabledLoading] = useState(false);
function changeloading() {
setloadings(true);
setDisabledLoading(true);
setTimeout(() => {
setloadings(false);
}, 1630);
}
function passwordEnterPress(e) {
e.target.blur()
}
return (
<div>
<Card className="home-card">
<Form>
<Form.Item name="Username">
<Input name="username" />
</Form.Item>
<Form.Item name="Password">
<Input.Password name="password" onPressEnter={passwordEnterPress} />
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
onClick={() => changeloading()}
>
Log in
</Button>
</Form.Item>
</Form>
</Card>
</div>
);
}
export default Login;
add this in your forms onSubmit
<Form
onSubmitCapture={() => {
if ("activeElement" in document) document.activeElement.blur();
}}
>
...
</Form>
updated answer with form submit. Check the logs in console.
import React, { useState, useRef } from "react";
import "antd/dist/antd.css";
import { Form, Input, Button, Card } from "antd";
function Login() {
const [loadings, setloadings] = useState(false);
const [disabledLoading, setDisabledLoading] = useState(false);
const formRef = useRef()
function changeloading() {
setloadings(true);
setDisabledLoading(true);
setTimeout(() => {
setloadings(false);
}, 1630);
}
function onFinish(values) {
console.log(values)
}
function passwordEnterPress(e) {
e.target.blur()
formRef.current.submit()
}
return (
<div>
<Card className="home-card">
<Form ref={formRef} onFinish={onFinish}>
<Form.Item name="Username">
<Input name="username" />
</Form.Item>
<Form.Item name="Password">
<Input.Password name="password" onPressEnter={passwordEnterPress} />
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
onClick={() => changeloading()}
>
Log in
</Button>
</Form.Item>
</Form>
</Card>
</div>
);
}
export default Login;
I have a code for uploading excel file by clicking a button. So when I select a file by clicking button and again reselect same file by clicking, the onChange() event is not recognizing it.
My reference value :
this.inputFile = React.createRef(null)
My Upload Button :
<input
style={{ display: "none" }}
ref={this.inputFile}
onChange={this.onFileChange}
type="file"
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,
application/vnd.ms-excel"
/>
<div className="btn btn-success btn-sm" onClick={this.onButtonClick} >
Upload File
</div>
My two onChange and onClick methods :
onFileChange =(e)=> {
this.setState({
selectedFile:e.target.files[0],
})
};
onButtonClick = () => {
this.inputFile.current.click();
};
If you select the same file, onchange event won't re-trigger. But if you insist on doing it, you need to remove the current value of the input on each click:
<input
style={{ display: "none" }}
ref={this.inputFile}
onChange={this.onFileChange}
type="file"
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,
application/vnd.ms-excel"
onClick={this.clearFileInput} // ADD HERE
/>
<div className="btn btn-success btn-sm" onClick={this.onButtonClick} >
Upload File
</div>
clearFileInput = () => {
this.inputFile.current.value = null;
}
I have a checkbox filters. The problem is that I need to display all checked checkbox label (e.g. if clicked Vimeo there should be a <h1> with Vimeo filter applied).
const checkboxTarget = ['Dailymotion', 'Vimeo', 'VK']
{checkboxTarget.map((text, index) => (
<div>
<input type="checkbox" id="flexCheckIndeterminate" />
<label style={{ marginLeft: '5px' }} class="form-check-label" for="flexCheckIndeterminate">
{text}
</label>
</div>
))}
In a functional component,
const[selectedCheckbox, setSelectedCheckbox] = useState("");
And then, add an OnClick Listener to the checkbox. Don't forget to check if the checkbox is checked. I would write a function to update SelectedCheckbox if multiple selection is a possibility.
<input type="checkbox" value={text} id="flexCheckIndeterminate" onClick={(e) => {if(e.target.checked){setSelectedCheckbox(e.target.value)} }} />
I want to have a radio button where I can navigate and select the value using the arrow on the keyboard.
I have no problem making one:
const BareRadio = ({
id,
name,
value,
defaultChecked,
onChange,
children,
tabIndex
}) => (
<div
>
<input
type='radio'
defaultChecked={defaultChecked}
value={value}
id={id}
name={name}
onChange={onChange}
tabIndex={tabIndex}
/>
<label htmlFor={id}>
<span >
<span ></span>
</span>
<span>{children}</span>
</label>
</div>
);
But now I have a custom radio button, which the structure hide the input tag and use css to mimic the label. Can I still use tabindex to achieve the same thing? or I need to use javascript?
demo https://stackblitz.com/edit/react-ts-7lgfpk?file=index.tsx
I have component that renders jsx like this
<section>
<div>
<input type="text" class="hide" />
<button id={item.uniqueID}>show input</button>
</div>
<div>
<input type="text" class="hide" />
<button id={item.uniqueID}>show input</button>
</div>
<div>
<input type="text" class="hide" />
<button id={item.uniqueID}>show input</button>
</div>
</section>
I want this behavior, when I click the button in the first div, the input in the first div will show. Similarly, I click the button in the third div the input in third div will show.
How you do that in react?
If it were me I would make a new component out of:
show input
Lets call it <InputToggler/>
and then it would have a state of inputHidden for its own input and use classes to determine if it should show or not and the button would have an onclick handler to toggle the state of hidden or shown. Here is a pen showing exactly that
http://codepen.io/finalfreq/pen/VKPXoN
class InputToggler extends React.Component {
constructor() {
super();
this.state = {
inputHidden: true
}
}
toggleInput = () => {
this.setState({
inputHidden: !this.state.inputHidden
})
};
render() {
const inputClass = this.state.inputHidden ? 'hide' : '';
const buttonLabel = this.state.inputHidden ? 'show input' : 'hide input'
return (
<span>
<input type="text" className={inputClass} />
<button onClick={this.toggleInput} id={this.props.item.uniqueID}>
{buttonLabel}
</button>
</span>
)
}
}
This is the concept not the exact code.
Each button should have onClick with callback to a function ex. toggleShow
<button id={item.uniqueID} onClick={this.toggleShow.bind(this)}>show input</button>
toggleShow do something like:
toggleShow(e){
var item = e.target.id;
this.setState({inputClassName1: "hide"})
at the same time the input field classname should refer to the state
Note that I omitted the fact that you have multiple objects, you may want to handle their references in arrays.