I'm wondering how I could save an uploaded image in grails.
The situation:
I have a gsp page with a form, containing a file upload. I tried to get the data from the fileupload, but it just won't work.
In the controller:
def file = request.getFile('fileupload')
appearanceInstance.logo = file.encodeAsBase64().toString()
In the view:
<g:form action="save" enctype="multipart/form-data">
<div class="file-upload">
<label >Choose logo</label>
<input id="fileupload" type="file" name="fileupload" onchange="handleFileSelect(this)"/>
</div><br/>
<br/>
</g:form>
Anyone who had experience with this?
this might be another way to do it, but since I adapt an in the view when an image is selected using the file upoad, can I get the image data from the in the controller?
Thanks in advance!
UPDATE:
to be clear, there are some other controls in the form, from which I get the other parameters to save.
I guess this example Simple Avatar Uploader will answer all your questions
try this i hope this will help you it works for me also see this post
Class SomeController{
def uploader(){
}
def save(){
String s=""
CommonsMultipartFile f=request.getFile('fileupload')
final String name =f.getOriginalFilename()
def fos= new FileOutputStream(new File(name))
f.getBytes().each{ fos.write(it) }
s=Base64.encode(f.getBytes())
fos.flush()
fos.close()
render 'done now refresh your source directory to see the file ${s}'
}
and the view 'uploader.gsp'
<g:form action="save" enctype="multipart/form-data">
<div class="file-upload">
<label>Choose logo</label> <input id="fileupload" type="file"
name="fileupload" />
</div>
<input type="submit" class="buttons" value="Upload" />
</g:form>
Hi try with this one .
def save = {
def requestInstance = new Request(params)
def requestNumberInstance = new RequestNumber()
if(requestInstance.validate() && requestInstance.save(flush: true)){
println "Saved successfully with ${requestInstance.picture1.length} bytes"
}
else {
println "Save failed"
}
Related
I am having an issue getting multiple file from an upload using the UploadPortletRequest.
I can see in my ActionRequest that the files are here: using debug i see that actionRequest.multipartFiles.[0].fileItem.tempFile give me the location of the first uploaded file.
Though, in order to get the multipartParameterMap I need to convert the ActionRequest in UploadPortletRequest. when I do :
UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(actionRequest);
My uploadRequest.getSize("fileName")) returns 0...
Do you know what could be the cause?
Do you have another solution to get the temp uploaded files from the ActionRequest ?
Here is the .jsp I use :
<portlet:actionURL var="fileUploadURL">
<portlet:param name="formAction" value="fileUpload" />
</portlet:actionURL>
<form:form name="fileUploader" commandName="springFileVO"
method="post" action="${fileUploadURL}" enctype="multipart/form-data">
<label> Select a File</label>
<input type="file" name="uploadedFile" multiple="multiple">
<input type="submit" value="<liferay-ui:message key="upload" />" onClick="<%= uploadProgressId %>.startProgress(); return true;"/>
</form:form>
<liferay-ui:upload-progress id="<%= uploadProgressId %>" message="uploading" redirect="<%= HtmlUtil.escape(fileUploadURL) %>" />
Here is the Controller :
#ActionMapping(params="formAction=fileUpload")
public void fileUpload(ActionRequest request, ActionResponse response){
UploadPortletRequest uploadPortletRequest = PortalUtil.getUploadPortletRequest(request);
System.out.println("Size: "+uploadPortletRequest.getSize("uploadedFile"));
[...] }
Thank you for your help!
I think you're missing portlet:namespace attribute.
<input type="file" name="<portlet:namespace/>uploadedFile" multiple="multiple">
As your uploading multiple files, you can use following.
UploadPortletRequest uploadPortletRequest = PortalUtil.getUploadPortletRequest(request);
File[] files = uploadPortletRequest.getFiles("uploadedFile");
for (File file : files) {
System.out.println("Size: "+ file.length());
}
Using Grails 3.0.9
Making a Clear Form/session button for the filter class. however nothing i do works.
The button is just stuck there, nothing happens
Any help will be appreciated
SupplyController
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
if (params.name)
session.name = params.name
else if (request.method != "POST")
params.name = session.name
else
session.name = null
def criteria = Supply.createCriteria()
def query = {
and{
if (params.name) {
like ("name", '%' + params.name + '%')
}
}
}
def results = criteria.list(params, query)
respond results, model:[supplyCount: results.getTotalCount()]
}
G:field type of code
<div class="filter">
<h3>Filter:</h3>
<g:form action="index" method="post" >
<label for='name'>Name:</label>
<input type="text" id="name" name="name" value="${session.name}"/><br/>
<span class="button">
<g:submitButton name="index" class="index" value="Apply Filter" /></span>
<g:field type="reset" name="myReset" value="Reset" />
</g:form>
</div>
HTML tag type
<div class="filter">
<h3>Filter:</h3>
<g:form action="index" method="post" >
<label for='name'>Name:</label>
<input type="text" id="name" name="name" value="${session.name}"/><br/>
<span class="button">
<g:submitButton name="index" class="index" value="Apply Filter" /></span>
<input type='reset' value='Reset' />
</g:form>
</div>
An HTML form reset button for a form rests the form to the initial state. In this case back to the values it had when the form loaded. A HTML form reset button does not CLEAR the form or CLEAR the session.
wondering why you are using session for where typicalls form params should be used? In order to clear HTML session you would need to trigger a call back to the originating controller just like you would to post but when it receives via this call. It does a session.invalidate() and then renders same view again. You should try to stick with params for forms. The fact that you have the session information already really no need to post it via a form. Your controller receiving the form would be aware of that same session value.
You could easily create a jquery functionality that you do with a button that triggers and a resetform. jQuery/Javascript function to clear all the fields of a form
Or if that does not work you could try for example in your case:
<g:form ..>
..
<button onClick="clearName();" name="clickme">
</g:form>
<g:javascript>
function clearName() {
$('#name').val();
}
</g:javascript>
This is My Index method by which I am getting the list of data in webgird.How can I write a method for exporting this list of data when I click on button?
public ActionResult Index(string eMailId)
{
var refEntry = _moneyReport.GetAll().Where(a => a.EmailId == eMailId).ToList();
var credittotal = _moneyReport.GetAll().Where(a => a.EmailId == eMailId && a.PromoValue < 0).Sum(a => a.PromoValue);
decimal TotalCredit = Convert.ToDecimal(credittotal * -1);
var debittotal = _moneyReport.GetAll().Where(a => a.EmailId == eMailId && a.PromoValue >0).Sum(a => a.PromoValue);
decimal TotalDebit = Convert.ToDecimal(debittotal);
ViewBag.TotDebit = TotalDebit;
ViewBag.TotCredit = TotalCredit;
if(TotalCredit>TotalDebit)
{
decimal FinalTotal = TotalCredit - TotalDebit;
ViewBag.Total = FinalTotal;
}
else
{
decimal FinalTotal = TotalDebit - TotalCredit;
ViewBag.Total = FinalTotal;
}
return View(refEntry);
}
This is my View page where I am entering an emailid,load and Export button`enter code here.
#using (Html.BeginForm())
{
<div class="container-fluid form-row">
<div class="col-md-12 no-padding">
<div class="col-md-3 no-padding">
<input type="text" name="eMailId" id="eMailId" />
<span class="highlight"></span>
<span class="bar"></span>
<label class="no-left">Enter Email Id <sup class="star">*</sup></label>
</div>
<div class="col-md-3">
<input type="text" id="gName" name="gName" readonly="readonly" />
<span class="highlight"></span>
<span class="bar"></span>
<label>Name</label>
</div>
<div class="col-md-3">
<input type="submit" id="btnLoad" class="btn btn-md pm-create" value="Load" />
<input type="submit" id="btnLoad" class="btn btn-md" value="Export To PDF" />
</div>
<input type="hidden" id="HdnEmail" value='#TempData["MailID"]' />
</div>
</div>
}
<div id="report-grid">
#{Html.RenderPartial("ImportMoneyReport", Model);}
</div>
ImPortMoneyReport is my partial page where i ve the webgrid.
To export model data to PDF you will have to use one of third party pdf export libraries such as few below. You will find sample examples on respective sites or google them. You will need to implement code to export pdf in and add that file/stream into Response.OutputStream by setting respective content type in ImportMoneyReport action. Also you will have to invoke ImportMoneyReport method on post/event you can not use Html.RenderPartial to export; otherwise you can put export code in Index action only.
PDF Sharp
iTextSharp
It you want something that's working and very easy to use. Take a look at https://github.com/andyhutch77/MvcRazorToPdf
Just read the documentation.
For sample code. Take a look at this.
https://github.com/andyhutch77/MvcRazorToPdf/tree/master/MvcRazorToPdfExample
If you encounter some issues go to their github page and click the Issues tab, maybe some of your questions are already resolved there.
P.S.
Some of the PDF libraries like Rotativa will require an executable program to run that will not work when your app is deployed to Azure because Azure doesn't support exe files (I guess for security purposes) else you'll create a webjob just for the exe file.
I am still new to Grails. I have an app that has a file upload. I have added this to the controller
def upload = {
def f = request.getFile('myFile')
if(!f.empty) {
f.transferTo( new File("${f.name}") )
response.sendError(200,'Done');
} else {
flash.message = 'file cannot be empty'
render(view:'uploadForm')
}
}
and this is in _forms.gsp
<div class="fieldcontain ${hasErrors(bean: reportInstance, field: 'myFile', 'error')} ">
<label for="myFile">
<g:uploadForm action="upload">
<input type="file" name="myFile"/>
<input type= "submit" value="Upload"/>
</g:uploadForm>
</label>
When I use a g:link to try to retrieve the upload I get redirected and there is nothing displayed
Any advice would be greatly appreciated
g:link I am using
<g:link controller ="Report"
action="listByUserCompany"
>Show first ten ordered by Title</g:link>
class UploadController {
def index() { }
def fileupload () {
def f = request.getFile('myFile')
if(!f.empty) {
f.transferTo( new File("${f.name}") )
render(view:'upload')
}
else {
flash.message = 'file cannot be empty'
render(view:'upload')
}
}
}
<body>
<g:uploadForm name="myUpload" action="fileupload" controller="upload">
<input type="file" name="myFile" />
<input type= "submit" value="Upload"/>
</g:uploadForm>
</body>
i used the above code in my controller and gsp and i made a view named upload in view->upload->upload.gsp .My file uploaded success fully in the root directory of the project itself with name myfile
HI. I have this classes:
class Carro {
String name
String marca
String matricula
static constraints = {
name(nullable:false, blank:false)
}
static mapping = {
version false
}
}
class CarroMovel {
String move
String rodas
String espelhos
Carro carro
static hasMany = [carros: Carro]
static constraints = {
move(nullable:false, blank:false)
}
static mapping = {
version false
}
}
And the controllers:
class CarroController{
def save2 = {
def carroInstance = new Carro()
carroInstance.name = params.name
carroInstance.marca = params.marca
carroInstance.matricula = params.matricula
if (carroInstance.save(flush: true)) {
redirect(uri:"/home.gsp")
}
else {
render(view: "/testeAdd", model: [carroInstance: carroInstance])
}
}
And the view testeAdd.gsp
<g:form controller="carro" action="save2">
<h1>Add New Carro Record</h1>
<p>Basic Information</p>
<label>Name
<span class="small">as</span>
</label>
<input type="text" name="name" value="${carroInstance?.name}" /><br>
<label>Marca
<span class="small">as</span>
</label>
<input type="text" name="marca" value="${carroInstance?.marca}" /><br
<label>Matricula
<span class="small">as</span>
</label>
<input type="text" name="matricula" value="${carroInstance?.matricula}" /><br>
<g:submitButton name="save" value="Save" id="oneone"/>
<div class="spacer"></div>
</g:form>
<g:hasErrors bean="${carroInstance}">
<div class="errors">
<g:renderErrors bean="${carroInstance}" as="list" />
</div>
</g:hasErrors>
This is working good. Now i would like to be able to data binding multiple domain classes. So, along with the current code from my gsp file, i would also like to add carroMovel occurrences all in same save2. Im not sure how to do that, specially cause class Carro will need to have an id from class carroMovel. Any help please? Thank you.
I folowed some suggestions and now the results are as follows (im not concerned about error validation yet):
def save3 = {
def carroInstance = new Carro()
def carroMovelInstance = new CarroMovel()
carroInstance.name = params.carro.name
carroInstance.marca = params.carro.marca
carroInstance.matricula = params.carro.matricula
carroMovelInstance.move = params.carroMovel.move
carroMovelInstance.rodas = params.carroMovel.rodas
carroMovelInstance.espelhos = params.carroMovel.espelhos
carroInstance.save()
carroMovelInstance.carro = carroInstance
carroMovelInstance.save()
}
<g:form controller="carro" action="save3">
<h1>Add New Conference Record</h1>
<p>Basic Information</p>
<label>Name
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.name" value="${carroInstance?.name}" /><br>
<label>Marca
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.marca" value="${carroInstance?.marca}" /><br
<label>Matricula
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.matricula" value="${carroInstance?.matricula}" /><br>
<label>Move
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.move" value="${carroMovelInstance?.move}" /><br>
<label>Rodas
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.rodas" value="${carroMovelInstance?.rodas}" /><br>
<label>Espelho
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.espelho" value="${carroMovelInstance?.espelho}" /><br>
<g:submitButton name="save" value="Save" id="addConference"/>
The Carro object is saved in the database, altought, nothing happens with CarroMovel and it is not saved and i can't figure it out.
First I would change the input names to carro.name, carro.marca, carroMovel.move, ... so that they are differentiated by name.
<input type="text" name="carro.name"/><br>
<input type="text" name="carro.marca"/><br>
<input type="text" name="carroMovel.move"/><br>
This has the advantage that the binding in the controller can be done the standard Grails way, and that the correct values are entered in the form without the value attribute set.
carro.properties = params.carro
carroMovel.properties = params.carroMovel
In the controller action you can also save and link the Carro and CarroMovel instances.
carro.save()
carroMovel.carro = carro
carroMovel.save()
if(carroMovel.hasErrors(){
render(view: 'save3', model: [carro: carro, carroMovel.carroMovel])
}
If I understand your question correctly, you can give this a try.
First, edit our form to include the necessary fields for the CarroMovel class,
e.g
<label>Move
<span class="small">as</span>
</label>
<input type="text" name="move" value="${carroMovelInstance?.move}" />
then
in your save2 action,
def carroInstance = new Carro()
carroInstance.name = params.name
carroInstance.marca = params.marca
carroInstance.matricula = params.matricula
def carroMovelInstance = new CarroMovel()
carroMovelInstance.name = params.move
carroMovelInstance.marca = params.rodasa
carroMovelInstance.matricula = params.espelhos
carroMovelInstance.carro = carroInstance
Since Carro does not belong to CarroMovel saving a carroMovelInstance will not cascade to the carroInstance, therefore you will need to save each instance individually before saving its owning instance.
carroMovelInstance.carro.save()
if (carroMovelInstance.save(flush: true)) {
redirect(uri:"/home.gsp")
}
else {
render(view: "/testeAdd", model: [carroInstance: carroInstance, carroMovelInstance:carroMovelInstance])
}
Let me know if that works out for you.
Some of the other answers may be simpler, but I've been using this technique:
http://omarello.com/2010/08/grails-one-to-many-dynamic-forms/
In order for Carro to cascade save the CarroMovel reference, CarroMovel needs belongsTo = Carro or you need to manually tell hibernate to cascade it upon save using something like this:
class CarroMovel{
static mapping = {
carro cascade: 'all'
}
}
Here's the hibernate documentation about cascading:
https://docs.jboss.org/hibernate/orm/4.0/javadocs/org/hibernate/metamodel/binding/CascadeType.html
I usually use a command object for this type of thing.
In your controller do something like this:
class CarroController {
def show = {
[cmd: new MyCommand()]
}
def save2 = { MyCommand cmd ->
def carro = cmd.carro
if (carro.save()) {
cmd.movel.carro = carro
if (cmd.movel.save()) {
redirect uri: 'home.gsp'
} else {
// show form again
render view: 'show', model:[cmd:cmd]
}
} else {
// show form again
render view: 'show', model:[cmd:cmd]
}
}
// same file or some other class file
class MyCommand {
Carro carro
CarroMovel movel
}
}
You will need to adjust your form a bit as well...
Where you have "Carro" fields reference them like this:
<input type="text" name="carro.matricula" value="${cmd.carro?.matricula}" />
Where you have the "CarroMovel" fields, like this:
<input type="text" name="movel.rodas" value="${cmd.movel?.rodas}" />
This code might not be exactly right (I didn't test it), but should get you down the correct path. Also instead of referencing the objects in the command object, you could just have the fields that you are binding, and then build the actual domain objects from them, either through a helper method (def buildCarro(){...}) or by hand in the controller method.