sara
sara

Reputation: 320

grails - display flash message

I’m new to Grails, and I have a question that should be easy for most of you.

I have a page displaying an object list. I want to display a message if there’s a DataIntegrityViolation when an object is deleted. What I’m doing is:

def delete() {

    def instanceToDelete= Myobject.get(params.id)
    try {
        instanceToDelete.delete(flush: true)
        redirect(action: "list", id: params.id)
    }
    catch (DataIntegrityViolationException e) {
        flash.message = "some message"
        //I want to refresh the div containing the flash.message here
    }
}

Here is where the flash message should be displayed:

  <g:if test="${flash.message}">
  <div class="alert alert-error" style="display: block">${flash.message}</div>

Sorry — I know it’s a silly question, but I really can't find a solution.

Upvotes: 13

Views: 34941

Answers (4)

Asif
Asif

Reputation: 397

// backend code example

def save () { 
    if(params.name) { 
          . 
          . 
      object.save(); 
      flash.message =  "Saved successfully" 
    } 
    else { 
        flash.message = "Saved fail"
    }

// HTML example

<g:if test="${flash.message}">
   <div class="update_message" role="status">${flash.message}</div>
</g:if>

Upvotes: 6

IgniteCoders
IgniteCoders

Reputation: 4980

This can help you:

def delete() {
    def instanceToDelete= Myobject.get(params.id)
    try {
        instanceToDelete.delete(flush: true)
        flash.success = "Object deleted correctly"
    } catch (DataIntegrityViolationException e) {
        flash.error = "Something goes wrong"
    }
    redirect(action: "list", id: params.id)
}

redirect to the gsp after all the code, to can store if there is an error or everything goes well.

you can put the messages in different variable to discriminate between error and success.

<g:if test="${flash.success}">
    <div class="alert alert-success" style="display: block">${flash.success}</div>
</g:if>
<g:if test="${flash.error}">
    <div class="alert alert-error" style="display: block">${flash.error}</div>
</g:if>

Upvotes: 3

Isammoc
Isammoc

Reputation: 893

Strict answer : Just return your message (or render with a model map)

for your controller :

def delete() {

    def instanceToDelete= Myobject.get(params.id)
    try {
        instanceToDelete.delete(flush: true)
        redirect(action: "list", id: params.id)
    }
    catch (DataIntegrityViolationException e) {
        render view:'delete', model:[message: "some message"]
        //I want to refresh the div containing the flash.message here
    }
}

for your gsp :

<g:if test="${message}">
    <div class="alert alert-error" style="display: block">${message}</div>

But Gregg is right, you should never modify client data without a redirect. If you do, the user might refresh (or come back to) the same url, and attempt again same action accidentally. You should really do like in hitt5's answer.

Upvotes: 1

hitty5
hitty5

Reputation: 1673

The flash object is a Map which stores key/value pairs, so you can define your own key for error messages. For example:

try {
    instanceToDelete.delete(flush: true)            
    flash.message = "successfully deleted object"
 }
 catch (DataIntegrityViolationException e) {
    flash.error = "could not delete object"            
 }
redirect(action: "list", id: params.id)

Then you can check the flash object containing the error key, and use a different style for that kind of message:

<g:if test="${flash.error}">
  <div class="alert alert-error" style="display: block">${flash.error}</div>
</g:if>
<g:if test="${flash.message}">
  <div class="message" style="display: block">${flash.message}</div>
</g:if>

Upvotes: 23

Related Questions