In my app - grails 3.0 I'm trying to return custom URL: /book/showbook/2
The controller has two actions:
action1 - collecting user form and create object book
action2 - showing the information of the created book.
Spring security plugin is installed.
Problem: instead of displaying: /book/showbook/2 the result of the submit button is:
/book/showbook.
URL mappings code:
static mappings = {
"/book/showbook/$id?(.$format)?"(controller: 'game', action: 'showbook')
"/$controller/$action?/$id?(.$format)?"{
constraints {
}
}
View action 1 code:
<button type="submit" class="btn btn-danger btn-xs" params:[id: ${bookID}]>Submit data</button>
Action2 code:
def showbook(Book book) {
respond book
}
I don't think you are creating the form as it should be.
You can read the Grails official form tag.
http://docs.grails.org/latest/ref/Tags/form.html
Please try this
<g:form name="book" action="showbook" id="${bookID}">
<button type="submit" class="btn btn-danger btn-xs">Submit data</button>
</g:form>
Please make sure that ${bookID} is defined somewhere in your gsp or passed from your modal to the appropriate view otherwise, it will not work.
Related
I created a simple ActionResult in AccountController that should redirect to a specific URL:
[Route("account/redirect")]
public ActionResult RedirectGoogle()
{
return Redirect("https://google.com");
}
And I want to call the action in view using Razor like this:
<a class="btn btn-primary" href="#Url.Action("RedirectGoogle","AccountController")"> Goto Google</a>
but when clicking the link, nothing happens and the action is not even called. What am I doing wrong?
You need remove controller text in Url.Action, change to
<a class="btn btn-primary" href="#Url.Action("RedirectGoogle","Account")"> Goto Google</a>
I'm trying to get the results from a g:uploadForm action I have in my GSP file. I need to upload the file, then after it's successfully uploaded I need to tell if the upload was successful, then display another area in the GSP file.
<g:uploadForm action="save" method="post">
<h1>
<g:message code="upload"/>
</h1>
<h5>
<g:message code="upload.message"/>
</h5>
<br/>
<input type="file" id="Upload" name="Upload" class="input"/>
<br/>
<g:formButton type="submit" buttonClass="btn-primary btn-lg" buttonTextCode="upload.button" />
</g:uploadForm>
I just need something to say if it was successful or not.
Is this something I need to handle in the controller and just post to the GSP after that? I'm new to grails and groovy.
It's pretty common to use flash scoped variables for these types of messages. In fact, if you look at the Grails documentation about uploading files you will see it does just that.
def upload() {
def f = request.getFile('myFile')
if (f.empty) {
flash.message = 'file cannot be empty'
render(view: 'uploadForm')
return
}
f.transferTo(new File('/some/local/dir/myfile.txt'))
redirect(render: 'uploadForm')
}
Using the above example you could then include the following in your uploadForm GSP page.
${flash.message} to display this.
Here is my Grails (2.3.6) controller:
class WidgetController {
def index() {
render(
view: "createNew",
model:[
]
)
}
def execute() {
println "Executing form submission!"
redirect(action: "listAll")
}
def listAll() {
// Does some stuff
}
}
The index URL is, say, http://localhost:8080/myapp/widget. The idea is that when someone goes to this URL, they are presented with an HTML form. When they fill out the form, they are sent (on the server side) to the execute() method, which does some heavy duty stuff and then redirects them to the listAll() method which does some final stuff and renders a web page for them to see.
Here is the HTML form on the createNew.gsp (rendered from the index() method:
<g:form name="create-new-form" url="[action:'execute',controller:'widget']">
<table class="pure-table pure-table-bordered">
<tr>
<td class="row-header">Fizz:</td>
<td><g:textField id="app-fizz" name="fizz" /></td>
</tr>
<tr>
<td class="row-header">Buzz:</td>
<td><g:textField id="app-buzz" name="buzz" /></td>
</tr>
</table>
<g:actionSubmit value="Create" />
</g:form>
When I go to this URL and submit the form (clicking the Create button) I get redirected to http://localhost/myapp/widget/execute which displays one of my customized error pages (basically a "Sorry this page is unavailable"-type error.
Additionally, in the log outputs, my println stating "Executing form submission!" is not firing. This tells me that I don't have something wired correctly: Grails is trying to redirect to an /execute URL but somehow isn't linking that URL with my controller's execute() method. Ideas?
Try with:
<g:actionSubmit action="execute" value="Create" />
If you specify only value for g:actionSubmit it creates button with this label and also redirect to action based on this value. If action name is different than button label you should specify action and value attributes. Take a look at documentation.
Note that if you use g:actionSubmit then action attribute of g:form will be ignored (which you specified btw.). You'll find more info where it may be useful in docs linked above.
use plain <input type="submit" value="go"/>. thus the form is submitted to the URI defined in <g:form> tag
g.actionSubmit or g.submitButton are needed, if you want to submit your form somewhere ELSE.
Let's suppose I have a form with two submit buttons: save and delete.
How can I remove/disable model validations on delete button?
Assuming you're using standard unobtrusive/jQuery validate; Disable client-side validation by putting a class of "cancel" on the button:
<button type="submit" class="cancel">Delete</button>
This will prevent client-side validation from firing at all in the event of this button being clicked.
For server side, just don't check if the model's valid or not.
For example, if you have a property Name on the model and you want NOT to validate it on delete.
You first need to differentiate if the httppost is coming from the save or delete button.
Add to your Model field IsDelete.
I suggest you add in your view something like:
#Html.HiddenFor(x => x.IsDelete)
Add onclick event to your delete button:
<button type="submit" onclick="javacript: $('#IsDelete').val('true');"> Delete </button>
In the controller do something like:
public ActionResult MyAction(MyModel model)
{
if(model.IsDelete)
ModelState.Remove("Name");
var valid = ModelState.IsValid();
}
You can use two separate forms in the view for the edit and delete.
Ex:
#using(Html.BeginForm("Edit", "Employee"))
{
//Edit inputs - ex textboxes for employee details such as name, age...
<input type="submit" value="Edit" />
}
#using(Html.BeginForm("Delete", "Employee"))
{
//Delete inputs - ex: hidden input for employee id
<input type="submit" value="Delete" />
}
I have two submit buttons in one form. I want to call different actions in both buttons. Is there any way to accomplish this without using JavaScript.
Calling different actions is not possible without javascript. You could call the same controller action and inside this action determine which button was pressed using the name property:
<% using (Html.BeginForm()) { %>
<input type="submit" name="save" value="Save" />
<input type="submit" name="update" value="Update" />
<% } %>
and in your controller action:
[HttpPost]
public ActionResult Index(string save)
{
if (!string.IsNullOrEmpty(save))
{
// the save button was pressed
}
else
{
// the update button was pressed
}
return View();
}
Give the buttons different name attributes. Then in your view handler (or equivalent - sorry, not an ASP.NET MVC person), you can check if that button's name is in the HTTP response and act accordingly.
Only one of the submit button names should exist in the response.
Of course there is!
for example, we have following form:
<form>
<input name='customer_name' type='text'/>
<input name='update_user' type='submit' value='Update user info'/>
<input name='delete_user' type='submit' value='Delete user'/>
</form>
when server gets form request there exists only one parameter in the collection: either update_user or delete_user. depends on what user has pressed.