How to automatically populate fields from ajax request in spring boot? - javascript

I made an ajax request to the server for checking whether a particular username exists in the database. Here is the code for that..
$("input[placeholder='Username']").focusout(function() {
var username = $("input[placeholder='Username']").val();
if(username.length <3 || username.length>20) {
$("#username_taken").html("Username must be between 3-20 characters!");
usernameFlag = true;
}
else if(username != null) {
$.ajax({
type: "POST",
url: "/data/validate_username",
data: username,
success: function(isValid) {
if(!isValid) {
$("#username_taken").html("The username has already been taken!");
usernameFlag = true;
}
},
error: function() {
$("#username_taken").html("Could not verify username from server!");
}
});
}
});
In the server side I have written a RestController to handle this request and provide the data on whether the user exists or not.
// necessary imports done...
#RequestMapping("/data")
#RestController
public class UserAccountRest {
#Autowired
private UserAccountService userAccountService;
#PostMapping("/validate_username")
public boolean validateUsername(String username) {
return !userAccountService.accountExists(new UserAccount(username));
}
}
Normally spring auto populates the parameters like username, if it was a form submit. But here status 500 Internal Server Error occurs, and in the console it says that the id must not be null. This means that the username is not populated.
I could probably use HttpRequest object in the parameter and get the username from it. But is there any way to configure so that the username is directly populated?

The data sent needs to have key/value pairs.
When you get the value of an <input> you only have 1/2 of the pair. Your variable username only contains the value part
Change
data: username,
To
data: {username : username}

Have you tried doing
public boolean validateUsername(#RequestBody String username) {
return !userAccountService.accountExists(new UserAccount(username));
}
You are probably posting a JSON value which should be a key value pair.

Related

Returning variable value from controller to view

