Display of image in show page - grails

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

Related

Add form to layout

I need to add a login popup to the header of every page, so naturally I want to add it to the layout as a partial view.
The problem is, the layout doesnt have a pagemodel.
We do use a BasePageModel that every page inherits from, where I can add 2 strings for username/password. But how would the layout see those fields?
You can specify a model for the Layout page just as you would a standard content page:
#model BasePageModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
...
Then your properties are accessible via the Model property of the Layout page. The BasePageModel will also be passed to any partials that you add to the layout (unless you specify a different model for the partial), so you can also access the properties in those.
I need to add a login popup to the header of every page, so naturally
I want to add it to the layout as a partial view.
According to your description, I do a demo for that situation. But I don’t use a BasePageModel that every page inherits from.
The demo as below, hoping it can help you.
1.Add a Login page with page model, and post method
Login.cshtml.cs:
public class LoginModel : PageModel
{
[BindProperty]
public string Username { get; set; }
[BindProperty]
public string Password { get; set; }
public string Msg { get; set; }
public void OnGet()
{
}
public IActionResult OnPost(string Username, string Password)
{
//do your other things...
return Page();
}
}
Login.cshtml:
#page
#model Login.Pages.LoginModel
#{
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login</title>
</head>
<body>
<h3>Login Form</h3>
#Model.Msg
<form method="post" asp-page="Login">
<table>
<tr>
<td>Username</td>
<td><input type="text" asp-for="#Model.Username" /></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" asp-for="#Model.Password" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="Login" /></td>
</tr>
</table>
</form>
</body>
</html>
Add the login form in the layout. Using name attribute: change input type="text" asp-for="#Model.Username" into input type="text" name="Username"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
</ul>
</div>
<div>
<fieldset>
<div class="container">
<div class="row">
<div class="col-xs-12">
<button id="btnShowModal" type="button"
class="btn btn-sm btn-default pull-left col-lg-11 button button4">
login
</button>
<div class="modal fade" tabindex="-1" id="loginModal"
data-keyboard="false" data-backdrop="static">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
×
</button>
</div>
<div class="modal-body">
<form method="post" asp-page="Login">
<table border="0" cellpadding="2" cellspacing="2">
<tr>
<td>Username</td>
<td><input type="text" name="Username"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="Password"></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="Login"></td>
</tr>
</table>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</fieldset>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
#RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - Login - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
#await RenderSectionAsync("Scripts", required: false)
<script type="text/javascript">
$(document).ready(function () {
$("#btnShowModal").click(function () {
$("#loginModal").modal('show');
});
$("#btnHideModal").click(function () {
$("#loginModal").modal('hide');
});
});
</script>
</body>
</html>
Results:

angular ui bootstrap popover not working

