In my aplication I need photo upload. I want that User first creates album folder and after cliking on that album, uploads photos. My album has: ID, album_name, username and my photo:ID, album_ID, photo_name, type
album controller:
import java.io.File
import grails.plugin.springsecurity.annotation.Secured
import java.text.SimpleDateFormat
#Secured(['ROLE_USER','ROLE_ADMIN', 'IS_AUTHENTICATED_FULLY'])
class AlbumController {
def springSecurityService
def index() { }
def create(){
def user = User.get(springSecurityService.currentUser.id)
def album = new Album()
album.a_name = params.name
album.user = user
album.save(failOnError:true)
def photo = new Photo()
def uploadedFile = request.getFile('myFile')
def name = System.currentTimeMillis()
if (uploadedFile.empty) {
flash.message = 'file cannot be empty'
redirect (action:'index')
return
}
photo.type = uploadedFile.contentType
photo.p_name = name
photo.album = album
uploadedFile.transferTo(new File("../test101111/web-app/album/" + user.username + "/"+ photo.getP_name() + ".jpg"))
//response.sendError(200, 'Done')
photo.save(failOnError:true)
redirect (action:'index')
}
}
Photo controller:
import java.io.File
import grails.plugin.springsecurity.annotation.Secured
import java.text.SimpleDateFormat
#Secured(['ROLE_USER','ROLE_ADMIN', 'IS_AUTHENTICATED_FULLY'])
class PhotoController {
def springSecurityService
def index() { }
def create(){
def photo = new Photo()
def uploadedFile = request.getFile('myFile')
def name = System.currentTimeMillis()
if (uploadedFile.empty) {
flash.message = 'file cannot be empty'
redirect (action:'index')
return
}
photo.type = uploadedFile.contentType
photo.p_name = name
photo.album = params.albumId
uploadedFile.transferTo(new File("../test101111/web-app/album/" + photo.getP_name() + ".jpg"))
//response.sendError(200, 'Done')
photo.save(failOnError:true)
redirect (action:'index')
}
}
Photo view:
<%# page contentType="text/html;charset=UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<meta name="layout" content="main" />
<title>Photo</title>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("span.button").click(function() {
$("form.forma_album").toggle();
});
});
</script>
</head>
<body>
<div class="body">
<div class="album_title">
<span class="title1">Fotografije</span>
<div class="new_album">
<img class="plus" src="${resource(dir: 'images', file: 'plus.png')}" />
<span class="button">Dodaj novu sliku</span>
</div>
</div>
<hr class="usual">
<g:uploadForm action="create" class="forma_album">
<input type="file" name="myFile" />
<input type="submit" />
</g:uploadForm>
</div>
</body>
</html>
Album view:
<%# page contentType="text/html;charset=UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<meta name="layout" content="main" />
<title>Album</title>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("span.button").click(function() {
$("form.forma_album").toggle();
});
});
</script>
</head>
<body>
<div class="body">
<div class="album_title">
<span class="title1">Foto albumi</span>
<div class="new_album">
<img class="plus" src="${resource(dir: 'images', file: 'plus.png')}" />
<span class="button">Kreiraj novi album</span>
</div>
</div>
<hr class="usual">
<g:form action="create" class="forma_album">
<g:textArea class="album_name" name="name" placeholder="Ime albuma"></g:textArea>
<g:submitButton class="submit2" name="Dodaj" />
</g:form>
<g:each in="${albums}" var="album">
<g:link controller="photo" action="index" class="contact"
params="[albumId: album.id]">
${album.a_name}
</g:link>
</g:each>
<%--<g:uploadForm action="create" class="forma_album">
<g:textArea class="album_name" name="name" placeholder="Ime albuma"></g:textArea>
<input type="file" name="myFile" />
<input type="submit" />
</g:uploadForm>
--%>
<div>
<%--<g:each in="${albums}" var="album" class="picture">
<div class="picture">
<img src="${resource(dir: 'images', file: 'picture.png')}" />
<div class="album_name">
${album.a_name}
</div>
</div>
</g:each>
--%>
</div>
</div>
</body>
</html>
My Error is: No signature of method: org.springframework.security.web.servletapi.HttpServlet3RequestFactory$Servlet3SecurityContextHolderAwareRequestWrapper.getFile() is applicable for argument types: (java.lang.String) values: [myFile] Possible solutions: getXML(), getPart(java.lang.String), getAt(java.lang.String), getAt(java.lang.String), getLocale(), getJSON()
What is wrong? sorry for my English and thanks for the answer ;)
You can either set grails.servlet.version = "2.5" in your BuildConfig.groovy or in application.properties
or
use the request.getPart(String) instead of request.getFile(String)
see JavaDoc on Part interface
Could you please print the params and paste them here.
Alternatively you can try with request.getInputStream().
Related
Right so my codes for my test view is:
#Secured(["IS_AUTHENTICATED_REMEMBERED", "IS_AUTHENTICATED_FULLY"])
def list(){
def allPosts = postService.getPosts()
}
<body>
<h1>Welcome to the main feed, <sec:loggedInUserInfo field="username" var="username"/></h2>
<g:if test="${flash.message}">
<div class="messageContainer">
<div style="display: block">${flash.message}</div>
</div>
</g:if>
<p/>
<div>
<g:each var="post" in="${allPosts}">
<p>Last Name: ${post.content}</p>
<p>First Name: ${post.content}</p>
</g:each>
</div>
</body>
</html>
And this works,
This was just to test if there was another issue though as what I want it to work on is this:
#Secured(["IS_AUTHENTICATED_REMEMBERED", "IS_AUTHENTICATED_FULLY"])
def wall() {
def allPosts = postService.getPosts()
profile = springSecurityService.currentUser.getProfile()
if(!profile){
redirect(controller: "profile", action: "viewProfile")
}else {
[profile: profile]
}
}
and
<!doctype html>
<html>
<head>
<meta name="layout" content="main"/>
</head>
<body>
<h1>Welcome to the main feed, <sec:loggedInUserInfo field="username" var="username"/></h2>
<g:if test="${flash.message}">
<div class="messageContainer">
<div style="display: block">${flash.message}</div>
</div>
</g:if>
<p/>
<div>
<h3>
What are you thinking?
</h3>
</p>
<div>
<g:form action="addPost">
<g:textArea class="postContent" id="postContent" name="content" rows="3" cols="50"/><br/>
<g:submitButton class="postSubmit loginButton" name="post" value="Post"/>
</g:form>
<div>
</div><br/>
<div class="PostContainer">
<g:each var="post" in="${allPosts}">
<p>${post.content}</p>
<p>${post.content}</p>
</g:each>
</div>
</div>
</body>
</html>
but the posts and content will not render on the second example
also the postService:
#Transactional
class PostService {
def getPosts() {
[allPosts:Post.list()]
}
}
Any insight into this would be greatly appreciated.
I am using windows 10 and chrome for the browser
Try to return from the service in this way
#Transactional
class PostService {
def getPosts() {
Post.list()
}
}
I'm having a hard time figuring out how to essentially reload a section of my view with new data after a selection from a DropDownMenu(in grails 3.3.9)
I've tried using the same convention of a button in grails, which is pretty straight forward:
<g:select class="btn bg-primary" action="filterByCommittee" controller="management"
from="${Committee.list()}" optionKey="id" optionValue="${name}"
name="committees" value="${committees}" noSelection="${['null':'Select..']}"/>
the code above means(AFAIK) i want to trigger an action(filterByCommittee) which resides in a controller(Management), using params.committees(the name of the field). the mentioned action would filter the purchases(a list shown to the user) by the selected committee.
any help would be greatly appreciated!
some relevant code:
class ManagementController {
PurchaseService purchaseService
CommitteeService committeeService
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
List<Purchase> purchaseList = Purchase.findAllByAccountantApprovalInList(Approval.findAllByApproved(true))
}
respond purchaseList, model:[purchaseCount: purchaseService.count()]
}
def filterByCommittee() {
Committee selectedCommittee = Committee.findByName(params.committees)
List<User> userList = User.findAllByCommittee(selectedCommittee)
List<Purchase> purchaseList = Purchase.findAllByUserInList(userList)
respond purchaseList, model:[purchaseCount: purchaseService.count()]
}
}
class Committee {
String name
static hasMany = [users:User, summaries:Summary]
static constraints = {
users(nullable: true)
summaries(nullable: true)
}
#Override
public String toString() {
return name
}
}
<!DOCTYPE html>
<!--<%# page import="attainrvtwo.Committee" contentType="text/html;charset=UTF-8" %>-->
<html xmlns:g="http://www.w3.org/1999/html">
<body>
<g:message code="default.link.skip.label" default="Skip to content…"/>
<div class="nav" role="navigation">
<ul>
<li><g:select class="btn bg-primary" action="filterByCommittee" controller="management" from="${Committee.list()}" optionKey="id" optionValue="${name}" name="committees" value="${committees}" noSelection="${['null':'Select..']}"/></li>
</ul>
</div>
<div id="list-purchase" class="content scaffold-list" role="main">
<h1><g:message code="default.list.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message" role="status">${flash.message}</div>
</g:if>
<f:table collection="${purchaseList}" />
<div class="pagination">
<g:paginate total="${purchaseCount ?: 0}" />
</div>
</div>
</body>
</html>
In gsp file, on select (fill "" with the corresponding values):
<g:select id="" name="" value="" from='${}' optionKey="id"
onchange="optionChanged(this.value);" >
</g:select>
<div id="tabla" style="display:block;"></div>
In same gsp file:
<script>
function optionChanged(committeeId) {
<g:remoteFunction controller="management" action="filterByCommittee"
update="tabla" params="'commId='+committeeId"/>
}
</script>
In another gsp file name="filterByCommittee.gsp":
Code to display
In the controller add the id param to the function:
def filterByCommittee(commId)
the solution i pieced together looks something like this:
in the ManagementController
package attainrvtwo
class ManagementController {
CommitteeService committeeService
List<Purchase> purchaseList
def filterByCommittee() {
session.filterPurchases = true
Committee selectedCommittee = committeeService.get(params.id)
List<User> userList = User.findAllByCommittee(selectedCommittee)
purchaseList = Purchase.findAllByUserInList(userList)
respond purchaseList, model:[purchaseCount: purchaseService.count()]
}
}
in the index.gsp file of management view
<!DOCTYPE html>
<!--<%# page import="attainrvtwo.Committee" contentType="text/html;charset=UTF-8" %>-->
<html xmlns:g="http://www.w3.org/1999/html">
<head>
<meta name="layout" content="main" />
<g:set var="entityName" value="${message(code: 'purchase.label', default: 'Purchase')}" />
<title></title>
</head>
<body>
<g:message code="default.link.skip.label" default="Skip to content…"/>
<div class="nav" role="navigation">
<ul>
<!-- <li><a class="home" href="${createLink(uri: '/volunteer/index')}"><g:message code="default.home.label"/></a></li>-->
<li><g:select class="btn bg-primary" id="commDDLid" name="committeeDDL" action="filterByCommittee" controller="management" from="${Committee.list()}" optionKey="id" optionValue="${name}" value="${committees}" noSelection="${['null':'Select..']}" onchange="goToPage(this.value)"/></li>
</ul>
</div>
<div id="list-purchase" class="content scaffold-list" role="main">
<h1><g:message code="default.list.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message" role="status">${flash.message}</div>
</g:if>
<f:table collection="${purchaseList}" />
<div class="pagination">
<g:paginate total="${purchaseCount ?: 0}" />
</div>
</div>
<script type="text/javascript">
function goToPage(requestParams) {
window.location.href="${'/management/filterByCommittee'}" + "/" + requestParams;
}
</script>
</body>
</html>
then i've also added the filterByCommitty.gsp view which is basically a copy of my index.gsp
(notice the import line at the beginning and the script tag at the end)
<!DOCTYPE html>
<!--<%# page import="attainrvtwo.Committee" contentType="text/html;charset=UTF-8" %>-->
<html xmlns:g="http://www.w3.org/1999/html">
<head>
<meta name="layout" content="main" />
<g:set var="entityName" value="${message(code: 'purchase.label', default: 'Purchase')}" />
<title></title>
</head>
<body>
<g:message code="default.link.skip.label" default="Skip to content…"/>
<div class="nav" role="navigation">
<ul>
<li><g:select class="btn bg-primary" id="commDDLid" name="committeeDDL" action="filterByCommittee" controller="management" from="${Committee.list()}" optionKey="id" optionValue="${name}" value="${committees}" noSelection="${['null':'Select..']}" onchange="goToPage(this.value)"/></li>
</ul>
</div>
<div id="list-purchase" class="content scaffold-list" role="main">
<h1><g:message code="default.list.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message" role="status">${flash.message}</div>
</g:if>
<f:table collection="${purchaseList}" />
<div class="pagination">
<g:paginate total="${purchaseCount ?: 0}" />
</div>
</div>
<script type="text/javascript">
function goToPage(requestParams) {
window.location.href="${'/management/filterByCommittee'}" + "/" + requestParams;
}
</script>
</body>
</html>
i hope this helps someone.
if there are any improvement suggestions i'd be glad to correct them.
cheers ;)
I'm trying to make an app with an login form (index.html) and a mini control panel (panel.html), but when i try to login the app only show the Notificaction and dont redirect to the panel.html page.
This is the code of my index.html
<script type="text/javascript">
function loginTrue() {
Ti.UI.currentWindow.setURL("app://panel.html");
}
function showNotify(title, message) {
var notification = Ti.Notification.createNotification({
'title': title || 'Sin Titulo',
'message': message || 'Sin mensaje',
'timeout': 10
});
notification.show();
}
</script>
<script type="text/javascript">
</script>
<script type="text/python">
import MySQLdb
import os
db = MySQLdb.connect(host="localhost",user="root", passwd="toor", db="db")
cursor = db.cursor()
def login():
username= document.getElementById('usuario').value;
passw= document.getElementById('contrasena').value;
cursor.execute("SELECT * FROM usuarios WHERE userlUsuario='"+username+"' and userContrasena='"+passw+"'" )
res = cursor.fetchone()
if(res==None):
showNotify("Error!", "Datos Invalidos, intente de nuevo.");
else:
showNotify("Acceso!", "Login Correcto!");
loginTrue();
</script>
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="css/style.css" media="all" />
</head>
<body class="login">
<div class="login">
<section id="login">
<h1><strong>Login</strong></h1>
<form method="link">
<input id="usuario" type="text" placeholder="Usuario" />
<input id="contrasena" type="password" placeholder="Contraseña" />
<button class="blue" onclick="login()">Entrar</button>
</form>
</section>
</div>
</body>
</html>
I found it, the problem was with the Login form that redirects the page to it self when someone click on the submit button, i resolve it adding "javascript:void(0);" as action of the form.
<form action="javascript:void(0);">
I want to fetch a text box value from jsp to my action class.
But my action class in not getting called while submitting the page.
My code are
Jsp page
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<form action="AddedColor" method="post">
<div class="box">
<span class="label">Color Name</span>
<span class="ib"> <input type="text" name="color" id="color"/></span>
</div>
<div class="box">
<input type="button" id="submit_color" value="Add Color"/>
</div>
</form>
</body>
</html>
In struts.xml
<package name="colorpkg" extends="struts-default">
<action name="AddedColor" class="iland.work.ColorAction" method="insert">
<result name="success">/pages/colors/showColors.jsp</result>
</action>
</package>
In ActionClass
public class ColorAction extends ActionSupport {
private String color;
//getter and setter of color
public String insert() {
System.out.println("-> ColorAction insert()");
System.out.println(getColor());
return SUCCESS;
}
}
try this:
<div class="box">
<input type="submit" id="submit_color" value="Add Color"/>
</div>
I have option of photo upload in my create.gsp page. I'm able to see the uploaded photo in my create page and able to upload my photo in database, but cannot see that photo in my show page.
This is create.gsp page
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="layout" content="billing-without-grid" />
<g:set var="entityName"
value="${message(code: 'skeletonBill.label', default: 'SkeletonBill')}" />
<title><g:message code="default.create.label"
args="[entityName]" /></title>
<script>
function showPhoto(imageFile) {
var fileReader = new FileReader();
var image = document.getElementById("uploadPhotoFile");
fileReader.onload = function(e) {
image.src = e.target.result;
}
fileReader.readAsDataURL(imageFile.files[0]);
}
</script>
</head>
<body>
<div class="body">
<div class="container-fluid">
<div class="row">
<div class="span6">
<img src="" name="uploadPhotoFile" id="uploadPhotoFile"
height="200" width="160" />
<table style="width: 25%">
<tbody>
<tr class="prop">
<td valign="top" class="name"><label for="uploadPhoto"><g:message code="uploadInformation.uploadPhoto.label" default="Upload Photo" /></label></td>
<td valign="top" class="value ${hasErrors(bean: uploadInformationInstance, field: 'uploadPhoto', 'errors')}">
<input type="file" id="uploadPhoto" name="uploadPhoto" onchange="showPhoto(this)" />
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
</html> '
Domain class that I created
class UploadInformation {
static constraints = {
uploadPhoto(nullable:true, maxSize: 16384 /* 16K */)
}
byte[] uploadPhoto
static transients = ["uploadPhoto"]
static mapping = {
uploadPhoto column:"uploadPhoto",sqlType: "blob"
}
}
Anuj.
The problem I see after quick look at your code is:
static transients = ["uploadPhoto"]
UploadPhoto will not be saved to database because it's declarated as transient.
See more details transient properties