Expand my Community achievements bar.

SOLVED

Passing all form data to custom servlet

Avatar

Level 4

I have a form with multiple panels and various other things going on. I have it set up to save to a database for drafts and submissions. Due to the nature of the form, we need to keep it as a draft to maintain editability for the nature of this project.

We're looking to add a way to generate an email of the form data when a particular button is pushed. I've got it set up to transmit the form data as JSON to a custom servlet to be iterated over. Unfortunately, generating the JSON data for the form without knowing all of the form field names is causing some issues. In other forms, I just reference the fieldName.value to pass the value through as a set parameter name. This time, though, the form could be modified at any point with new options added or removed. I need to be able to pass everything through to the servlet regardless of changes.

My only real problem here is that when I change the values of the form fields, the name of the field goes from referencing the field name I defined to the SOM position in a way that is not useful when I go to parse the data.

When logging the JSON data to console, I get back the following where the form name I provided for the first line is status1 and the second is notes1. I currently have 18 status and notes fields, with the number at the end increasing, but once the value is changed, I'm not getting statusX or notesX back anymore. Is there a way to get a more useful name for each field after data has been updated without being able to reference the field by name specifically?

  1. guideContainer-rootPanel-timeline-180-days-panel1548963120967-guidedropdownlist___jqName: "Complete"
  2. guideContainer-rootPanel-timeline-180-days-panel1548963120967-guidetextbox___jqName: "This is a test. "
1 Accepted Solution

Avatar

Correct answer by
Level 4

That doesn't fix my problem of not being able to reference certain fields because AEM is changing the field names to something I don't know. Plus I needed to be able to pass the panel titles into the email I was working on as well.

Here's what I went with. It lets me define the fields I want by the names I defined. Then, based on the field name, I can pass through the info about the fields the way I want them to be and I can process them on the other end into readable output without much manipulation.

var array = ["180-days.panel1","status1","notes1","180-days.panel6","status6","notes6","180-days.panel2","status2","notes2","180-days.panel3","status3","notes3"];

$.each(array, function(index, item) {

  if(item.indexOf("panel") >= 0) {

     json[guideBridge.resolveNode(item).name] = guideBridge.resolveNode(item).title || '';

  } else if(item.indexOf("status") >= 0 || item.indexOf("notes") >= 0) {

     json[guideBridge.resolveNode(item).name] = guideBridge.resolveNode(item).value || '';

  } else {

     json[guideBridge.resolveNode(item).title] = guideBridge.resolveNode(item).value || '';

  }

});

View solution in original post

10 Replies

Avatar

Level 10

If I understand it correctly, you could iterate all form fields in js/jquery  -

How to loop through all elements of a form jQuery - Stack Overflow

or

$(document).ready(function() {

    $('#yourButtonID').click(function () {

        $(':input').each(function() {

            alert(this.name + ': ' + this.value);

        });

    });

});

Avatar

Level 4

I'm currently doing the following to create the JSON to pass to the Java servlet. I created the check for the fields I didn't create and don't intend to use so that they're not being added to the JSON.

var array = $("form").serializeArray();

var json = {};

$.each(array, function() {

      if( $.inArray(this.name, [':redirect', ':selfUrl', '_guideValueMap', '_useSignedPdf']) < 0 ) {

          json[this.name] = this.value || '';

      }

});

console.log(json);

So for input fields that I've named status1, notes1, status2, notes2, and country, I'm getting back the following output when status1, notes1, and country have been filled in. "Not Started" is the default option for a select field.

guideContainer-rootPanel-guide1-guide1-guidedropdownlist_1666771090___jqName: "Germany"

guideContainer-rootPanel-timeline-180-days-panel1548963120967-guidedropdownlist___jqName: "Complete"

guideContainer-rootPanel-timeline-180-days-panel1548963120967-guidetextbox___jqName: "This is a test. "

notes2: ""

status2: "Not Started"

I don't know why when I generate the data this way that my field name changes from status1 to guideContainer-rootPanel-timeline-180-days-panel1548963120967-guidedropdownlist___jqName

