0

I have a Properties hashmap, that i pass to my form in settings.html:

<form action="#" th:action="@{/settings/modify}" method="post" th:object="${properties}">
    <div th:each="property : ${properties}">
        <div class="form-group">
                    <label th:for="${property.key}" name="key" th:text="${property.key}">Property</label>
                    <input type="text"
                           class="form-control"
                           name="value"
                           th:id="${property.key}"
                           th:value="${property.value}" />
        </div>
    </div>
    <button type="submit" class="btn btn-default" name="action" value="save">Submit</button>
    <button type="reset" class="btn btn-default" name="action" value="reload">Reset</button>
</form>

The general idea is to show the properties, that can be saved and passed back to controller SettingsController:

@Controller
@RequestMapping(value = "/settings")
public class SettingsController {

    @Autowired
    SettingsService settingsService;

    @Value("${postgres-bin-dir}")
    private String pgDirectory;

    @GetMapping(value = "/current")
    public String currentSettings(Model model) {

    Map<String, String> propertiesMap = settingsService.getSettingsMap();

    model.addAttribute("pgpath", pgDirectory);
    model.addAttribute("properties", propertiesMap);
    model.addAttribute("title", String.format("Current PgBackupper'a settings(%d)", propertiesMap.size()));
    return "settings/settings";
}

    @PostMapping(value = "/modify", params = "action=save")
    public String changeProperties(
        @RequestParam(value = "properties") Map<String, String> properties,
        RedirectAttributes redirectAttributes){

    redirectAttributes.addFlashAttribute("message","Settings changed succesfully");
    return "redirect:/settings/current";
}

}

So I want to get my post method "modifyProperties()" work, bunt i can't send changed parameters back.

As it is mentionet at official doc, I've tried to use such a th:field method, like, and used Entry set for looping:

<div th:each="property : ${properties.entrySet()}">
    <div class="form-group">
                <label th:for="${property.key}" name="key" th:text="${property.key}">Property</label>
                <input type="text"
                       class="form-control"
                       name="value"
                       th:id="${property.key}"
                       th:value="${property.value}" 
                       th:field="*{property.get(${property.key})}" />
    </div>
</div>

All my attempts fail with an error:

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Sun Mar 04 14:07:42 MSK 2018
There was an unexpected error (type=Internal Server Error, status=500).
Error during execution of processor 
'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (settings/settings:29)

What do I do wrong?

1 Answer 1

4

As far as I know, you can't use a Map as your form object. You need to have an object that has a Map as one of its properties.

public class PropertiesForm {
    private Map<String, String> properties = new HashMap<>();

    public Map<String, String> getProperties() {
        return properties;
    }

    public void setProperties(Map<String, String> properties) {
        this.properties = properties;
    }
}

Once you've done that, and changed your controller methods:

// public String currentSettings(Model model) {
PropertiesForm form = new PropertiesForm();
form.setProperties(settingsService.getSettingsMap());
model.addAttribute("form", form);

and

public String changeProperties(@ModelAttribute("form") PropertiesForm form, RedirectAttributes redirectAttributes) {

The html for the form should look something like this:

<form th:object="${form}" method="post">
    <div th:each="property : ${form.properties.entrySet()}">
        <div class="form-group">
            <label th:for="*{properties['__${property.key}__']}" th:text="${property.key}">Property</label>
            <input type="text" class="form-control" th:field="*{properties['__${property.key}__']}" />
        </div>
    </div>
</form>
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.