Submit Embedded Mailchimp Form with Javascript AJAX (not jQuery) - javascript

I have been trying to submit an embedded Mailchimp form with AJAX but without using jQuery. Clearly, I am not doing this properly, as I keep ending up on the "Come, Watson, come! The game is afoot." page :(
Any help with this would be greatly appreciate.
The form action has been altered to replace post?u= with post-json?u= and &c=? has been added to the end of the action string. Here is my js:
document.addEventListener('DOMContentLoaded', function() {
function formMailchimp() {
var elForm = document.getElementById('mc-embedded-subscribe-form'),
elInputName = document.getElementById('mce-NAME'),
elInputEmail = document.getElementById('mce-EMAIL'),
strFormAction = elForm.getAttribute('action');
elForm.addEventListener('submit', function(e) {
var request = new XMLHttpRequest();
request.open('GET', strFormAction, true);
request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
var resp = JSON.parse(request.responseText);
request.send(resp);
} else {
console.log('We reached our target server, but it returned an error');
}
};
request.onerror = function() {
console.log('There was a connection error of some sort');
};
});
}
formMailchimp();
});
Also, I anticipate the inevitable "why don't you just use jQuery" comment. Without going into the specifics of this project, jQuery is not something I am able to introduce into the code. Sorry, but this HAS to be vanilla javascript. Compatibility is for very modern browsers only.
Thanks so much for any help you can provide!

A few days back I've had the exact same problem and as it turns out the MailChimp documentation on native JavaScript is pretty sparse. I can share with you my code I came up with. Hope you can build from here!
The simplified HTML form: I've got the from action from the MailChimp form builder and added "post-json"
<div id="newsletter">
<form action="NAME.us1.list-manage.com/subscribe/post-json?u=XXXXXX&id=XXXXXXX">
<input class="email" type="email" value="Enter your email" required />
<input class="submit" type="submit" value="Subscribe" />
</form>
</div>
The JavaScript: The only way to avoid the cross-origin problem is to create a script and append it to the header. The callback occurs then on the ā€œcā€ parameter. (Please note there is no email address validation on it yet)
function newsletterSubmitted(event) {
event.preventDefault();
this._form = this.querySelector("form");
this._action = this._form.getAttribute("action");
this._input = this._form.querySelector("input.email").value;
document.MC_callback = function(response) {
if(response.result == "success") {
// show success meassage
} else {
// show error message
}
}
// generate script
this._script = document.createElement("script");
this._script.type = "text/javascript";
this._script.src = this._action + "&c=document.MC_callback&EMAIL=" + this._input;
// append script to head
document.getElementsByTagName("head")[0].appendChild(this._script);
}
var newsletter = document.querySelector("#newsletter")
newsletter.addEventListener("submit", newsletterSubmitted);

Related

execute code after typing indication over

