Expand my Community achievements bar.

Adobe Campaign User Groups are live now. Join our Adobe Campaign User Groups and connect with your local leaders!
SOLVED

Subscription to Newsletter service from web form in ACC

Avatar

Level 2

Hello, my team and I are stuck in the process of subscribing a recipient to 1 or more newsletter services in ACC. 

 

Context: 

 

We have an array called 'Categories' in context variable that contains 5 values (all of them are services), and we will need to iterate through it in order to dynamically render them in the landing page as checkbox options. 

 

In our subscription page, we are running the next script in the HTML file (pageLoader is a function that allow us to access context variables and executes in the body of the HTML code as explained in a previous question https://experienceleaguecommunities.adobe.com/t5/adobe-campaign-classic-questions/web-app-accessing-...)

 

Script

 

alejandroluzuriaga_0-1698999155189.png

 

We use the 'noSpaceCategory' value in order to match the internal newsletter's name in ACC, so the main difference between 'noSpaceCategory' and categories[i] is just one allows having more than one word and the other does not.

 

HTML Body

 

alejandroluzuriaga_1-1698999155197.png

 

 We have 2 important things here:

  • Div element with id="checkboxes": where we are going to append all the checkbox elements with the for loop in script
  • Div element with class="agree" (just after de first <hr.>): static element that comes by default in 'Subscription page' activity in a 'Newsletter subscription (subNewsletter)' workflow. Lets call it "Magic checkbox option".

Rendered Page:

alejandroluzuriaga_2-1698999438362.png

 

Problem: 

We can dynamically render the content with the for loop opening the Sandbox URL with Chrome, but none of the options actually works after clicking 'I subscribe' except for the "Magic checkbox option". That checkbox is the only one that actually subscribe the recipient in the newsletter specified in the line. 

 

We made sure that the internal newsletter services names are the correct, and we don't have a clue about why is not working.

 

What did we try:

 

  • Create a string with all the HTML code generated just as we did in the script but in a previous script and importing it by a context variable to append it inside of 'checkboxes' container.
    • Result: Failed.

We could not find a way of converting the string into HTML code. 

 

  • Manually put all the "checkboxes" elements directly in the HTML code one by one.
    • Result: Succeed.

Everything works just fine, but the thing here is that doing it this way we are not able to dynamically render more newsletter categories in case the 'Categories' array changes.

 

We have been trying to look for a better way to do this, but we can not avoid the 'Categories' array.

Can anyone help us on this taking a look at our logic?

 

Thank you.

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

1 Accepted Solution

Avatar

Correct answer by
Level 2

Hello, Manoj!

We finally managed to solve the problem yesterday after doing something interesting. We were taking a look at the generated code in ACC for the web page and we realised that the subscription actually was made by searching the service name in the context. This is were services should be added when we want to add a subscription:

 

alejandroluzuriaga_1-1699432471473.png

The path for accessing this services in Recipient is 'ctx -> Recipient -> svc'.

This 'svc' is added by default when using a Subscription in web pages for ACC, so it is only necessary to add as many as we want there, and the form will handle the innerText for subscribing (1 will subscribe and 0 will not)

How can we dynamically add new services to the Recipient services path?

This is how we managed to add them based in our array:

 

function addCheckboxFromArray(array) {
  for (var i = 0; i < array.length; ++i) {
    if (array[i]) {
      var noSpaceCategory = deleteSpaces(array[i]); //This only deletes any spaces from the string
      var htmlString = `
        <div class="agree">
          <input name="agree${i}" id="agree${i}" type="checkbox" class="checkbox-listen" 
            data-nl-ismandatory="false" data-nl-bindto="service" data-nl-servicelabel="academy_newsletter_${noSpaceCategory}" 
            data-nl-servicename="academy_newsletter_${noSpaceCategory}" data-nl-checkboxbehavior="subscription" 
            data-noSpaceCategory="${noSpaceCategory}" />
          <label style="display: inline;" for="agree${i}" data-nl-localizable="true">
            ${array[i]}
          </label>
        </div>
      `;

      checkboxes.innerHTML += htmlString;

      document.controller.setValue(`/ctx/recipient/svc/academy_newsletter_${noSpaceCategory}`, 0, `agree${i}`);
    }
  }

  var checkboxListenElements = document.querySelectorAll('.checkbox-listen');
  checkboxListenElements.forEach(function (checkbox, index) {
    checkbox.addEventListener('change', function () {
      var isChecked = checkbox.checked ? 1 : 0;
      var currentNoSpaceCategory = checkbox.getAttribute('data-noSpaceCategory');
      document.controller.setValue(`/ctx/recipient/svc/academy_newsletter_${currentNoSpaceCategory}`, isChecked, `agree${index}`);
    });
  });
}

(We used modern JS to run the script because we were using Chrome. ACC does not run this in 'Preview' mode)

Basically, we use JS to add the checkboxes dynamically with the array and we do two important things here:

  • We add the service with setValue in the specified path with a default value '0' when each checkbox is created.
  • Then we add eventListeners to all dynamic checkbox to handle the innerText value of each service based on if checked by user or not. 

This is an example of how a checkbox selection should look like in both page and recipient services:

alejandroluzuriaga_2-1699433238139.png

If services are set properly in the context, ACC handles the subscription as expected when form is submitted.

 

Thank you.

 

View solution in original post

5 Replies

Avatar

Community Advisor

Hello @alejandroluzuriaga 

 

I see you are using JavaScript to render the checkboxes. It is a client-side code.

 

Did you try using the server-side code? Something like:

<% 
for each(var cat in categories) {
%>
<input type="checkbox" value="<%= cat.@internalName %>"> <%= cat.@label%>
<%
}
%>

 

 


     Manoj
     Find me on LinkedIn

Avatar

Level 1

Hello @_Manoj_Kumar_,
I hope you are having a great day. 
I am part of @alejandroluzuriaga's Team. We are executing the code from the server side as you suggested. Sadly, we are having the same issue. The code renders the array dynamically but it doesn't subscribe the recipient to the newsletter. Do you have any other suggestion for this issue?

Thanks in advance.

Avatar

Community Advisor

Hello @angeles_arcia 

 

Could you please share the code you are using for this?  I will try to troubleshoot it.


     Manoj
     Find me on LinkedIn

Avatar

Correct answer by
Level 2

Hello, Manoj!

We finally managed to solve the problem yesterday after doing something interesting. We were taking a look at the generated code in ACC for the web page and we realised that the subscription actually was made by searching the service name in the context. This is were services should be added when we want to add a subscription:

 

alejandroluzuriaga_1-1699432471473.png

The path for accessing this services in Recipient is 'ctx -> Recipient -> svc'.

This 'svc' is added by default when using a Subscription in web pages for ACC, so it is only necessary to add as many as we want there, and the form will handle the innerText for subscribing (1 will subscribe and 0 will not)

How can we dynamically add new services to the Recipient services path?

This is how we managed to add them based in our array:

 

function addCheckboxFromArray(array) {
  for (var i = 0; i < array.length; ++i) {
    if (array[i]) {
      var noSpaceCategory = deleteSpaces(array[i]); //This only deletes any spaces from the string
      var htmlString = `
        <div class="agree">
          <input name="agree${i}" id="agree${i}" type="checkbox" class="checkbox-listen" 
            data-nl-ismandatory="false" data-nl-bindto="service" data-nl-servicelabel="academy_newsletter_${noSpaceCategory}" 
            data-nl-servicename="academy_newsletter_${noSpaceCategory}" data-nl-checkboxbehavior="subscription" 
            data-noSpaceCategory="${noSpaceCategory}" />
          <label style="display: inline;" for="agree${i}" data-nl-localizable="true">
            ${array[i]}
          </label>
        </div>
      `;

      checkboxes.innerHTML += htmlString;

      document.controller.setValue(`/ctx/recipient/svc/academy_newsletter_${noSpaceCategory}`, 0, `agree${i}`);
    }
  }

  var checkboxListenElements = document.querySelectorAll('.checkbox-listen');
  checkboxListenElements.forEach(function (checkbox, index) {
    checkbox.addEventListener('change', function () {
      var isChecked = checkbox.checked ? 1 : 0;
      var currentNoSpaceCategory = checkbox.getAttribute('data-noSpaceCategory');
      document.controller.setValue(`/ctx/recipient/svc/academy_newsletter_${currentNoSpaceCategory}`, isChecked, `agree${index}`);
    });
  });
}

(We used modern JS to run the script because we were using Chrome. ACC does not run this in 'Preview' mode)

Basically, we use JS to add the checkboxes dynamically with the array and we do two important things here:

  • We add the service with setValue in the specified path with a default value '0' when each checkbox is created.
  • Then we add eventListeners to all dynamic checkbox to handle the innerText value of each service based on if checked by user or not. 

This is an example of how a checkbox selection should look like in both page and recipient services:

alejandroluzuriaga_2-1699433238139.png

If services are set properly in the context, ACC handles the subscription as expected when form is submitted.

 

Thank you.

 

Avatar

Community Advisor

Hello @alejandroluzuriaga 

 

I am glad you found the solution.

 

You can always use the enable-debug option in the web app to check the path and all context variables.


     Manoj
     Find me on LinkedIn