I am aware that this is a recurring question, for all web programming languages. I have spent five hours trying to apply solutions found here without success, which is why I write this question.
What I want:
I have two selectors, both when loading the page are filled with information directly from the database successfully.
If I select an option from the first selector (selectSchraubfall) I want the second selector (selectWorkplace) to update, showing only those possible results for the first selector.
What I did:
Created the selectors inside the jsp getting the information from a servlet that executes a sql query ✔.
Created the onChange event listener for the first selector ✔.
Created a js function with an Ajax call to make a new query from the controller and get a filtered list of options for the second select ✔.
Inside the success function I tried to inject the result of the Ajax call into the second select via .html(), it does not work. How can I inject JSTL? In other words, how can I inject the content of wpFilteredList in selectWorkplace? ✕
What I tried:
Using JSON -> Didn't work ✕
Using JAVA scriplets inside the JSP -> Didn't work ✕
JSP
html:
<div class="row">
<div class="col-md">
<label style="font-size: 20px;">Schraubfall ID: </label>
<select id="selectSchraubfall" name="selectSchraubfall" form="formResult" class="form-control" >
<option>Select ID</option>
<c:forEach items="${screwdriverlist}" var="screwdriverlist">
<option><c:out value="${screwdriverlist.screwdriverid}" /></option>
</c:forEach>
</select>
</div>
<div class="col-md">
<label style="font-size: 20px;">Workplace: </label>
<select id="selectWorkplace" name="selectWorkplace" form="formResult" class="form-control">
<option>Select workplace</option>
<c:forEach items="${workplaceList}" var="workplaceList">
<option><c:out value="${workplaceList.workplacename}" /></option>
</c:forEach>
</select>
</div>
</div>
JS:
var options="";
$("#selectSchraubfall").on('change',function(){
var value=$(this).val();
resultSelectValue('Schraubfall', value);
});
function resultSelectValue(columnName, value) {
// Statements
var params = {};
params.colname = columnName;
params.valuecol = value;
$.ajax({
type: "GET",
url: 'ResultSelectValuesController',
data: params,
success: function (data) {
var workplaceArray = [];
$("#selectWorkplace").empty().html();
<c:forEach items="${wpFilteredList}" var="wpFilteredList">
//<option value="${wpFilteredList.name}"></option>
workplaceArray.push('"${wpFilteredList.name}"');
</c:forEach>
$("#selectWorkplace").html(workplaceArray); //I know this is not correct but how can I do something similar using the wpFilteredList?
},
error : function(ex) {
swal("Error", "Error loading workplace info " + ex.Message, "error");
}
});
}
Java (ResultSelectValuesController)
#Override
public void processMethodGET(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String colname = request.getParameter("colname");
String valuecol = request.getParameter("valuecol");
if(colname.contains("Schraubfall")) {
//GET WORKPLACES
workplacesfilteredlist = wcdao.workplacesListFilter(colname, valuecol);
request.setAttribute("wpFilteredList", workplacesfilteredlist);
}
request.getRequestDispatcher("/Views/Results/ResultPage.jsp").forward(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
processError(e, request, response);
}
}
Below block is JSTL server side interpolation. Javascript can't process this syntax.
You need to replace below JSTL code with javascript version which pushes the data from ajax requests response to workplaceArray.
<c:forEach items="${wpFilteredList}" var="wpFilteredList">
//<option value="${wpFilteredList.name}"></option>
workplaceArray.push('"${wpFilteredList.name}"');
</c:forEach>
The code below is adds new data to the select element as option elements. You need to replace data as your response type.
data.forEach(workplace => {
$('#selectWorkplace').append($('<option>', {
value: workplace,
text: workplace
})
})
After the changes you don't need the below code anymore.
$("#selectWorkplace").html(workplaceArray);
Finally I solved the problem by myself, It worked using Gson. Basically I am returning an Array of Arrays and I manipulate the data as I want in the JSP.
The code now:
JSP
function resultSelectValue(columnName, value) {
// Statements
var params = {};
params.colname = columnName;
params.valuecol = value;
$.ajax({
type: "GET",
url: 'ResultSelectValuesController',
data: params,
success: function (data) {
$( "#selectWorkplace" ).empty();
$( "#selectSchraubfall").empty();
var htmlWorkplace = "<option>Seleccionar Workplace</option>";
var htmlsf = "<option>Todos los Schraubfalls</option>";
for (i = 0; i < data.length; i++) {
for(j = 0; j < data[i].length; j++){
alert(data[i][j]);
if(i == 0) {
htmlWorkplace += "<option>"+data[i][j]+"</option>";
}
if(i == 1){
if(data[i][j] != 'null' && data[i][j] != null){
htmlsf += "<option>"+data[i][j]+"</option>";
}
}
}
}
$( "#selectWorkplace" ).html(htmlWorkplace);
$( "#selectSchraubfall").html(htmlsf);
JAVA
#Override
public void processMethodGET(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
response.setContentType("application/json");
String colname = request.getParameter("colname");
String valuecol = request.getParameter("valuecol");
if(colname.contains("Atornillador")) {
//GET WORKPLACES
wpfilteredlist = wcdao.workplacesListFilter(colname, valuecol);
//GET SF
sffilteredlist = sfdao.SFListFiltered(colname, valuecol);
ArrayList<ArrayList<String>> listGet = new ArrayList<ArrayList<String>>();
ArrayList<String> wpList = new ArrayList<String>();
ArrayList<String> sfLista = new ArrayList<String>();
for (int i = 0; i < wpfilteredlist.size(); i++) {
wpList.add(wpfilteredlist.get(i).getName());
}
for(int i = 0; i < sffilteredlist.size(); i++) {
sfList.add(sffilteredlist.get(i).getSfname());
}
listGet.add(wpList);
listGet.add(sfList);
Gson gson = new Gson();
JsonElement element = gson.toJsonTree(listGet);
PrintWriter out = response.getWriter();
out.print(element);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
processError(e, request, response);
}
}
Related
My problem is, that I have to implement an AJAX function to display whether the selected item is out of stock or not. However, instead of displaying my error message it kind of duplicates the site completely and I'm very, nothing I've tried seems to work.
My idea behind the code was, that I have a dropdown form with action set to a controller (Webservlet) that handles both doGet and doPost, and an onchange event showing to a javascript function which invokes the AJAX stuff (You can see I'm not very confident in these aspects, I don't know nearly enough about it).
The JSP part that is relevant would be this:
<%#page contentType="text/html" pageEncoding="UTF-8" import="PCConfigurator.*"%>
<%
session.setMaxInactiveInterval(0);
ConfController ctrl = new ConfController();
%>
...
<script type="text/javascript">
var xmlHttpObject = new XMLHttpRequest();
function checkArticle(selectedArticleId) {
var url = '?id=' + selectedArticleId.value;
xmlHttpObject.open('GET', url);
xmlHttpObject.onreadystatechange = handleStateChange;
xmlHttpObject.send();
}
function handleStateChange() {
if (this.readyState == 4 && this.status == 200) {
var response = this.responseText;
var result = document.getElementById("errorDiv");
result.innerHTML = response;
}
}
</script>
<form method="POST" action="ConfController" >
<table>
<h1>PC Konfigurator GO Inc.</h1>
<tr>
<td><br><br></td>
</tr>
<tr>
<td>Welchen Prozessor wollen Sie haben?:</td>
<td><select name="cpuId" onchange="checkArticle(this)">
<%
for (Article article : ctrl.getCertainArticles("CPU")) {
out.print("<option value=\"" + article.getId() + "\">" + article.getName() + "</option>");
}
%>
</select>
</td>
</tr>
...
And the Controller looks something like this:
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
int id = Integer.parseInt(req.getQueryString().split("=")[1]);
if (findArticle(id).getCapacity() < 1) {
resp.getWriter().write("<p><font color=\"red\">Leider ist dieser Prozessor nicht mehr verfügbar.</font></p>");
} else {
resp.getWriter().write("");
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
This is how the site looks on startup. So far so good.
But as soon as I choose another item in the dropdown, well, this happens...
I mean at least the id is right.
Its just the stupid AJAX I cant get to work.
In your code you did not specified the controller for your AJAX request. This is the reason you are getting same as the response and the response shown using AJAX.
In console you can also see the full url which is being called AJAX request by hovering on the ?id=2.
function checkArticle(selectedArticleId) {
var url = 'myController?id=' + selectedArticleId.value;
xmlHttpObject.open('GET', url);
xmlHttpObject.onreadystatechange = handleStateChange;
xmlHttpObject.send();
}
In above code replace myController with your actual controller name which points to your servlet.
I am using STS 3.9.0 Tool, my project based on Spring Boot, Thymeleaf,
Mysql, Html-Bootstrap and JQuery.
I am showing a dropdown component as apartment list which is taken from thymeleaf,which holds entity values, so I am showing apartment name, But passing entity of particular(selected) apartment only.
But I am posting the data using JQUERY via Ajax call..
I have done the code like below
HTML code..
<div class="form-group">
<label for="societyname">Society Name</label>
<select id="societyname" class="form-control">
<option th:each="propertydetails:${propertydetails}" th:value="${propertydetails}" th:text="${propertydetails.propertyname}">
</option>
</select>
</div>
Jquery
var formData = {
entPropertyMaster : $("#societyname").val(),
}
alert(JSON.stringify(formData));
// DO POST
$.ajax({
type : "POST",
contentType : "application/json",
url : url+"/saveflat",
data :JSON.stringify(formData),
dataType : 'json',
success : function(result) {
if(result.status == "saved") {
$("#resultid").html("<strong>" +result.dataObj.flatname+ " Registered Successfully!" );
} else {
$("#resultid").html("<strong>Error</strong>");
}
alert(result.status);
console.log(result);
},
error : function(e) {
alert("Error!");
alert(url);
console.log("ERROR: ", e);
}
});
#controller
//To save the flat registration details
#PostMapping("/saveflat")
public ResponseMsg doSaveFlatDetails(#ModelAttribute EntFlatMaster flatDetails) {
ResponseMsg responsemsg = new ResponseMsg();
EntFlatMaster flatMaster = new EntFlatMaster();
try {
String logResponse = null;
/*for Master*/
if(flatDetails!=null) {
flatMaster = serflatDetails.doSaveFlatDetails(flatDetails);
/*for Log*/
if(flatMaster!=null) {
logResponse = doSaveLogFlatDetails(flatDetails,flatMaster.getPkflatid());
}
/*for response message to web for master and Log both are saved checking process*/
if(logResponse.equals("saved")) {
responsemsg = new ResponseMsg("saved",flatMaster);
} else {
responsemsg = new ResponseMsg("failed",flatMaster);
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
responsemsg = new ResponseMsg("failed",flatMaster);
}
return responsemsg;
}
#Entity
#Entity
#Table(name="flatdetails")
public class EntFlatMaster implements Serializable {
private static final long serialVersionUID = 7066060644146063944L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="pkflatid")
private int pkflatid;
#OneToOne
#JoinColumn(name="fkpropertymasterid")
private EntPropertyMaster entPropertyMaster = new EntPropertyMaster();
}
Please Help to solve this...Thank You
Can you please be more specific with errors you are facing? Stacktrace and so on?
Firstly your Thymeleaf code is wrong, use the below:
<div class="form-group">
<label for="societyname">Society Name</label>
<select id="societyname" class="form-control">
<option th:each="pd :${propertydetails}" th:value="${pd.id}"
th:text="${pd.propertyname}"></option>
</select>
</div>
Look at the th:value="${pd.id}" this will hold the identifier for your property.
While building the form data you need to use pkflatid and not entPropertyMaster
I'm trying to return an arraylist via ajax function call and return the results to my HTML dropdown list.
Below is my ajax function, servlet code and html.
My dropdown list keeps coming back empty. Not sure where it is going wrong.
Servlet code:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer p = Integer.parseInt(request.getParameter("studentid"));
ArrayList<SessionDataBean> result = new ArrayList<>();
String sessid = null;
try ( Connection con = JdbcUtil.getConnection()) {
String sql= "select distinct F.SESSIONID "
+ "from Students F "
+ "where F.studentid = "+p;
try (Statement st = con.createStatement()) {
System.out.println(sql);
ResultSet rs = st.executeQuery(sql);
while (rs.next()){
result.add(new SessionDataBean(rs.getString(1)));
}
} catch (Exception e) {
e.printStackTrace();
}
}
catch (Exception e) {
e.printStackTrace();
}
response.setContentType("application/json");
new Gson().toJson(result, response.getWriter());
}
Ajax function call code:
function listSession(){
var name = document.getElementById("studentid").value;
$.ajax({
url : "<%=context%>/ListSessionsServlet?studentid=" + name,
type : "POST",
async : false,
dataType: "json",
success : function(data) {
var toAppend = '';
$.each(data,function(i,o){
toAppend += '<option>'+o.id+'</option>'; <---issue might be here?
});
$('#sessid').append(toAppend);
}
});
}
HTML code:
<div class="cell">
Select Session for Student
<div class="input-control select mutiple full-size">
<select id="sessid" name="sessid">
</select>
</div>
</div>
Server is expecting a POST parameter "studentid" at
Integer p = Integer.parseInt(request.getParameter("studentid"));
though "name" is passed. Substitute
url : "<%=context%>/ListSessionsServlet?studentid=" + name
for
url : "<%=context%>/ListSessionsServlet?name=" + name
Part of my index.html contains 3 buttons-anchors like this (There is some bootstrap as well)
Index.html
<a id="category1" href="html/auctionBay.html" class="portfolio-link" >
<a id="category2" href="html/auctionBay.html" class="portfolio-link" >
<a id="category3" href="html/auctionBay.html" class="portfolio-link" >
These buttons redirect me to the auctionBay.html which contains a div
auctionBay.html
<div id="result" class="container"></div>
What i need, is when i press a button from the above, to go to the auctionBay.html and accordingly to what was pressed, print the data from the appropriate table (category1-3) from my database into the 'result' div (it's important to be in the div).
I currently have a servlet that can do this statically when auction.html loads using an ajax call
var j = jQuery.noConflict();
function myFunction() {
j.ajax({
type : 'GET',
url : '../auctionsDisplay',
success : function(data) {
j("#result").html(data);
}
});
}
but only works if i specify the category manually.(antiques=category1 for example)
AuctionDisplay.java
public class AuctionsDisplay extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String result = "";
try {
Connection con = DBConnection.getCon();
String category = "antiques";
String query = "select id, name, price from " + category;
PreparedStatement ps = con.prepareStatement(query);
ResultSet rs = ps.executeQuery();
int i;
result = "";
boolean flag = rs.next();
while (flag) {
result += "<div class='container'><div class='row'><h1 id='antiques' class='category'>Antiques</h1></div><div class='row'>";
i = 0;
while (i < 4 && flag) {
ps = con.prepareStatement("select highestBidder, ends from auctions where itemId=?");
ps.setString(1, rs.getString("id"));
ResultSet rs2 = ps.executeQuery();
rs2.next();
String price = rs.getString("price");
if (rs2.getString("highestBidder") != null)
price = rs2.getString("highestBidder");
result += "<div class='col-md-3' portfolio-item>";
result += "<div class='w3-container w3-hover-shadow w3-center'>" + "<h2>" + rs.getString("name")
+ "</h2><div class='w3-card-20' style='width:100%'>"
+ "<input id='2' type='image' src='../img/portfolio/w3.jpg' data-toggle='modal' "
+ "data-target='#MoreInfo'style='width:90%;'>"
+ "<div class='w3-container w3-center responsive'>"
+ "<p style='padding:5px;'>Highest Bid: " + price + "\u20ac <br> " + "Ends at: "
+ rs2.getString("ends") + "<p></div></div></div></div>";
flag = rs.next();
i++;
}
result += "</div></div>";
}
} catch (Exception e) {
e.printStackTrace();
}
out.println(result);
}
I understand jquery, ajax, get-post requests, javascript (no php please), so how can i achieve what i want ? It's propably simple but it's confusing me
You can achieve what you want in javascript thanks to window.LocalStorage. Since you want your data from one page to be sent to another page(where the browser loads a whole new page which results in the loss of any data retrieved by the last page), via javascript you WILL need to make use of localStorage to get the desired results.
How to?
var j = jQuery.noConflict();
function myFunction(category_id) {
//use this id to fetch your appropriate data
j.ajax({
type : 'GET',
url : '../auctionsDisplay',
success : function(data) {
localStorage.setItem("category_result", data);
}
});
}
j('.portfolio-link').click(function(){
var category_id = this.id //this will give you the pressed <a>'s ID value
myFunction(category_id);
})
//then on document load retrieve the localStorage value you stored.
$(document).ready(function () {
if (localStorage.getItem("category_result") !== null) {
//feed the value to the 'results' div
j('#result').html(localStorage.getItem("category_result"));
}
}
Let me know if this helped
I'm with a little problem on my project.
Hi have several jsp's and Java class. In one jsp i create a form with only a input type="file" and type="submit", then I have an ajax call and send all the formdata to a doPost class on my servel. Then I send that file to the DataBase and it all's go fine, my problem is I want to return the id from the database to the .jsp. I can access and have prints on the doPost to check my key, but cant send it to success function inside the ajax call..
Here's my code, i really apreciate any kind of help, thanks!
<form id="uploadDocuments" target="invisible" method="POST" action="UploadDocumentsAjaxService" enctype="multipart/form-data">
<iframe name="invisible" style="display:none;"></iframe>
<h3 style="width: 71%;margin-left: 8%;">ANEXAR FICHEIROS:</h3>
<h4 style="margin-left: 8%; color: #F7A707" >Escolher ficheiro para anexar: </h4>
<input type="file" id="file_input" name="file" size="50" style="width: 60%; margin-left: 8%;"/>
<input type="submit" value="Upload" />
</form>
the I have my Ajax Call:
$("#uploadDocuments").submit(function (e) {
alert(10);
alert($("#uploadDocuments").attr('action'));
$.ajax({
type: $("#uploadDocuments").attr('method'),
url: $("#uploadDocuments").attr('action'),
contentType: $("#uploadDocuments").attr( "enctype"),
data: new FormData($("#uploadDocuments")[0]),
processData: true,
success: function (data) {
alert("submitDocument");
alert();
/* key = data;
addFilesToTable(key); */
return true;
}
});
e.preventDefault();
$(form).off('submit');
return false;
});
And then my servlet class:
protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
response.setContentType("text/html;charset=ISO-8859-1");
PrintWriter out = response.getWriter();
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
ChangeEntityRequestActionBean actionBean = new ChangeEntityRequestActionBean();
if(!isMultipart)
return;
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Sets the size threshold beyond which files are written directly to
// disk.
factory.setSizeThreshold(MAX_MEMORY_SIZE);
// constructs the folder where uploaded file will be stored
String uploadFolder = getServletContext().getRealPath("") + DATA_DIRECTORY;
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Set overall request size constraint
upload.setSizeMax(MAX_REQUEST_SIZE);
String fileName = "";
Long documentKey = null;
String key = "";
try {
// Parse the request
List items = upload.parseRequest(request);
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (!item.isFormField()) {
fileName = new File(item.getName()).getName();
String filePath = uploadFolder + File.separator + fileName;
File uploadedFile = new File(filePath);
System.out.println(filePath);
// saves the file to upload directory
item.write(uploadedFile);
}
documentKey = actionBean.insertDocument(item, fileName);
System.out.println("Key from DAO ------->>>>>"+documentKey);
key = String.valueOf(documentKey);
}
System.out.println("Key in String from DAO ----->"+key);
System.out.println();
out.println("success");
response.flushBuffer();
}catch (FileUploadException ex) {
throw new ServletException(ex);
} catch (Exception ex) {
throw new ServletException(ex);
} finally {
out.close();
}
}
All I want is to send the key value to out.println so I can use that value on a jquery function
In the first line of doPost() in your servlet, change the content-type of the response to "application/json". Then write a JSON string to the output stream. There are libraries available to do this for you, but for something so simple, you can compose the JSON yourself. This might actually have an advantage because your key is a java long; treat it as a string and you don't have to worry about how the integer is represented.
// replace out.println("success"); with this:
out.print("{\"key\": \"" + key + "\"}");
Then in the success callback function, you can access the key as a field of the data object. You'll need to specify the data type in the ajax method (dataType: 'json').
success: function (data) {
var key = data['key'];
addFilesToTable(key);
return true;
}