I am trying to create grails app not using Scaffolding to understand it's "way of thinking" better. :)
I am stuck with edit/update method.
On "edit" button I open the same kind input form as when creating object.
All the fields are filled with info and id is passed in link.
On "Edit the msg" I want to update existing object, but all that I've got was either creating new or having error - Cannot set property 'sender' on null object
My "edit.gsp" looks like this:
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main"/>
</head>
<body>
<h2>Edit this message</h2>
<g:if test="${flash.message}">
<div class="alert alert-error" style="display: block">${flash.message}</div>
</g:if>
<div class="createStuff" id ="inputs">
<g:formRemote url="[action: 'editSave']" update="allTheMessages"
name="updateStatusForm">
<table>
<tr>
<td>Sender:</td>
<td><g:textField name="sender" value="${message.author}"/></td>
</tr>
<tr>
<td>Message</td>
<td><g:textArea name="msg" value="${message.text}"/></td>
</tr>
<tr>
<td>Some status</td>
<td><g:textField name="status" value="${message.status}"/></td>
</tr>
<tr>
<td>Wanna publish?</td>
<td><g:select name="toPublish" from="${['Publish','Archive']}" keys="${[true,false]}"/></td>
</tr>
</table>
<g:submitButton name="Edit the msg"/>
</g:formRemote>
</div>
</body>
</html>
And my method in controller has varied:
def editSave() {
def message2save = Message.get(params.id)
message2save = new Message(text: params.msg, author: params.sender, status: params.status, toPublish: params.toPublish).save(insert: false, update: true) //1st way - still creates new Message - obviously because of "new Message"
message2save.sender = params.sender //part of 2nd way - in this case there appears NullPointerException mentioned above --> Cannot set property 'sender' on null object
message2save.save()
redirect(action:"index")
}
What am I doing wrong? How can I update existing record?
Huge thanks in advance. :)
GORM knows if you're updating a record when you successfully loads it from the database. This is done in your code:
def message2save = Message.get(params.id)
The problem is that you're not sending the id of your message in the forms. So you need to add:
<g:hiddenField name="id" value="${message.id}" />
Related
I have an HTML file that needs to update on the fly. Basically, I want to populate that HTML file based upon the details fetched from Database. Now I don't know how to update the HTML using any java API.
Example:
<head>
<title>Sample</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Sample File</h1>
<p>
<span class="abc">abc</span>
<span class="description"> Sample Document</span>
</p>
<table>
<tr>
<th class="label">Title</th>
<td>Sample Value</td>
</table>
</body>
Then Updating:
<table>
<tr>
<th class="label">Title1</th> <-------------- Updating the table value
<td>123</td>
</table>
Any suggestion will be really helpful.
If you need to constantly update the data on the page, without reloading it. Pay your attention to EventSource (js).
const source = new EventSource(url);
source.onmessage = function (e) {
handleResponse(e);
};
And on the java side it uses a controller that returns stream.
#RequestMapping(value = "/checkData", method = {RequestMethod.GET}, produces = "text/event-stream;charset=UTF-8")
...
return "data:" + data + "\n\n";
I was going through spring MVC tutorials and came across ModelAndView.
My JSP view looks like this,
<%#taglib uri = "http://www.springframework.org/tags/form" prefix = "form"%>
<html>
<head>
<title>Spring MVC </title>
</head>
<body>
<h2>Submitted Student Information</h2>
<table>
<tr>
<td>Name</td>
<td>${student.getName()}</td>
</tr>
<tr>
<td>Age</td>
<td>${student.getAge()}</td>
</tr>
<tr>
<td>ID</td>
<td>${student.getBranch()}</td>
</tr>
</table>
</body>
</html>
It worked when I set both attribute name and attribute value in controller like the following,
ModelAndView mv = new ModelAndView();
mv.setViewName("result");
Student student = new Student("arun2", "CSE", 22);
mv.addObject("student",student);
return mv;
Then I came across other overloaded method ModelAndView.addObject(Object attributeValue) and I tried setting only attribute value mv.addObject(student); But this time it doesn't show student details in the browser.
My questions:
Is it possible to access those values in JSP by just setting attribute value as i did second-time mv.addObject(student);.
If yes, How? If not, Why do we have such overloaded method? Why do we need to set only value if we can't access it in the view (JSP)?
I went through the javadocs, But didn't find anything that could make me understand.
Yes, you can do it like that and access the parameters,but need to pay some attention.
Check the API for addObject at ModelAndView,it will shows method as below:
Then,let's look at the definition of ModelMap.addAttribute(Object)
It shows using a generated name,the definition of generated name listed as below:
So,if you just want to use the mv.addObject(student) method,you can access data in your jsp page as below:
<%#taglib uri = "http://www.springframework.org/tags/form" prefix = "form"%>
<html>
<head>
<title>Spring MVC </title>
</head>
<body>
<h2>Submitted Student Information</h2>
<table>
<tr>
<td>Name</td>
<td>${student.name}</td>
</tr>
<tr>
<td>Age</td>
<td>${student.age}</td>
</tr>
<tr>
<td>ID</td>
<td>${student.branch}</td>
</tr>
</table>
</body>
</html>
If the object is a Group class, then you can get value via ${group.name}
And pay attention that the ModelAndView is from org.springframework.web.servlet.ModelAndView
Also,I suggest you use the EL Expressions to access data in your jsp page directly.
I have the following basic html table with a Java function to print only the table content However the Print button does nothing when clicked,I figure probably the java coding is the issue, however it is not working could I get a third pair of eyes to assist please
<html>
<body>
<table border="1" cellpadding="3" id="printTable">
<tbody><tr>
<th>First Name</th>
<th>Last Name</th>
<th>Points</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>Adam</td>
<td>Johnson</td>
<td>67</td>
</tr>
</tbody></table>
<br />
<br />
<button>Print me</button>
<script>
function printData()
{
var divToPrint=document.getElementById("printTable");
newWin= window.open("");
newWin.document.write(divToPrint.outerHTML);
newWin.print();
newWin.close();
}
$('button').on('click',function(){
printData();
})
</script>
</body>
</html>
When working with javascript, it is often useful to look at your browser's console. After opening this page, mine has the error:
ReferenceError: $ is not defined
$ is a global variable inserted by jQuery. Try adding
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
to the code. This will include the jQuery library.
The call to the javascript function is not correct. When you're using the '$' symbol it means that you're using JQuery. You have 2 options:
1 - Include the jquery library to your page:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
2 - Call the javascript function directly on the button on the 'onclick' event. This is the best option in your case:
<button onclick="printData()">Print me</button>
Change this var divToPrint=document.getElementById("printTable");
to this var divToPrint=document.getElementById("<%=printTable.ClientID>");
and add jquery library <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
I am trying to create a servlet that displays a simple form with checkboxes , when the user selects the number of checkboxes he wants and clicks on a "confirm" the POST request in my servlet checks for which boxes have been checked and queries the database based .
I am unsure on how to do this in Java as the user may select either 1 or more checkboxes . if somebody could explain this with a small example this would be great.
I am very new to programming and would provide a code snippet if I knew how to do it .
<%# page language="java"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>JSP Multiple Checkbox</title>
</head>
<body>
<form name="form1" onsubmit="checkBoxValidation()">
<h3>Select your favorite Fruits</h3>
<p><input type="checkbox" name="fruit" value="Mango"/>Mango</p>
<p><input type="checkbox" name="fruit" value="Apple"/>Apple</p>
<p><input type="checkbox" name="fruit" value="Grapes"/>Grapes</p>
<p><input type="checkbox" name="fruit" value="Papaya"/>Papaya</p>
<p><input type="checkbox" name="fruit" value="Lychee"/>Lychee</p>
<p><input type="checkbox" name="fruit" value="Pineapple"/>Pineapple</p>
<p><input type="submit" value="submit"/>
</form>
<%String fruits[]= request.getParameterValues("fruit");
if(fruits != null){%>
<h4>I likes fruit/s mostly</h4>
<ul><%for(int i=0; i<fruits.length; i++){%>
<li><%=fruits[i]%></li><%}%>
</ul><%}%>
</body>
</html>
Run this sample jsp on your web container to get some basic idea on how it works. You need to move the display logic on this page that gets request parameter into your servlet code on form submission. This example can be found from here. Hope this would help.
This is actually the HTML form behavior question. When you check a few checkboxes with one "name" attribute and different "value" attributes and press submit button, your browser will send request to the server with checked checkbox values. So you can get value names from this url parameters.
For example:
<form name="input" action="html_form_action.asp" method="get">
<input type="checkbox" name="vehicle" value="Bike">I have a bike<br>
<input type="checkbox" name="vehicle" value="Car">I have a car
<br><br>
<input type="submit" value="Submit">
</form>
If you check both of checkboxes your server will receive this parameters like so:
http://example.com/your_page.jsp?vehicle=Bike&vehicle=Car
After that you can get values like this:
String checkboxValues = request.getParameter("vehicle");
checkboxValues gets all values separated by comma.
In your servlet you would use getParameter() like so:
request.getParameter( "id_of_checkbox" )
That function returns null if the the box is not checked. So you could do something like:
boolean myCheckBox = request.getParameter( "id_of_checkbox" ) != null;
Now myCheckBox is true if checked, false if not checked.
This one might be neater if you just want the output. Assuming you're using jstl libraries, which I prefer because it makes your pages cleaner:
<c:forEach var='fruitValue' items='${paramValues.fruit}'>
${fruitValue} <br>
</c:forEach>
I am having a problem with JSTL and empty operator. I already made few simple pages and everything worked fine, but now I have:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
<form action="/Projekt/myaccount" method="post">
<table border="1">
<tr>
<td>Artist</td>
<td>Record Name</td>
<td>Delete</td>
</tr>
<c:forEach var="item" items="${records}">
<tr>
<td>${item.artist}</td>
<td>${item.recordName}</td>
<td>
<input type="checkbox" name='${item.recordName}|${item.recordName}'/>
</td>
</tr>
</c:forEach>
</table>
<hr/>
<input type="submit" name="back" value="back"/>
<c:if test='${not empty "${records}"}'>
<input type="submit" name="delete" value="delete selected"/>
</c:if>
</form>
</body>
</html>
now no matter if I set the records attribute or not, the delete button shows up:
<c:if test='${not empty "${records}"}'>
<input type="submit" name="delete" value="delete selected"/>
</c:if>
in normal situation to records attribute I pass ArrayList and then use foreach, but sometimes ArrayList is empty, so in those situations I don't want delete button to show up, I fought that easiest way to achieve this would be to use this empty operator. Where am I making a mistake?
I even tried to manually set this attribute to null:
if (ar.size() != 0)
request.setAttribute("records", ar);
else
request.setAttribute("records",null);
EDIT:
#Qwe: yes you are right, it worked for me before because I tested if attribute was empty in my way, it was always true, because I used wrong construct, but it worked because I just wanted to show one string, if there was no String nothing showed up so I was thinking that everything worked fine.
<c:if test='${not empty "${records}"}'> as well as <c:if test="${!empty '${showWarning}'}"> (from your comment) will always resolve to true because you're are actually testing if a String ${records} is empty or not, and obviously it is not.
Just to be sure - by String ${records} I mean a String value, just as if you were assigning it in Java like String foo = "${records}";.
The next line of code will test if records variable (that is looked up from page, request, session or application scope) is empty or not:
<c:if test="${not empty records}">
The line of code is 100% guaranteed to work :)
Also, request.setAttribute("records",null) is a bad way to remove attributes because empty tests not just request scope, but page, session etc. Use <c:remove var='records'/> instead.