Calling a jsp/html page using ajax in play 2.0 - java

Can anyone guide me how can i call a jsp/html page using ajax in play framework?
I want to open a lightbox on click of a button and want to load that with a page containing data from database.
Currently i have just displayed the message using ajax. Below is the method inApplication.java
public static Result index()
{
return ok(index.render("Your new application is ready."));
}
My index.scala.html is:
#(products: List[Products])
#import helper._
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<h1>#products.size() product(s)</h1>
<table border=1>
<tr>
<td>Product Name</td>
<td>Quantity</td>
<td>Price</td>
</tr>
#for(product <- products) {
<tr>
<td>
#product.productname
</td>
<td>
#product.quantity
</td>
<td>
#product.price
</td>
<td id="items">
<input type="button" value="Add Product" name="#routes.Application.user(product.product_id)" id="but"/>
</td>
</tr>
}
</table>
<div class="result1" style="border: 1px solid black; padding: 5px;">not sent yet...</div>
<script type="text/javascript">
jQuery("#items a").click(
function () {
$.get(jQuery(this).attr("href"), function (data) {
$('.result').html(data);
});
return false;
}
)
</script>

You are on the good way.
Create a new action which will return only the html you need in your div (and not the complete html page).
public static Result detail(Integer productId)
{
Product product = .... (productId);
return ok(productDetail.render(product));
}
// with the route of course
productDetail.scala.html
#(product: Product)
My product #product.product_id is beautiful !
....
You must also add a jquery plugin to display your lightbox (there are a thousand...)
Your JsCode will be something like that:
$("#items a").click(function () {
$("#result").load($(this).attr("href"), function() {
displayPopup(); // code this
});
});
(Or maybe a totally different code if the plugin natively handle ajax...)
In resume, there is a lot of work to do, and many ways to do it.
Just try !

Related

Reading list from Restful API

