30

I am a beginner with react.js and it's amazing but I am facing a real problem: I need to set the value of an input using plain and pure javascript but for some reason react.js is not working as expected. Take this example: open this URL http://autoescolalatorreta.wix.com/latorreta#!contact/c24vq

You will see there is an "Email" input field which id is "CntctFrm2emailField". I try to change the value of it using javascript with this code:

document.getElementById("CntctFrm2emailField").value = "testing@gmail.com";

But for some reason, React.js is not updating this value on its core cause if you try to send the form (Clicking the SEND button) you will see that it will display an error message saying that the email is not filled right. BUT once I click inside the email field and type any letter and click the SEND button it works fine, I mean, React.js sees the new value.

So how can I change an input value and have React.js to update that value too?

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
Sitepor500.com.br
  • 388
  • 1
  • 5
  • 11
  • 1
    If you can't post the code as you mention in the other comments, I'm afraid your question is unsuitable for this website and I suggest you remove it. – Hannes Johansson Jul 16 '15 at 09:59

7 Answers7

39

For React 16, use following code. Check this issue.

function setNativeValue(element, value) {
    let lastValue = element.value;
    element.value = value;
    let event = new Event("input", { target: element, bubbles: true });
    // React 15
    event.simulated = true;
    // React 16
    let tracker = element._valueTracker;
    if (tracker) {
        tracker.setValue(lastValue);
    }
    element.dispatchEvent(event);
}

var input = document.getElementById("ID OF ELEMENT");
setNativeValue(input, "VALUE YOU WANT TO SET");
Ajay Bhosale
  • 1,872
  • 24
  • 35
16

I have written and use this function to trigger the change state for the field:

function doEvent( obj, event ) {
    /* Created by David@Refoua.me */
    var event = new Event( event, {target: obj, bubbles: true} );
    return obj ? obj.dispatchEvent(event) : false;
}

Use it like this:

var el = document.getElementById("CntctFrm2emailField");
el.value = "testing@gmail.com";
doEvent( el, 'input' );
David Refoua
  • 3,476
  • 3
  • 31
  • 55
10

You should post your code in order to get a better/ more to your situation suited answer, but one think that will work is just setting the

defaultValue

instead of value of the input. Take a look at your browsers console, that's what react will log there.

Depending on your code, you can set the states value onKeyUp or similar with a function or fetch the new inputs value when the form is submitted.

baao
  • 71,625
  • 17
  • 143
  • 203
  • 1
    Thank @michael . Sorry for not posting the code but I was not who did that website, I am just adding some features and the code is a mess. But look, I tried your suggestion and it does not work -> document.getElementById("CntctFrm2emailField").defaultValue = "testing@gmail.com"; . I think I need for some reason fire the onchange event of that input cause I think react.js is listening to the onchange event to update the internal value. I already tried triggering the onchange() event with js but it does not work too. Maybe there is some way to trigger that change event with react? – Sitepor500.com.br Jun 06 '15 at 14:12
  • 1
    Thank you! Did not realize that this prop existed. – Con Antonakos Dec 30 '15 at 23:16
  • 1
    @ArtemAliev Why don’t you just ask another question that addresses your specific problem, instead of down voting and complaining without any kind of explanation? As you can see, this answer worked for hundreds of people, so you should consider that it’s you who can’t make it work, not the answer... – baao Mar 24 '18 at 19:09
3

I had a form that I needed to submit for some monitoring. I did it like this:

$("input[type=email]").value = "me@something.com"
$("input[type=email]").defaultValue = "me@something.com"
$("input[type=password]").value = "mystellarpassword"
$("input[type=password]").defaultValue = "pinpmystellarpasswordss"
$("input[type=email]").dispatchEvent(new Event('input', {target: $("input[type=email]"), bubbles: true} ));
$("input[type=password]").dispatchEvent(new Event('input', {target: $("input[type=password]"), bubbles: true} ));
$("button.login").click()

Note that for the website I was logging into, I had to set both value and defaultValue. There was some extra validation logic bound to the input.value

Kenny Cason
  • 12,109
  • 11
  • 47
  • 72
0

This is the key in your question,

But for some reason React.js is not updating this value on its core

The main reason is that react works within a 'shadow dom', and your

document.getElementById("CntctFrm2emailField").value = "testing@gmail.com";

Inst updating the reacts value in any way just the window dom object.

React has built in functions to update the value of the input. Try that way.

Check this page for more info about react forms: https://facebook.github.io/react/docs/forms.html#controlled-components

John Weisz
  • 30,137
  • 13
  • 89
  • 132
jmingov
  • 13,553
  • 2
  • 34
  • 37
  • 2
    Thank you for explaning me that, indeed there is a "virtual dom" with react, and it is what makes it so fast. But I think that what I need is to fire the change event in that input. I already tried firint that with plain javascript .onchange() but it does not work. I think I need to fire it with react.js . Could you please help me with this? I cant believe it's so hard to update an input value using react.js – Sitepor500.com.br Jun 06 '15 at 14:14
  • If you want help i need to see the code... but , looking at the site, the whole form is a react component called `ContactForm` and the inputs events are handled by react too (`onclick && onchange`). Are you using js or jsx? – jmingov Jun 06 '15 at 14:27
  • I would love to show you the code but I have no idea how this form was programmed cause I heard of react.js for the first time today. I dont even see a
    tag around the Email input. In your browser do you see a form? I trigered the onclick and onchange right now and unfortunatelly it's not working too...any other idea? I just want to set the value of the email input, just that! I want to set the value and I want the react.js to recognize this value.
    – Sitepor500.com.br Jun 06 '15 at 15:47
  • jmingov I studied the link you provided but had no luck. I am about this entire day studying this but I still cant fire the change event in a way that the react.js updates the value. – Sitepor500.com.br Jun 06 '15 at 21:21
  • 2
    This answer only covers what OP, and I, already knew. It does not solve the problem of accessing the "virtual dom" value and changing it. – Tomáš Zato Mar 15 '17 at 12:08
0

First of all, you should never ever work with "document" object in React.js. It is a big no no. You should not access DOM element neither, but if you know what you are doing(like animations) you should create "ref" object, which is off the topic, to access DOM element.

First thing you should have an object inside the state object for your form. Lets say you have "username" and "password" fields in your form.

state={form:{username:"","password:""}

Because input fields have their own state, whatever we type in there will be stored in the input field. We should get rid of the state of input field and only rely on the state object. We want to have single source of truth so convert "input" to “controlled element”. Controlled elements do not have their own state, they get all data, via props and they notify changes to the data by raising events. We are using "value" prop to set inputs value. Since input fields are initialized as empty strings, we will not be able to type something inside input field. Solution is we have to handle the change event for input fields dynamically.

handleChange=e=>{
    const form={...this.state.form}
    form[e.currentTarget.name]=e.currentTarget.value
    this.setState({account})}

<input value={this.state.form.username} change={this.handleChange} name="username"/>
<input value={this.state.form.password} change={this.handleChange} name="password" />
Yilmaz
  • 35,338
  • 10
  • 157
  • 202
0
<Button onClick={ async () => {
            await setShowModal(true);
            document.getElementById('name').value = e.location_name;
            document.getElementById('province_id').value = e.province_id;
            document.getElementById('id').value = e.id;
        }} 
    className="btn-round" color="success" type="Button">
        Edit
</Button>