Search code examples
javaformsdomweb-scrapingjsoup

Change a FormElement’s information by changing directly its formData keyVals’s list jsoup


I’m trying to fill out a form using Jsoup library’s class FormElement. My problem is that it doesn’t change the values in the KeyVals it submits. I have found on Jsoup documentation that they have done this on purpose:

public List<Connection.KeyVal> formData()
Get the data that this form submits. The returned list is a copy of the data, and changes to the contents of the list will not be reflected in the DOM.
Returns:
a list of key vals

Can anyone tell me how I can change the KeyVals within a list of key vals retrieved from the method formData available for FormElement. By now this is what I’m doing and getting, so that you may understand me better:

FormElement form = (FormElement) document.select(form#formulaire).first();
System.out.println(form.formData().get(4).value()); //printing the value of  KeyVal #4 
form.formData().get(4).value("value changed");//changing its value
System.out.println(form.formData().get(4).value());//printing again its value which must be different
Result: 
Old value
Old value

Please, notice that I know that I can do this myself by changing the value on every element inside the DOM. However, I don’t think this way is neither the cleanest nor the fastest. So is there any way to do this by changing the values directly in the form data?


Solution

  • Each call to the method formData() creates a new list of results by walking the DOM and pulling the values out. So, just don't keep re-evaluating that method. Instead, take a reference and set the values from that. E.g.:

    FormElement form = (FormElement) document.select(form#formulaire).first();
    List<Connection.KeyVal> formData = form.formData();
    System.out.println(formData.get(4).value()); //printing the value of  KeyVal #4 
    form.formData().get(4).value("value changed");//changing its value
    System.out.println(form.formData().get(4).value());//printing again its value which must be different
    
    Result: 
    Old value
    value changed
    

    You can then pass the same form data into a new post/get request.

    I actually did expect people just to update the DOM. It's pretty efficient and there's no real different in efficiency in changing the value of something in a formdata object vs changing its value in the DOM, they're all backed by the same kind of hashes / arrays. And there's no HTML parsing or anything.