Using jquery-ajax with play 2.0 framework - java

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.

Related

How to submit table data in Spring Thymeleaf

I am following given link to submit table data to be saved in database
http://viralpatel.net/blogs/spring-mvc-multi-row-submit-java-list/
But the difference between given link and my implementation is that the front-end of link uses JSTL (JSP) while i am using Thymeleaf (HTML)
Below are the files being used
HTML Form :
<form method="POST" th:action="#{/updateAllRules}" th:field="${ruleForm}">
<table>
<thead>
<tr>
<th>S No</th>
<th>Title</th>
<th>Body</th>
</tr>
</thead>
<tbody>
<tr th:each="ruleModel,iteration : ${allRules}">
<td th:text="${ruleModel.id}"></td>
<td><input type="text" th:name="${'rule'+iteration.index+'.title'}" th:value="${ruleModel.title}"></td>
<td><input type="text" th:name="${'rule'+iteration.index+'.body'}" th:value="${ruleModel.body}"></td>
</tr>
</tbody>
</table>
<br>
<input type="submit" value="Update All">
</form>
Model Class :
public class Rule {
private Integer id;
private Date timestamp;
private String title;
private String body;
// constructor and Getter/Setters
}
Form Class :
public class RuleForm {
private List<Rule> rule;
public List<Rule> getRule() {
return rule;
}
public void setRule(List<Rule> rule) {
this.rule = rule;
}
}
Controller Method :
#RequestMapping(value = "/updateAllRules", method = RequestMethod.POST)
public String updateAllRules(#ModelAttribute("ruleForm") RuleForm ruleForm) throws IOException
{
System.out.println(ruleForm); // this prints com.web.model.RuleForm#235f9fcb
System.out.println(ruleForm.getRule()); //this prints null
return "redirect:/admin";
}
Please let me know what i am missing.
UPDATE 1:
Made changes as suggested. My new HTML form is as below
<form method="POST" th:action="#{/updateAllRules}" th:object="${ruleForm}">
<table>
<thead>
<tr>
<th>S No</th>
<th>Title</th>
<th>Body</th>
</tr>
</thead>
<tbody>
<tr th:each="rule,iteration : ${ruleForm}">
<td th:field="*{rule[__${iteration.index}__].id}"></td>
<td><input type="text" th:field="*{rule[__${iteration.index}__].title}"></td>
<td><input type="text" th:field="*{rule[__${iteration.index}__].body}"></td>
</tr>
</tbody>
</table>
<br>
<input type="submit" value="Update All">
</form>
On making these changes following exception is being received when the page loads.
org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'rule' cannot be found on object of type 'java.util.ArrayList' - maybe not public?
Please see that i am sending original list in model attribute "ruleForm" on page load. Once page loads the data and user make changes , i want to POST complete table back to controller.
Forms should have a th:object, rather than a th:field:
<form method="POST" th:action="#{/updateAllRules}" th:object="${ruleForm}">
Instead of using th:name and th:value, you should instead be using th:field which does both of those for you. Fields also should be specified using the *{...} syntax, which assumes the th:object automatically.
<input type="text" th:field="*{rule[__${iteration.index}__].title}" />
Everything else looks correct to me.

how to pass checkbox value(checked/unchecked) to controller as href parameter in jsp

I am a beginner in jsp.I want to get data from database and show checked on a checkbox depending on db value i.e. 0 or 1.This is working for me.But I also want o that when I check or uncheck the checkbox it will reset value and pass it to controller as a href parameter.
here is my jsp:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# page session="false" %>
<html>
<head>
<title>Investor Account</title>
</head>
<body>
<script type="text/JavaScript">
function updateCheck(){
if(document.getElementById('chk').checked){
document.getElementById('chk').value = 1;
location.href=""
alert(document.getElementById('chk').value);
}
else{
document.getElementById('chk').value = 0;
alert(document.getElementById('chk').value);
}
}
</script>
<div align="center">
<h1>Investor Account List</h1>
<table border="1">
<th>ID</th>
<th>Investor Code</th>
<th>Investor Name</th>
<th>SMS Subscriber</th>
<th>Action</th>
<c:forEach var="investorAcc" items="${listInvestorAcc}" varStatus="st">
<tr>
<td>${st.index + 1}</td>
<td>${investorAcc.investor_code}</td>
<td>${investorAcc.investor_name}</td>
<td> <input type="checkbox" id="chk" name="chkSms" value= <c:if test="${investorAcc.sms_sub==1}">1</c:if> onclick="updateCheck();"
<c:if test="${investorAcc.sms_sub==1}">checked="checked"</c:if>/>
<td>
1</c:if>"> Update
</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>
To update checkbox value, the easiest way is to use form in loop. Try
<c:forEach var="investorAcc" items="${listInvestorAcc}" varStatus="st">
<form action="updateInvestorAcc">
<input type="hidden" name="id" value="${investorAcc.id}"/>
<tr>
<td>${st.index + 1}</td>
<td>${investorAcc.investor_code}</td>
<td>${investorAcc.investor_name}</td>
<td>
<c:choose>
<c:when test="${investorAcc.sms_sub==1}">
<input type="checkbox" id="chk" name="chkSms"
value="${investorAcc.sms_sub}" checked="checked"/>
</c:when>
<c:otherwise>
<input type="checkbox" id="chk" name="chkSms"
value="${investorAcc.sms_sub}"/>
</c:otherwise>
</c:choose><td> <!-- end of checkbox -->
<td><input type="submit" value="Update"></td>
</tr>
</form>
</c:forEach>
Edit:
You need a Servlet to get updated value
#WebServlet("/updateInvestorAcc")
public class UpdateInvestorAcc extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String idStr=request.getParameter("id");
int id= Integer.parseInt(idStr);// If you need to parse to int
String[] chkSms=request.getParameterValues("chkSms");
boolean isChkSms =false;
if(chkSms !=null && chkSms.length > 0){//If checkbox is checked than assign it with true or 1
isChkSms=true;
}
// Now update the DB with id and checkbox value.
}
you can simplify the middle bit in the other posters suggestion with a basic IF test. Because it's only going to be 1 or 0 (choose is overkill IMO). Technically because it's 1/0 you don't even need to ==1 comparitor, just reference it raw in the test="" block as test="${investorAcc.sms_sub}". The JSTL is smart enough to handle all angles (including NULL). 1=true, 0=false, NULL=false.
<c:forEach var="investorAcc" items="${listInvestorAcc}" varStatus="st">
<form action="updateInvestorAcc">
<input type="hidden" name="id" value="${investorAcc.id}"/>
<tr>
<td>${st.index + 1}</td>
<td>${investorAcc.investor_code}</td>
<td>${investorAcc.investor_name}</td>
<td>
<input type="checkbox" id="chk" name="chkSms"
value="${investorAcc.sms_sub}" <c:if test="${investorAcc.sms_sub==1}">checked="checked"</c:if>/>
<td> <!-- end of checkbox -->
<td><input type="submit" value="Update"></td>
</tr>
</form>
</c:forEach>
For your second bit about the 'unchecked' box passing invalid values. That's a super annoying thing with HTML. Unchecked boxes get 'dropped to null' when a form is submitted. A lot of people are supplementing with a 2nd hidden input to get this done without NULL errors (note, it MUST be second). Different "ID", but same "NAME" so the Servlet will see it and capture the 'unchecked' value from it instead of the NULLed original checkbox:
ex:
<td>
<input type="checkbox" id="chk" name="chkSms"
value="${investorAcc.sms_sub}" <c:if test="${investorAcc.sms_sub==1}">checked="checked"</c:if>/>
<input type="hidden" id="chk_0" name="chkSms"
value="0"/>
<td> <!-- end of checkbox -->