i have problem figuring out a solution . i am developing a chatbot .
this is my html where i print all the discussion , its just one :
<div id="divChat"> </div>
i want to add typing indicator to it .here is how it works on each message:
1)User types his message (exemple : Hello), and click on a button
<button onclick="sendMessage()" id="btn1" > Send </button>
2) i read his message and i sent it to mybackend application to receive the response and print it in the chat element.
function sendMessage(){
var url = "http://localhost:3000/api/v1/bots/renault/converse/user1";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var reponseBot= JSON.parse(xhr.responseText);
if(reponseBot!='undefined'){
$("#divChat").append(reponseBot+"</br>");
}
}
}
};
var values = {
type: "text"
}
values.text=$("#userMessage").val();
var data= JSON.stringify(values);
xhr.send(data);
}
the chat works fine , now i want to add typing indicator which is this element (u dont need see css of it):
<div class="typing-indicator"></div>
i want When the user send his message i Append the typing indicator to the chat , show it for 2sec then hide it and append then response bot : like this
if (xhr.readyState === 4 && xhr.status === 200) {
var reponseBot= JSON.parse(xhr.responseText);
if(reponseBot!='undefined'){
$("#divChat").append("<div class='typing-indicator' ></div>");
/// I WANT TO HIDE IT AFTER 2SEC THEN APPEND THE USER RESPONSE
$("#divChat").append(reponseBot+"</br>");
}
}
Please any idea how to achieve this and thanks
You can use setTimeout to delay an action.
Also note that if you've already included jQuery in the page you may as well use its AJAX methods to simplify the code. Try this:
let $divChat = $('#divChat');
function sendMessage() {
$.post('http://localhost:3000/api/v1/bots/renault/converse/user1', {
type: 'text',
text: $('#userMessage').val()
}, function(response) {
$('#userMessage').val(''); // empty the typed message
let $indicator = $('<div class="typing-indicator"></div>').appendTo($divChat);
setTimeout(() => {
$indicator.remove();
$divChat.append(response + "</br>");
}, 2000);
});
};
Also note that from the response to your AJAX request it looks like you're returning a plain text response which is not ideal, as it can be affected by whitespace. I'd suggest you amend your server side logic to return a serialised format, such as JSON or XML.

how to ajax for chatting website without page reload

want to create a fully dynamic chat UI for my website, But it reloads the whole page if a person submits the button page should not reload like many chat website.
<form action="action.php" method="post" id="formpost">
<input type="text" id="input" value="php echo">
<input type="submit" value="send">
</form>
I want to submit this form through ajax and show the last xml <message> containing <message>talk 123<message>
<messages category="short">
<person1>
<time>
r
<message>Djssjs</message>
</time>
</person1>
<person2>
<time>
r
<message>1234fdg</message>
</time>
</person2>
<person1>
<time>
r
<message> talk 123</message>
</time>
</person1>
</messages>
i want to show that talk 123 in the html document bit confused how to do that
//for form submit
$("#formpost").submit(function(e) {
var form = $(this);
var url = form.attr('action');
$.ajax({
type: "POST",
url: action.php,
data: form.serialize(), // serializes the form's elements.
success: function(data)
{
alert(data); // show response from the php script.
}
});
e.preventDefault(); // avoid to execute the actual submit of the form.
});
//for xml
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this);
}
};
xhttp.open("GET", "name.xml", true);
xhttp.send();
}
function myFunction(xml) {
var xmlDoc = xml.responseXML;
var msg = "";
//how to select the last person's of the <messages> child
msg = getElementsByTagName("messages").lastChild.childNodes[1].nodeValue ;
document.getElementById("demo").innerHTML = msg;
}
$("#formpost").on('submit', function(event){
event.preventDefault();
// rest of your ajax code here...
});
Points to note
1. Make sure you have also added JQuery script source on the head tag of your chat page.
2. Make sure to put preventDefault() immediately before any other code is executed.
You can use reverse ajax method pulling data from the server.
In reverse ajax a request is auto-generated at a certain time interval or hold the request for fetching new message.
There are three technologies for reverse ajax:-
Piggyback
Polling
Comet

How to call existing REST api from a HTML form?

