Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind a Map (key and value) to spring form in jsp

I have a class like this:

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

I need a form where the user can add key value pairs in the properties map. All SO answers I've found on this just show how to use an already known key to enter a value using:

<form:input path="properties['keyName']" />

How can I make the key editable also? I something like...

<form:input path="properties.key" /><form:input path="properties.value" />
like image 669
Abby Avatar asked Nov 01 '22 13:11

Abby


1 Answers

I got this working and had to find this page again to provide my answer.

I was dynamically adding a key and value map to my <form> and my solution had an input for the key and a separate input for the value. I then registered a change listener on the key to update the name on the value input.

For me, the hard part is that JQuery did not have access to the ID of the dynamically added key/value elements. This meant that if the map was already populated, I could use JQuery with no problem, but if it was a new entry I had problems and doing a search on the value input's ID was not successful.

To solve this, I had to essentially travel the DOM to get to the value input. Here is my code JSP code.

<c:forEach var="points" items="${configuration.pointsValueMap}" varStatus="index">
  <div class="col-xs-3 ">
    <label for="pointMap[${index.index}]">Type:</label>
    <input type="text" id="pointMap[${index.index}]" class="pointMap" value="${points.key}"> : 
  </div>
  <div class="col-xs-3 ">
    <label for="pointMap[${index.index}]-value">Value:</label>
    <input type="text" id="pointMap[${index.index}]-value" name="pointsValueMap[${points.key}]" value="${points.value}">
  </div>
</c:forEach>

And here is my JS that updated the value of the name path.

/**
 * Register a listener on the form to detect changing the map's key
 */
$('form').on('change', 'input.pointMap', function(){
    var content = $(this).val();
    var id = $(this).attr('id');
    // have to travel the DOM for added elements to be accessed.
    // JQuery does not have visibility to the IDs of added elements
    $(this).parent().next().children('input').attr('name', 'pointsValueMap['+content+']');
    // if you are not dynamically adding key/values then 
    // all fields are accessible by JQuery and you can update by:
    $('#'+id+'-value').attr('name', 'pointsValueMap['+content+']');
});
like image 138
Jon Tinsman Avatar answered Nov 11 '22 19:11

Jon Tinsman