0

I have a Spring-Boot project using Thymeleaf.

The HTML form has groups of fields for inputting personal details like:

<button type="button" class="btn btn-default" id="btnGetPerson"><i class="fa fa-search"></i></button>
<Input type="text" id="id0" name="id" th:field="*{person[0].id}" />
<Input type="text" name="surname" th:field="*{person[0].surname}" />
<Input type="text" name="firstname" th:field="*{person[0].firstname}" />
...
<button type="button" class="btn btn-default" id="btnGetPerson"><i class="fa fa-search"></i></button>
<Input type="text" id="id1" name="id" th:field="*{person[1].id}" />
<Input type="text" name="surname" th:field"=*{person[1].surname}" />
<Input type="text" name=firstname" th:field="*{person[1].firstname}" />
etc

The results are coming back from the server correctly as JSON and look like:

surname : Smith
firstname: Bob

Then in the script file I got as far as:

    // GET AND RETURN PERSON
$( '#btnGetPerson').click(function() {
    var $theForm = $(this).closest('.panel-body');
    $.get('/person/' +$('#id0').val(), function(result) {
        $theForm.find('input[name="surname"]').val(result.surname);
    });
});

I was then going to do something like:

Object.keys(result).forEach(function(key) {
$('[name="' + key + '"]').val(result[key]);
});

To iterate over the keys and values in the JSON - but Thymeleaf renames the name fields in the HTML to match the form backing object, so my name="surname" gets over written with name="event.person[0].surname" where event is the backing object.

How should I approach mapping getting the JSON data that comes back from the server into the DOM?

UPDATE

A sample of the rendered html looks like:

                    <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">Victim / Subject</h3>
                    </div>
                    <div class="panel-body">


                        <div class="row">
                            <input type="text" class="form-control hidden" id="personId0" name="persons[0].id" value="1" />
                            <div class="col-sm-5">
                                <div class="form-group">

                                    <label for="surname0" class="col-sm-2 control-label">Surname</label>
                                    <div class="col-sm-10">
                                        <input type="text" class="form-control" id="surname0" placeholder="surname" name="persons[0].surname" value="EASTWOOD"/>
                                    </div>
                                </div>
                            </div

I should also add that the form initially renders with three people (index 0,1,2) and then there is a button to add another set of people fields dynamically by cloning the html fragment.

8
  • Note - I dont want to really use a result div block - I would rather split the JSON key value pairs off to the respective inputs. Commented Jul 4, 2017 at 23:35
  • Do you really want to use th:field? "Note - I dont want to really use a result div block" Commented Jul 5, 2017 at 4:10
  • As opposed to what other thymeleaf? Commented Jul 5, 2017 at 4:25
  • th:value="${value}" Commented Jul 5, 2017 at 4:36
  • 1
    "[...] Thymeleaf renames the name fields in the HTML to match the form backing object, so my name="surname" gets over written with name="event.person[0].surname" where event is the backing object." So your example isn't complete. Try sharing the actual rendered HTML so we can actually see what it looks like. Commented Jul 5, 2017 at 18:38

1 Answer 1

1

The JSON data coming back from server looks like:

{  
"id":1,
"surname":"EASTWOOD",
"middlename":"James",
"firstname":"Clint",
"countryOfBirth":"US",
"occupation":"Actor",
"gender":"Male",
"phoneHome":"555-1234",
"dob":"1965-06-17"
}

Map this to inputs, but the name and id's are renamed by thymeleaf. So in order to get around this use data-property field with names that match the key names in the JSON. So html inputs look like:

<input type="text" class="form-control  person" data-property="surname" placeholder="surname" th:field="*{persons[0].surname}"/>
<input type="text" class="form-control  person" data-property="firstname" placeholder="Firstname" th:field="*{persons[0].firstname}"/>
<select class="selectpicker form-control person" data-property="countryOfBirth" data-live-search="true" title="Birth Country" th:field="*{persons[0].countryOfBirth}">

Now the data-property provides tags that match the JSON names.

The jquery and javascript to find the closest panel-body and then update the inputs is below. Note that because of the way dropdowns are displayed in twitter-bootstrap as buttons I had to find a different class:

// GET AND RETURN PERSON
$( '#btnGetPerson').click(function() {
    var $theForm = $(this).closest('.panel-body');
    $.get('/person/' +$('#nia0').val(), function(result) {

        // LOOPS OVER THE PERSON INPUTS
        $theForm.find('.form-control.person').each(function()  {
            var formkey = $(this).attr('data-property');
            $(this).val(result[formkey]);
        });

        // LOOPS OVER THE SELECT PICKERS
        $theForm.find('.bootstrap-select').each(function() {
            var formkey = $(this).find('.selectpicker.form-control').attr('data-property');
            $(this).find('.filter-option').text(result[formkey]);
            $(this).find('.filter-option').val(result[formkey]);
        });
    });
});

Thanks to all those that helped.

Hope this helps someone else.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.