Understanding WebFlow on Grails - spring

I'm using Spring Web Flow on Grails (2.0.8.1 on grails 2.3.11). I've created all dir under views and this is my little flow:
def registrazioneUtenteFlow = {
log.info("Registrazione Flow")
step1_informazioni_personali {
on("next").to("step2_informazioni_personali")
}
step2_informazioni_personali {
on("submit").to "step3_informazioni_personali"
on("return").to "step1_informazioni_personali"
}
step3_informazioni_personali {
}
}
I created three gsp under controllerName/flowName. Inside each JSP there is a form with a submit button. Ex. for first GSP:
<g:form action="registrazioneUtente">
<g:submitButton name="next" value="NEXT" />
</g:form>
Now.. If i put inside the state the "on" rule, I have an 404 with this url
registrazioneUtente?execution=e8s1&format=
But if I leave this from step1_informazioni_personali, I can see the page.
Why?!?
Thanks in advance

I found the problem:
The error happens because my controller have a namespace : "SITE". Removing it, all it work.

Related

Trigger Ajax request on settings page

I'm writing a plugin that have some fields defined in backend settings.
One of that field is a partial that contain a button, that trigger an Ajax request thanks to the data-attribute API.
<button type="button" class="btn btn-danger" data-request="onReset">
My button
</button>
Where should I put the "onReset()" function ? I tried to put it in my Settings model, even tried to create a Settings controller (whereas not necessary to work with settings page), but I always get the following error :
Ajax handler 'onReset' was not found
I don't know what to do to be able to trigger that onReset() function, can somebody familiar with Laravel / OctoberCMS could point me the right direction ?
Thanks
Settings are rendered by the \System\Controllers\Settings so whatever you write will be handled by \System\Controllers\Settings Controller Class,
so we need to extend \System\Controllers\Settings and we can add dynamic
method there,
inside your plugin's boot method you need to write this extension code
I am renaming your onReset handler to onPrefixReset in this example to avoid any other conflicts.
public function boot() {
\System\Controllers\Settings::extend(function($model) {
$model->addDynamicMethod('onPrefixReset', function() {
\Flash::success('You did it!');
// OR
//return ['some data data'];
});
});
}
onPrefixReset : we are adding some Prefix here, so accidentally we are not overriding internal original methods.
now inside your _partial
<button type="button" class="btn btn-danger" data-request="onPrefixReset">
My button
</button>
so now this onPrefixReset ajax handler is defined in \System\Controllers\Settings as we did that dynamically ;) it will handle your request.
you can return any data from here and it will be received at back-end settings page.
In HTML forms if you have an onReset event, you can add your call inside there:
function updateForm()
{
$.each($('form').find(":input"), function(){
$.uniform.update($(this));
});
}
<form onReset="updateForm();">
In this link you can you can do your own ordering within a click event:
$(document).ready(function() {
$("input:reset").click(function() { /click event
this.form.reset();
window.alert($("input:text").val());
return false;
});
});

How to execute an action without going to another view in grails?

I have a code that starts the server and stops the server. However when i press the button the server gets started but it also redirects me to a new view. The code in controller i have is
def test= amazonWebService.ec2.startInstances(new StartInstancesRequest([InstanceToStart]))
I want to execute test when button is pressed without going to new view. The code I have in my gsp page is
<g:link action="test">
<input type="button" value="Start Server" class="button" id="startServer1" />
</g:link>
If you don't mind the page refreshing, in your test action, redirect to the same view you came from. So assuming you got to your current view via index:
class SomeController {
def index() {
// index.gsp rendered via convention
}
def test() {
// execute your code then
redirect action: index, params: params
}
}
You're other option is to submit an Ajax request when the link is clicked and not have to refresh the page at all.
Use a remote function, see here http://grails.org/doc/2.1.0/ref/Tags/remoteFunction.html
Following is the alternative answer to the question.
By default Grails view resolver tries to find a view similar to the action name. In your case, Grails is trying to find test.gsp and if it is there in your repository it renders that. You can override this behaviour by using the Grails URL mappings feature. There you will get to specify which view should be rendered for a certain action.
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
}
For further information visit : http://grails.org/doc/2.2.x/ref/Plug-ins/URL%20mappings.html

