I am having difficulty understanding why my form submits successful when i disable the ajax function. When i enable ajax on my input form. Input values i fill are not submitted. I used chrome developer tools to check the FormData being submitted. I realized nothing was being submit.
Hence i get an error asking me to fill those fields.
Controller
#PostMapping(value = "/basicAjax.json")
#ResponseBody
public ResponseEntity<Object> addCertJson(#Valid #ModelAttribute CertificateProgramme certificate, BindingResult result, Principal principal) {
User user = (User) ((UsernamePasswordAuthenticationToken) principal).getPrincipal();
certificate.setUser(user);
if (result.hasErrors()) {
List<String> errors = result.getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.toList());
return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
} else {
certificateService.save(certificate);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
}
JS Script
var $form = $('.editCert');
var formData = $form.serialize();
var url = $form.attr('action');
var storage = {};
$.each($('.editCert').serializeArray(), function(i, field) {
storage[field.name] = field.value;
});
$form.on('submit',function(e){
e.preventDefault();
$.ajax(url,{
dataType: 'JSON',
data: storage,
type: "POST",
}).done(function(response){
if(response.status === 'SUCCESS'){
console.log('I am Okay' + response);
}else{
console.log('Holly Molly');
}
}).fail(function(jqXHR, textStatus, errorThrown){
var errorInfo="";
for(i =0 ; i <jqXHR.responseJSON.length ; i++){
errorInfo += "<br>" + (i + 1) +". " + jqXHR.responseJSON[i];
}
var $myerror = $form.find('.flash').addClass(' failure');
$myerror.html("Please correct following errors: " + errorInfo);
});
});
Form
<form method="post" th:object="${certificate}"
th:action="#{${action1}}" class="form-inline inline new-item editCert">
<input type="hidden" th:field="*{id}"/>
<div th:replace="common/layout :: flash"></div>
<div class="flash"></div>
<fieldset>
<legend th:text="${heading}"> Personal Information</legend>
<div class="row" th:classappend="${#fields.hasErrors('fullName')}? 'error' : ''">
<input type="text" class="form-control input-sm" th:field="*{fullName}"
placeholder="Full Name example Jane Doe"/>
<div class="error-message" th:if="${#fields.hasErrors('fullName')}" th:errors="*{fullName}"></div>
</div>
<div class="row" th:classappend="${#fields.hasErrors('gender')}? 'error' : ''">
<select th:field="*{gender}" class="form-control input-lg ">
<option value="">[Select Gender]</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
<div class="error-message" th:if="${#fields.hasErrors('gender')}" th:errors="*{gender}"></div>
</div>
<div class="row" th:classappend="${#fields.hasErrors('date')}? 'error' : ''">
<input th:type="date" data-value="20/04/2015" class="form-control input-sm datepicker" th:field="*{date}"
placeholder="Date Of Birth"/>
<div class="error-message" th:if="${#fields.hasErrors('date')}" th:errors="*{date}"></div>
</div>
Solved my problem, Moved the form iteration into the submit $.ajax submit function
$form.on('submit',function(e){
e.preventDefault();
$.each($(this).serializeArray(), function(i, field) {
storage[field.name] = field.value;
});
console.log(storage);
$.ajax(url,{
//dataType: 'json',
data: storage,
type: "POST",
}).done(function(response){
console.log('I am Okay' + response);
}).fail(function(jqXHR, textStatus, errorThrown){
console.log(jqXHR);
if(jqXHR.status === 400){
var errorInfo="";
for(i =0 ; i <jqXHR.responseJSON.length ; i++){
errorInfo += "<br>" + (i + 1) +". " + jqXHR.responseJSON[i];
}
var $myerror = $form.find('.flash').addClass(' failure');
$myerror.html("Please correct following errors: " + errorInfo);
}
});
});
Related
Upon ajax successful return, the return data contains status. if status is false(not ajax fail), return data contains array of element names and associated error message. The goal is to replicate .validate() error functionality by appending msg after element and highlight.
HTML form:
<form class="form-horizontal" id="chngPwdForm" action="changepwd.php" method="post">
.
. various HTML....
.
<div class="form-group">
<div class="alert alert-div font-weight-bold" id="errorTxt" role="alert" style="display:none;"> </div>
<label for="crntPwd">Existing Password:</label>
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-key fa-fw"></i></span>
<input type="password" class="form-control" id="crntPwd" name="crntPwd" required>
</div>
</div>
.
. more HTML follows
.
JQUERY:
.
.yada, yada, yada
.
$("#chngPwdForm").submit(function(event){
event.preventDefault();
if ($("#chngPwdForm").valid() ) {
$('#chngPwdForm div[id="errorTxt"]').hide();
Msg = $('#chngPwdForm div[id="errorTxt"]').text("Password changed. Click on Login to continue.");
var formURL = $("#chngPwdForm").attr('action');
$.ajax({
url: formURL,
type: 'POST',
data: $(this).serialize(),
dataType: 'JSON'
})
.done (function(data, textStatus, jqXHR) {
if (!data.status) {
var Msg = "Password Not Changed. Password Change Failed.";
var element;
var errorObj = new Error("");
$.each(data.Msg, function(elemName, errMsg) {
element = $("#chngPwdForm").filter("#" + elemName);
errorObj.message = errMsg;
$(element).closest(".form-group").addClass("has-error");
errorObj.insertAfter(element);
});
}
$('#chngPwdForm div[id="errorTxt"]').text(Msg).show();
})
.fail (function(response){
var Msg = "chngPwd call failed. errorThrown: " + response;
var obj = JSON.stringify(response);
alert("obj is: " + obj);
$('#chngPwdForm div[id="errorTxt"]').text(Msg);
})
}
else {
$('#chngPwdForm div[id="errorTxt"]').text('Please Correct errors').show();
}
return false;
The JSON response from changepwd.php:
{\"status\":false,\"Msg\":{\"crntPwd\":\"Current Password may only contain a-z, A-Z, 0-9, ! or #\"}
JS error
"TypeError: errorObj.insertAfter is not a function" is thrown for
"errorObj.insertAfter(element);"
The implemented solution:
JQuery:
// New Code has leading and trailing *
$("#chngPwdForm").submit(function(event){
*$(".chngPwderr").removeClass("error").text('');* //used to remove old messages
event.preventDefault();
if ($("#chngPwdForm").valid() ) {
$('#chngPwdForm div[id="errorTxt"]').hide();
Msg = $('#chngPwdForm div[id="errorTxt"]').text("Password changed. Click on Login to continue.");
var formURL = $(this).attr('action');
$.ajax({
url: formURL,
type: 'POST',
data: $(this).serialize(),
dataType: 'JSON'
})
.done (function(data, textStatus, jqXHR) {
if (!data.status) {
var Msg = "Password Not Changed. Password Change Failed.";
var focusSet = false;
$.each(data.Msg, function(elemName, errMsg) {
*$("#" + elemName).attr("type", "text");
if (!$("#" + elemName).parent().hasClass("error")) {
$("#" + elemName).parent().append('<div class="chngPwderr error">' + errMsg + '</div>');
}
if (!focusSet) {
$("#" + elemName).focus();
focusSet = true;
}*
});
}
$('#chngPwdForm div[id="errorTxt"]').text(Msg).show();
})
I searched the internet and found this JavaScript and jQuery template for a file upload progress bar that works 100% fine(given the fact that you only use one form input).
My situation is that I need to pass one file and 4 other inputs like text and select to a Controller Action. The action works fine. My problem is to pass all these values through ajax to the Action whilst maintaining the progress bar functionality.
Action Parameters
[HttpPost]
public ActionResult Add_Attachment_to_Process(int id, int Department_id, HttpPostedFileBase Attachment, string sel_checkTask, string cbx_checkTask = null)
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<form method="post" enctype="multipart/form-data" action="/Processes/Add_Attachment_to_Process" id="myform">
<input type="file" id="media" name="file" />
<div class="input-group mb-3">
<div class="input-group-prepend">
<div class="input-group-text">
<input type="checkbox" aria-label="Checkbox for following text input" id="cbx_checkTask" name="cbx_checkTask">
<span id="span_checkTask">Link Task</span>
</div>
</div>
<select class="form-control" id="sel_checkTask" name="sel_checkTask" style="width : 700px;" disabled>
#foreach (var t in Model.User_Tasks)
{
<option value="#t.Task_Discription">#t.Task_Discription - #t.Key_Terms</option>
}
</select>
</div>
<input id="id" name="id" value="#ViewBag.process_id " />
<input id="Department_id" name="Department_id" value="#ViewBag.Department_id" />
<input type="submit" />
</form>
<div class="progress" style="width:40%">
<div id="uploadprogressbar" class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width:0%">
0%
</div>
</div>
JavaScript
$(document).ready(function () {
$("#myform").on('submit', function (event) {
event.preventDefault();
var formData = new FormData($("#myform")[0]);
$.ajax({
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener('progress', function (e) {
if (e.lengthComputable) {
console.log('Bytes Loaded: ' + e.loaded);
console.log('Total Size: ' + e.total);
console.log('Percentage Uploaded: ' + ((e.loaded / e.total) * 100) + '%');
var percent = Math.round((e.loaded / e.total) * 100);
$("#uploadprogressbar").html(percent + '%');
$("#uploadprogressbar").width(percent + '%');
}
});
return xhr;
},
type: 'POST',
url: '/Processes/Add_Attachment_to_Process',
data: formData,
processData: false,
contentType: false,
success: function () {
alert('File Uploaded');
},
error: function (xhr, status, error) {
var errorMessage = xhr.status + ': ' + xhr.statusText;
alert('Error - ' + errorMessage);
}
});
});
});
AS per the discussion above, try this sort of pattern to better see what values are not being sent
let f = new FormData();
f.append('id', getYouFormValue("id"));
f.append('sel_checkTask', getYouFormValue("sel_checkTask"));
f.append('cbx_checkTask ', getYouFormValue("cbx_checkTask "));
if (form.File) {
f.append('File', getYouFormValue("file"));
}
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: f
}
return fetch(`/Processes/Add_Attachment_to_Process`, requestOptions)
.then(handleResponse)
.then(result => {
//do stuff
});
function handleResponse(response) {
return response.text().then(text => {
const data = text && JSON.parse(text);
if (!response.ok) {
if (response.status === 401) {
console.log('not logged in')
}
const error = (data && data.message) || data.title || response.statusText;
return Promise.reject(error);
}
return data;
});
}
function getYouFormValue(element){
let val = document.getElementById(element);
if(!val){
console.log('empty value');
return null;
}
return val;
}
I have created a Spring-boot REST service and It's working as expected and returned JSON array as response.
End Point:
https://localhost:8081/displayProduct?productId=1234
Output(Example):
{
"dataSet":[
{
"productName": "mobile",
"product_OS":"Android"
},
{
"productName": "Laptop",
"product_OS":"Linux"
}
]
}
Code:
#ApiOperation(responseContainer = "request", response = HadoopCALDTO.class, value = "shows_component")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
#RequestMapping(value = "/displayProduct", produces = MediaType.APPLICATION_JSON, method = RequestMethod.GET)
#ResponseBody
public ResponseEntity<String> getETLResponse(#RequestParam("productId") String productId)
throws Exception {
Map<String, String> data = new HashMap<String, String>();
Map<String, String> dataError = new HashMap<String, String>();
String response = Utils.sendGET(ConfigReader.getProperty("getBaseURL")
+ productId);
data = Utils.getHttpUrl(response, productId);
System.out.println(data.size());
if (Utils.getDataError().size() > 0) {
Utils.getDataError().clear();
}
for (Map.Entry<String, String> getValue : data.entrySet()) {
String tempUrl = Utils.replaceUrl(getValue.getKey());
System.out.println(tempUrl);
String tempresponse = Utils.sendGET(tempUrl);
Utils.getErrorData(tempresponse);
}
System.out.println(dataError.size());
String finalResponse = Utils.buildJSONSkelton(Utils.getDataError());
System.out.println(finalResponse);
return new ResponseEntity<String>(finalResponse,HttpStatus.OK);
}
The above code works perfectly fine. I tested the End point in postman which returned 200 Ok response and proper response body as expected.
The above code I have a JSON that I stored in "finalResponse" string variable and showing it as response body (Sample output mentioned above).
I'm getting the productId is the input from user and getting the result and publishing the data. And I just want to do this from Responsive HTML page. Like I just need a text box where the user needs to enter the product id and click submit button. And the value is pass into the REST client and displaying the JSON array result as table view in HTML page.
Really I don't have any idea how to kick start this. I'm very new to web application development, and not sure how to achieve this. Googled about Spring MVC and some library called xmlhttprequest javascript. But not sure how to get the value from text field and pass it to REST client and wait for respose (It takes close to 20 seconds to fetch all the productID from hadoop) JSON array and display the result as dynamic HTML table as like below.
S.No || Product_Name || Product_OS
1 || Mobile || Android
2 || Laptop || Linux
Please can someone help me on this.
Updates:
I just tried the below steps to hit the REST client and get the response as dynamic html table
<html>
<head>
<script type="text/javascript">
function myFunction() {
var name = document.getElementById("name").value;
var dataString = 'calId=' + name ;
if (name == '') {
alert("Please Fill All Fields");
} else {
$.ajax({
url: 'http://localhost:8081/api/displayProduct?',
data: dataString
dataType: 'json',
success: function(data) {
for (var i=0; i<data.length; i++) {
var row = $('<tr><td>' + data[i].productName+ '</td><td>' +
data[i].product_os + '</td> </tr>');
$('#myTable').append(row);
}
},
error: function(jqXHR, textStatus, errorThrown){
alert('Error: ' + textStatus + ' - ' + errorThrown);
}
});
}
}
</script>
</head>
<body>
<form id="form" name="form">
<h3>Fill Your Information!</h3>
<div>
<label>Name :</label>
<input id="name" type="text">
<input id="submit" onclick="myFunction()" type="button" value="Submit">
</div>
</form>
</body>
</html>
<table id="myTable">
<tr>
<th>Zipcode</th>
<th>City</th>
<th>County</th>
</tr>
</table>
Observed below Error message:
MyTest_sta.html:39 Uncaught ReferenceError: myFunction is not defined
at HTMLInputElement.onclick (MyTest_sta.html:39)
Please find below code snippet, here I am rendering ajax response into a table, you can probably make this ajax call attach to any event/ form submit
HTML:
<form id="form" name="form">
<h3>Fill Your Information!</h3>
<div>
<label>Name :</label>
<input id="name" type="text">
<label>Email :</label>
<input id="email" type="text">
<input id="submit" onclick="myFunction()" type="button" value="Submit">
</div>
</form>
<table id="myTable">
<tr>
<th>Zipcode</th>
<th>City</th>
<th>County</th>
</tr>
</table>
JS:
function myFunction() {
var name = document.getElementById("name").value;
var email = document.getElementById("email").value;
var dataString = 'name1=' + name + '&email1=' + email;
if (name == '' || email == '') {
alert("Please Fill All Fields");
} else {
$.ajax({
url: 'https://localhost:8081/displayProduct?productId=1234',
data: dataString
dataType: 'json',
success: function(data) {
for (var i=0; i<data.length; i++) {
var row = $('<tr><td>' + data[i].zipcode+ '</td><td>' +
data[i].city + '</td>
<td>' + data[i].county + '</td></tr>');
$('#myTable').append(row);
}
},
error: function(jqXHR, textStatus, errorThrown){
alert('Error: ' + textStatus + ' - ' + errorThrown);
}
});
}
}
I am new to Javascript and spring coding.
It is a web app working on Spring framework and with frontend with Mustache template with jQuery.
What I want add new form field (id="exampleTextarea") to the working example. I think this problem is on JavaScript part because checking in java code back null on added field value.
Anybody can direct me what things I am missing?
In post.html I added new field, smile duplicate existed on.
<!-- add textarea in form-->
<div class="form-group">
<label for="exampleTextarea" class="col-sm-2 control-label" >Textarea</label>
<div class="col-sm-10 ">
<textarea type="text" class="form-control input-sm" id="exampleTextarea" name="exampleTextarea" rows="3"></textarea>
</div>
</div>
In graphstory.js javascript file was changed functions.
addContent(), contentformToJSON(), on
.on()
$('#contentAddEdit').on('click', 'a#addcontent', function() {
console.log( $( this ).text() );
if ( $("#contentform").is(":visible") ) {
$("#addcontent").text('Add Content');
$("#contentform")[0].reset();
$("#contentform").hide();
$("#btnSaveContent").text('Add Content XXX');
}else{
$("#contentform").show();
$("#addcontent").text("Cancel");
$("#btnSaveContent").text('Add Content');
}
return false;
});
addContent()
function addContent(){
$.ajax({
type: 'POST',
contentType: 'application/json',
url: '/posts/add',
dataType: "json",
data: contentformToJSON(),
success: function(data, textStatus, jqXHR){
$('#content').prepend('<tr><td>'+data.title+'
<br/>tags: '+data.tagstr+' ::
//text fild
<br/>Textarea: '+data.exampleTextarea+' ::
Posted by '+data.userNameForPost+' at '+data.timestampAsStr+'<br/></td></tr>');
$('#title').val("");
$('#url').val("");
$("#contentform").hide();
$("#addcontent").text('Add Content');
},
error: function(jqXHR, textStatus, errorThrown){
alert('add contnt error: ' + errorThrown);
}
});
}
contentformToJSON()
function contentformToJSON() {
/* added text fild*/
if($("#tagstr").length == 0 | $("#exampleTextarea").length == 0) {
return JSON.stringify({"title": $('#title').val(), "url": $('#url').val() });
}if else($("#tagstr").length == 0){
return JSON.stringify({"title": $('#title').val(), "url": $('#url').val(), "exampleTextarea": $('#exampleTextarea').val() });
}if else($("#exampleTextarea").length == 0){
return JSON.stringify({"title": $('#title').val(), "url": $('#url').val(), "tagstr": $('#tagstr').val() });
}else{
return JSON.stringify({"title": $('#title').val(), "url": $('#url').val(), "tagstr": $('#tagstr').val(),"exampleTextarea": $('#exampleTextarea').val() });
}
}
I changes the code only in two files post.html and graphstory.js here code from files.
Here is post.html
<div class="global/base-app"><!-- add textarea in form-->
<div class="form-group">
<label for="exampleTextarea" class="col-sm-2 control-label" >Textarea</label>
<div class="col-sm-10 ">
<input type="text" class="form-control input-sm" id="exampleTextarea" name="exampleTextarea" rows="3"></textarea>
</div>
</div>
I found a cure for this stack. It was made from html tag <textarea>. Exchange it with <input> works fine.
I have Send data using $.ajax and validation with jQuery validation plugin like this :
<div class="" id="ajax-form-msg1"></div>
<form id="myform" action="load.php">
<input type="input" name="name" id="name" value="" />
<input type="hidden" name="csrf_token" id="my_token" value="MkO89FgtRF^&5fg#547#d6fghBgf5" />
<button type="submit" name="submit" id="ajax-1">Send</button>
</form>
JS:
jQuery(document).ready(function ($) {
$('#myform').validate({
rules: {
name: {
required: true,
rangelength: [4, 20],
},
},
submitHandler: function (form) {
$("#ajax-1").click(function (e) {
e.preventDefault(); // avoid submitting the form here
$("#ajax-form-msg1").html("<img src='http://www.drogbaster.it/loading/loading25.gif'>");
var formData = $("#myform").serialize();
var URL = $("#myform").attr("action");
$.ajax({
url: URL,
type: "POST",
data: formData,
crossDomain: true,
async: false
}).done(function (data, textStatus, jqXHR) {
if (data == "yes") {
$("#ajax-form-msg1").html(' < div class = "alert alert-success" > ' + data + ' < /div>');
$("#form-content").modal('show');
$(".contact-form").slideUp();
} else {
$("#ajax-form-msg1").html('' + data + '');
}
}).fail(function (jqXHR, textStatus, errorThrown) {
$("#ajax-form-msg1").html(' < div class = "alert alert-danger" >AJAX Request Failed < br / > textStatus = ' + textStatus + ', errorThrown = ' + errorThrown + ' < /code></pre > ');
});
});
}
});
});
In action my form validate using jQuery validation but after validation not submit and not send data.
how do fix this problem?!
DEMO HERE
The submitHandler is expecting a submit and you have a click event inside it and then an ajax call.
If you have a button type="submit" inside a form you don't even need a click event, the plugin will do the validation automatically. So just make the ajax call inside the submitHandler.
If you need to bind the action to a button using the click event, the proper approach should be something like this:
$('#button').click(function(){
var form = $('#myform').validate({...}); #store the validator obj
if (form.is_valid()){
// submit using ajax
} else {
// dont do anything
}
});
Call form.submit() at the end of your done function.
See: http://jqueryvalidation.org/validate/
Also, you do not need $("#ajax-1").click() because the submitHandler will be called automatically when you click on that button anyways. You can test this yourself by putting a console.log as the first line of submitHandler. Then fill out the form and press the button. See if it prints out your log message.
In submitHandler you are handling the submit , then again why did you write click event?
Here is the fix.
jQuery(document).ready(function($) {
$('#myform').validate({
rules: {
name: {
required: true,
rangelength: [2, 20],
},
},
submitHandler: function(a, e) {
//a is form object and e is event
e.preventDefault(); // avoid submitting the form here
$("#ajax-form-msg1").html("<img src='http://www.drogbaster.it/loading/loading25.gif'>");
var formData = $("#myform").serialize();
var URL = $("#myform").attr("action");
$.ajax({
url: URL,
type: "POST",
data: formData,
crossDomain: true,
async: false,
success: function(data) {
console.log(data)
},
error: function(err) {
console.log(err)
}
}).done(function(data, textStatus, jqXHR) {
if (data == "yes") {
$("#ajax-form-msg1").html(' < div class = "alert alert-success" > ' + data + ' < /div>');
$("#form-content").modal('show');
$(".contact-form").slideUp();
} else {
$("#ajax-form-msg1").html('' + data + '');
}
}).fail(function(jqXHR, textStatus, errorThrown) {
$("#ajax-form-msg1").html(' < div class = "alert alert-danger" >AJAX Request Failed < br / > textStatus = ' + textStatus + ', errorThrown = ' + errorThrown + ' < /code></pre > ');
});
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdn.jsdelivr.net/jquery.validation/1.14.0/jquery.validate.min.js"></script>
<form id="myform" action="load.php">
<input type="input" name="name" id="name" value="" />
<input type="hidden" name="csrf_token" id="my_token" value="MkO89FgtRF^&5fg#547#d6fghBgf5" />
<button type="submit" name="submit" id="ajax-1">Send</button>
</form>
Use success and error call backs to get data or error messages.
Note: Here (In StackOverflow) you will get 404 Page Not Found error when you submit. So try in your local.