How To Autofill Custom Forms?



  • I have a webapp I frequently use, which have such kind of forms:

    
      
      
      
      
    
    

    What I want to do is to be able to autofill those fields with specified values (e.g.: urname=kristian, secretid=abcdefghijkl, otherfield=000111222333444555666777888999).

    Currently I do it by opening "note" app then copy-pasting its content each time, which can get tedious since it's quite long and I have to go back and forth 3 times. Also, the content of the autofill input is not exactly a secret.

    Is there a way to do it?

    I found a question with similar problem on Super User: https://superuser.com/questions/1242775/autofill-web-forms (but instead of Chrome on PC I want to do it in Chrome in Android). The comments seems to recommend a Cchrome extension that can inject JavaScript into the page. I don't mind that, I can write JS, but I don't think Chrome extensions are available on Android.

    EDIT: I found here that I can execute bookmarked JS via chrome without extensions here: https://android.stackexchange.com/questions/159308/how-can-a-bookmarklet-be-added-on-mobile-chrome-without-copying-and-pasting/210701

    So I made a bookmark with such content:

    javascript:(function(){ document.querySelector(`#urname`).value=`kristian`; document.querySelector(`#secretid`).value=`abcdefghijkl` ; document.querySelector(`#otherfield`).value=`000111222333444555666777888999` ; })()
    

    Which if it gets prettified/formatted it will looks like:

    javascript:(function(){
      document.querySelector(`#urname`).value=`kristian`;
      document.querySelector(`#secretid`).value=`abcdefghijkl` ;
      document.querySelector(`#otherfield`).value=`000111222333444555666777888999` ; 
    })()
    

    But I still have problem: the page seems to use some kind of data binding (e.g.: react two-way binding). So when the value got changed via JS, when I click on the element it goes back to its old (empty) value. Now, how should I circumvent it?



  • After some research and digging github issues, here is my own solution:

    In general I have to do:

    1. inject custom/self-written JS to chrome android
    2. figure out why it didn't work and the element value changes back to its old / empty value
    3. call correct function so 'react' framework can change the input element AND its internal / 2-way binded data

    First step: inject custom/self-written JS to chrome android

    From this question: https://android.stackexchange.com/questions/159308/how-can-a-bookmarklet-be-added-on-mobile-chrome-without-copying-and-pasting/210701 I learned that I can add custom JavaScript to bookmark in chrome

    First step cleared

    Second step: figure out why it didn't work and the element value changes back to its old / empty value

    First look, wonder why the value was not changed even after injecting code like:

    document.querySelector(`#otherfield`).value=`000111222333444555666777888999` ; 
    

    So I suspected if it used some kind of JavaScript framework to do 2-way data binding (bind a variable value with an input element).

    To detect which framework they used, I installed this extension: Library Detector https://chrome.google.com/webstore/detail/library-detector/cgaocdmhkmfnkdkbnckgmpopcbpaaejo (disclaimer: I'm not associated with the author of said extension)

    The result: they used react.js

    So, the reason why it didn't work and the element value changes back to its old / empty value is because it used react 2-way data binding

    Second step cleared

    Third step: call correct function so 'react' framework can change the input element AND its internal / 2-way binded data

    After some googling, I find this github issue: https://github.com/facebook/react/issues/11488 which links to this issue comment: https://github.com/facebook/react/issues/10135#issuecomment-314441175

    Basically the solution is to call such function:

    function setNativeValue(element, value) {
      const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
      const prototype = Object.getPrototypeOf(element);
      const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
      if (valueSetter && valueSetter !== prototypeValueSetter) {
        prototypeValueSetter.call(element, value);
      } else {
        valueSetter.call(element, value);
      }
    }
    

    setNativeValue(textarea, 'some text');
    textarea.dispatchEvent(new Event('input', { bubbles: true }));

    After changing my JS to

    function setNativeValue(element, value) {
      const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
      const prototype = Object.getPrototypeOf(element);
      const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
    

    if (valueSetter && valueSetter !== prototypeValueSetter) {
    prototypeValueSetter.call(element, value);
    } else {
    valueSetter.call(element, value);
    }
    }

    var element1 = document.querySelector(#urname);
    setNativeValue(element1, kristian);
    element1.dispatchEvent(new Event('input', { bubbles: true }));

    var element2 = document.querySelector(#secretid);
    setNativeValue(element2, abcdefghijkl);
    element2.dispatchEvent(new Event('input', { bubbles: true }));

    var element3 = document.querySelector(#otherfield);
    setNativeValue(element3, 000111222333444555666777888999);
    element3.dispatchEvent(new Event('input', { bubbles: true }));

    And then enclosing them in

    javascript:(function(){  ...  })()
    

    Now it works perfectly




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2