How to check checkbox based on row table (database)?

I've a form that can edit/update data build in modal (bootstrap), I want to check the checkbox based on my row table...
this is my edit/update form :
<td><fieldset id="menu_e">
<input type="checkbox" name="menu" value="User" class="ceksmenu">User<br />
<fieldset id="sub_menu_user_e">
<input type="checkbox" name="sub_menu_user" value="User1" class="ceksmuser">User1
<input type="checkbox" name="sub_menu_user" value="User2" class="ceksmuser">User2
<input type="checkbox" name="sub_menu_user" value="User3" class="ceksmuser">User3<br />
</fieldset>
<input type="checkbox" name="menu" value="Monitoring" class="ceksmenu">Monitoring<br />
<fieldset id="sub_menu_monitoring_e">
<input type="checkbox" name="sub_menu_monitoring" value="Monitoring1" class="ceksmmonit">Monitoring1
<input type="checkbox" name="sub_menu_monitoring" value="Monitoring2" class="ceksmmonit">Monitoring2
<input type="checkbox" name="sub_menu_monitoring" value="Monitoring3" class="ceksmmonit">Monitoring3<br />
</fieldset>
<input type="checkbox" name="menu" value="Parameter" class="ceksmenu">Parameter<br />
<fieldset id="sub_menu_parameter_e">
<input type="checkbox" name="sub_menu_parameter" value="Parameter1" class="ceksmparam">Parameter1
<input type="checkbox" name="sub_menu_parameter" value="Parameter2" class="ceksmparam">Parameter2
<input type="checkbox" name="sub_menu_parameter" value="Parameter3" class="ceksmparam">Parameter3</fieldset>
</fieldset>
</td>
this is my table code :
<tbody>
<c:forEach var="row" items="${requestScope.authorityuser}">
<tr>
<td>${row.id_authority}</td>
<td>${row.nama_authority}</td>
<td><c:forEach var="u" items="${row.menu}">|${u}| </c:forEach></td>
<td><c:forEach var="u" items="${row.sub_menu_user}">|${u}| </c:forEach></td>
<td><c:forEach var="u" items="${row.sub_menu_monitoring}">|${u}| </c:forEach></td>
<td><c:forEach var="u" items="${row.sub_menu_parameter}">|${u}| </c:forEach></td>
<input type="hidden" name="id_authority" value="${row.id_authority }">
<td><a href="#update" role="button" data-toggle="modal"
class="update" id_update="${row.id_authority}"
nama_authority="${row.nama_authority}" menu="${row.menu}"
sub_menu_user="${row.sub_menu_user}" sub_menu_monitoring="${row.sub_menu_monitoring}"
sub_menu_parameter="${row.sub_menu_parameter}"> <i class="icon-edit"></i> <spring:message code="edit" text="default text" />
</a><a href="#delete" role="button" data-toggle="modal"
class="delete" id_delete="${row.id_authority}">
<i class="icon-trash"></i> <spring:message code="delete" text="default text" />
</a></td>
</tr>
</c:forEach>
</tbody>
I tried like this and it's not work :(
<script type="text/javascript">
$(document).ready(function() {
$('.update').click(function() {
if($('input:checkbox[name=sub_menu_user]').is(':checked')){
$('input:checkbox[name=sub_menu_user]').prop('checked', true);
}else{
$('input:checkbox[name=sub_menu_user]').prop('checked', false);
}
var id_update = $(this).attr("id_update");
var nama_authority = $(this).attr("nama_authority");
var menu = $('input:checkbox[name=menu]').is(':checked');
var sub_menu_user = $('input:checkbox[name=sub_menu_user]').is(':checked');
var sub_menu_monitoring = $('input:checkbox[name=sub_menu_monitoring]').is(':checked');
var sub_menu_parameter = $('input:checkbox[name=sub_menu_parameter]').is(':checked');
$('#id_authority_e').val(id_update);
$('#id_authority_l').val(id_update);
$('#nama_authority_e').val(nama_authority);
$('#menu_e').val(menu);
$('#sub_menu_user_e').val(sub_menu_user);
$('#sub_menu_monitoring_e').val(sub_menu_monitoring);
$('#sub_menu_parameter_e').val(sub_menu_parameter);
});
$('.delete').click(function() {
var id_delete = $(this).attr("id_delete");
$('#id_authority_d').val(id_delete);
});
$('#example').dataTable({
});
});
</script>
this is the output of my table
how is it possible?? any help will be pleasure :)
this is my edit/update form
this is my table
Well i just looked at the javascript portion, here is my answer.
You would have to read the Text in the HTML and parse it, for that you need to be able to get a specific cell. With the row_id you can narrow your search down and over the classname for the cloumn you get the right cell.
I hope this short working demo on jsFiddle might help you with your "problem".
HTML:
<table class="data-table">
<tr id="row_1"><td class="authority">...</td>
<!-- id should be constructed something like id="row_${row.id_authority}" -->
<td class="...">...</td>
<td class="users">|user1|user2|user3|</td>
<td class="...">...</td>
<td> edit </td>
<!-- id_update should be as in your code id="${row.id_authority}" -->
</tr>
</table>
Javascript:
$(function(){
$(".update").click(function(){
var id_update = $(this).attr("id_update");
var users = $("#row_" + id_update).find(".users").text().split("|").slice(1,-1);
for(var user in users)
alert(users[user]);
});
});
// tested on Windows 7 with Chrome 33+
edit: added some "Code"
possible JSP Code:
<c:forEach var="row" items="${requestScope.authorityuser}">
<tr id="row_${row.id_authority}">
<td class="...">${row.id_authority}</td>
<td class="...">...</td>
<td class="users"><c:forEach var="u" items="${row.sub_menu_user}">|${u}| </c:forEach></td>
<td class="...">...</td>
<td>
<a href="#update" role="button" data-toggle="modal"
class="update" id_update="${row.id_authority}"
nama_authority="${row.nama_authority}" menu="${row.menu}"
sub_menu_user="${row.sub_menu_user}" sub_menu_monitoring="${row.sub_menu_monitoring}"
sub_menu_parameter="${row.sub_menu_parameter}"> <i class="icon-edit"></i> <spring:message code="edit" text="default text" />
</a> ...
</td>
</tr>
</c:forEach>
edit:
i updated the jsFiddle (this link is different to the one above).
the important part is here...
for(var user in users){
// it could be optimized, but like this it could work.
$("input[name='sub_menu_user'][value='" + users[user] + "']")[0].checked=true;
}
// tested on Windows 7 with Chrome 33+

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.

Calling a jsp/html page using ajax in play 2.0

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 !

Categories