I'm really getting started with controllers for my small application, and i have this for now:
#RequestMapping("/users/{id}")
public ModelAndView showMemeber(#PathVariable Integer id) {
ModelAndView mav = new ModelAndView("user/show");
mav.addObject("title", "Show User");
mav.addObject("user", userService.findById(id));
return mav;
}
#RequestMapping(value="/users/{id}", method=RequestMethod.DELETE)
public String deleteMemeber(#PathVariable Integer id) {
userService.delete(id);
return "redirect:users";
}
the first one, is working properly, but the second doesn't, i have the following view for the first controller:
<div class="panel-heading">Personal information</div>
<div class="panel-body">
<form>
...
<button type="submit" class="btn btn-danger" onclick="return confirm('Are you sure you want to delete {{ user.username }}?')"><span class="glyphicon glyphicon-remove"></span> Delete</button>
</form>
</div>
like you see, i have two buttons here, one for edit the object and one for delete it.
Once deleted it, must redirect to https://<my domain>/users.
The problem is, when i click on Delete it just refresh the page and the object persist on the database, what is wrong here?
I try send a DELETE request like curl -X "DELETE" http://localhost:8080/my-app/users/18 but this didn't work.
I try another alternative using jQuery's ajax-method (but the same error persist):
$.ajax({
url: '/users/' + someUserId,
type: 'DELETE',
success: function(result) {
// Do something with the result
}
});
You have to use ajax to send a DELETE from the web page. The form tag itself only supports POST or GET. In your submit-Handler you have to suppress the default behaviour of the submit button, i.e. the submit of the form via GET or POST (event.preventDefault()):
$("form").submit(function (event) {
event.preventDefault();
$.ajax({
url: '/users/' + someUserId,
type: 'DELETE',
success: function(result) {
// Do something with the result
}
});
}
Related
I try to send form data through thymeleaf + ajax to Java Controller.
But at ReplyDto, can't receive data.
This is my code.
Themeleaf, Ajax .html
function insertReply() {
$.ajax({
type: 'POST',
url: '/reply/insertReply',
data: $("#replyForm").serialize(),
contentType: "application/json",
success: function(data) {
alert("test");
},
error: function(request, status, error) {
alert("Error : " + error + "\nStatus : " + status + "\nRequest : " + request);
}
});
}
<form id="replyForm" th:object="${replyDto}" th:method="post">
<input type="hidden" th:field="${post.postNo}" th:value="${post.postNo}">
<input class="form-control" type="text" th:field="*{replyTitle}" placeholder="replyTitle">
<textarea class="form-control" th:field="*{replyContent}" placeholder="insert" id="replyContentData" style="height: 100px"></textarea>
<button class="btn btn-primary" id="replyInsertButton" type="button" onclick='insertReply()'>댓글 입력</button>
</form>
ReplyDto.java
private int replyNo;
private String replyTitle;
private String replyContent;
private int postNo;
ReplyContoller.java
#PostMapping("/insertReply")
public int insertReply(ReplyDto replyDto) {
System.out.println(replyDto.getPostNo());
System.out.println(replyDto.getReplyTitle());
System.out.println(replyDto.getReplyContent());
return replyService.insertReply(replyDto);
}
Controller has annotation #RestController.
At console, log 0, null, null each postNo, replyTitle, replyContent.
How can I get form data to Controller?
Please help!
Your are missing #RequestBody
public int insertReply(#RequestBody ReplyDto replyDto) { ...
$("#replyForm").serialize() turns form into query string. You need valid JSON
You should probably go for a solution like this: Spring RestController POST accepting a basic HTML form
If you insist on proceeding with your current solution:
Start with verifying controller in Postman when fixed missing #RequestBody.
Converting form to JSON:
https://www.learnwithjason.dev/blog/get-form-values-as-json/
https://medium.com/#mwakatumbula_/code-15ecdb18c2ef
https://css-tricks.com/snippets/jquery/serialize-form-to-json/
Suppose I have a Login Object, when I make a get request for 'login', I send the Login object and in the JSP Page I use model attribute and paths to map the attributes as follows:
ViewController:
#GetMapping("/login")
public String login(Model model){
Login login = new Login();
model.addAttribute("login",login);
return "login";
}
JSP Page:
...
<form:form action="login" method="post" modelAttribute="login">
<form:hidden path="id"/>
<label for="username">UserName</label>
<form:input path="username"/><br>
<label for="password">Password</label>
<form:password path="password"/><br>
<form:button>Login</form:button>
</form:form>
...
Now when I hit on the Login Button, the login object is sent to the appropriate controller and it returns a ResponseEntity Object accordingly with some message.Once the processing is done, the page refreshes and the message in the ResponseEntity object is displayed, say "Login Successful".
But I want to display this message in the form of an alert.
To do that I'll have to make an AJAX request and upon success call the alert with the message, but in this approach I can no longer use the modelAttribute and AJAX has so sent a Login object, would that be possible?
Is there any way to use the functionality of the modelAttribute and also making AJAX requests?
After digging up for details about the same, I finally got the solution!
I had to make the following changes.
Login.jsp - Add a new button tag outside the tag
...
<form:form id="myform" action="login" method="post" modelAttribute="login">
<form:hidden path="id"/>
<label for="username">UserName</label>
<form:input path="username"/><br>
<label for="password">Password</label>
<form:password path="password"/><br>
</form:form>
<button id="login-btn">Login</button>
...
AJAX Script:
$(document).ready(function () {
$("#login-btn").click(function () {
$.ajax({
type: "POST",
url: "login",
data : $("#myform").serialize(),
success: function (data) {
alert(data);
},
error: function(data){
alert(data);
}
});
})
});
Controller:(to check if the login was valid or not)
#PostMapping("/login")
public ResponseEntity<?> login(#ModelAttribute("login") Login login){
boolean status = loginDao.isValidLogin(login);
String message = (status)?"Login Succcessful":"Incorrect Login Credentials!";
return new ResponseEntity<>(message,HttpStatus.OK);
}
I've googled for the past 2 days and still can't find a solution to this problem. I can upload fine using the input element with type attribute set to file. But I cannot upload the cropped image using croppie to the server.
Here is my register.scala.html:
#helper.form(action = routes.ProfilesController.upload, 'id -> "profileForm", 'class -> "", 'enctype -> "multipart/form-data") {
#CSRF.formField
<div class="col-6 col-md-3 pic-padding">
<div id="upload-demo" class="upload-demo pic-1 mx-auto d-block rounded">
</div>
<div class="pic-number" href="#">1</div>
<label for="upload-pic1" class="pic-control-bg">
<img src="#routes.Assets.versioned("images/plus.png")" class="pic-control">
</label>
<input type="file" id="upload-pic1" name="pic1" class="upload-btn" accept="image/*">
<button type="button" class="upload-result">Result</button>
<script>
Demo.init();
</script>
</div>
}
Here is my main.js:
$('.upload-result').on('click', function (ev) {
$uploadCrop.croppie('result', {
type: 'canvas',
size: 'viewport'
}).then(function (resp) {
$.ajax({
url: "http://localhost:9000/upload",
type: "POST",
data: {"image":resp},
success: function (data) {
alert(resp);
}
});
});
});
Here is my ProfilesController.java
public Result upload() {
File file = request().body().asRaw().asFile();
return ok("File uploaded");
}
Here is a snippet from routes file:
POST /upload controllers.ProfilesController.upload()
The error i get with the above solution is:
[CompletionException: java.lang.NullPointerException]
Please help! This has been stressing me out for the past 2 days, I just can't figure it out.
This is not fully solved, but i've progressed enough to produce a different problem. I ended up changing my ajax request in main.js to:
$.ajax({
url: "http://localhost:9000/upload",
type: "POST",
data: resp,
success: function (data) {
alert(resp);
Then I also changed the profilecontroller.java to
public Result upload() {
String dataUrl = request().body().asText();
System.out.println(dataUrl);
return ok("Data URI Passed");
}
This gave me the Data URI from javascript and passed it to the JAVA code. Now I need to try and upload the image using the Data URI. If you know the answer to this then please contribute to this post.
I have got a <form> and AJAX script that sending data from form to controller.
<form:form method="POST" modelAttribute="message"
accept-charset="utf-8" ng-app="vandh" ng-controller="validateCtrl"
name="messageForm" novalidation="true">
<form:textarea path="text" class="form-control" rows="1" name="message"
id="message" ng-model="message" required="true"></form:textarea>
<div style="color: black"
ng-show="messageForm.message.$dirty && messageForm.message.$invalid">
<span ng-show="messageForm.message.$error.required"><spring:message
code="label.entermessage" /></span>
</div>
<br>
<div class="text-center">
<button class="btn btn-success" id="addMessage" name="addMessage"><spring:message
code="label.sendmessage"/></button>
</div>
</form:form>
<script>
$("#addMessage").click(function() {
var text = $('#message').val();
$.ajax({
type : "POST",
url: "/app/user/messages/${iddialog}" ,
async : true,
dataType:'json',
contentType: 'application/json',
data : {
text : text
}
});
});
</script>
And here is my controller for this page
#RequestMapping(value = "/user/messages/{iddialog}", method = RequestMethod.POST)
public #ResponseBody Message messages(HttpServletRequest request, HttpServletResponse response,
#PathVariable(value = "iddialog") int iddialog, Principal principal,#RequestParam(value="text")String text ) {
System.out.println("ITS HERE");
if (checkingMessage(text) != true) {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// get current date time with Date()
Date date = new Date();
System.out.println(dateFormat.format(date));
Dialog dialog = new Dialog();
dialog.setIddialog(iddialog);
Message mess = new Message();
mess.setText(text);
mess.setDialog(dialog);
mess.setDate(dateFormat.format(date));
mess.setMessender(principal.getName());
this.messageService.addMessage(mess);
this.dialogService.updateUnreadMessInfo(iddialog, principal.getName());
System.out.println("message sent!");
return mess;
// return "redirect:/user/messages/"+iddialog;
}
else{
Message mess1 = new Message();
return mess1;
}
}
#RequestMapping(value = "/user/messages/{iddialog}", method = RequestMethod.GET)
public String messagesList(#PathVariable(value = "iddialog") int iddialog, Model model, Principal principal) {
model.addAttribute("message", new Message());
model.addAttribute("listMessagesForUser", messageService.listMessagesForUser(iddialog));
model.addAttribute("userDialogWith", dialogService.usernameDialogWith(iddialog, principal.getName()));
model.addAttribute("countOfNewUsers", this.usersService.countOfNewUsers());
model.addAttribute("allUserMess", this.dialogService.allNewMessForUser(principal.getName()));
System.out.println("ID dialog is: " + iddialog);
return "messagesWithUser";
}
When i'm sending data from AJAX script to my controller, it returns me my Message object:
But i need to prevent reloading my page when i'll submit my <form>. I saw a lot of guides but it's the highest result that i get! Help me pls! What i need to do that my page will not refresh when i'm submiting my form!!!!
You need to return false from your click handler to prevent the default action (submitting the form) from executing.
You can stop default action using prevent default.
https://api.jquery.com/event.preventdefault/
Based from your front end code you are using AngularJS, but you are using jQuery to trigger the button click.
What you can do is create a function in your controller(validateCtrl) to handle the click event and post the message model to the backend, by using the ng-click directive of angular and add an attribute type='button' to button to prevent triggering the submit of the form.
Your button would be like:
<button type="button" class="btn btn-success" id="addMessage" name="addMessage" ng-click="addMessageClick(message)">
Documentation on Angular $http: https://docs.angularjs.org/api/ng/service/$http
angular.module('app', []);
angular.module('app', []).controller('validateCtrl', ['$scope', '$http',
function($scope) {
//You could pass the message model here as a parameter or access it using $scope.message
$scope.addMessageClick = function(message) {
//Use AngularJS's $http or jQuery Ajax to post to backend and send the message model
console.log('test');
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<html>
<head></head>
<body ng-app="app">
<form name="messageForm" ng-controller="validateCtrl" novalidate>
<button ng-click="addMessageClick('test')">Test</button>
</form>
</body>
</html>
You have added the submit button with in the form, and when you click on the submit button along with ajax call because of the form the page is getting reloaded
Please put that submit button outside of the form tag and check, your page reloading problem will be resolved
I have a form to edit user and i would like to insert user data from database into forms' fields. What i do is
Link
Edit
Script
function editUser(url) {
$( "#edit-form" ).dialog( "open" );
$.ajax({
url: url,
type: "POST",
success: function (resp) {
$('input[name="elogin"]').val(resp.login);
}
})
}
Form
<div id="edit-form" title="Edit user">
<p class="validateTips">All form fields are required.</p>
<form:form>
<fieldset>
<label for="elogin">Login</label>
<input type="text" name="elogin" id="elogin" class="text ui-widget-content ui-corner-all" />
</fieldset>
</form:form>
</div>
My Spring controller returns following(in wrapper i have field login)
#RequestMapping(value="/edit/{userLogin}", method=RequestMethod.POST)
#ResponseBody
public Wrapper edit(#PathVariable String userLogin) {
return wrapper.wrap(userService.findByLogin(userLogin));
}
But the form is empty. I also tried to set manual values but still no use. Please help me set input field value.
You should send your form data with your post request.
$.ajax({
url: url,
type: "POST",
data:$('form').serialize(),
success: function (resp) {
$('input[name="elogin"]').val(resp.login);
}
})
function editUser(url) {
$( "#edit-form" ).dialog( "open" );
$.ajax({
url: url,
type: "POST",
success: function (resp) {
$('#elogin').val(resp.login);
}
})
}
Should work just fine, as you've set an ID for the input.
Not quite sure you have the order right, surely you would make the ajax call first and then open up the jQuery dialog?
Either way, you could supply data into the dialog as follows;
//call ajax method to get value you want to show.
var somevariable = etc.....
var dto = {
loginName: somevariable
}
$( "#edit-form" ).data('params', dto).dialog( 'open' );
Then in your dialog use the open() method.
$("#edit-form").dialog({
bgiframe: true,
autoOpen: false,
height: 280,
width: 320,
draggable: false,
resizable: false,
modal: true,
open: function () {
//so values set in dialog remain available in postback form
$(this).parent().appendTo("form");
//get any data params that may have been supplied.
if ($(this).data('params') !== undefined) {
//stuff your data into the field
$("#elogin").val($(this).data('params').loginName);
}
}
});