Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thymeleaf page refresh followup - Now with AJAX

As a followup to my earlier question about using Thymeleaf and preventing page refresh:

http://forum.thymeleaf.org/Preventing-page-refresh-Thymeleaf-amp-Spring-MVC-td4029155.html

Basically I had a working Spring MVC app that uses Thymeleaf to save form data. When the user saves the data the page would refresh (since I wanted to leave them on the page for more edits) and I wanted to eliminate the page refresh.

I have coded up some Javascript to use JQuery Ajax to post the data to my Spring MVC Controller. The trick seemed to be to not use a submit button, just a regular button and bind a JS function to it for sending the data to the server.

It all seems to work perfectly, but I want to make sure I understand what is happening. In particular I'm wondering if Thymeleaf is now redundant. I don't think it is because when I initially load the page Thymeleaf is still bound to the data bean. From using the debugger on the server side in the controller it looks like the post request calls the mapped method and passes in the data to the model.

I would appreciate your comments on whether or not this is the correct way to accomplish this.

Finally, how do I handle an error, say for example the repository fails to persist the data for any reason?

Thanks very much.

Here are the important parts of the form:

<FORM id="adminDataForm" action="#" th:action="@{/admin_ajax}" th:object="${adminFormAjax}" method="post">


<input type="button" value="Save Changes" id="post" onClick="sendData()" />

Here is the Javascript:

function sendData()
{
        $.ajax(
        {
            type: "POST",
            data: $("#adminDataForm").serialize(),
            cache: false,
            url: "/admin_ajax",
            success: function(data) 
            {
                alert("Your changes have been saved");
            },
            error: function()
            {
                alert("Error - Data not saved");
            }

        });
}

Here is the controller:

@SessionAttributes("adminFormAjax")
@Controller
public class TestController 
{
    final static protected long INDEX_RA = 2L;

    @Autowired
    private AdminDataRepository rep;

    @RequestMapping(value="/admin_ajax", method=RequestMethod.GET)
    public String adminFormAjax(Model model) 
    {
        AdminData ad = rep.findById(INDEX_RA);

        // If there is no configuration record, create one and assign the primary key
        if(ad == null)
        {
            ad = new AdminData();
            ad.setId(INDEX_RA);
        }

        model.addAttribute("adminFormAjax", ad);
        return "adminFormAjax";
    }

    @RequestMapping(value="/admin_ajax", method=RequestMethod.POST)
    public @ResponseBody AdminData adminSubmit(@ModelAttribute("adminFormAjax") AdminData ad, Model model) 
    {
        rep.save(ad);
        model.addAttribute("adminFormAjax", ad);
        return ad;
    }

}
like image 369
Jim Archer Avatar asked Oct 19 '22 06:10

Jim Archer


1 Answers

So breakdown of answer.

  1. Thymeleaf not redundant, it will still render the HTML page prior to sending to client. Ajax just does the further processing for you on client side.
  2. You can use submit button as well, you just need to ensure your form is properly structured and you have javascript listening for your submit button click e.g.

    $("#submitbutton").on('click', function (){//do stuff});

  3. You handle any and all exceptions/issues within your Ajax controller as you would with standard controller. You need to separate issue handling at different levels. e.g. respository level issues should be managed at rep level, controller/pojo should be at controller level (or pojo if you using one for processing). You should also be capturing any exceptions through a global medium (e.g. ControllerAdvice).

  4. Any issues/errors you pick up you should be communicating back via your return call in adminSubmit, and managing the relevant client response in ajax.
like image 161
Aeseir Avatar answered Oct 28 '22 15:10

Aeseir