I have a REST API that I am using in a mobile application to register/store data into a Mongo database. I would now like to view the data stored in the DB on a webpage.
I know that I basically have all of the functionality already (the login request used in my mobile application) but I am so confused on how to call my REST from my HTML page.
Something like this: How to call a REST web service API from Javascript button Handler? ?
I am also confused on how/where I should be creating my html page. Any help is appreciated.
Thanks, Joe
Typically When user would like to get data from the server. client need to send a request to the server and get a response. Usually programmer will bind a request function with an specific element and events.
In this case you need to bind a request function with form element. As you didn't mention which event you want to happen, so I couldn't tell exactly solution.
The following code is a simple code that call REST API when user type on a text input, and show the result below the input text
Note that replace "URL" with your API call.
<!DOCTYPE html>
<html>
<body>
<form>
Keyword:<br>
<input type="text" name="keyword" onkeyup="callREST()"><br>
</form>
<div id="response"></div>
<script>
function callREST() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("response").innerHTML = this.responseText;
}
};
xhttp.open("GET", "URL", true);
xhttp.send();
}
</script>
</body>
</html>
This is how you do it...
HTML Code:
<form id="form" onsubmit="return setAction(this)">
<input name="senderEmail" type="email" placeholder="Email" required>
<textarea name="senderMessage" cols="30" rows="10" placeholder="Message.." required></textarea>
<button type="submit">Send message</button>
</form>
Javascript:
function setAction(form) {
const url = 'https://example.com/xyz?';
const andSign = '&';
const senderParameter = 'sender='+form.senderEmail.value;
const bodyParameter = 'body='+form.senderMessage.value;
const newUrl = url+senderParameter+andSign+bodyParameter;
fetch(
newUrl,
{
headers: { "Content-Type": "application/json" },
method: "POST",
body: ""
}
)
.then(data => data.json())
.then((json) => {
alert(JSON.stringify(json));
document.getElementById("form").reset();
});
return false;
}
This also resets your form after a successful api call is made.

Angularjs canceled a post and refresh the page without sense