I'm new at Laravel and I'm actively trying to code better, but I'm currently stuck with problems I don't know how to solve.
The controller :
public function sendGiving($contents){
$redirectURL = $contents->redirectURL;
var_dump($redirectURL); // the variable is available, logged in network section
return View::make('giving/giving')->with('redirectURL', $redirectURL);
}
The view (on AJAX) :
function submitForm() {
if (is_personal_data_complete() == true && is_offering_filled() == true && isreCaptchaChecked() == true) {
var base_url = window.location.origin;
//send ajax request
$.post("{{ route('send_giving') }}",
{
_method: 'POST',
_token: '{{ csrf_token() }}',
name: $('#txtName').val(),
email: $('#txtEmail').val(),
phone_number: $('#txtnohp').val(),
thanksgiving_offerings: total_thanksgiving,
tithe_offerings: total_tithe,
firstborn_offerings: total_firstborn,
build_offerings: total_build,
deacon_offerings: total_deacon,
mission_offerings: total_mission,
paud_offerings: total_paud,
dataType: "jsonp",
async : false,
success: function($redirectURL){
alert($redirectURL);
},
});
}
else if (is_personal_data_complete() == false) {
alert("Please fill in your data form");
}
else if (is_offering_filled() == false) {
alert("Please fill in your offerings");
}
else if (isreCaptchaChecked() == false){
alert("Please check the captcha");
}
return false;
}
The alert always returns undefined though, what am I missing?
Please try this:
return response()->json($redirectURL)
When you use Laravel and write API, you need to use this command to reponse JSON for frontend
The view() function just creates an instance of the View class. Not just an HTML string. For that you should call render():
$returnHTML = view('giving/giving')->with('redirectURL', $redirectURL)->render();
return response()->json(array('success' => true, 'html'=>$returnHTML));
When you return in your controller return View::make('giving/giving')->with('redirectURL', $redirectURL);
You are returning a VIEW file, which will be return as the body of the HTTP request.
and you are also passing to Your view file redirectUrl which will be accessible in your view file.
And when you perform your AJAX request, you are getting a response with a body which contain HTML/TEXT Content not JSON.
SO YOU CAN'T HAVE ACCESS TO redirectURL VARIABLE
So what you should do by the way is to return simple a JSON body by returning in your Controller something like
return response()->json([
'redirectURL' => $redirectURL
]);
No need to return a VIEW FILE
You can't return in the same controller JSON data in the body and a VIEW FILE
The main issue is here that you try to send a POST with JSONP data type.
There are a lot of explanations on this on SO, e.g https://stackoverflow.com/a/18934048/8574551
Try to remove it and use smth like the next:
...
contentType: "application/json",
dataType: "json",
...
On another hand, you can omit these 2 parameters (check https://api.jquery.com/jquery.post/)
To return the data from the controller action you can use response()->json(..) (as described in other answers)
the problem is on the ajax request, as after changing the format it works nicely

Pass message from Controller to AJAX script in View

I'm using jQuery and AJAX in the View to send some data to the Controller that writes it to the database. On success I show a div tag with a green background with "OK" text. But what if I do a check first in the Controller if the data already exist in the database, then I would like to alert the user that the data could not be added. Is there a way to pass some kind of message back to the AJAX script?
I guess the success option is just a confirm of contact with the Controller and not a real confirm that everything is OK and the data has been added to the database!?
What action in the Controller would cause the error function in the AJAX code to run?
Finally I just wonder what kind of return I should use since I'm actually not returning anything?
My script in the View:
$.ajax({
url: "/Orders/AddOrder",
type: "GET",
cache: false,
data: { a: order, b: seller },
success: function () {
console.log('AJAX successful');
// Show confirm message
$(".messageOk").show();
$(".messageOk").text("OK").delay(2000).queue(function () {
location.reload();
});
},
error: function () {
????
},
complete: function () {
????
}
});
Controller:
// Add new Resource
public ActionResult AddOrder(int a, int b)
{
var order = new Order
{
OrderNumber = a,
Seller = b
};
db.Orders.Add(order);
db.SaveChanges();
//return new EmptyResult();
return RedirectToAction("Index", "Home"); // ??????
}
You could return the appropriate HTTP status code from your controller action: 409 Conflict.
if (the resource already exists in db) {
return new HttpStatusCodeResult(HttpStatusCode.Conflict);
}
which will trigger the error AJAX function in which you could check whether you are in this situation and act accordingly:
error: function(jqXHR) {
if (jqXHR.status == 409) {
alert('Sorry but this resource already exists');
}
}
As you can see this way it's up to the view to decide what error messages to display based on proper HTTP status codes returned from the server. This way you are not cluttering the server with view logic.
Along with the correct response status code, you can also pass in your response body error messages from the server may be as JSON string or plain string

Spring MVC back end ajax validation

For my current project Java/Spring project I have to validate a form. The webpage is a freemarker template file.
The <form> has no special attribute to send the data to the controller. The project uses Ajax to send the request. The controller doesn't receive the form at all.
When the user submits the data, a JavaScript function is called to receive all the data by collecting the elementID's. The data is put in a variable, like this (short version);
var userId = document.getElementById('input_id').value.toLowerCase();
var width = document.getElementById("width");
var height = document.getElementById("height");
The function then puts all the data into a JSON. This JSON is put in the Ajax, and then Ajax calls the right controller.
**Ajax code **
$.ajax({
url: url,
type: "POST",
dataType: "json", // expected format for response
contentType: "application/json", // send as JSON
Accept: "text/plain; charset=utf-8",
"Content-Type": "text/plain; charset=utf-8",
data: data,
success: function (response) {
// we have the response
if (response.status == "SUCCESS") {
console.log("succes");
//Redirect to the right page if the user has been saved successfully
if (type === "setupuser") {
window.location = "/setup/user/" + userId;
} else if (type === "simulatoruser") {
window.location = "/simulator/user/" + userId;
}
} else {
errorInfo = "";
for (i = 0; i < response.result.length; i++) {
errorInfo += "<br>" + (i + 1) + ". " + response.result[i].code;
}
$('#error').html("Please correct following errors: " + errorInfo);
$('#info').hide('slow');
$('#error').show('slow');
}
},
error: function (e) {
alert('Error: ' + e);
}
});
The following controller is called by the Ajax request:
#RequestMapping(method = RequestMethod.POST, value = "/adduser/{userType}")
#ResponseBody
JsonResponse addUserMapping(#ModelAttribute(value="user") User user, BindingResult result, #RequestBody String jsonString, #PathVariable String userType) {
def json = new JsonSlurper().parseText(jsonString)
String userId = json.userId
String userName = json.userName
user.setId(userId)
user.setName(userName)
log.warn("User id..... "+user.getId())
log.warn("User name..... "+user.getName())
JsonResponse res = new JsonResponse();
ValidationUtils.rejectIfEmpty(result, "id", "userId can not be empty.");
ValidationUtils.rejectIfEmpty(result, "name", "userName can not be empty");
if(!result.hasErrors()){
userService.addUser(jsonString)
res.setStatus("SUCCESS");
}else{
res.setStatus("FAIL");
res.setResult(result.getAllErrors());
}
return res;
}
As you can see, Ajax sends a JSON to the controller. The controller unpacks the JSON and puts the data into the user object. Then the user object is being validated using "rejectIfEmpty()" method...
Now I've been reading about making a userValidator class extending Validator, or simply putting Annotations in the bean class like:
#Size(min=1, max=3)
I prefer these annotations since you don't have to write special code for checking certain simple things (like the field not being empty .. #NotEmpty)
But that doesn't work because the controller doesn't take a user object the second it's called, instead it takes the JSON and then unpacks it (Validating is too late..)
TL:DR
Controller takes a JSON as a parameter instead of an Object. The JSON has to be unpacked and then validated in the controller as a java object using rejectIfEmpty as an example. I don't want a full page reload, but I still want to keep Ajax.
BTW: I want to validate the data against more things like regex etc. But the rejectifEmpty is a simple example.
Does anyone have an idea how to handle this?
I fixed the validation by parsing the JSON in the controller and setting it in the user object. The user object is then put in my UserValidator class and validated.
Link for more info using the validator:
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/validation.html

jquery validation plug-in remote function with codeigniter

I'm using the jquery validation plug-in. I don't have any idea how the remote function works.
So far this is my code:
functions.js
user: {
required: true,
remote: {
url: "http://localhost/iTransaction/home/checkUser",
type: "post",
async: false
}
}
Controller:
function checkUser(){
return $this->itransaction_model->checkUser();
}
Model:
function checkUser(){
$this->db->select("user");
$query = $this->db->get("member");
$row = $query->row();
echo $row->user;
if($row->user == $this->input->post("user")){
return true;
}else{
return false;
}
}
The remote is supposed to check whether the username already exists or not.
From the docs:
The serverside resource is called via jQuery.ajax (XMLHttpRequest) and gets a key/value pair corresponding to the name of the validated element and its value as a GET parameter. The response is evaluated as JSON and must be true for valid elements, and can be any false, undefined or null for invalid elements, using the default message; or a string, eg. "That name is already taken, try peter123 instead" to display as the error message.
Your controller method returns a boolean value in a way that does not makes any sense to the library and is interpreted as false. You need to return the validation result in a different way:
function checkUser(){
$this->output->set_content_type('application/json');
$this->output->set_header('Cache-Control: no-cache, must-revalidate');
$this->output->set_header('Expires: '.date('r', time()+(86400*365)));
$output = json_encode(
$this->itransaction_model->checkUser() ? true : 'That username is alreay in use'
);
$this->output->set_output($output);
}

$.post throwing "Illegal invocation "

Edit: None of the answers suggested so far have worked at all.
I'm running this call with django. The first time it runs, the server returns "n_usr" (which changes the form the user files in). The second time, it just throws an Illegal invocation error.
function log_in () {
username = $('#usr_enter').val();
password = $('#pass_enter').val();
if(!n_usr){
$.post('/ajax/login',{password: password, username: username}, function(data) {
if(data == "n_usr"){
$('#new_user_entry').show('slow');
n_usr = true;
}
else {
}
})
}else {
password2 = $('#pass_re_enter');
penname = $('#pen_enter');
$.post('/ajax/login', {password: password, password2: password2, username: username, pen_name: penname, TN: "TN"}, function(data) {
if(data == "e_act"){
} else {
}
});
}
}
In your else, you have:
password2 = $('#pass_re_enter');
penname = $('#pen_enter');
Then you have:
{password: password, password2: password2, username: username, pen_name: penname, TN: "TN"}
You are getting Illegal invocation because jQuery is trying to serialize the jQuery object for $.post, and it can't. It's probably trying to call a string method, and is passing it a jQuery object as context, thus causing the error.
You need to add .val().
password2 = $('#pass_re_enter').val();
penname = $('#pen_enter').val();
Well you are not calling them the same -- the first time:
$.post(url_base+'/ajax/login' ...
and the 2nd
$.post('/ajax/login', {....
Change the 2nd one to include url_base.

Categories