1

New version of Campaign Monitor subscribe code works differently. As you can see code provides a js file (copypastesubscribeformlogic.js) which is responsible for sending data.

What has changed?

Previously it was just one static request to CM endpoint to subscribe a user and it was quite easy to make subscription requested by ajax. Now, it needs two separate requests to subscribe a user. First request is being done by ajax and is provided by CM (js file copypastesubscribeformlogic.js handles this request).

My Problem : I want to load a success message on same page as form without page refresh or redirect, but it keeps redirecting to default CM thank you page.

My Form:

<form id="subForm" class="js-cm-form" action="https://www.createsend.com/t/subscribeerror?description=" method="post" data-id="XXXX-XXX-XX-X">
<p>       
    <input placeholder="Full Name" id="fieldName" name="cm-name" type="text" />
</p><br/>
<p>        
    <input placeholder="Email" id="fieldEmail" class="js-cm-email-input" name="cm-fhutty-fhutty" type="email" required /> 
</p><br/>
<p>
    <label for="fieldeihjlu">How did you hear of us?</label><br />
    <select  id="fieldeihjlu" name="cm-fo-eihjlu">
        <option value="1985454">Word of Mouth</option>
        <option value="1985450">Social Media</option>
        <option value="1985451">Press</option>
        <option value="1985452">Web Search</option>
        <option value="1985453">Sales and Marketing Activities</option>            
    </select>
</p>
<p>         
    <input class="js-cm-submit-button" type="submit" value="Submit">
</p>
</form>
<script type="text/javascript" src="https://js.createsend1.com/javascript/copypastesubscribeformlogic.js"></script>

Success message (same page as form):

<div id="success">
<h2 class='thank-you'>Thank you for subscribing</h2>
</div>

Then as per this LINK i added the following js:

var campaign = (function (c, d, $) {

var body,
  form,
  form_id,
  config,
  successMessage;

c.init = function () {

body = $('body');
form = body.find('#' + config.formSelector);
form_id = form.attr('data-id');
successMessage = $('#' + config.successSelector);
successMessage.hide();

// On form submit.
form.submit(function (evt) {

  // Disable default form submit.
  evt.preventDefault();

  // Get e-mail value.
  email = $('input[type=email]', form).val();

  // Build request data for tokenRequest.
  request_data = "email=" + encodeURIComponent(email) + "&data=" + form_id;

  // Prepare tokenRequest.
  tokenRequest = new XMLHttpRequest();
  tokenRequest.open('POST', 'https://createsend.com//t/getsecuresubscribelink', true);
  tokenRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  tokenRequest.send(request_data);

  // Ready state.
  tokenRequest.onreadystatechange = function() {
    if (this.readyState === 4) {
      if (this.status === 200) {
        // Having token and new submit url we can create new request to subscribe a user.
        subscribeRequest = new XMLHttpRequest();
        subscribeRequest.open('POST', this.responseText, true);
        subscribeRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        subscribeRequest.send(form.serialize());
        // On ready state call response function.
        subscribeRequest.onreadystatechange = function() {
          c.response(subscribeRequest);
        }
      } else {
        c.response(tokenRequest);
      }
    }
  }
});
};

// Handle ajax response.
c.response = function(request) {
if (request.readyState === 4) {
  if (request.status === 200) {
    successMessage.show('slow');
  } else {
    form.prepend('<p class="error">' + config.errorMessage + '</p>');
  }
}
};

// Private
config = {
formSelector: 'form',
errorMessage: 'There was a problem submitting this form. Please try later.',
successSelector: 'success',
};

return c;

}(campaign || {}, {}, jQuery));

(function () {
 campaign.init();
})(jQuery);

*On page load i don't get any Console errors.

*On Submit i get error : Refused to execute script from https://www.createsend.com/t/subscribeerror?description=..... because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled ,

but then it still executes to the default CM thank you page.

Ylama
  • 2,449
  • 2
  • 25
  • 50
  • I'm also looking for a solution to this - does anyone know how to create a custom made campaign monitor subscribe form? – alib0ng0 Aug 31 '18 at 08:53
  • https://stackoverflow.com/questions/51528519/campaign-monitor-ajax-form-submission – Ylama Aug 31 '18 at 08:59
  • @alib0ng0 i see you already commented on that ... ill post an answer here but after the recent updates not sure if it wil work. you cab try it tho, hust basically replace the script under the form to the js from above. – Ylama Aug 31 '18 at 09:02

1 Answers1

2

So basically it does the call and then displays message. Just to remember to update the ids in the script (at the bottom half) var successMessage = $('#success'); var form = $('#subForm').

Not tested with the new CM update, but this worked for me.

CSS

#success {display: none;}

HTML / js:

