I'm creating a login form with html,css and javascript.
I'm doing a POST to an API in order to receive some JSON with the identified username that I just submitted in the form.
If the email and password are correct, I receive the JSON with all the info from my API. The problem is that I don't know how to manipulate the info that I receive... I'd like to save the JSON I'm receiving through the POST to a variable and then be able to access the account type or the other properties of that object.
<form name="login" id="myForm" action="API_URL" method="post" class="form-signin">
<h3 class="form-signin-heading">Por favor inicie sesión</h3>
<label for="inputEmail" class="sr-only">E-mail</label>
<input type="email" name="email" class="form-control" placeholder="E-mail" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" name="password" class="form-control" placeholder="Contraseña" required>
<div class="checkbox">
<label>
<input type="checkbox" value="remember-me"> Recordarme
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" id type="submit">Iniciar sesión</button>
</form>
After hitting submit, I receive the JSON like this:
!(https://imgur.com/a/wbUcp)
This is my JQuery:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js%22%3E
$(document).ready(function() {
$('#myform').submit(function() {
$.ajax({
type: "POST",
url: '/form/',
data: {
email: $("#inputEmail").val(),
password: $("#inputPassword").val()
},
success: function(data)
{
if (data === 'Correct') {
var objeto = data.parse();
console.log(objeto);
}
else {
alert(data);
}
}
});
});
});
</script>
Can anyone please point me in the right direction?
If you are using Javascript try like this:
$.ajax({
type: "POST",
url: '/form/',
data: {
email: $("#inputEmail").val(),
password: $("#inputPassword").val()
},
success: function(response){
var data = response;
contactData = JSON.parse(data);
console.log("ID: " + contactData.id);
console.log("ID: " + contactData.user_type_id);
console.log("ID: " + contactData.first_name);
console.log("ID: " + contactData.last_name);
console.log("ID: " + contactData.email);
console.log("ID: " + contactData.password);
},
failure : function(data){
alert('Server Connection failed');
},
error : function(request,error){
alert(error);
}
});
You can get Json in array in php with
mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )
You are posting data and it will be received in string format.If you are only dealing with JSON then you can use JSON parser like this
let body = JSON.Parse(req.body);
Now body variable will contain an object and you can access properties easily.If you are using nodeJs on server side than body-parser middle ware can be used also.Let me know in comment if there is something contrary.
You need to invoke the call using JavaScript & AJAX.
Add an OnClick event listener to the submit button and call handleLoginClicked().
Collect all variable from the inputs and use ajax to post to the url.
Get back the response and parse the JSON, assign to a javascript variable.
You can use jQuery for example to do so: jQuery.Post
Related
I'm having trouble figuring out why my "Remove" button is not working as intended. I'm working on a webpage. Long story short, the main page contains a table whose rows are added via user input, some SQL database queries, and Flask. I want to be able to remove rows w/o refreshing the page, so I got some help constructing an AJAX call to do just that. This is the portion meant to handle that action:
$("#button").clicked(function() {
var rowsToRemove = [];
$(".checkitem:checked").each(function() {
var rowIndex = $(this).parent("tr").index(this);
rowsToRemove.push(rowIndex+1);
});
delete_ajax = $.ajax({
type : 'POST',
method: 'POST',
url : "/home",
data : JSON.stringify({rowsToRemove:rowsToRemove, typeofpost: 'delete'}),
dataType: "json",
contentType: "application/json"
});
delete_ajax.done(function(responseObject, textStatus, jqXHR) {
if(responseObject.status == 200) {
reloadTable();
}
});
delete_ajax.error(function() {
alert("Unable to delete row(s). Please try again.");
});
});
And here is the portion that I was assisted with from the Flask side that would distinguish between delete calls and posted data:
if request.json.get('type') == 'add':
if not request.form.get("password"):
return apology("'Password' field required. Please enter a symbol.", 403)
if not request.form.get("website"):
return apology("'Website' field required. Please enter a share.", 403)
password=request.form.get("password")
db.execute("INSERT INTO passwords (user_id, password, cipher, website) VALUES (:userID, :password, :cipher, :website)",
userID=session["user_id"],
password=password,
cipher=encrypt(password),
website=request.form.get("website"))
length = db.execute("SELECT COUNT(password) FROM passwords WHERE user_id = :userID", userID=session["user_id"])#.fetchone()[0]
db.execute("UPDATE passwords SET row_id = :rowID WHERE user_id = :userID AND password = :pw",
rowID=length[0]["COUNT(password)"],
userID=session["user_id"],
pw=password)
#return redirect("/home")
return {"status":200}
# from delete
if request.json.get('type') == 'delete':
length = db.execute("SELECT COUNT(password) FROM passwords WHERE user_id=:userID", userID=session["user_id"]).fetchone()[0]
index = list(range(1, length+1))
data_to_delete = request.json.get("data")
rowsToRemove = db.execute("DELETE FROM passwords WHERE row_id IN :data AND user_id:=userID", data=data_to_delete, userID=session["user_id"])
db.execute("UPDATE passwords SET row_id=:rowID WHERE user_id=:userID", rowID=index, userID=session["user_id"])
return {"status":200}
Just in case I need to fix something I overlooked on the HTML side, I'll that as well:
<div class="form-group container">
<table class="table table-hover thead-dark">
<thead>
<th><div class="checkbox">
<label><input type="checkbox" class="checkbox" id="checkall" name="checkall"> Select/Deselect All</label>
</div></th>
<th>Row</th>
<th>Password</th>
<th>Cipher</th>
<th>Website</th>
</thead>
<tbody>
{% for row in rows %}
<tr>
<td><div class="checkbox">
<input type="checkbox" class="checkitem">
</div></td>
<td>{{row["row_id"]}}</td>
<td>{{row["password"]}}</td>
<td>{{row["cipher"]}}</td>
<td>{{row["website"]}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="form-group form-inline container center row">
<form action="/home" method="/post">
<input class="form-control" autocomplete="off" name="password" placeholder="Password" type="text" required>
<input autocomplete="off" class="form-control" name="website" placeholder="Website" type="text" required>
<input class="btn btn-primary" type="submit" id="encrypt" value="Encrypt">
</form>
<button type="button" class="btn btn-outline-danger" style="margin: auto" id="button">Remove</button>
</div>
I have a habit of overlooking things, so if there's something I'm missing, please let me know a.s.a.p.
If you separate the function, it will be easy to debug. I gave an example here, I have a table called account. I made different functions to make the CRUD operations
from flask import Flask, jsonify, request, render_template
import sqlite3
app = Flask(__name__)
con = sqlite3.connect("sql.db", check_same_thread=False)
con.row_factory = sqlite3.Row
cur = con.cursor()
#app.route('/account', methods=['GET'])
def get_account():
args = []
where = ''
if request.args:
for i in request.args:
args.append(i + ' = "' + request.args[i]+'"')
where = ' WHERE '+' and '.join(args)
cur.execute('SELECT * FROM account{}'.format(where))
data = [dict(i) for i in cur.fetchall()]
return jsonify({'data':data})
#app.route('/account', methods=['POST'])
def post_account():
acc = request.form['acc']
cur.execute("INSERT INTO account (account) VALUES ('{}')".format(acc))
con.commit()
a = cur.lastrowid
cur.execute('SELECT * FROM account WHERE id = {}'.format(a))
data = cur.fetchone()
return jsonify(data)
#app.route('/account', methods=['PUT'])
def put_account():
data = request.form
cur.execute("UPDATE account set account = '{}' WHERE id = {}".format(data['acc'], data['id']))
con.commit()
cur.execute('SELECT * FROM account WHERE id = {}'.format(data['id']))
data = cur.fetchall()
return jsonify(data)
#app.route('/account', methods=['DELETE'])
def dalete_account():
data = request.form
cur.execute("DELETE from account WHERE id = {}".format(data['id']))
con.commit()
return jsonify({'status': 'Deleted Successfully', 'deleted_id': data['id']})
Table Schema
CREATE TABLE IF NOT EXISTS account(
id integer PRIMARY KEY,
account text)
And the AJAX,
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<marquee behavior="" direction="">Press F12 and See the console.</marquee>
ID: <input type="number" id="id" ><br>
Acc: <input type="text" id="acc"><br>
<button onclick="post()">Post: Add Acc and Submit</button>
<button onclick="put()">Put: Add ID and acc and Submit</button>
<button onclick="del()">Delete: Add ID and Submit</button>
<div id="result"></div>
<script>
function post() {
dic = {'acc': document.getElementById('acc').value}
$.ajax({
type: "POST",
url: '/account',
data: dic,
success: function(data){
console.log(data)
$('input').val('')
}
})
}
function put() {
dic = {'id': document.getElementById('id').value, 'acc': document.getElementById('acc').value}
$.ajax({
type: "PUT",
url: '/account',
data: dic,
success: function(data){
console.log(data)
$('input').val('')
}
})
}
function del() {
dic = {'id': document.getElementById('id').value}
$.ajax({
type: "DELETE",
url: '/account',
data: dic,
success: function(data){
console.log(data)
$('input').val('')
}
})
}
</script>
</body>
</html>
You may need to add few things to AJAX, and it is already there in your code,
contentType (default: 'application/x-www-form-urlencoded; charset=UTF-8')
Type: Boolean or String
When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent).
dataType (default: Intelligent Guess (xml, json, script, or html))
Type: String
A function to be used to handle the raw response data of XMLHttpRequest. This is a pre-filtering function to sanitize the response. You should return the sanitized data. The function accepts two arguments: The raw data returned from the server and the 'dataType' parameter.
I have created a very simple html page with 2 inputs and a button (username, password and log in/submit). When I press submit, the username and password is converted into JSON, and sent as the body of a POST request to a private API which I have no control over. The API should then respond with another JSON containing a JWT access token. I then need to put this token into the request header of a GET request (Bearer token), but I haven't gotten this far yet, hence why I'm here.
I have tested the API with Postman, and it is working perfectly as expected. I am now trying to do what Postman does, only in my own small web application.
The JSON I need to send is like this:
{"username": "someUsername", "password": "somePassword"}
And the response is like this:
{"access_token": "A very long random string"}
Here is my code so far:
HTML:
<link href="/resources/css/bootstrap.min.css" rel="stylesheet">
<script src="apirequest.js"></script>
<div class="container">
<form class="form-signin">
<h2 class="form-heading">Send POST request</h2>
<div class="form-group">
<input type="text" id="username" class="form-control" placeholder="Username" autofocus />
<input type="password" id="password" class="form-control" placeholder="Password" />
<button class="btn btn-lg btn-primary btn-block" type="submit" onclick="getToken()">Log in</button>
</div>
</form>
</div>
apirequest.js this URL is not the real one
alert("script loaded");
var token_;
function getToken() {
alert("button pressed");
var request = new XMLHttpRequest();
var key;
var username_ = document.getElementById("username").val();
var password_ = document.getElementById("password").val();
request.open("POST", "https://api.dummyurl.test", true);
request.setRequestHeader("Content-type", "application/json");
request.send(JSON.stringify({
username: username_,
password: password_
}));
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
var response = request.responseText;
var obj = JSON.parse(response);
key = obj.access_token; // store the value of the accesstoken
token_ = key; // store token in global variable "token_"
alert(token_); //test if token is stored
}
}
}
I have put some alerts in there just to test things; I get "script loaded" and "button pressed", but not the alert with the token.
I have also tried with AJAX/jQuery to no avail, also no alert pop up:
<script type="text/javascript">
$(document).ready(function() {
$(".btn").click(function() {
alert("Script loaded");
const Data = {
"username" : document.getElementById("username").val(),
"password" : document.getElementById("password").val()
}
$.ajax({
url : "https://api.dummyurl.test",
type : "POST",
data : Data,
contentType : "application/json; charset=utf-8",
dataType : "json",
success : function(result) {
alert(result)
console.log(result)
},
error : function(error) {
console.log(error)
}
})
})
})
</script>
I load the page and get "script loaded", then I enter a valid username and password, then I get "button pressed". The page just refreshes and I get "script loaded" again with the last username already typed in. None of the questions I've read have had an answer that works for me. Do you see any problems with my code? Also, as a last note; I'd like to use the first script example as that one is much easier to understand and work with for me.
Update
So, it's kind of working. I didn't know Postman generated code I could copy. As mentioned, I have tested the API with Postman and it works. Here's what the script looks like now:
$(document).ready(function() {
var settings = {
"async" : true,
"crossDomain" : true,
"url" : "https://api.dummyurl.test",
"method" : "POST",
"headers" : {
"Content-Type" : "application/json",
"cache-control" : "no-cache"
},
"processData" : false,
"data" : "{ \r\n\"Username\":\"someUsername\",\r\n\"Password\":\"somePassword\"\r\n}"
}
$.ajax(settings).done(function(response) {
console.log(response);
});
})
I actually got the access token from this. The problem now is that username and password is hardcoded (not from html input) and that the script runs as soon as the page is loaded. Any ideas how I can make the script run only after I press the button? And how I can replace the hardcoded username and password with the values from the input fields? Postman generated code with so many \ and ", can I still use variables and not strings inside that line of code?
I just tried reformatting the data to {"Username":"someUsername","Password":"somePassword"} and it wouldn't work that way, so I guess the \r\n is necessary?
Your forgot the method on your form element, While serialize method will get form values, try to set your form like this:
<form class="form-signin" method="post">
<h2 class="form-heading">Send POST request</h2>
<div class="form-group">
<input type="text" id="username" class="form-control" placeholder="Username" autofocus />
<input type="password" id="password" class="form-control" placeholder="Password" />
<button class="btn btn-lg btn-primary btn-block" type="submit" onclick="return getToken(this.form)">Log in</button>
</div>
</form>
<script type="text/javascript">
$(document).ready(function() {
function getToken(form){
var formData = $(form).serialize();
$.post("https://api.dummyurl.test", formData).done(function(result){
alert(result);
console.log(result)
})
return true;
}
})
</script>
I want to use Acymailing Joomla! component installed at example.com/mailer to manage subscriptions from non Joomla site on example.com
In that case I have simple script
$(function () {
$('form').on('submit', function (e) {
e.preventDefault();
$.ajax({
type: 'post',
url: 'https://example.com/mailer/index.php?option=com_acymailing&ctrl=sub',
data: $('form').serialize(),
success: function () {
swal('Great success!');
}
});
});
});
and form
<form class="form-inline" action="https://example.com/mailer/index.php?option=com_acymailing&ctrl=sub" method="post">
<div class="form-group">
<label class="sr-only" for="user_name">Email address</label>
<input id="user_name" type="text" name="user[name]" value="" class="form-control" placeholder="Email">
</div>
<div class="form-group">
<label class="sr-only" for="user_email">Password</label>
<input id="user_email" type="text" name="user[email]" value="" class="form-control" placeholder="Password">
</div>
<button type="submit" class="btn btn-default">Sign Up!</button>
<input type="hidden" name="user[html]" value="1" />
<input type="hidden" name="acyformname" value="formAcymailing1" />
<input type="hidden" name="ctrl" value="sub"/>
<input type="hidden" name="task" value="optin"/>
<input type="hidden" name="redirect" value="https://example.com"/>
<input type="hidden" name="option" value="com_acymailing"/>
<input type="hidden" name="visiblelists" value=""/>
<input type="hidden" name="hiddenlists" value="1"/>
</form>
Everything works fine except success, error states...
Joomla Acymailing have sub.php file to handle ajax responses
if($config->get('subscription_message',1) || $ajax){
if($allowSubscriptionModifications){
if($statusAdd == 2){
if($userClass->confirmationSentSuccess){
$msg = 'CONFIRMATION_SENT';
$code = 2;
$msgtype = 'success';
}else{
$msg = $userClass->confirmationSentError;
$code = 7;
$msgtype = 'error';
}
}else{
if($insertMessage){
$msg = 'SUBSCRIPTION_OK';
$code = 3;
$msgtype = 'success';
}elseif($updateMessage){
$msg = 'SUBSCRIPTION_UPDATED_OK';
$code = 4;
$msgtype = 'success';
}else{
$msg = 'ALREADY_SUBSCRIBED';
$code = 5;
$msgtype = 'success';
}
}
}else{
if($modifySubscriptionSuccess){
$msg = 'IDENTIFICATION_SENT';
$code = 6;
$msgtype = 'warning';
}else{
$msg = $modifySubscriptionError;
$code = 8;
$msgtype = 'error';
}
}
if($msg == strtoupper($msg)){
$source = acymailing_getVar('cmd', 'acy_source');
if(strpos($source, 'module_') !== false){
$moduleId = '_'.strtoupper($source);
if(acymailing_translation($msg.$moduleId) != $msg.$moduleId) $msg = $msg.$moduleId;
}
$msg = acymailing_translation($msg);
}
$replace = array();
$replace['{list:name}'] = '';
foreach($myuser as $oneProp => $oneVal){
$replace['{user:'.$oneProp.'}'] = $oneVal;
}
$msg = str_replace(array_keys($replace),$replace,$msg);
if($config->get('redirect_tags', 0) == 1) $redirectUrl = str_replace(array_keys($replace),$replace,$redirectUrl);
if($ajax){
$msg = str_replace(array("\n","\r",'"','\\'),array(' ',' ',"'",'\\\\'),$msg);
echo '{"message":"'.$msg.'","type":"'.($msgtype == 'warning' ? 'success' : $msgtype).'","code":"'.$code.'"}';
}elseif(empty($redirectUrl)){
acymailing_enqueueMessage($msg,$msgtype == 'success' ? 'info' : $msgtype);
}else{
if(strlen($msg)>0){
if($msgtype == 'success') acymailing_enqueueMessage($msg);
elseif($msgtype == 'warning') acymailing_enqueueMessage($msg,'notice');
else acymailing_enqueueMessage($msg,'error');
}
}
}
And JSON looks like on Joomla side registration to the same form by index.php?option=com_acymailing&ctrl=sub
message Subscribe confirmed
type success
code 3
{"message":"Subscribe confirmed","type":"success","code":"3"}
The question is: how to obtain that submission statuses success, error, already submbited etc on external submission form (at example.com page)?
this simple change may do it for you:
$(function () {
$('form').on('submit', function (e) {
e.preventDefault();
$.ajax({
type: 'post',
url: 'https://example.com/mailer/index.php?option=com_acymailing&ctrl=sub',
data: $('form').serialize()
}
}).done(function (data) {
swal('Great success!');
});
});
});
I personally like:
$.post("https://example.com...", {
data: $('form').serialize()
}, function(data) {
swal('Great success!');
});
since your result is in JSON, that should be more like:
$.post("https://example.com...", {
data: $('form').serialize()
}, function(data) {
console.log(data); // shows full return object in console
swal('Great success!');
}, "json");
Try the following, I have explained the changes inside comments:
$(function () {
$('form').on('submit', function (e) {
e.preventDefault();
var formdata = $(this).serializeArray(); //i really prefer serializeArray better than serialize (up2u)
$.ajax({
type: 'post',
dataType: 'json', //because your data is json
url: 'https://example.com/mailer/index.php?option=com_acymailing&ctrl=sub',
data: formdata,
success: function (d) {//d is the return/response of your url (your question answer)
swal(
d.type+': '+d.code ,
d.message,
d.type
);
},
error: function(d){
swal(
'Oops..' ,
'Something went wrong!', //your json must be in trouble
'error'
);
console.log(d); //delete this in production stage
console.log(d.responseText); //i add this so you will know what happenned exactly when you get this error. delete this too in production stage
}
});
});
});
I don't feel your ajax had issues, what i can see from the Joomla php code, everytime when you request that joomla URL you will always get a response header status code as 200, so your javascript will always land on success block of ajax code, returning with some json based message, when i checked the joomla acymaling (version 5.8.1 for joomla 3.8.3) code for that controller, i saw on line number 74 they are checking if the request is made using ajax, but missing Access-Control-Allow-Origin in php header which will restrict your outside call so you can replace this if condition from :
if($ajax){
#ob_end_clean();
header("Content-type:text/html; charset=utf-8");
}
to
if($ajax){
#ob_end_clean();
header("Content-type:text/html; charset=utf-8");
header("Access-Control-Allow-Origin: *");
}
so to allow calls from any other domain as well, but do remember this can also cause vulnerabilities to you joomla code. also you need to change your HTML form as well add one more hidden field in your HTML :
<input type="hidden" name="ajax" value="1" />
so to allow ajax request by your joomla controller file.
now in your success block of ajax you can make a check something like this :
success:function(data, status, xhr){
var json = $.parseJSON(data);
swal(json.message, json.type);
}
I hope this will help you in acomplishing what you want to, Happy coding.
I also face this type of problem.for solving this type of problem i Put a variable in the success as argument html.
e.g. success(html)
and
console.log(html)
this shows all errors including notices and all. turn on errore_reporting['E_ALL'];. and do not set dataType to 'json' .
Simple solution to your question is :
success: function (data) {
$("#<id_of_tag>").html(data);
}
data : Response returned from the server to your AJAX call
id_of_tag : where you want to display your returned output.
Its just an example, you can decide, what kind of data you want to return and what you want to do with your response.
To answer your question: On Success parameter in function will contain your response.
As in my case, i am returning another JSP page, which i want to display in div tag.
Also check below link : I think it might help you
Best way to check if AJAX request was successful in jQuery
I followed a tutorial to adapt the code. Here I am trying trying to auto-populate my form fields with AJAX when an 'ID' value is provided. I am new to Jquery and can't get to work this code.
Edit 1 : While testing the code, Jquery isn't preventing the form to submit and sending the AJAX request.
HTML form
<form id="form-ajax" action="form-ajax.php">
<label>ID:</label><input type="text" name="ID" /><br />
<label>Name:</label><input type="text" name="Name" /><br />
<label>Address:</label><input type="text" name="Address" /><br />
<label>Phone:</label><input type="text" name="Phone" /><br />
<label>Email:</label><input type="email" name="Email" /><br />
<input type="submit" value="fill from db" />
</form>
I tried changing Jquery code but still I couldn't get it to work. I think Jquery is creating a problem here. But I am unable to find the error or buggy code. Please it would be be very helpful if you put me in right direction.
Edit 2 : I tried using
return false;
instead of
event.preventDefault();
to prevent the form from submitting but still it isn't working. Any idea what I am doing wrong here ?
Jquery
jQuery(function($) {
// hook the submit action on the form
$("#form-ajax").submit(function(event) {
// stop the form submitting
event.preventDefault();
// grab the ID and send AJAX request if not (empty / only whitespace)
var IDval = this.elements.ID.value;
if (/\S/.test(IDval)) {
// using the ajax() method directly
$.ajax({
type : "GET",
url : ajax.php,
cache : false,
dataType : "json",
data : { ID : IDval },
success : process_response,
error: function(xhr) { alert("AJAX request failed: " + xhr.status); }
});
}
else {
alert("No ID supplied");
}
};
function process_response(response) {
var frm = $("#form-ajax");
var i;
console.dir(response); // for debug
for (i in response) {
frm.find('[name="' + i + '"]').val(response[i]);
}
}
});
Ajax.php
if (isset($_GET['action'])) {
if ($_GET['action'] == 'fetch') {
// tell the browser what's coming
header('Content-type: application/json');
// open database connection
$db = new PDO('mysql:dbname=test;host:localhost;', 'xyz', 'xyz');
// use prepared statements!
$query = $db->prepare('select * from form_ajax where ID = ?');
$query->execute(array($_GET['ID']));
$row = $query->fetch(PDO::FETCH_OBJ);
// send the data encoded as JSON
echo json_encode($row);
exit;
}
}
I don't see where you're parsing your json response into a javascript object (hash). This jQuery method should help. It also looks like you're not posting your form using jquery, but rather trying to make a get request. To properly submit the form using jquery, use something like this:
$.post( "form-ajax.php", $( "#form-ajax" ).serialize() );
Also, have you tried adding id attributes to your form elements?
<input type="text" id="name" name="name"/>
It would be easier to later reach them with
var element = $('#'+element_id);
If this is not a solution, can you post the json that is coming back from your request?
Replace the submit input with button:
<button type="button" id="submit">
Note the type="button".
It's mandatory to prevent form submition
Javascript:
$(document).ready(function() {
$("#submit").on("click", function(e) {
$.ajax({type:"get",
url: "ajax.php",
data: $("#form-ajax").serialize(),
dataType: "json",
success: process_response,
error: function(xhr) { alert("AJAX request failed: " + xhr.status); }
});
});
});
Is there any way to integrate mailchimp simple (one email input) with AJAX, so there is no page refresh and no redirection to default mailchimp page.
This solution doesn't work jQuery Ajax POST not working with MailChimp
Thanks
You don't need an API key, all you have to do is plop the standard mailchimp generated form into your code ( customize the look as needed ) and in the forms "action" attribute change post?u= to post-json?u= and then at the end of the forms action append &c=? to get around any cross domain issue. Also it's important to note that when you submit the form you must use GET rather than POST.
Your form tag will look something like this by default:
<form action="http://xxxxx.us#.list-manage1.com/subscribe/post?u=xxxxx&id=xxxx" method="post" ... >
change it to look something like this
<form action="http://xxxxx.us#.list-manage1.com/subscribe/post-json?u=xxxxx&id=xxxx&c=?" method="get" ... >
Mail Chimp will return a json object containing 2 values: 'result' - this will indicate if the request was successful or not ( I've only ever seen 2 values, "error" and "success" ) and 'msg' - a message describing the result.
I submit my forms with this bit of jQuery:
$(document).ready( function () {
// I only have one form on the page but you can be more specific if need be.
var $form = $('form');
if ( $form.length > 0 ) {
$('form input[type="submit"]').bind('click', function ( event ) {
if ( event ) event.preventDefault();
// validate_input() is a validation function I wrote, you'll have to substitute this with your own.
if ( validate_input($form) ) { register($form); }
});
}
});
function register($form) {
$.ajax({
type: $form.attr('method'),
url: $form.attr('action'),
data: $form.serialize(),
cache : false,
dataType : 'json',
contentType: "application/json; charset=utf-8",
error : function(err) { alert("Could not connect to the registration server. Please try again later."); },
success : function(data) {
if (data.result != "success") {
// Something went wrong, do something to notify the user. maybe alert(data.msg);
} else {
// It worked, carry on...
}
}
});
}
Based on gbinflames' answer, I kept the POST and URL, so that the form would continue to work for those with JS off.
<form class="myform" action="http://XXXXXXXXXlist-manage2.com/subscribe/post" method="POST">
<input type="hidden" name="u" value="XXXXXXXXXXXXXXXX">
<input type="hidden" name="id" value="XXXXXXXXX">
<input class="input" type="text" value="" name="MERGE1" placeholder="First Name" required>
<input type="submit" value="Send" name="submit" id="mc-embedded-subscribe">
</form>
Then, using jQuery's .submit() changed the type, and URL to handle JSON repsonses.
$('.myform').submit(function(e) {
var $this = $(this);
$.ajax({
type: "GET", // GET & url for json slightly different
url: "http://XXXXXXXX.list-manage2.com/subscribe/post-json?c=?",
data: $this.serialize(),
dataType : 'json',
contentType: "application/json; charset=utf-8",
error : function(err) { alert("Could not connect to the registration server."); },
success : function(data) {
if (data.result != "success") {
// Something went wrong, parse data.msg string and display message
} else {
// It worked, so hide form and display thank-you message.
}
}
});
return false;
});
You should use the server-side code in order to secure your MailChimp account.
The following is an updated version of this answer which uses PHP:
The PHP files are "secured" on the server where the user never sees them yet the jQuery can still access & use.
1) Download the PHP 5 jQuery example here...
http://apidocs.mailchimp.com/downloads/mcapi-simple-subscribe-jquery.zip
If you only have PHP 4, simply download version 1.2 of the MCAPI and replace the corresponding MCAPI.class.php file above.
http://apidocs.mailchimp.com/downloads/mailchimp-api-class-1-2.zip
2) Follow the directions in the Readme file by adding your API key and List ID to the store-address.php file at the proper locations.
3) You may also want to gather your users' name and/or other information. You have to add an array to the store-address.php file using the corresponding Merge Variables.
Here is what my store-address.php file looks like where I also gather the first name, last name, and email type:
<?php
function storeAddress(){
require_once('MCAPI.class.php'); // same directory as store-address.php
// grab an API Key from http://admin.mailchimp.com/account/api/
$api = new MCAPI('123456789-us2');
$merge_vars = Array(
'EMAIL' => $_GET['email'],
'FNAME' => $_GET['fname'],
'LNAME' => $_GET['lname']
);
// grab your List's Unique Id by going to http://admin.mailchimp.com/lists/
// Click the "settings" link for the list - the Unique Id is at the bottom of that page.
$list_id = "123456a";
if($api->listSubscribe($list_id, $_GET['email'], $merge_vars , $_GET['emailtype']) === true) {
// It worked!
return 'Success! Check your inbox or spam folder for a message containing a confirmation link.';
}else{
// An error ocurred, return error message
return '<b>Error:</b> ' . $api->errorMessage;
}
}
// If being called via ajax, autorun the function
if($_GET['ajax']){ echo storeAddress(); }
?>
4) Create your HTML/CSS/jQuery form. It is not required to be on a PHP page.
Here is something like what my index.html file looks like:
<form id="signup" action="index.html" method="get">
<input type="hidden" name="ajax" value="true" />
First Name: <input type="text" name="fname" id="fname" />
Last Name: <input type="text" name="lname" id="lname" />
email Address (required): <input type="email" name="email" id="email" />
HTML: <input type="radio" name="emailtype" value="html" checked="checked" />
Text: <input type="radio" name="emailtype" value="text" />
<input type="submit" id="SendButton" name="submit" value="Submit" />
</form>
<div id="message"></div>
<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#signup').submit(function() {
$("#message").html("<span class='error'>Adding your email address...</span>");
$.ajax({
url: 'inc/store-address.php', // proper url to your "store-address.php" file
data: $('#signup').serialize(),
success: function(msg) {
$('#message').html(msg);
}
});
return false;
});
});
</script>
Required pieces...
index.html constructed as above or similar. With jQuery, the appearance and options are endless.
store-address.php file downloaded as part of PHP examples on Mailchimp site and modified with your API KEY and LIST ID. You need to add your other optional fields to the array.
MCAPI.class.php file downloaded from Mailchimp site (version 1.3 for PHP 5 or version 1.2 for PHP 4). Place it in the same directory as your store-address.php or you must update the url path within store-address.php so it can find it.
For anyone looking for a solution on a modern stack:
import jsonp from 'jsonp';
import queryString from 'query-string';
// formData being an object with your form data like:
// { EMAIL: 'emailofyouruser#gmail.com' }
jsonp(`//YOURMAILCHIMP.us10.list-manage.com/subscribe/post-json?u=YOURMAILCHIMPU&${queryString.stringify(formData)}`, { param: 'c' }, (err, data) => {
console.log(err);
console.log(data);
});
Based on gbinflames' answer, this is what worked for me:
Generate a simple mailchimp list sign up form , copy the action URL and method (post) to your custom form. Also rename your form field names to all capital ( name='EMAIL' as in original mailchimp code, EMAIL,FNAME,LNAME,... ), then use this:
$form=$('#your-subscribe-form'); // use any lookup method at your convenience
$.ajax({
type: $form.attr('method'),
url: $form.attr('action').replace('/post?', '/post-json?').concat('&c=?'),
data: $form.serialize(),
timeout: 5000, // Set timeout value, 5 seconds
cache : false,
dataType : 'jsonp',
contentType: "application/json; charset=utf-8",
error : function(err) { // put user friendly connection error message },
success : function(data) {
if (data.result != "success") {
// mailchimp returned error, check data.msg
} else {
// It worked, carry on...
}
}
As for this date (February 2017), it seems that mailchimp has integrated something similar to what gbinflames suggests into their own javascript generated form.
You don't need any further intervention now as mailchimp will convert the form to an ajax submitted one when javascript is enabled.
All you need to do now is just paste the generated form from the embed menu into your html page and NOT modify or add any other code.
This simply works. Thanks MailChimp!
Use jquery.ajaxchimp plugin to achieve that. It's dead easy!
<form method="post" action="YOUR_SUBSCRIBE_URL_HERE">
<input type="text" name="EMAIL" placeholder="e-mail address" />
<input type="submit" name="subscribe" value="subscribe!" />
<p class="result"></p>
</form>
JavaScript:
$(function() {
$('form').ajaxChimp({
callback: function(response) {
$('form .result').text(response.msg);
}
});
})
This Github code works perfectly for me. This has a detailed explanation of how to use it. I use it on my WP site. Here is the link -
https://gist.github.com/DmitriyRF/34f659dbbc02637cf7465e2efdd37ef5
In the other hand, there is some packages in AngularJS which are helpful (in AJAX WEB):
https://github.com/cgarnier/angular-mailchimp-subscribe
I wasn't able to get this working with fetch so had to combine a few answers here using GET and parsing form inputs into the query string for the URL. It also wasn't necessary for the name of the input to be EMAIL but I guess it makes it more legible and doesn't break the code (in this simple case. Play around if you have other form fields).
Here's my code;
<form action="https://me.usxx.list-manage.com/subscribe/post-json?" id="signup" method="GET">
<input type="hidden" name="u" value="xxxxxxxxxxxxxxxxxx"/>
<input type="hidden" name="id" value="xxxxxxxxx"/>
<input type="hidden" name="c" value="?"/>
<input name="EMAIL" type="text" />
</form>
// Form submission handler
const formData = new FormData(signup);
fetch(signup.action + new URLSearchParams(formData).toString(), {
mode: 'no-cors',
method: signup.method,
})
.then((res) => {
// Success
})
.catch((e) => {
// Error
})
You could make it no-js friendly with...
<form action="https://me.usxx.list-manage.com/subscribe/post" id="signup">
fetch(signup.action + '-json?' + new URLSearchParams(formData).toString(), {
And just to save those who fumbled around as I did needlessly, you must create a signup form for an Audience within Mailchimp and by visiting that page you can get your u value and id as well as the action. Maybe this was just me but I thought that wasn't explicitly clear.