2

I am currently coding a small website with Thymeleaf and Spring which should show a dynamic matrix which you can load and save. The problem with that is, though, that I can't set a definitive value with Thymeleaf since once I have th:field in an element I can't give it a value anymore.

Now I searched a bit and found out, that you can give the filled object to the Thymeleaf component, and it will automatically insert the data. Now this somewhat works, but Thyemeleaf now puts the whole list into every single field.

This is my code:

html

<form th:object="${projectData}" method="post" class="card">
    <div class="card-content">
        <div class="content">
            <div class="columns is-gapless is-multiline is-mobile">
                <tr th:each="_, index: ${projectData.matrixData}">
                    <div th:if="${index.index % matrixSize == 0}" class="break column is- 
                    desktop"></div>

                <input th:field="*{matrixData}"
                       class="column"
                       type="text"
                       th:if="${#arrays.contains(matrixDisabledFields, index.index)}"
                       th:id="${index.index}"
                       disabled>

                <input th:field="*{matrixData}"
                       class="column"
                       type="text"
                       th:unless="${#arrays.contains(matrixDisabledFields, index.index)}"
                       th:id="${index.index}">
                </tr>
            </div>
            <input type="submit" class="button is-light is-pulled-right" value="Save">
        </div>
    </div>
</form>

Controller

@GetMapping("/matrix/{id}")
String getMatrix(Model model, @PathVariable Integer id) {
    ProjectData projectData = JsonConverter.getProjectDataWithID(id);

    if (projectData == null) {
        model.addAttribute("error", "Invalid id");
        return "error";
    }

    String[] matrix;
    if (projectData.getMatrixData() == null) {
        matrix = 
        new String[(int) Math.pow(projectData.getProjectOptions().getMatrixSize(), 2)];
    } else {
        matrix = projectData.getMatrixData();
    }

    int matrixLength = (int) Math.sqrt(matrix.length);

    Integer[] matrixDisabledFieldIds = new Integer[matrixLength];

    Integer pastIndex = -matrixLength - 1;
    for (int i = 0; i < matrixLength; i++) {
        matrixDisabledFieldIds[i] = pastIndex + matrixLength + 1;
        pastIndex = matrixDisabledFieldIds[i];
        matrix[pastIndex] = "X";
    }

    projectData = new ProjectData();
    projectData.setMatrixData(matrix);

    model.addAttribute("matrixSize", matrixLength);
    model.addAttribute("matrixDisabledFields", matrixDisabledFieldIds);
    model.addAttribute("projectData", projectData);

    return "matrix";
}

And this is how it looks in the application:

enter image description here

And this is how it's supposed to look:

enter image description here

1 Answer 1

1

The simplest fix is probably to change both of these lines in your template from this:

th:field="*{matrixData}"

to this:

th:field="*{matrixData[__${index.index}__]}"

The __${...}__ syntax is the Thymeleaf preprocessor expression (an expression surrounded by double-underscores).

In your case, this will evaluate to each of the index values into the matrix array, so you can grab only the one relevant value you want for each cell.

It will end up looking something like this (but nicer, with your CSS styling):

enter image description here

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

3 Comments

That actually works great to display it. Sadly it's throwing an error when trying to save. Seems like it can't assign the values. Any idea for how to fix that? Error is: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'matrixData[1000]' of bean class [com.matrix.entities.objects.project.ProjectData]: Invalid array index in property path 'matrixData[1000]'; nested exception is java.lang.ArrayIndexOutOfBoundsException]
You can ask that as a brand new question but I expect you need to use indexes from 0 to 999, and not from 1 to 1000, when saving data. Just a guess.
Well, didn't work, But thank you anyway ^^ I will make a new question then

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.