thornjad
thornjad

Reputation: 155

How do I call a method in a Grails controller without rendering a new view?

I have a page which allows the building of a PDF file incrementally over time (saving info to a database). I'm adding in the ability to save images as well. I currently have a <g:uploadForm> sending the file back to an upload method in the controller (which then calls a service). However, after uploading has finished, Grails tries to render a view associated with the upload method, which ends up being a blank page. I want to have the functionality of sending the file to the back-end Grails without so much as reloading the view (since it would get rid of any data which was entered but not saved). I also have a working version using JavaScript to make an AJAX request to the Grails server, but I'd prefer a Grails solution.

Here's the relevant part of the GSP:

<g:uploadForm action="upload" useToken="true" id="5">
  <div class="chooseFileButtonContainer">
    <input type="file" name="imgfile" class="chooseFileButton" />
  </div>
  <div class="uploadFileButtonContainer">
    <input type="button" value="Upload File" /> 
  </div>
</g:uploadForm>

Here's the controller:

def uploadToSP() {
  if (params.imgfile) {

    if (params.imgfile instanceof org.springframework.web.multipart.commons.CommonsMultipartFile) {
      def (sectionID, reportID) = params.id.tokenize(':')
      try {
        Service.upload(params.imgfile, sectionID, reportID)
      } catch (Exception e) {
        System.err << "Upload Failed : " + e.getMessage() +"\n"
      }
    } else {
      System.err << "Invalid file format\nExpected org.springframework.web.multipart.commons.CommonsMultipartFile\nGot ${params.imgfile.getClass()}\n"
    }
  } else {
    System.err << "No file supplied\n"
  }
  response.sendError(200, "Done")
}

Everything is working very well except that after clicking the Upload button, it goes to a URL like mysite.com/myapplication/controller/upload/id:id which is just a blank page (the /id:id part is on purpose).

I am able to do this using JavaScript, but I'm interested in a Groovy/Grails-only solution. My question is how to use a controller method without loading a new view.

Upvotes: 0

Views: 1718

Answers (2)

thornjad
thornjad

Reputation: 155

As far as I can tell from a lot of research, there is no way to do it. It comes down to Grails' "convention over configuration". When a function in a controller is called, it always wants to render a new view because that's just how Grails works. The closest I can seem to get is to just render the current page over again, but that isn't quite the same.

In reality, the solution is to use AJAX, but the answer to the question is that there is no way to call a controller without rendering a new view.

Upvotes: 0

Daniel
Daniel

Reputation: 3370

In general, it sounds like you need to look at ajax handling of requests and uploads instead of just a complete request/response cycle. There are a lot of examples of how to upload a file using JQuery, or plain javascript, or really any framework that you want to use. Take a look at one of those and I think you'll find it provides the solution you're looking for.

Upvotes: 1

Related Questions