I am trying to convert a filled in form in the HTML to a JSON request that can then be send to the server over HTTP POST. Although the form is filled, all that i see in the JSON request is an empty JSON array..
JS Snippet is given below
$("#submitSurveyBtn").on("click", function (event) {
event.preventDefault();
var formData = JSON.stringify($("#surveyForm").serializeArray());
console.log(formData);
$.ajax({
type: "POST",
url: "/api/friends",
data: formData,
dataType: "json"
}).then(function (res) {
console.log(res)
});
});
HTML snippet is given below
<form id="surveyForm">
<div class="form-group">
<label for="nameInput">Name(Required)</label>
<input id="name" type="text" class="form-control" id="nameInput" placeholder="name">
</div>
<div class="form-group">
<label for="imgInput">Link to Photo Image (Required)</label>
<input id="imgURL" type="text" class="form-control" id="imgInput" placeholder="http://...">
</div>
codepen - https://codepen.io/rajdhandus/pen/pKWLzR
Your form HTML:
<input id="name" type="text" class="form-control" id="nameInput" placeholder="name">
....
<input id="imgURL" type="text" class="form-control" id="imgInput" placeholder="http://...">
You don't have name of your input so it can not be serialised as it is invalid
change to:
<input id="name" name="name" type="text" class="form-control" id="nameInput" placeholder="name">
...
<input id="imgURL" name="imgURL" type="text" class="form-control" id="imgInput" placeholder="http://...">
That's the main problem you have!
I would prefer to use the following construction, but it's up to you:
$("#surveyForm").on("submit", function (e) {
e.preventDefault();
var formData = $(this).serialize();
// ...
});
Related
What I want to achieve is: Getting the form validation information from server using an ajax call and show the errors/invalid feedback inside .invalid-feedback with :invalid css applied to the input fields.
<form id="register-form" novalidate>
<div class="form-group">
<label class="sr-only" for="first_name">first name</label>
<input type="text" id="first_name" name="first_name" value="" class="form-control" >
<div class="invalid-feedback"></div>
</div>
....other inputs
</form>
I was able to set the error messages inside the related invalid-feedback using:
$.ajax({
url: actionUrl,
method: "POST",
dataType: "json",
timeout: 5000,
data: form.serialize(),
success: function (response) {
if(response.errors === ''){
pageRedirect("register/login");
} else {
$.each(response.errors, function(field, error) {
form.find('[name="' + field + '"]').siblings('.invalid-feedback').text(error);
});
//feedback is set now how to show them??
}
},
As documented on Bootstrap's Forms documentation here:
Server side
We recommend using client side validation, but in case you require server side, you can indicate invalid and valid form fields with .is-invalid and .is-valid. Note that .invalid-feedback is also supported with these classes.
In short, you need to add the CSS class is-invalid to form controls that have validation errors. When you do this:
the form control will be surrounded with a red-outline to indicate that it has a validation error
sibling divs with the invalid-feedback CSS class will be rendered as red text
Here's a code snippet illustrating this in action with a "mock" response. Try click the Validate button:
var form = $("form").first();
$("#validate").click(function() {
var mockResponse = {
errors :
{
'first_name': 'First name must not be blank',
'last_name': 'Last name must not be blank'
}
};
$.each(mockResponse.errors, function(fieldName, error) {
let field = form.find('[name="' + fieldName + '"]');
field.addClass("is-invalid");
let immediateSibling = field.next();
if (immediateSibling.hasClass('invalid-feedback')) {
immediateSibling.text(error);
} else {
field.after("<div class='invalid-feedback'>" + error + "</div>")
}
});
return false;
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body class="bg-light">
<div class="container">
<form id="register-form" novalidate>
<div class="form-group">
<label class="sr-only" for="first_name">First Name</label>
<input type="text" id="first_name" name="first_name" value="" placeholder="First Name" class="form-control" >
</div>
<div class="form-group">
<label class="sr-only" for="last_name">Last Name</label>
<input type="text" id="last_name" name="last_name" value="" placeholder="Last Name" class="form-control" >
</div>
<div class="form-group">
<label class="sr-only" for="email">Email Name</label>
<input type="text" id="email" name="email" value="" placeholder="Email" class="form-control" >
</div>
<button id="validate" class="btn btn-primary btn-lg btn-block" type="submit">Validate</button>
</form>
</div>
https://getbootstrap.com/docs/4.5/components/forms/#custom-styles
As you can see, the script shown there doesn't use AJAX at all. Form validation on the client side is done entirely on the client side.
Because my the totality of my page is a basic "name and email" registration form, I don't see why I can't do a good ole-fashioned
<form action="/Account/Register/" method="POST" id="registration-form">
<fieldset class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" name="pname" id="name" placeholder="Example input">
</fieldset>
<fieldset class="form-group">
<label for="email">Email Address</label>
<input type="text" class="form-control" name="eaddr" id="email" placeholder="Another input">
</fieldset>
<button class="btn btn-primary" type="submit">Take Survey</button>
</form>
It seems like the definition of overengineering to do
$.ajax({
url : '/Account/Register',
method : 'POST',
data : { pname : $('input[name="pname"]').val(),
eaddr : $('input[name="eaddr"]').val() },
});
After all, that's what a form is for in the first place!
But I do want one thing from the submission of the form and that is success and error callbacks. Is there any way to submit that form in an HTML manner and still hook up callbacks? If so, how?
Use $.submit(), this is the way you can do it with jQuery. As the other commenters wrote, you either post & refresh the page or use ajax:
$("#registration-form").submit(function(){
$.ajax({
url : '/Account/Register',
method : 'POST',
data : { pname : $('input[name="pname"]').val(),
eaddr : $('input[name="eaddr"]').val() },
success: function(data) {},
error: function() {}
});
return false;
});
I have a form as follows:
<form name="signupForm" id="signupForm" method="POST" ng-submit="create()">
<input type="hidden" name="username" id="username" value="mtest">
<input type="text" placeholder="Account name" name="webid" ng-model="account.webid" ng-focus="isFocused" ng-blur="isFocused = false"><br>
<input type="text" placeholder="Full name" name="name" ng-model="account.name"><br>
<input type="text" placeholder="Email" name="email" ng-model="email"><br>
<input type="text" placeholder="Picture URL" name="pictureURL" ng-model="account.pictureURL"><br>
<keygen id="spkac" name="spkac" challenge="randomchars" keytype="rsa" form="signupForm" hidden>
<br>
<input type="submit" id="submit" value="Submit">
</form>
The data is passed to the POST as follows:
$http({
method: 'POST',
url: uri,
data: $("#signupForm").serialize(),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/x-x509-user-cert'
},
withCredentials: true
}).
Once I submit the form to send it with a POST http request, I get the $("#signupForm").serialize() as follows:
"username=mtest&webid=mtest.databox.me%2Fprofile%2Fcard%23me&name=M+Test&email=mtest%40test.com&pictureURL=picURL&spkac="
Why is the keygen element always empty? Is there anything wrong I am doing?
Any answer is appreciated, thanks in advance.
Solved!
So preparing an HTTP Request to do that doesn't work for some reason. Instead the form action needs to be set and form submitted straight away in order to send the keygen with it. Here the solution:
in the Template the action is parametrical:
<form name="signupForm" id="signupForm" method="POST" action="{{actionUrl}}">
...
<input type="submit" id="btnSubmit" value="Submit" ng-click="completeForm()">
and the Controller sets the action and submits the form as follows:
$scope.completeForm = function () {
$scope.actionUrl = "https://" + document.getElementById("username").value + "...";
document.getElementById("signupForm").submit();
};
I have two forms, one for uploading a file and another for filling the form with information. I need to upload the file without refreshing the page first and then submit the form using ajax. And here are the codes:
form_file
<h1>Insert Employee</h1>
<form id="form">
<input id="name" placeholder="arabic name.." type="text" name="name_ar"/><br>
<input id="name" placeholder="english name.." type="text" name="name_en" value=""/><br>
<input id="name" placeholder="arabic department.." type="text" name="dep_ar" /><br>
<input id="name" placeholder="english department.." type="text" name="dep_en" /><br>
<input id="name" placeholder="arabic job.." type="text" name="job_ar"/><br>
<input id="name" placeholder="english job.." type="text" name="job_en" /><br>
<input id="name" placeholder="extention#.." type="text" name="ext" /><br>
<input id="name" placeholder="office#.." type="text" name="office" /><br>
<input id="name" placeholder="mobile#.." type="text" name="mobile" /><br>
<input id="email" placeholder="email" type="text" name="email"/><br>
<br /><br />
<div class="upload_form">
<form id='form1'>
<input type="file" name="userfile" size="20" />
<input type="button" value="upload" id="upload" />
</form>
<br/><br/>
</div>
<input type="button" value="Click" id="submit"/>
<input type="reset" value="Reset"/>
</form>
</div>
AND HERE IS THE AJAX: I know how to submit data using ajax but I need help for how to upload a file using ajax without refreshing the page, and then take the name of that file, send it again with the form, and save it to database.
<script>
$(document).ready(function(){
$('#upload').click(function(){
console.log('upload was clicked');
//ajax POST
$.ajax({
url:'upload/do_upload',
type: 'POST',
success: function(msg) {
//message from validation php
//append it to the contact_form id
$('#uploud_form').empty();
$('#uploud_form').append(msg);
}
});
return false;
});
$('#submit').click(function(){
console.log('submit was clicked');
//empty msg value
//$('#msg').empty();
//Take form values
var form_data = {
name: $('#name').val(),
email: $('#email').val(),
message: $('#message').val()
};
//ajax POST
$.ajax({
url:'',
type: 'POST',
data: form_data,
success: function(msg) {
//message from validation php
//append it to the contact_form id
$('#contact_form').empty();
$('#contact_form').append(msg);
}
});
return false;
});
});
</script>
Not sure whether I get it properly or not. I will try to answer as per my understanding.
You need to write server side code which will save the image on server.
I believe you are able to make the AJAX call to initiate point 1.
From your upload service (point 1), your should return the "relative path" of the image which was uploaded.
In success callback of your AJAX call (point 2) you should be able to capture the relative path.
Once the relative path has been captured you should add it to DOM or say any element.
Then you can start another AJAX call or post back (submit form) based on your requirement.
If this is not the problem then please be specific in what you need and provide more information.
I do it like this and it's work for me :)
<div id="data">
<form>
<input type="file" name="userfile" id="userfile" size="20" />
<br /><br />
<input type="button" id="upload" value="upload" />
</form>
</div>
<script>
$(document).ready(function(){
$('#upload').click(function(){
console.log('upload button clicked!')
var fd = new FormData();
fd.append( 'userfile', $('#userfile')[0].files[0]);
$.ajax({
url: 'upload/do_upload',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
console.log('upload success!')
$('#data').empty();
$('#data').append(data);
}
});
});
});
</script>
Script code:
function submitdata(){
alert("hi");
//var formRequest = JSON.stringify($("#submitdatafrm").serializeArray());
var test = JSON.stringify({
"firstName": $('#fname'),
"email":$('#email'),
});
console.log(test);
$.ajax({
type: "POST",
contentType: 'application/json',
url: "http://localhost:8080/formdataserver/rest/reqdemo/add",
data: test ,
dataType:"text",
success:successmethod,
error: function(data,status) {
alert("Error "+status);
}
});
}
function successmethod(data){
alert("sucess")
}
Html code:
<form class="form-horizontal" id="submitdatafrm">
<div class="form-group">
<label class="col-md-4 control-label" for="fname">First Name</label>
<div class="col-md-6"><input id="fname" name="fname" type="text" placeholder="First Name" class="form-control input-md"></div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="email">Email</label>
<div class="col-md-6"><input id="email" name="email" type="email" placeholder="Email" class="form-control input-md"></div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="button"></label>
<div class="col-md-4">Request a demo now</div>
</div>
</fieldset>
</form>
In the above code when i pass values through json statically(hardcoded values) it is working fine and values are stored in database.but when i pass the values dynamically(dynamic values through form) the values are not passed and showing an error alert message??what is the wrong am doing in the json code??Any help would be Appreciated...
How to send a whole form:
The following is sufficient to send all values in the form:
data: $('#submitdatafrm').serialize()
Is there a particular reason you need to send as JSON? This should convert the name/values to JSON:
data: JSON.stringify($('#submitdatafrm').serialize())
Note: You need to ensure your target URL is on the same website to avoid cross-site issues (why do you have an absolute URL?).
Your sample data uses firstname but the input is called fname, so it may just be a typo, but without server code that is hard to see :)
Whats in a name?
From your class code I see that the server expects a value of firstName, so if you want to simply serialize the form you will need to have name="firstname" (not fname):
<input id="fname" name="firstname" type="text" placeholder="First Name" class="form-control input-md">
Test sample needs val():
As CBroe mentioned in comment, your sample code is not actually sending the values of the fields, but instead the entire jQuery object. It should have been:
var test = JSON.stringify({
"firstName": $('#fname').val(),
"email": $('#email').val(),
});