Search code examples
javascriptformsgrails

Passing a dynamically generated form to a controller


This is my JavaScript function to generate checkboxes at run time based on an XML file when a user clicks on a create button:

function createform(){
       var xml = '<root><note ><to>x1</to><from><firstname>x2</firstname><lastname>x3</lastname></from><heading>x4</heading></note><note><to>x5</to><from><firstname>x6</firstname><lastname>x7</lastname></from><heading>x8</heading></note></root>';
       var node = (new DOMParser()).parseFromString(xml, "text/xml").documentElement;
       var nodes = node.querySelectorAll("*");
       for (var i = 0; i < nodes.length; i++) {
          var label = document.createElement('label');
          var br = document.createElement('br');

          var alabel = document.getElementById('div');
          var last = alabel[alabel.length - 1];
          label.htmlFor = "lbl"+i;
          label.appendChild(Createcheckbox(nodes[i].tagName));

          label.appendChild(document.createTextNode(nodes[i].tagName));
          label.appendChild(br);

          document.getElementById('div').appendChild(label);
       }
    }

    function Createcheckbox(chkboxid) {
       var checkbox = document.createElement('input');
       checkbox.type = "checkbox";
       checkbox.id = chkboxid;
       checkbox.value = chkboxid; 
       checkbox.checked = false;
       return checkbox;
    }

Also on my gsp page, I have this HTML script.

<body>
<g:form name="myForm" controller="dynamicform" action="index">
<input type="button" id="btncreate" value="Create" onclick="createform()"/>
<g:submitButton name="submit" value="Submit" />
<Div id='div'>
</div>
</g:form>
</body>

Since the elements in this form are unknown until the user clicks the "create" button, I'm not sure what is the best way to handle this form.

I need to pass the values of the elements to a controller to render them in a view (I'll need to use these values later to retrieve some data from my database).

I tried different ways to view these elements after submission, such as:

for (name in params.list('name')) {
    println name
}

and

params.name.each{i->System.out.println(i);}

It seems that my params are not passed to the controller. Is that because my form elements generated using regular HTML instead of Grails forms <g: checkbox ... >, so the DOM elements can't be passed to the controller? If yes, is there a way to re-write my createform() function using Grails form?

I'm trying to follow best practices while learning Grails so I'd appreciate any suggestion or advice about that.


Solution

  • It was a simple fix -

    function Createcheckbox(chkboxid) {
        var checkbox = document.createElement('input');
        checkbox.type = "checkbox";
        checkbox.id = chkboxid;
        checkbox.value = chkboxid;
        checkbox.checked = false;
        checkbox.name = chkboxid; // <-- the fix!!!
        return checkbox;
    }
    

    In controller: println params

    [submit:Submit, note:note, to:to, lastname:lastname, heading:heading, controller:dynamicform, action:index]

    enter image description here

    Comment : In HTML form submit, any input with a name attribute will be submitted. Without name attr no form data will be passed to server.

    Suggestion : Place your JS function Createcheckbox(chkboxid) before createform()