(First time asking a question here) I created a rest api on java that returns all the cars available in the table Cars from my db. I found a way to get one of the cars with an specific Id and can show it on my page, but it can't understand how to show all the cars in the same page. Basically i don't understand how to show the arraylist that I get from my Rest Api and show it. I see the whole array in the console but not on my html. I not asking for the whole architecture of angular, just want to know how to show on my app-component when I click a button all the items that my rest has.
My rest:
#GET
#Produces({ "application/json" })
public List<CarDto> getCars() {
Car macchina;
// CarDao trasform1 = new CarDao();
CarDto trasform2;
// java 8+ lambda function, Stream (per divertimento)
List<Car> listaMac = carDao.getCars();
List<CarDto> listaMacAgg = new ArrayList<>();
for (int i = 0; i < listaMac.size(); i++) {
trasform2 = new CarDto(listaMac.get(i));
listaMacAgg.add(trasform2);
}
return listaMacAgg;
}
The class from my app component that gets the response from my rest:
import { Component } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'rest agency test';
caid: string = "";
response: any;
response2:any;
constructor(private http: HttpClient){}
ngOnInit(){
}
search(){
this.http.get('http://localhost:8080/rest_agency/rest/hello/'+this.caid)
.subscribe((response) => {
this.response = response;
console.log(this.response);
})
}
allCars(){
this.http.get('http://localhost:8080/rest_agency/rest/hello')
.subscribe((response2) => {
this.response = response2;
console.log(this.response);
})
}
}
my app.component.html
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<p><button (click)="allCars()"> All Cars</button></p>
<p>Search id:<input type="text" [(ngModel)]="caid">
<button (click)="search()">Search</button></p>
<div *ngIf="response2">
<table>
<ul class="heroes">
<tr>
<td>ID</td>
<td>Brand</td>
<td>Color</td>
<td>Year</td>
<td>Price</td>
<td>Sold</td>
</tr>
<tr>
<div *ngFor="let all of response | keyvalue">
<td><li>{{response.caId}}</li></td>
<td><li>{{response?.brand}}</li></td>
<td><li>{{response?.color}}</li></td>
<td><li>{{response?.year}}</li></td>
<td><li>{{response?.price}}</li></td>
<td><li>{{response?.sold}}</li></td>
</div>
</tr>
</ul>
</table>
</div>
<div *ngIf="response"> {{response.caid}}
<table>
<ul class="heroes">
<tr>
<td>ID</td>
<td>Brand</td>
<td>Color</td>
<td>Year</td>
<td>Price</td>
<td>Sold</td>
</tr>
<tr>
<td><li>{{response?.caId}}</li></td>
<td><li>{{response?.brand}}</li></td>
<td><li>{{response?.color}}</li></td>
<td><li>{{response?.year}}</li></td>
<td><li>{{response?.price}}</li></td>
<td><li>{{response?.sold}}</li></td>
</tr>
</ul>
</table>
</div>
</div>
I was expecting the result of all the info of the arraylist that comes from the rest
here is what it shows calling one id : https://imgur.com/FHX4aiO
and here's what happens when call the whole list: https://imgur.com/pdjg4aq)
You say <div *ngIf="response2"> but you never store anything in response2. As a result this block is never shown. Please change to
allCars(){
this.http.get('http://localhost:8080/rest_agency/rest/hello')
.subscribe((response2) => {
this.response2 = response2;
console.log(this.response);
})
}
--
<div *ngIf="response2">
<table>
<ul class="heroes">
<tr>
<td>ID</td>
<td>Brand</td>
<td>Color</td>
<td>Year</td>
<td>Price</td>
<td>Sold</td>
</tr>
<tr>
<div *ngFor="let all of response2 | keyvalue">
<td><li>{{all.caId}}</li></td>
<td><li>{{all.brand}}</li></td>
<td><li>{{all.color}}</li></td>
<td><li>{{all.year}}</li></td>
<td><li>{{all.price}}</li></td>
<td><li>{{all.sold}}</li></td>
</div>
</tr>
</ul>
</table>
</div>
Is the keyvalue really necesary? I highly recommend to type your stuff, avoid any
PS.: Your Lamba function likely looks like this (much shorter)
#GET
#Produces({ "application/json" })
public List<CarDto> getCars() {
return carDao.getCars().stream().map(car => new CarDto(car)).collect(Collectors.toList());
}
Here is error
<div *ngFor="let all of response2 | keyvalue">
change to
<div *ngIf="response">
<table>
<ul class="heroes">
<tr>
<td>ID</td>
<td>Brand</td>
<td>Color</td>
<td>Year</td>
<td>Price</td>
<td>Sold</td>
</tr>
<tr>
<div *ngFor="let respone_one of response | keyvalue">
<td><li>{{respone_one?.caId}}</li></td>
<td><li>{{respone_one?.brand}}</li></td>
<td><li>{{respone_one?.color}}</li></td>
<td><li>{{respone_one?.year}}</li></td>
<td><li>{{respone_one?.price}}</li></td>
<td><li>{{respone_one?.sold}}</li></td>
</div>
</tr>
</ul>
</table>
</div>
Your issue comes from the ngFor let all of response | keyvalue. The values you are looking for are in the all reference, not response.
Try this:
<div *ngFor="let all of response | keyvalue">
<td><li>{{all?.caId}}</li></td>
<td><li>{{all?.brand}}</li></td>
<td><li>{{all?.color}}</li></td>
<td><li>{{all?.year}}</li></td>
<td><li>{{all?.price}}</li></td>
<td><li>{{all?.sold}}</li></td>
</div>

How to set link in onClick method in thymeleaf?

When I do a project with jsp, I try to keep it simple. Now I wanted to do project in Thymeleaf. I wanted to show a confirm dialogue box before deleting. I did it. But while I click ok I get an error. I think I cannot set a link properly inside the onclick method.
Here is my html code:
<tr th:each="student,iterStat : ${studentList}">
<td th:text="${student.id}"></td>
<td th:text="${student.roll}"></td>
<td th:text="${student.firstName}"></td>
<td th:text="${student.lastName}"></td>
<td th:text="${student.age}"></td>
<td>
<!-- <a th:href="#{/deleteStudent/(id=${student.id})}">Delete</a> -->
<a href="#" onclick="confirmRemoveQuestion('#{/deleteStudent/(id=${student.id})}')">
Delete
</a>
</td>
<script>
function confirmRemoveQuestion(link) {
if (show_confirm()) {
window.location = link;
this.hide();
} else {
this.hide();
}
}
function show_confirm() {
return confirm("Are you sure you want to do this?");
}
</script>
</tr>
Here is my Controller:
#RequestMapping(value = "/deleteStudent", method = RequestMethod.GET)
public String deleteStudent(#RequestParam(name="id") int id) {
studentService.deleteStudent(id);
return "redirect:/getStudents";
}
Note: Without dialogue box I can delete an object easily. That code is in comment line.
At last i have fixed it. i have replaced the line
Delete
with
Delete
And i have deleted javascript code. Because it is no longer needed!

