how to pass params using action button in grails

2019-04-07 18:09发布

问题:

been having toruble with the button that has action. I have several btns which I want to know its paramaeter. In grails tutorial it says it should be like this:

 <g:actionSubmit    action="action" value="${message(code: 'default.button.edit.label', default: 'Edit')}" params="['actionTaken':editPhone]"/>

I tried using remotelink, submitButton, submitToRemote tags but none works. I always get null when I try parsing it in my controller:

def action=
    {
        def actionTaken = params.actionTaken
        def employeeId= params.employeeId

        MySession session = MySession.getMySession(request, params.employeeId)
        profileInstance = session.profileInstance

        switch(actionTaken)
        {
            case "editPhone" :
                isEditPhone=true
                break

            case "editEmail" :
                isEditEmail=true
                break
        }
        render(view:"profile", model:[profileInstance:session.profileInstance, isEditPhone:isEditPhone, isEditEmail:isEditEmail])
    }

What am I missing? is my params code wrong? Is my code in parsing params wrong? this just gets me in circles with no progress. help. thanks.

回答1:

The Grails documentation doesn't list params as one of the attributes accepted by actionSubmit.

It is possible to inject the value you want in your params list in the controller by exploiting what that tag actually does:

def editPhone = { forward(action:'action', params:[actionTaken: 'editPhone'])}
def editEmail = { forward(action:'action', params:[actionTaken: 'editEmail'])}

You may also just want to just code completely separate logic into the editPhone and editEmail actions if that makes your code cleaner.

Updated View Code:

<g:actionSubmit action="editPhone" value="${message(code: 'default.button.edit.label', default: 'Edit')}" />


回答2:

The params attribute is parsed as a map, where the keys are treated a strings but the values are treated as expressions. Therefore

params="['actionTaken':editPhone]"

is trying to define the key named actionTaken to have the value from the variable named editPhone in the GSP model. Since there is no such variable you're getting null. So the fix is to move the quotes:

params="[actionTaken:'editPhone']"

which will set the value to the string "editPhone".



回答3:

You could also pass the parameter inside the POST-data using

<input type="hidden" name="actionTaken" value="editPhone" />

inside the form. Then it is also accessible through the params variable. It works for me.



回答4:

I just had a similar problem (I needed to submit a delete together with an id) and found a solution using HTML5's "formaction" attribute for submit-inputs. They can be given a value that can include a controller, action, additional parameters, etc.

In General, to add a parameter to a submit button such as a edit of a specific sub-object on a form would looks like this:

<input type="submit" formaction="/<controller>/<action>/<id>?additionalParam1=...&additionalParam2=..." value="Action" >

and in your example:

<input type="submit" formaction="action?actionTaken=editPhone" value="${message(code: 'default.button.edit.label', default: 'Edit')}" >


回答5:

In my situation, I had a single form element with multiple actions on each row of a table (i.e. data table edit buttons). It was important to send the entire form data so I couldn't just use links. The quickest way I found to inject a parameter was with javascript. Not ideal, but it works:

function injectHiddenField(name, value) {
    var control = $("input[type=hidden][name='" + name + "']");
    if (control.size() == 0) {
        console.log(name + " not found; adding...");
        control = $("<input type=\"hidden\" id=\"" + name + "\" name=\"" + name + "\">");
        $("form").append(control);
    }
    control.val(value);
}

Your button can look like this:

<g:each in="${objects}" var="object">
     ...
     <g:actionSubmit value="edit" action="anotherAction"
                     onclick="injectHiddenField('myfield', ${object.id})"/>
</g:each>