Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set React Input Field Value from JavaScript or JQuery

How can you programmatically set the value of an input field generated by React, either with vanilla JS or JQuery?

I've tried the following and nothing seems to work.

$(obj).val('abc');
$(obj).attr('value', 'abc');
$(obj).keydown();
$(obj).keypress();
$(obj).keyup();
$(obj).blur();
$(obj).change();
$(obj).focus();

I've also tried to simulate keyPress (as suggested here) events but it doesn't seem to work either.

simulateKeyPresses (characters, ...args) {
  for (let i = 0; i < characters.length; i++) {
    this.simulate('keyPress', extend({
      which: characters.charCodeAt(i),
      key: characters[i],
      keyCode: characters.charCodeAt(i)
    }, args));
  }
}
like image 725
Ovi Avatar asked Apr 16 '17 14:04

Ovi


People also ask

Is react js better than jQuery?

While jQuery is a fine choice for simple web building, using animations and effects, React helps you perform more sophisticated functions and principally highlights UI development, DOM manipulation and the likes.

Is React dependent on jQuery?

jQuery isn't React and React isn't jQuery: We utilize jQuery to directly alter the Document Object Model (DOM) (i.e. add/hide UI components) and to conduct simple AJAX requests. It also calls browser APIs in a cross-browser consistent manner.

Can you use both React and jQuery?

Our jQuery app initially creates the React component using a call to React. createElement and passing in the context of the jQuery app to the components constructor. The component can then store the reference (available via the props argument) in its state and use it to update key elements on the web page.


3 Answers

Out of all the answers and after a lot of googling, I found this to be working

function changeValue(input,value){

    var nativeInputValueSetter = Object.getOwnPropertyDescriptor(
      window.HTMLInputElement.prototype,
      "value"
    ).set;
    nativeInputValueSetter.call(input, value);

    var inputEvent = new Event("input", { bubbles: true });
    input.dispatchEvent(inputEvent);
}

We are using window.HTMLInputElement.prototype that is HTMLInputElement. An interface that provides special properties and methods for manipulating the options, layout, and presentation of input elements.

Then we will use Object.getOwnPropertyDescriptor() method to set input value. Last we will dispatch change event on the input to simulate with React onChange

Here is a detailed explanation of this answer: https://hustle.bizongo.in/simulate-react-on-change-on-controlled-components-baa336920e04

like image 58
Anand Singh Avatar answered Oct 20 '22 06:10

Anand Singh


As showcased in the react test utils docs in the simulate section, you can see what they're basically doing is changing the DOM node value and then triggering an input event.

What you could do is something like the following, calling it with your input DOM element and new value.

const changeValue = (element, value) => {
  const event = new Event('input', { bubbles: true })
  element.value = value
  element.dispatchEvent(event)
}

Depends on how you defined your components though, if for example you're expecting an enter keypress, you'll have to dispatch the matching event.

like image 44
Preview Avatar answered Oct 20 '22 07:10

Preview


This is a well tested solution that works for IE11 as well as other browsers. It is the createNewEvent that differentiate this solution form the others in here I guess. The setReactValue method also returns the changed value.

function setReactValue(element, value) {
  let lastValue = element.value;
  element.value = value;
  let event = createNewEvent("input", element);
  event.simulated = true;
  let tracker = element._valueTracker;
  if (tracker) {
    tracker.setValue(lastValue);
    element.dispatchEvent(event);
  }
  return lastValue;
}

function createNewEvent(eventName, element) {
    let event;
    if (typeof(Event) === 'function') {
        event = new Event(eventName, {target: element, bubbles:true});
    } else {
        event = document.createEvent('Event');
        event.initEvent(eventName, true, true);
        element.addEventListener(eventName, function(e) {
          e.target = element;
        });
    }
    return event;
}
like image 28
javabeangrinder Avatar answered Oct 20 '22 07:10

javabeangrinder