Avatar

Level 10

most likely because of how $.inArray() works internally - The $.inArray() method is similar to JavaScript's native .indexOf() method in that it returns -1 when it doesn't find a match. If the first element within the array matches value, $.inArray() returns 0.

If 'this.name' or 'status1' is not found in the passed array, it returns -1 and it picks up entire dom string. you should be able to find it easily. Add console.log() and you'll find the root cause & solution.

https://api.jquery.com/jQuery.inArray/

https://eric.blog/2015/01/11/jquery-inarray-fooled-me/

javascript - jQuery.inArray(), how to use it right? - Stack Overflow

Avatar

Level 4

I added the inArray specifically to remove the items listed because I don't need them. I am checking inArray for a negative number because I do not want to enter the if statement for those values I'm checking inArray for.  "if( $.inArray(this.name, [':redirect', ':selfUrl', '_guideValueMap', '_useSignedPdf']) < 0 )"

While status1 wouldn't be found in the array currently, I'm trying to figure out why the form element's name changes after the field is filled out. I can get the value of status1 with status1.value, but I specifically do not want to have to reference every field in the form to generate the data being passed to the servlet. I just want to pass the data through with the field names that I provided.

Avatar

Level 10

I'm not sure of the reason but you may've to debug further. Could you check if that's not related with stringified variable names that you've used in the array?

Could you test this code and share the results from browser console in developer toolbar?

​$.each(array, function() {

console.log("before--" + this.name + "  status -- "+ $.inArray(this.name, [':redirect', ':selfUrl', '_guideValueMap', '_useSignedPdf']) < 0);

      if( $.inArray(this.name, [':redirect', ':selfUrl', '_guideValueMap', '_useSignedPdf']) < 0 ) {

console.log("after--" + this.name);

          json[this.name] = this.value || '';

      }

});

Avatar

Level 4

I was getting the same name output before I built the JSON for it, when I was just passing the serialized form through to the Java class.

With the code you sent over, it was only showing false in the before for everything. I removed the inArray piece, and the field name before and after matches. And once it gets to the fields that haven't been modified, it shows the names I defined.

Maybe I'll just have to build my own JSON to pass through, even though that's what I was trying to avoid.

1694936_pastedImage_0.png

Avatar

Level 4

I would up creating an array of all of the field names that I want to pass through data for and then looped through them to create a JSON array with the field name at the key and the value as the value. Then based on some different checks in my JAVA class, I'm outputting the value with a relevant subject. It works for what I needed even though it requires adding all the field names to the array in the order I need them to appear in. In theory, it'll work how we need it to.

Thanks for trying to help!

Avatar

Level 10

If the fields to be parsed are more than what you want to exclude then just try this -

var serializedReturn = $('input[name!=security]', this).serialize();  

jquery - Excluding certain inputs on serialize - Stack Overflow

javascript - Hide certain values in output from JSON.stringify() - Stack Overflow

Avatar

Correct answer by
Level 4

That doesn't fix my problem of not being able to reference certain fields because AEM is changing the field names to something I don't know. Plus I needed to be able to pass the panel titles into the email I was working on as well.

Here's what I went with. It lets me define the fields I want by the names I defined. Then, based on the field name, I can pass through the info about the fields the way I want them to be and I can process them on the other end into readable output without much manipulation.

var array = ["180-days.panel1","status1","notes1","180-days.panel6","status6","notes6","180-days.panel2","status2","notes2","180-days.panel3","status3","notes3"];

$.each(array, function(index, item) {

  if(item.indexOf("panel") >= 0) {

     json[guideBridge.resolveNode(item).name] = guideBridge.resolveNode(item).title || '';

  } else if(item.indexOf("status") >= 0 || item.indexOf("notes") >= 0) {

     json[guideBridge.resolveNode(item).name] = guideBridge.resolveNode(item).value || '';

  } else {

     json[guideBridge.resolveNode(item).title] = guideBridge.resolveNode(item).value || '';

  }

});