Grails remoteField - Can I call a render/redirect?

I'm not looking for a div update. I'm looking for a full page "refresh"
So I have a tag:
<g:remoteField controller="person" action="updatePerson" id="${personInstance.id}" paramName="search" name="updatePerson" value="${personInstance?.favoriteBreed}" />
In my attached method, I want to perform the action of updating the domain object, then refresh the entire page. I've tried both renders and redirects to simple actions within the application, but nothing is called. So I'm thinking this isn't possible with the remoteField tag.
Is this true?
Why reimplementing via AJAX the normal behaviour of a page? Why don't you just call a redirect to the right action at the end of the called controller?
Let's say you are in the view resulted from the showPerson action. In this view, call the updatePerson with a simple (don't care about the params attribute, it's only an example):
<g:Link controller="person" action="updatePerson" id="${personInstance.id}" params="${name: 'search'}">click me</g:link>
and in the controller do something like:
def updatePerson = {
// your own updating stuff
redirect(action: "show", id: person.id)
}
Isn't it easier? :)
<g:remoteField /> have the event onSuccess that can be used to do what you want. You can check more options here.
Try (not tested):
<g:remoteField controller="person" action="updatePerson"
id="${personInstance.id}" paramName="search" name="updatePerson"
value="${personInstance?.favoriteBreed}" onSuccess="reloadPage()" />
And you will need to create the javascript function:
function reloadPage() {
window.location.reload();
}

How to call a controller method from an html page in asp.net?

In the application I am working on, I have an Html page inside views folder and I have mentioned the action as follows.
<form name="form" onsubmit="return validateForm();" method="post" action="//Controllers/RegistrationController.cs">
The registration controller returns a view.
public ActionResult Detail(string name)
{
return View();
}
When I run the program, I get server not found error.
I also tried changing the action string to action="//Controllers/RegistrationController.cs/Detail"
but got the same error.
Does the action string have to be written in some other way?
Thank you very much in advance for your help.
Assuming you are using the default routes ({controller}/{action}/{id}) you need:
action="/Registration/Detail"
Actually I would recommend you using HTML helpers to generate forms and never hardcode them as you did:
#using (Html.BeginForm("Details", "Registration", FormMethod.Post, new { name = "form", onsubmit = "return validateForm();" }))
{
...
}
Description
You don't have to set the path like in your solution. You don't need to set Controllers because the framework knows that you mean the controller.
Assuming that you dont change the routing in global.asax, your RegistrationController.cs has an ActionMethod called Detail (decorated with [HttpPost]) and the following folder structure within your project.
Controllers/RegistrationController.cs
Views/Registration/Detail.cshtml
#using (Html.BeginForm("Detail", "Registration", FormMethod.Post, new { #onSubmit = "return validateForm();" }))
{
// Your Form's content
}
/registration/detail - you don't need to reference the path to the actual file. The framework finds the controller class and invokes the requested action for you. It uses the routes as defined in global.asax.cs to determine the controller and action from the url. The default route is {controller}/{action}/{id} where the first two have defaults of "Home" and "Index", respectively, and the third is optional. You can change this if you want by adding/modifying the route set up.

jQuery.validate stops my form from being submitted

jQuery.validate stops my form from being submitted. I would like it to just show the user what is wrong but allow them to submit anyway.
I am using the jquery.validate.unobtrusive library that comes with ASP MVC.
I use jquery.tmpl to dynamically create the form and then I use jquery.datalink to link the input fields to a json object on the page. So my document ready call looks something like this.
jQuery(function ($) {
// this allows be to rebind validation after the dynamic form has been created
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse($("form"));
// submit the answers
$("form").submit(function(e) {
$("input[name=jsonResponse]").val(JSON.stringify(answerArray));
return true;
});
}
I note that there is an option
$("form").validate({ onsubmit: false });
but that seems to kill all validation.
So just to recap when my form is rendered I want to show all errors immediately but I don't want to prevent the submit from working.
So after some research (reading the source code) I found I needed to do 2 things
add the class cancel to my submit button
<input id="submitButton" type="submit" class="cancel" value="OK" />
This stops the validation running on submit.
To validate the form on load I just had to add this to my document ready function
$("form").valid();
Hope this helps someone else

Resources