简体   繁体   中英

Thymeleaf dynamic array insertion

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:

在此处输入图像描述

And this is how it's supposed to look:

在此处输入图像描述

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):

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM