I have an application where I am constantly facing a need to dynamically add/remove group of fields from one to many relationship of domain objects in forms. The fields can be textfields, selects, radio buttons etc. I can't find any simple approach to do this.
For this the best solution according to me would have been to render a div using my grails tags into a javascript string and add remove divs on the form.
E.g. on clicking Add
var vector = $.parseHTML('<div><label>Vector:</label><g:select from="${..}" /><g:text......');
$("#vectorDiv").append(vector);
But approach doesn't work for a variety of reasons. One being javascript doesn't allow newlines in string(without a / at the end which i can't enforce with grails tags).
I don't want to start using React yet. Just jquery and grails tags.
I wanted to get some opinions on this "design pattern" if you will. render a div in my gsp.
<!--templates-->
<div id="templates" hidden>
<div id="templateAccessoryVector" class="form-group accessoryVector">
<div class="col-sm-4">
<g:select class="form-control" name="accessoryVectorsTemplate.vectorId"
from="${Vector.getAccessoryVectors()}" optionKey="id" optionValue="alias" />
</div>
<label class="control-label col-sm-2">Percentage:</label>
<div class="col-sm-2 input-group">
<g:textField class="form-control text-right" name="accessoryVectorsTemplate.percentage" />
<span class="input-group-addon">%</span>
</div>
</div>
</div>
and then in javascript
var templateAccessoryVectorDiv = $("#templateAccessoryVector").removeAttr('id');
function addAccessoryVector(){
var newAccessoryVectorDiv = templateAccessoryVectorDiv.clone();
$("[name^='accessoryVectorsTemplate']", newAccessoryVectorDiv).each (function(index, element) {
element.name = element.name.replace('accessoryVectorsTemplate', 'accessoryVectors[' + accessoryVectors + ']');
});
newAccessoryVectorDiv.appendTo($("#accessoryVectors"));
accessoryVectors++;
}
//add, remove functions
All such templates could live in the templates section, hidden and used when required.