Multiple Row JQuery Dialog Issue

I am getting critical issue while working on JQuery.
Do $(this).dialog('close'); removes content which is being bind to display? If yes then how can I prevent this.
Below is my code.
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Dialog - Modal form</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
function cool_function(event){
//alert(event.data.param1);
alert($('#'+event.data.param2).html());
//var dialog = $('#'+event.data.param2).children('#content').html();
$('#'+event.data.param2).children('#content').dialog({
model : true,
autoOpen: true,
buttons: {
"Save": function() {
alert('Content Will be Saved');
},
"Cancel": function() {
$(this).dialog('close');
}
}
});
$('#'+event.data.param2).children('#content').dialog('open');
}
</script>
</head>
<body>
<div id="users-contain" class="ui-widget">
<h1>Existing Users:</h1>
<table id="users" class="ui-widget ui-widget-content">
<thead>
<tr class="ui-widget-header ">
<th>Name</th>
<th>Email</th>
<th>Password</th>
<th>Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>john.doe#example.com</td>
<td>johndoe1</td>
<td class="click" id="clickTest1">
<script>
$("#clickTest1").click({param1: "Hello Darshak", param2: "clickTest1"}, cool_function);
</script>
<div>
<img id='' src="gray.jpg"/>
</div>
<div id='content' title='John Doe' style="display:none;">
<div><textarea>Hello this is Text Area</textarea></div>
</div>
</td>
</tr>
<tr>
<td>Ketan B</td>
<td>ketan.b#example.com</td>
<td>ket1</td>
<td class="click" id="clickTest2">
<script>
$("#clickTest2").click({param1: "Hello Ketan", param2: "clickTest2"}, cool_function);
</script>
<div>
<img id='' src="gray.jpg"/>
</div>
<div id='content' title='Ketan B' style="display:none;">
<div><textarea>One more text area Hurrey!!!</textarea></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Now issue is, Check the alert in code when I load page first time. alert will give me whole div code including the content id code.
Once the content displayed on dialog bar, I close or cancel that dialog then try to click the same first row again and it doesn't have content div at all and I could not get dialog again.
Below is screen shot to understand it better.
Dialog box 1
Dialog display only first time when I click on comment image
Update - Answer
I got my answer. Here are the changes in same.
Column change is like this,
<td class="click" id="clickTest2">
<script>
$("#clickTest2").click({param1: "content2", param2: "One more text area Hurrey!!!"}, cool_function);
</script>
<div>
<img id='' src="file://c://gray.jpg"/>
</div>
<div id='content2' title='Ketan B' style="display:none;">
<div><textarea>One more text area Hurrey!!!</textarea></div>
</div>
and Script change is like this,
function cool_function(event){
$('#'+event.data.param1).dialog({
model : true,
buttons: {
"Save": function() {
alert('Content Will be Saved');
$(this).dialog('close');
},
"Cancel": function() {
$(this).dialog('close');
}
}
});
}
Okay, so i have gone through the whole code that you had provided, and it was way too much complex.. too many recursive calls. So i made the code a little simple and instead of calling the modal recursively (which in fact leads to the un binding of the content from the dialog), i segregated stuff like this :
HTML:
<div id="users-contain" class="ui-widget">
<h1>Existing Users:</h1>
<table id="users" class="ui-widget ui-widget-content">
<thead>
<tr class="ui-widget-header ">
<th>Name</th>
<th>Email</th>
<th>Password</th>
<th>Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>john.doe#example.com</td>
<td>johndoe1</td>
<td class="click" id="clickTest1">
<div>
<img id='' src="http://www.eventbelladesigns.com/sitebuildercontent/sitebuilderpictures/gray.jpg"/>
</div>
<div id='content1' title='John Doe' style="display:none;">
<div><textarea>Hello this is Text Area</textarea></div>
</div>
</td>
</tr>
<tr>
<td>Ketan B</td>
<td>ketan.b#example.com</td>
<td>ket1</td>
<td class="click" id="clickTest2">
<div>
<img id='' src="http://www.eventbelladesigns.com/sitebuildercontent/sitebuilderpictures/gray.jpg"/>
</div>
<div id='content2' title='Ketan B' style="display:none;">
<div><textarea>One more text area Hurrey!!!</textarea></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
JS:
$("#clickTest1").on('click', callModal1);
$("#clickTest2").on('click', callModal2);
function callModal1(){
$(function() {
$( "#content1" ).dialog(({
buttons: [
{
text: "Cancel",
click: function() {
$( this ).dialog( "close" );
}
}
]
}));
});
}
function callModal2(){
$(function() {
$( "#content2" ).dialog(({
buttons: [
{
text: "Cancel",
click: function() {
$( this ).dialog( "close" );
}
}
]
}));
});
}
Here, once the call happens , the modal/dialog will open, but once you close the dialog by clicking on the close icon or the cancel button, the content will not be un loaded and the dialogues will still appear during subsequent clicks.
I have binned it out for you, you can see the working solution at : http://jsbin.com/oxucak/1/edit. And remember to run with js.

