0

I have a problem that's been giving me a bit of a headache for a while and I'm hoping someone can help. I've had a look at various questions including, but not limited to:

javascript get all inputs inside div including select and textarea

How to get all elements inside "div" that starts with a known text

Javascript - Recursive function to iterate through elements

but I haven't been able to figure out exactly what I need.

For a bit of background I need to take information from a web form that then needs to go into XML format to be read into another system. There will be an indefinite number of Divs and my HTML/XSL snippet might look like this:

<div class="Beneficiary">
    <div>
        <label for="field@code_TF01">Applies to</label>
        <select name="Applies to" id="field@code_TF01" required="required" class="field">
            <option id="field@code_TF01-1" value="Client 1">Client 1</option>
            <option id="field@code_TF01-2" value="Client 2">Client 2</option>
            <option id="field@code_TF01-3" value="Both">Both</option>
        </select>
    </div>
    <br/>
    <div>
        <label for="field@code_TF02">Full name</label>
        <input name="Full name" id="field@code_TF02" required="required" type="text" onfocus="buildPeopleList(this.id)" class="field"/>
    </div>
    <div id="field@code_TF03-container">
        <label for="field@code_TF03">Full Address</label>
        <textarea name="Full Address" id="field@code_TF03" required="required" class="field"/>
    </div>
    <br/>                           
</div>
<div class="Beneficiary">
    <div>
        <label for="field@code_TF11">Applies to</label>
        <select name="Applies to" id="field@code_TF11" required="required" class="field">
            <option id="field@code_TF11-1" value="Client 1">Client 1</option>
            <option id="field@code_TF11-2" value="Client 2">Client 2</option>
            <option id="field@code_TF11-3" value="Both">Both</option>
        </select>
    </div>
    <br/>
    <div>
        <label for="field@code_TF12">Full name</label>
        <input name="Full name" id="field@code_TF12" required="required" type="text" onfocus="buildPeopleList(this.id)" class="field"/>
    </div>
    <div>
        <label for="field@code_TF13">Full Address</label>
        <textarea name="Full Address" id="field@code_TF13" required="required" class="field"/>
    </div>
    <br/>                           
</div>

What I'm looking to get, either in a string or XML format is

<Benificiaries>
    <Beneficiary>
        <Applies To>Client 1</Applies To>
        <Full name>Name 1</Full name>
        <Full address>Address 1</Full address>
    </Beneficiary>
    <Beneficiary>
        <Applies To>Client 2</Applies To>
        <Full name>Name 2</Full name>
        <Full address>Address 2</Full address>
    </Beneficiary>
</Beneficiaries>

I've tried several methods but haven't been able to get this, I've had various results but I just can't get it right. My current function is:

function downloadData(contentType,data,filename){

    var link=document.createElement("A");
    link.setAttribute("href",encodeURI("data:"+contentType+","+data));
    link.setAttribute("style","display:none");
    link.setAttribute("download",filename);
    document.body.appendChild(link); //needed for firefox
    console.log(link.outerHTML);
    link.click();
    setTimeout(function(){
        document.body.removeChild(link);
        },1000);
    }

    function formToXml(form){    
    <![CDATA[
        var outdata='<?xml version="1.0"?/>';
        outdata = outdata + '<Beneficiaries>';
        $(function(){                            
            var $mainDiv = $('form:first');   
            console.log('MainDiv'+$mainDiv);                       
            var $benDiv = $('div.Beneficiary:first');
            console.log('benDiv'+$benDiv);
            var $fieldInput = $('input');

            $mainDiv.nextAll().children('div.beneficiary').each(function (){
            outdata=outdata + '<Beneficiary>';
            $benDiv.nextAll().children('.field').each(function (){
                var newText = $fieldInput.val();
                var newName = $fieldInput.attr('name');
                outdata =outdata + '<'+newName+'>'+newText+'</'+newName+'>'
                });
                outdata = outdata + '</Beneficiary>';
            })                            
        })
    outdata = outdata + '</Beneficiaries>';
    return outdata;
    ]]>
    }

    function download(frm){

        var data=formToXml(frm);
        console.log(data);                
        downloadData("text/xml",data,"export.xml");
    } 

Which returns:

<?xml version="1.0"?/>
<Beneficiaries>
</Beneficiaries>

I don't know if I'm missing something really stupid or going about it the wrong way but would appreciate any advice.

KT79
  • 89
  • 1
  • 2
  • 10
  • Well, you are performing `nextAll()` on the `$mainDiv`, which is a form, so that's going to get all the proceeding sibilings of the form. That seems like an issue, unless you have multiple forms on the page. From the way the markup is structured, it looks like you just need to loop over the `div.Beneficiary` elements. – Taplar Mar 19 '19 at 11:51
  • Thanks @Taplar, have tried that as well but get the same result. – KT79 Mar 19 '19 at 13:45

0 Answers0