I have form action with textarea and submit button
<form method="post" action="/analyze">
<div class="form-group">
<label for="text">Input text:</label>
<textarea class="w-100" name="text" id="text" cols="30" rows="10"></textarea>
</div>
<div class="form-group d-flex justify-content-center">
<input type="submit" class="btn__submit btn btn-dark my-auto" value="Обработать">
</div>
</form>
<div class="row">
<div class="col">
<p th:text="#{nertext}"></p>
</div>
</div>
When I click submit button, i want to get processed text from server in Spring Boot and paste in tag p in div col.
Java Controller
#RequestMapping(value = "/analyze", method = RequestMethod.POST)
public String analyzeText(#RequestParam String text, Model model) {
System.out.print(classifier.classifyToString(text, "tsv", false));
String asd = classifier.classifyToString(text, "tsv", false);
model.addAttribute("nertext", asd);
return "/analyze";
}
How can i do submit without reload page
Use the Fetch API (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) and the onsubmit event listener (https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onsubmit) to submit the form with JavaScript without reloading the page:
let form = document.getElementById("the-form");
form.onsubmit = function (e) {
e.preventDefault();
fetch(form.action, {
method: "post",
body: new FormData(form)
}).then(response => {
// do something with the response...
});
}
The e.preventDefault() makes sure that the page is not reloaded when you click the submit button. This assumes your form has the id the-form, like this:
<form id="the-form" method="post" action="/analyze"> ... </form>
Related
I have a side bar for my user profile page which has two items for 1) Updating the information and 2) showing the reviews that the user has already written.
The first item works perfectly (as it includes a form and has a submit button). But for the second one, I have no idea. The goal is that when I click on My Reviews, a method from the controller class is called, the reviews of the user are extracted from the database and the results are shown on the right side of the page.
As I don't have a submit button or a form for the second item, I don't know how I can implement it.
Here is my code:
<div class="module-inner">
<div class="side-bar">
<nav class="side-menu">
<div class="col-xs-3">
<ul class="nav nav-pills nav-stacked">
<li class="active"><a data-toggle="pill" href="#profile">Profile</li>
<li class="active"><a data-toggle="pill" href="#review">My
Reviews</a></li>
</ul>
</div>
</nav>
</div>
<div class="content-panel">
<div class="col-xs-9">
<div class="tab-content">
<div id="profile" class="tab-pane fade">
<form class="form-horizontal" th:action="#{/edit_profile}"> <fieldset class="fieldset">
<h3 class="fieldset-title">Personal Info</h3>
<div class="form-group">
<label class="col-md-2 col-sm-3 col-xs-12 control-label">User
Name</label>
<div class="col-md-10 col-sm-9 col-xs-12">
<input type="text" class="form-control"
th:disabled="${currentUser.email}"
th:value="${currentUser.email}">
</div>
</div>
<div class="form-group">
<label class="col-md-2 col-sm-3 col-xs-12 control-label">First
Name</label>
<div class="col-md-10 col-sm-9 col-xs-12">
<input name="firstname" type="text" class="form-control"
th:value="${currentUser.firstname}">
</div>
</div>
<div class="form-group">
<label class="col-md-2 col-sm-3 col-xs-12 control-label">Last
Name</label>
<div class="col-md-10 col-sm-9 col-xs-12">
<input name="lastname" type="text" class="form-control"
th:value="${currentUser.lastname}">
</div>
</div>
</fieldset>
<hr>
<div class="form-group">
<div
class="col-md-10 col-sm-9 col-xs-12 col-md-push-2 col-sm-push-3 col-xs-push-0">
<input class="btn btn-primary" type="submit"
value="Update Profile">
</div>
</div>
</form>
</div>
<div id="review" class="tab-pane fade">
<h3>Menu 2</h3>
<p>You have no reviews yet.</p>
</div>
</div>
</div>
</div>
</div>
Here is my controller:
#RequestMapping(value = "/findUserReviews", method = RequestMethod.GET)
public ModelAndView findUserReviews() {
ModelAndView modelAndView = new ModelAndView();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = userService.findUserByEmail(auth.getName());
..
modelAndView.addObject("reviews", reviewRepository.findUserRevies());
modelAndView.setViewName("profile");
return modelAndView;
}
I use the following technologies: Spring boot, Hibernate and Thymeleaf.
Any help would be appreciated.
Final update: The provided code in the accepted answer works, provided that I don't return a ModelAndView but a List<Review>.
With Ajax calls you can call the controller endpoints using javascript. One ajax call looks like this :
function getReviews() {
$.ajax({
type: "GET",
url: "/users/findUserReviews", //example
dataType: "JSON",
success: function (data) {
//do something with this JSON
fillReviews(data);
}
});
}
Now you can use this function as an on-click event for your button. And the fillReviews() is a function that gets the element with id="review" from the jsp page and create the list tree with the fetched data.
function fillReviews(data) {
var reviewDiv= document.getElementById('review');
var reviewList = document.createElement('ul');
for ( var i=0 ; i < data.length; i++)
{
var reviewListItem = createListItem(data[i]);
reviewList.appendChild(reviewListItem);
}
reviewDiv.appendChild(reviewList);
}
And createListItem(data[i]) could look like this:
function createListItem(data)
{
var listItem = document.createElement('li');
listItem.innerHTML = data["reviewName"]; // for example ..
return listItem;
}
And now all you have to do is to call getReviews() here :
<button onclick="getReviews()"/>
EDIT : The "data" from the ajax call is a JSON. So the "/users/findUserReviews" should return a List<Review> for example. And there is no need to change your original "/findUserReviews" endpoint. This was only an example, you can create a new endpoint in your controller which returns a list.
i am new to AngularJs, Initially when page loads ie. when loadResponseData() is processing i need to show progress div and after ajax call completed need to show success div with response data. but success is not showing
after loadResponseData() is completed. Is there any way to show progress bar before completing ajax call and should show success div after response received from ajax call. Sorry for my english and kindly save my day.
<%
PayBean payBean = (PayBean) session.getAttribute("payData");
%>
<div ng-controller="payCtrl" ng-init="loadResponseData()" id="loadResponseData">
<div class="row">
<div class="col-12 col-md-12 col-sm-12 col-lg-8">
<form id="response">
<div class="row row-space" ng-if="status=='success'">
// load response data in elements
</div>
<div class="row row-space" ng-if="status=='progress'">
// Progress bar takes place
</div>
</form>
</div>
<div>
Method in payCtrl:
$scope.loadResponseData = function() {
$http.post(contextRoot + getResponseData(function(data) {
var status = sessionStorage.getItem("status");
$scope.status = status ;
sessionStorage.setItem('data', JSON.stringify(data));
});
};
try this example in here $timeout directive replace with $http and use ng-show instead of ng-if
var app = angular.module('app',[]);
app.controller('payCtrl',function($timeout,$scope){
$scope.status = "progress"; //by default set as progress
$scope.loadResponseData = function() {
console.log("yes called");
$timeout(function(){
$scope.status = "success";
},2000);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' class="container" ng-controller="payCtrl" ng-init="loadResponseData()" id="oadResponseData">
<div class="row">
<div class="col-12 col-md-12 col-sm-12 col-lg-8 center">
<form id="response" class="success">
<div class="row row-space" ng-show="status== 'success'">
<h1>success code loaded</h1>
</div>
<div class="row row-space" ng-show="status== 'progress'">
<h1>Progress code loaded</h1>
</div>
</form>
</div>
<div>
Because you are using ng-if directive it creates new scope so status isn't visible. try use controllerAs syntax or use ng-hide or ng-show directive.
Try this one
<div ng-controller="payCtrl as vm" ng-init="vm.loadResponseData()" id="loadResponseData">
<div class="row">
<div class="col-12 col-md-12 col-sm-12 col-lg-8">
<form id="response">
<div class="row row-space" ng-if="vm.status=='success'">
// load response data in elements
</div>
<div class="row row-space" ng-if="vm.status=='progress'">
// Progress bar takes place
</div>
</form>
</div>
<div>
and in controller use var vm = this; instead $scope;
var vm = this;
vm.loadResponseData = function() {
vm.post(contextRoot + getResponseData(function(data) {
var status = sessionStorage.getItem("status");
vm.status = status ;
sessionStorage.setItem('data', JSON.stringify(data));
});
};
Created an application. Page A displays a droplist containing list of values. If user clicks on particular account, will display a chart. We have similar button right to the acccount droplist. Those are separate JSP's. If user clicks on Page A, then selected account name should move to those 4 jsp page. I have tried via URL. But not getting. Please help.
JSP 1
<a id="priorityCallAnalysis" class="item"> <button type ="button" onclick="getPriorityCall()">Priority </button> </a>
<form:form action="somepage" method="post" commandName="somedata"
id="taskDetails" enctype="multipart/form-data">
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label>Choose Account*</label>
<form:select path="accountName" class="form-control"
id="accountName" onchange="getDashboard()">
<form:option value="" label="--select--"></form:option>
<c:forEach items="${accountList}" var="accountName">
<form:option value="${accountName}" label="${accountName}"></form:option>
</c:forEach>
</form:select>
</div>
</div>
</div>
</form:form>
function getPriorityCall()
{
var accountName = $("#accountName").val();
alert(accountName);
window.location="priorityCall.html?accountName="+accountName+"";
}
Controller
#RequestMapping(value="/priorityCall")
public ModelAndView priorityCall(Map<String, Object> model,#RequestParam ("accountName") String accName)
{
System.out.println("entry");
SampleBean template = new SampleBean ();
model.put("template ", template );
List<String> accountList = Service.getAccountList();
model.put("accountList", accountList);
model.put("accName", accName);
return new ModelAndView("analByPrior","","");
}
JSP : analByPrior
<form:form action="#" method="post" commandName="somedata"
id="taskDetails" enctype="multipart/form-data">
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label>Choose Account*</label>
<form:select path="accountName" class="form-control"
id="accountName" onchange="getAssignmentGroups()">
<form:option value="" label="--select--"></form:option>
<c:forEach items="${accountList}" var="accName">
<form:option value="${accName}" selected="true"> ${accName}</form:option>
</c:forEach>
</form:select>
</div>
</div>
</div>
</form:form>
UPDATE
While clicking on Priority Button, this controller is getting called, instead of PriorityCall.. I dont know y..
#RequestMapping("/priorityCallAnalysis")
public String someAction(#ModelAttribute("accountName") TicketInfo data, Map<String, Object> map,
HttpServletRequest request) {
TicketInfo somedata = new TicketInfo();
map.put("somedata",somedata);
System.out.println(somedata);
System.out.println("acc=" + request.getParameter("accountName"));
/* do some process and send back the data */
map.put("somedata", data);
map.put("accountName", request.getParameter("accountName"));
return "analysisByPriority";
}
First in the .jsp file you can use a global variable to store context path and use this variable as prefix in all the relative paths.
<script>var context = "${pageContext.request.contextPath}"</script>
Now within your js function use the context path and call the controller.
function getPriorityCall(){
var accountName = $("#accountName").val();
alert("contextPath: "+context); // will print your {appName}
window.location=context+"/priorityCall?accountName="+accountName;
}
So your URI looks like below in your request call.
http://localhost:8080/{appName}/priorityCall?accountName={acountName}
PS:
benefit of use this ${pageContext.request.contextPath} is if you change your appName later you dont need to change it in views. It will automatically get the latest contextPath.
If you are using Firefow browser install the firebug add-on and Use it for to verify your requests. So you can validate your URI with params.(If its chrome use Inspect Element to validate URI)
I'm tryring to get an id from url but getParameter return null
this is how I'm sending the id in the url (tool.jsp):
Execute
this the doGet method where I want the id value
protected void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException
{
ToolDAO dao=new ToolDAO();
String id= req.getParameter("id");
Tool t=dao.getToolById(Integer.parseInt(id));
String first = req.getParameter("first");
byte[] bytes = first.getBytes(StandardCharsets.ISO_8859_1);
first= new String(bytes, StandardCharsets.UTF_8);
if(first!=null)
{
String [] input=first.split(" ");
System.out.println("input"+input[0]);
EXEJAVA exe=new EXEJAVA();
FileRead f=new FileRead();
f.writeinputfile(input);
ArrayList l=exe.executetool(t.getTool_path_exe());
req.setAttribute("l",l);
req.setAttribute("first", first);
req.getRequestDispatcher("executetool.jsp").forward(req, res);
}
and this is the form (executetool.jsp)
<form accept-charset="UTF-8" name="form" action="executetool" method="get">
<div class="centre">
<div class="row">
<div class="inline-div">
<label for="ta1">Text in Latin script</label>
<textarea cols="60" rows="15" id="first" name="first" class="inline-
txtarea">${first}</textarea>
</div>
<div class="inline-div">
<input type="button" value="Clear" onclick="javascript:eraseText();">
</div>
<div class="inline-div">
<label for="ta2" >Text in Arabic script</label>
<textarea cols="60" rows="15" id="second" name="second" class="inline-
txtarea"><c:forEach items="${l}" var="s">${s} </c:forEach>
</textarea>
</div>
</div>
</div>
</form>
Since it's method get the url keeps changing everytime the page is refreshed and so the "id=something" part gets replaced by the value of the two text areas that I have in the form what sould I do to always keep that part in the url?
Place a hidden field instead
<input type='hidden' name='id' value='${l.tool_id}'>
Then use input type submit for the button, not a generic <a> tag as that won't submit the form unless you have a javascript code somewhere that will submit the form for you.
You can also place the id in the action attribute of the form.
<form accept-charset="UTF-8" name="form" action="executetool?id=${l.tool_id}" method="get">
I'm attempting to utilize a REST API which is created using Spring by using AngularJS controllers. All I want to do, is send the credentials from the form using AngularJS to the Spring controllers in the back end; however, they don't seem to be communicating at all. Whenever I push the login button, the page simply refreshes. I placed loggers in the Spring controller I'm attempting to call, but they never print anything out which means the controller is never being called.
AngularJS controller:
angular.module('landing', [ 'ngRoute' ])
.controller('authentication',
function($rootScope, $scope, $http, $location) {
$scope.credentials = {};
$scope.login = function() {
$http.post('http://localhost:8090/login', $.param($scope.credentials), {
headers : {
"content-type" : "application/json"
}
}
};
});
The Spring controller I'm attempting to utilize:
#RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<BusinessUser> login(#RequestBody BusinessUser inputUser) {
logger.info(inputUser.getUsername());
logger.info(inputUser.getPassword());
BusinessUser requestedUser = businessUserService.findByUsername(inputUser.getUsername());
if(requestedUser != null)
if(BCrypt.checkpw(inputUser.getPassword(), requestedUser.getPassword()))
return new ResponseEntity<>(requestedUser, HttpStatus.OK);
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
Lastly, here's the form:
<body data-spy="scroll" data-target=".navbar" ng-app="landing">
<div id="home" class="border-shadow">
<div class="container-fluid container-background-color">
<div class="row border-shadow">
<div class="col-lg-7">
<h2 class="heading-margin main-color"><img class="imagesize" src="images/icon.png"/><b>Test Company</b></h2>
</div>
<div class="col-lg-5" ng-controller="authentication">
<form role="form" ng-submit="login()">
<div class="form-group row row-margin">
<div class="col-lg-5">
<input type="text" class="form-control" ng-model="credentials.username" placeholder="Username" required>
</div>
<div class="col-lg-5">
<input type="password" class="form-control" ng-model="credentials.password" placeholder="Password" required>
Forgot Your Password
</div>
<div class="col-lg-2">
<button type="submit" class="btn btn-success">Log in</button>
</div>
</div>
</form>
</div>
</div>
</div>
I can send requests using a Chrome add on called "Postman" and the results come back perfectly, so it's an AngularJS problem. Any idea what's wrong?
EDIT This is a Spring Boot project by the way.