Using jquery-ajax with play 2.0 framework

I have a problem where in i have to fetch the particular data of row on clicking that particular rows button and have to display that data via ajax on the same page.
Here is the code of index.scala.html:
#(products: List[Products])
#import helper._
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<h1>#products.size() product(s)</h1>
<table border=1>
<tr>
<td>Product Name</td>
<td>Quantity</td>
<td>Price</td>
</tr>
#for(product <- products) {
<tr>
<td>
#product.productname
</td>
<td>
#product.quantity
</td>
<td>
#product.price
</td>
<td>
<input type="button" value="Add Product" name="#routes.Application.user(#product.product_id)" id="but"/>
</td>
</tr>
}
</table>
<div class="result" style="border: 1px solid black; padding: 5px;">not sent yet...</div>
<script type="text/javascript">
jQuery("#but").click(
function () {
$.get(jQuery(this).attr("name"), function (data) {
$('.result').html(data);
});
return false;
}
)
</script>
My Application.java contains the method as shown below:
public static Result user( id){
return ok("Play's controller told that you're about to get data for user no. "+id);
}
The problem i am facing is in the line:
**<input type="button" value="Add Product" name="#routes.Application.user(#product.product_id)" id="but"/>**
Error is: Compilation error
illegal start of simple expression
Can anyone please help to load the dymanic data.
Please remove the second #:
#routes.Application.user(product.product_id)
The second one is not needed, since the first indicates that you're in the templating language.

How to evaluate a JSP tag which is stored in a String?

I have a Struts action class that sets a String with the markup of a custom JSP tag as request attribute. The action class forwards this to a JSP page, which contains another tag wherein the request attribute is printed. However, the custom JSP tag is not parsed and is displayed as plain text. The following shows how the JSP has rendered it:
<%# taglib uri="/tld/CdrReconTags.tld" prefix="reconTags" %>
<reconTags:renderHTML>
<form id=F_3_2>
<table align='center' width='100%' style='border:1px solid black;' cellpadding='0' cellspacing='0'>
<tr>
<td colspan='2'> </td>
</tr>
<tr>
<td align='center'>
<div class='label'>
<strong style='white-space: nowrap;'>STARTDATE : </strong>
</div>
</td>
<td>
<div class='label'>
<strong style='white-space: nowrap;'>
<reconTags:reportDatesDropDown id="STARTDATE_3_3" />
<span style='color:red;font-weight: bold; font-size: 20px;'>*</span>
</strong>
</div>
</td>
<td align='center'>
<div class='label'>
<strong style='white-space: nowrap;'>ENDDATE : </strong>
</div>
</td>
<td>
<div class='label'>
<strong style='white-space: nowrap;'>
</reconTags:renderHTML>
Note the unparsed custom JSP tag <reconTags:reportDatesDropDown id="STARTDATE_3_3" />. How can I let JSP evaluate it? The following code is the taghandler for <reconTags:renderHTML> and does not evaluate the body, as shown in the output above.
public class DynamicHTMLRendererTagHandler extends BodyTagSupport
{
private static final long serialVersionUID = 6457283471933854138L;
public int doStartTag() throws JspException
{
return EVAL_BODY_BUFFERED;
}
public int doAfterBody() throws JspException
{
/* Grab the body content */
BodyContent body = this.getBodyContent();
try
{
body.writeOut(body.getEnclosingWriter());
} catch (IOException e)
{
throw new JspTagException(e.toString());
}
return SKIP_BODY;
}
}
that reconTag should be with the initial code itself, and not by being added as a String output...
Do Note that what JSP does is:
1 - parse the document for tags.
2 - fills up with the Java outputs that are requested by the document.
Since this call is only done AFTER the tags are interpreted it's normal for these tags to come out as plain text.
If you want to add some sort of dynamic tags to your document you'll have to figure out a way of building the document with these tags in place prior to having it parsed... this however, might be a huge headache, if not impossible.

Categories