i am starting to learn to use angular's ui bootstrap library and trying to get a popover working. Am i missing something in my setup?
i've provided a plunker example. my requirement is to have a popover over cells in a table that gets refreshed by $interval every second.
http://plnkr.co/edit/hF3EDIRfKA1VOfSennZq?p=preview
<!DOCTYPE html>
<html ng-app="test">
<head>
<meta charset="UTF-8">
<title>angular-test</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" type="text/css" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-animate.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.2/ui-bootstrap-tpls.min.js"></script>
<script type="text/javascript">
var app = angular.module("test", ['ngAnimate', 'ui.bootstrap']);
app.controller("testCtrl", function($scope, $interval) {
var stats = [{
"name": "john",
"stat1": 3,
"stat2": 5
}];
var count = 0;
$scope.getTestInfo = function() {
$scope.count = count++;
$scope.stats = stats;
}
$interval(function(){$scope.getTestInfo();}, 1000);
});
</script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-lg-4" ng-controller="testCtrl" ng-init="count=0">
<table id="table1" class="table table-hover table-condensed">
<thead>
<tr>
<th>column1</th>
<th>column2</th>
<th>column3</th>
</tr>
</thead>
<tbody class="bg-info">
<tr ng-repeat="stat in stats">
<td uib-popover="testcolumn1">{{stat.name}}</td>
<td uib-popover="{{stat.stat1}}">{{stat.stat1 + count}}</td>
<td uib-popover="testcolumn3">{{stat.stat2}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
You just need to add the metadata (popover-trigger etc.) for the popover modal. I forked your plunkr to demonstrate. http://plnkr.co/edit/d1eAf2NEAA9mCXmNN5LC?p=preview

how to make a modal with asp mvc?

I have a question , I have in my view a form, this form contains a list , this list contains four attributes , vendor , application , product and value , these 4 we display only two ( as seen in the code) would like to display in a modal product and the value of the order , the list is displayed in the same position already has such data , how do I display that data through an action of my button that has the action " getFornecedor " ( this action has not yet been implemented , I do not know if it is necessary because the elements are in the same position in the list )
View
#model Test.Models.Order
<head>
<meta charset="utf-8" />
<title>Teste</title>
<meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="http://cdn.datatables.net/1.10.2/css/jquery.dataTables.min.css">
<script type="text/javascript" src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
#Styles.Render("~/Content/bootstrap.css")
#Scripts.Render("~/bundles/modernizr")
<style>
th {
height: 10px;
}
</style>
</head>
<body>
<div id="divbody">
<nav class="navbar navbar-inverse">
</nav>
#using (Html.BeginForm("Save", "Cab", FormMethod.Post))
{
<div class="table-responsive" id="table">
<table id="myTable" class="table table-striped" cellspacing="0">
<thead style="position:static">
<tr>
<th style="font-size:10px">SELECT</th>
<th style="font-size:10px">CONTACT</th>
<th></th>
<th style="font-size:10px">SUPPLY</th>
<th style="font-size:10px">ORDER</th>
</tr>
</thead>
#for (int i = 0; i < Model.listOrder.Count(); i++)
{
<tr>
<td align="center" height="2px">#Html.CheckBoxFor(m => m.listOrder[i].isEdit, new { #onclick = "habilit(" + i + ")", #id = "c" + i })</td>
<td colspan="2">
<a href="#Url.Action("getFornecedor", "MyController")" class="btn btn-xs btn-primary">
<i class="glyphicon glyphicon-phone-alt"></i>
</a>
<a href="#Url.Action("sendEmail", "MyController")" class="btn btn-xs btn-primary">
<i class="glyphicon glyphicon-envelope"></i>
</a>
</td>
<td height="2px"> #Html.TextBoxFor(m => m.listOrder[i].supply, new { #readonly = "readonly", #size = "18px", #class = "form-controlSupply" }) </td>
<td height="2px"> #Html.TextBoxFor(m => m.listOrder[i].order, new { #readonly = "readonly", #size = "75px", #class = "form-controlOrder" }) </td>
<td></td>
</tr>
}
</table>
</div>
<br />
<input type="submit" value="Salve" id="btn" disabled="disabled" class="btn btn-small btn-primary" />
}
</div>
</body>
</html>
MVC doesn`t have modal on fly .. (like control in web forms for example) i suggest you to use third party library , may be something like jquery UI .. You can see example here : https://jqueryui.com/dialog/
You just need client side event to show modal dialog. In that container you can put any data that you want.

What is wrong with this upload in Grails?

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().

Grails file upload Kendoui

can someone please tell me a running example of upload file in kendoui?
As I have tried to upload file and its uploading in view page but when I click on save button I can't find that file in show page.I searched on it on internet then I found some problem of server.So someone please tell me how to use server in my case.I'm working on a grails project
Code That I have Used.:--
<tr class="prop">
<td valign="top" class="name">
<label>File Upload</label>
<input name="photos[]" id="photos" type="file" /><script>$(document).ready(function ()$("#photos").kendoUpload({
autoUpload:true,
upload: onUpload,
error: onError
});
function onError(e) {
// Array with information about the uploaded files
var files = e.files;
if (e.operation == "upload") {
alert("Failed to uploaded " + files.length + " files");
}
// Suppress the default error message
e.preventDefault();
},
function onUpload(e) {
var files = e.files;
if (e.operation == "upload") {
alert("Successfully uploaded " + files.length + " files");
}
});</script>
</td>
</tr>
i'm ading the view file :- create.gsp
<%# page import="ten.SkeletonBill"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="layout" content="billing" />
<get var="entityName"
value="${message(code: 'skeletonBill.label', default: 'SkeletonBill')}" />
<title><g:message code="default.create.label"
args="[entityName]" /></title>
<script src="source/kendo.all.js"></script>
<link href="styles/kendo.common.css" rel="stylesheet" />
<link href="styles/kendo.default.css" rel="stylesheet" />
</head>
<body>
<content tag="menu-function">
<li><span class="k-link"><a href="#"
onclick="SkeletonBillForm.submit();return false;"><i
class="icon-plus-sign"></i>
<g:message code="default.button.save.label" /></a></span></li>
</content>
<div class="body">
<h1>
<g:message code="default.create.label" args="[entityName]" />
</h1>
<g:if test="${flash.message}">
<div class="message">
${flash.message}
</div>
</g:if>
<g:hasErrors bean="${skeletonBillInstance}">
<div class="alert alert-error">
<a class="close" data-dismiss="alert">×</a>
<g:renderErrors bean="${skeletonBillInstance}" as="list" />
</div>
</g:hasErrors>
<g:uploadForm name="SkeletonBillForm" action="save" method="post">
<div class="dialog">
<table>
<tbody>
<tr class="prop">
<td valign="top" class="name"><label for="bones"><g:message
code="skeletonBill.bones.label" default="Bones" /></label></td>
<td valign="top"
class="value ${hasErrors(bean: skeletonBillInstance, field: 'bones', 'errors')}">
<g:textField name="bones"
value="${fieldValue(bean: skeletonBillInstance, field: 'bones')}" />
</td>
</tr>
<tr class="prop">
<td valign="top" class="name"><label for="dateOfBirth"><g:message
code="skeletonBill.dateOfBirth.label" default="Date Of Birth" /></label>
</td>
<td valign="top"
class="value ${hasErrors(bean: skeletonBillInstance, field: 'dateOfBirth', 'errors')}">
<g:textField name="dateOfBirth"
value="${skeletonBillInstance?.dateOfBirth}" /> <script>$(document).ready(function () {$("#dateOfBirth").kendoDatePicker({format:"yyyy-MM-dd"})});</script>
</td>
</tr>
<tr class="prop">
<td valign="top" class="name">
<label>File Upload</label>
<input name="excelSheet" id="excelSheet" type="file" />
<script>
$(document).ready(function() {
$("#excelSheet").kendoUpload();
},
function onError(e) {
// Array with information about the uploaded files
var files = e.files;
if (e.operation == "upload") {
alert("Failed to uploaded " + files.length + " files");
}
// Suppress the default error message
e.preventDefault();
},
function onUpload(e) {
var files = e.files;
if (e.operation == "upload") {
alert("Successfully uploaded " + files.length + " files");
}
});
</script>
</td>
</tr>
</tbody>
</table>
</div>
</g:uploadForm>
</div>
</body>
</html>
And Also Controller.gsp
def save = {
def skeletonBillInstance = new SkeletonBill(params)
if(!skeletonBillInstance.empty){
println "Name: ${skeletonBill.bones}"
flash.message = "${message(code: 'default.created.message', args: [message(code: 'skeletonBill.label', default: 'SkeletonBill'), skeletonBillInstance.id])}"
redirect(action: "show", id: skeletonBillInstance.id)
}
} else {
render(view: "create", model: [skeletonBillInstance: skeletonBillInstance])
}
}
Couple of things
1) If you want to use KendoUI, I wouldn't use the gsp tags. Please use the normal form tags to define your form, if you do this grails resorts to using the prototype plugin for.
2) I will not mix the script code with the tags.
3) If you are using grails 2.0, you can use the KendoUI plugin, you can find more information at http://grails.org/plugin/kendo-ui
Hope that helps.

Resources