0

Edit: This issue appears to be isolated to Firefox - in Chrome/IE it works exactly as expected. Is this a Firefox bug, or just something I'm not understanding?

I have a spring form. The form contains, among other things, a <select> element- which is bound to a corresponding element in the ModelMap using a 'path' property in the JSP.

However, the <select> element's apparent value does not update on soft page refresh, even if the value in the model-map changes. Other references to the model value do update (e.g. if I just add ${MyModelMapValue } - then the value will update on soft refresh - so no caching or anything is taking place).

After hard refresh (CTRL+F5) the select updates. How can I update the select on soft refresh?

Use Case:

  • I browse to the page for the first time, I see the correct values bound correctly to the form fields - including my <select> element - which is bound to an element in the model map, say: MyModelMapValue = 'ordered'

  • In the background (say, someone elses's browser) while I have the page open in my browser, the value of MyModelMapValue changes, and persists that change to the DB. MyModelMapValue = 'shipped'

  • Initially the values don't change in my tab - which I would expect, as the values are not continuously updated from the DB.

  • Now I hit F5 in my browser.

  • I can see a normal GET call is generated, and hits my controller, the new model is correctly generated (With MyModelMapValue = 'shipped') and is served alongside the view to the browser.

  • All other references to the model value (e.g. ${MyModelMapValue} will show as 'shipped'

  • the <select> element is still bound to MyModelMapValue, but shows 'ordered' as it's value.

Question:

Is this the way Spring Forms binding is supposed to work, or am I doing something wrong?

Code:

Spring Form JSP definition:
<form:form commandName="productHolder" id="productForm" method="post">

        <form:input path="product.blah" placeholder="blah" class="blah-blah" />

        <br>

        ... a bunch of other fields ... 

        <br> 

        Supplier Status: 
        <form:select path="product.supplierStatusObjectFromListOfStatusObjects.currentSatus">
                <form:options items="${allProductSupplierStatuses}"/>
        </form:select>

        <br>

        Printing the value as a test: ${product.getSupplierStatusFromListOfStatusObjects.currentSatus}

        <br>

        <button class="btn btn-success" type="submit">Save</button>

</form:form>
Stripped back Java Controller:
@RequestMapping(method=RequestMethod.GET)
public String showProductStatusScreen(ModelMap model, @RequestParam(value = "productId", required=false) Long productId){
    this.checkAccess(this.getCaller());
    Product product = productBusinessObject.getProductById(productId);      
    ProductHolder productHolder = this.generateProductHolder(product); 
    model.put("productHolder", productHolder); 
    //printing it out as a test: 
    System.out.println(productHolder.GetProduct.getSupplierStatusObjectFromListOfStatusObjects.getCurrentSatus);// <- Prints out the correct value
    return "/WEB-INF/jsp/productStatusScreen.jsp"; 
}
Paul
  • 3,318
  • 8
  • 36
  • 60

1 Answers1

0

Answer in case anyone googles the same things I did in future...

It was indeed a browser issue - and nothing at all to do with Spring Forms specifically. I was just too many steps of abstraction away to realize at first.

It was already working by default in chorome(v71)/IE(11), only firefox(v64.0) was behaving strangely.

Firefox deliberately does not refresh the selected="selected" property on the currently selected option element. It seems this is to allow for auto-completion of fields. It is a feature, not a bug.

The quick fix was to simply add autocomplete="off"property to the select element - which disables this behaviour in the current version of firefox e.g.:

<select id="myBindingPath" name="myBindingPath" autocomplete="off"> 
    <option value = "fizz">fizz</option>
    <option value = "buzz">buzz</option>
    <option value = "bang" selected="selected">bang</option>
</selected>

But who knows how future versions of firefox will handle autocomplete="off" - so it's not the most robust solution in the world. I could also write Javascript to update the element on page load - which would probably be a more robust solution.

Links: 1, 2

Paul
  • 3,318
  • 8
  • 36
  • 60