<div id="success">
<h2 class='thank-you'>Thank you for subscribing</h2>
</div>


<form id="subForm" class="js-cm-form" action="https://www.createsend.com/t/subscribeerror?description=" method="post" data-id="XXXX-XXX-XX-X">
<p>       
    <input placeholder="Full Name" id="fieldName" name="cm-name" type="text" />
</p><br/>
<p>        
    <input placeholder="Email" id="fieldEmail" class="js-cm-email-input" name="cm-fhutty-fhutty" type="email" required /> 
</p><br/>
<p>
    <label for="fieldeihjlu">How did you hear of us?</label><br />
    <select  id="fieldeihjlu" name="cm-fo-eihjlu">
        <option value="1985454">Word of Mouth</option>
        <option value="1985450">Social Media</option>
        <option value="1985451">Press</option>
        <option value="1985452">Web Search</option>
        <option value="1985453">Sales and Marketing Activities</option>            
    </select>
</p>
<p>         
    <input class="js-cm-submit-button" type="submit" value="Submit">
</p>
</form>




    <script type="text/javascript" >
    ! function(e) {
    var t = {};

    function n(o) {
        if (t[o]) return t[o].exports;
        var r = t[o] = {
            i: o,
            l: !1,
            exports: {}
        };
        return e[o].call(r.exports, r, r.exports, n), r.l = !0, r.exports
    }
    n.m = e, n.c = t, n.d = function(e, t, o) {
        n.o(e, t) || Object.defineProperty(e, t, {
            configurable: !1,
            enumerable: !0,
            get: o
        })
    }, n.r = function(e) {
        Object.defineProperty(e, "__esModule", {
            value: !0
        })
    }, n.n = function(e) {
        var t = e && e.__esModule ? function() {
            return e.default
        } : function() {
            return e
        };
        return n.d(t, "a", t), t
    }, n.o = function(e, t) {
        return Object.prototype.hasOwnProperty.call(e, t)
    }, n.p = "", n(n.s = 1)
}([function(e, t) {
    var n;
    "function" != typeof(n = window.Element ? window.Element.prototype : window.HTMLElement.prototype).matches && (n.matches = n.msMatchesSelector || n.mozMatchesSelector || n.webkitMatchesSelector || function(e) {
            for (var t = (this.document || this.ownerDocument).querySelectorAll(e), n = 0; t[n] && t[n] !== this;) ++n;
            return Boolean(t[n])
        }), "function" != typeof n.closest && (n.closest = function(e) {
            for (var t = this; t && 1 === t.nodeType;) {
                if (t.matches(e)) return t;
                t = t.parentNode
            }
            return null
        }),
        function() {
            var e, t, n, o = document.documentElement || document.body;
            o.getAttribute("data-cm-hook") || (t = "submit", n = function(e) {
                var t = e.target.closest(".js-cm-form");
                t && (e.preventDefault ? e.preventDefault() : e.returnValue = !1, function(e, t, n) {
                    var o = n.querySelector(".js-cm-email-input"),
                        r = "email=" + encodeURIComponent(o.value) + "&data=" + encodeURIComponent(n.getAttribute("data-id")),
                        c = new XMLHttpRequest;
                    c.onreadystatechange=function(){
if (this.readyState === 4) {
if (this.status === 200) {

// Having token and new submit url we can create new request to subscribe a user.
var successMessage = $('#success');
var form = $('#subForm')

subscribeRequest = new XMLHttpRequest();
subscribeRequest.open('POST', this.responseText, true);
subscribeRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
subscribeRequest.send($("#subForm").serialize());
// On ready state call response function.
subscribeRequest.onreadystatechange = function() {

form.hide('fast');
successMessage.show('fast');
}
} else {
alert("error");
}
}
}, c.open(e, t, !0), c.setRequestHeader("Content-type", "application/x-www-form-urlencoded"), c.send(r)
                }("POST", "https://createsend.com//t/getsecuresubscribelink", t))
            }, (e = o).addEventListener ? e.addEventListener(t, n) : e.attachEvent("on" + t, n), o.setAttribute("data-cm-hook", "1"))
        }()
}, function(e, t, n) {
    e.exports = n(0)
}]);


    </script>
Ylama
  • 2,449
  • 2
  • 25
  • 50
  • 1
    Ok thanks for getting back to me...this is the error I'm getting. Failed to load https://www.createsend.com/t/subscribeerror?description=Server%20encountered%20an%20unknown%20error.: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://fuzzyduck.co.uk' is therefore not allowed access. (index):297 – alib0ng0 Aug 31 '18 at 09:46
  • I came here because I also have this 'has been blocked by CORS policy' error message. Still looking for a workaround. – Liam Mar 31 '20 at 20:10