I have an issue that appears recently (I don't know what was changed)when trying to upload a file to my server.
With all other GET and POST the site is working ok, but the issue is when I need to upload a file (for which I have an specific function).
My site is built with angularjs and Java Spring as backend.
Here you have the function that is use in the factory to upload a file:
var SaveMethod = function(params, callback){
var result = $q.defer();
var form = new FormData();
var xhr = new XMLHttpRequest;
// Additional POST variables required by the API script
form.append("file", params.files);
xhr.upload.onprogress = callback;
xhr.open('POST', SessionService.apiUrl + '/video/save');
xhr.setRequestHeader("Authorization", 'Bearer ' + SessionService.getToken());
xhr.timeout = result.promise;
xhr.onload = function(e) {
if (xhr.status == 200) {
result.resolve(e.target.response);
}
else {
result.reject(xhr.statusText);
}
};
xhr.send(form);
return result.promise;
};
And this is the controller:
$scope.upload = function(item) {
$scope.values.videosubmitted = true;
$scope.values.object.name = item.name.substr(0, item.name.lastIndexOf('.'));
$scope.values.uploading = true;
var params = {
files: item
};
VideoFactory.Save(params, callback).then(function(response){
response = JSON.parse(response);
$scope.values.uploading = false;
if (response.success) {
$scope.values.object.images = response.data.images;
$scope.values.object.code = response.data.code;
$scope.values.object.source = response.data.source;
$scope.values.object.preview = response.data.preview;
}
else
{
$scope.values.error = true;
$scope.values.errorMessage = response.code;
}
}, function(response){
if (response == null) {
$scope.values.error = true;
$scope.values.errorMessage = "ERROR__SERVER_NON_WORKING";
}
else
{
$scope.values.error = true;
$scope.values.errorMessage = response.code;
}
$scope.values.uploading = false;
});
}
And the view (just in case)
<div class="row" ng-show="!values.videosubmitted">
<div class="col-md-10 no-padding-right">
<div class="dropzone" id="dropbox" callback-fn="upload(video)" file-dropzone="[video/mp4, video/3gpp, video/quicktime, video/x-msvideo, video/x-ms-wmv]"
file="image" file-name="imageFileName" values-max-file-size="9000000000">
<span translate="MODULES.VIDEO.DROPVIDEO"></span>
</div>
</div>
<div class="col-md-2 upload-btn no-padding-left">
<label class="upload-search btn btn-primary no-padding">
<div>
<input type="file" onchange="angular.element(this).scope().upload(this.files[0])"/>
<i class="fa fa-upload"></i>
<span translate="COMMON.FILESEARCH"></span>
</div>
</label>
</div>
</div>
The thing is that after the file is sent to the server, it doesn't matter if I get a successful response from server or not, the page is reloaded and the request is canceled. In some cases, I get the successful response from the server but after that the page is reloaded, and in other cases the request is canceled and the page is refreshed.
I tried with the timeout but it doesn't work.
And this is how it looks like:
The issue was something related to CORS I guess..
The thing was that I was using two domains for the web development, localhost for regular use, and an specific domain for being recognize in social media pages to allow the login buttons.
So I discover that when I was using localhsot everything works ok, but when using the other domain it was not.
It was so weird because the backend responded correctly to the request.

AJAX file upload/form submit without jquery or iframes?

Is it possible to do an AJAX form submit without jQuery or IFrames (so just pure JavaScript)? I'm currently sending to a struts fileUploadAction that works. Would the action's code still work with the asynchronous submit, or are there additions required to pick up the async form submit?
I am using struts 1.x and current my form is:
<html:form action="fileUploadAction" method="post" enctype="multipart/form-data">
...form elements...
<html:file property="theFile" />
...other elements...
</html:form>
Can this form be submitted, and thus the file uploaded with AJAX?
If I understood you correct, you can use the following code to upload the file async. Modify it as you like
var AjaxFileUploader = function () {
this._file = null;
var self = this;
this.uploadFile = function (uploadUrl, file) {
var xhr = new XMLHttpRequest();
xhr.onprogress = function (e) {
...
};
xhr.onload = function (e) {
...
};
xhr.onerror = function (e) {
...
};
xhr.open("post", uploadUrl, true);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", file.name);
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("X-File-Type", file.type);
xhr.send(file);
};
};
AjaxFileUploader.IsAsyncFileUploadSupported = function () {
return typeof (new XMLHttpRequest().upload) !== 'undefined';
}
if (AjaxFileUploader.IsAsyncFileUploadSupported) {
ajaxFileUploader = new AjaxFileUploader();
$("form").submit(function () {
var uploader = $("#fileUploader")[0];
if (uploader.files.length == 0) {
return;
} else {
ajaxFileUploader.uploadFile(
"/YourUploadUrl",
uploader.files[0]);
}
return false;
});
}
To upload the form use the FormData class, populate it with form values and post it with XHR.
Update:
For HTML4 try the following
http://www.albanx.com/?pid=5&subid=21
Asynchronous file upload (AJAX file upload) using jsp and javascript
http://fineuploader.com/ is a ajax file-uploader.
This plugin uses XHR for uploading multiple files with progress-bar in FF3.6+, Safari4+, Chrome and falls back to hidden iframe based upload in other browsers, providing good user experience everywhere.
The up-to-date (march 2022), pure js solution, can be found in here. Summary:
You can use fetch optionally with await-try-catch
let photo = document.getElementById("image-file").files[0];
let formData = new FormData();
formData.append("photo", photo);
fetch('/upload/image', {method: "POST", body: formData});
No need to add jquery or any other third party library, just add IPerfect JS library and you are good to go.
IP_uploadFile(URL,responseType,this[object],[dynamicFunctionForResponse])
if user select responseType as 'html' then dynamicFunctionForResponse will get response in HTML format. In below example you will get 'done' response in alert.
HTML
<script type="text/javascript" src="http://services.iperfect.net/js/IP_generalLib.js"></script>
<script language='javascript'>
function testResponse(data){
alert(data)
}
</script>
Body
<form method="POST" enctype="multipart/form-data" onsubmit="IP_uploadFile('testupload.php','html',this,testResponse); return false;">
<input type="file" name="file1">
<input type="submit" name="submit1" value="Click here">
</form>
PHP: testupload.php
move_uploaded_file($_FILES['file1']['tmp_name'], realpath("./")."/upload/".$_FILES["file1"]["name"]);
echo "done";

Categories

Resources