fatfree framework, repopulate fields after unsuccessful validation - redirect

I have GET route which shows the contact form, and POST route when user submits the form, then in my controller method I do some validation tests on data being submitted.. how would I now send user back to form if data is not valid, with entered data being re-populated in form fields?
I know I can use isset(#POST.fieldname) in my template, but what's the right way of
sending entered data back to that view, and how to redirect user back to the
form? Is the f3->reroute method right way of doing that?

I think you can take as a rule to include input data inside your form views. This way, any form view will be easily reusable with any source of data.
For example:
Your form view:
<form action="" method="post">
<input type="text" name="email" value="{{ ##input.email }}"/>
<input type="text" name="message" value="{{ ##input.message }}"/>
<button type="submit">Submit form</button>
</form>
Your controller class:
class myController {
function get($f3) {
$this->renderForm();
}
function post($f3) {
$post=$f3->clean($_POST);
//validate form data here
if ($form_validated) {//valid form data
} else //invalid form data
$this->renderForm($post);
}
protected function renderForm($input=array()) {
$tpl=Template::instance();
//variant 1:
echo $tpl->render('form.html','text/html',array('input'=>$input))
// or variant 2:
Base::instance()->set('input',$input);
echo $tpl->render('form.html');
}
}
In some other contexts, you can feed a form view with data coming from a db mapper (for example when editing an entry from a back-office): $this->renderForm($mapper->cast())

Related

How to have one form with multiple actions

I have one doubt is it possible to have a single form(view page) with multiple actions like i want to save,update and delete on the same view page..if the user click on anyof the button then it have to call on a necessary controller function is it possible??
You have some ways to do it, but all of the them require some javascript code.
The easiest I can think of is to dynamically change the form action when clicking each button (of type button, not submit which is the default), and then submit the form.
Example:
<form id="myform" name="myform" method="post" action="">
<input id="myinput" name="myinput" type="text"/>
[..]other inputs[/..]
<button type="button" onClick="deleteAction()">DELETE</button>
<button type="button" onClick="updateAction()">UPDATE</button>
<button type="button" onClick="saveAction()">SAVE</button>
</form>
Where the JS functions are:
function deleteAction() {
changeActionAndSubmit('/action/delete');
}
function updateAction() {
changeActionAndSubmit('/action/update');
}
function saveAction() {
changeActionAndSubmit('/action/save');
}
function changeActionAndSubmit(action) {
document.getElementById('myform').action = action;
document.getElementById('myform').submit();
}
Hope I got your doubt and that this solves your issue :)
A non-JS way to achieve the same goal would be to use the name/value parameters on each button to have your backend decide what to do.
Example
<?php echo form_open('controller/method'); ?>
// form fields go here
<button type="submit" name="add" value="y">press to add</button>
<button type="submit" name="update" value="y">press to update</button>
<button type="submit" name="delete" value="y">press to delete</button>
<?php echo form_close(); ?>
then, on your controller, after validating user input, you can determine which button was pressed by reading what the buttons send about themselves to the controller (I'll assume you use CI's form helper)
if ($this->input->post('add') == 'y')
{
// the user wants to add
}
else if ($this->input->post('update') == 'y')
{
// user wants to update
}
else
{
// user wants to delete
}
// rest of code goes here
on each if structure, you can take the appropriate actions depending on which button the user pressed

How to bind a form field to the specific submit button in play framework? (form for POST request)

Basically I want to have two buttons in my view html template, and evaluate the Int param in my form for POST-request depending on which button has been clicked.
Like if button-number-1 was clicked I want my numParam to be 1
and if button-number-2 was clicked I want my numParam to be 2
Controller code:
case class Data(textParam: Option[String], numParam: Option[Int])
val form = Form(
mapping(
"textParam" -> optional(text),
"numParam" -> optional(number)
)(Data.apply)(Data.unapply)
)
View code:
#helper.form(helper.CSRF(routes.MyController.display)) {
#helper.inputText(form("paramA"))
<input type="submit" value="I want numParam to be 1">
<input type="submit" value="I want numParam to be 2">
}
Would appreciate any help!
I don't know whether this can be done with Play directly, so I propose to add some client-side JS into the mix.
What you could do:
Delete the <input type="submit" ...>, because it does not give you the possibility to modify form content before submission
add two <button>s instead
add a hidden input numValue
use javascript (in this case: jquery) to set the value of the hidden input when one of the buttons is clicked
submit the form using javascript
Something along these lines maybe (warning: untested):
#helper.form(helper.CSRF(routes.MyController.display), 'id -> "myForm") {
#helper.inputText(form("paramA"))
<button id="submit_numValue1">I want numParam to be 1</button>
<button id="submit_numValue2">I want numParam to be 2</button>
<input type="hidden" id="hiddenNumValue" name="numValue" value="0">
}
<script>
// add an `onclick` handler to first button
$('#submit_numValue1').click(function() {
// set hidden input to '1'
$('#hiddenNumValue').val("1");
// submit the form
$('#myForm').submit();
});
// add an `onclick` handler to the second button
$('#submit_numValue2').click(function() {
// set hidden input to '2'
$('#hiddenNumValue').val("2");
// submit the form
$('#myForm').submit();
});
</script>
As mentioned above, this requires that jquery is "imported" on the client-side as a javascript library.
No guarantee that this is the most idiomatic way to solve it in Play, but this answer seems to indicate that this approach is at least not uncommon.

MVC how can i post a form without using a model

I would like to know how i could sumbit a form in mvc 4 without using a model binding to the view.
can some one please demontrate how? and how can i use that form in the controller?
It is very easy to use a form without any sort of Model binding.
Simple set up your for using either #using(Html.BeginForm()){ ... } or plain html.
<form id="myForm" action="/ControllerName/ActionName" method="Post">
<input type="text" name="foo" value="FOOOO" />
<input type="text" name="bar" value="Baaaar" />
<button type="submit">Submit</button>
</form>
When you post this to the ActionResult, your action result just needs to be set up to accept a string value named foo and one named bar
[HttpPost]
public ActionResult ActionName(string foo, string bar){
// your code here
return View();
}

Multiple Form Actions to different pages / different target windows

I have a form on my page that needs to have multiple form actions associated with it. I'm using the following script in conjunction with the following code to achieve this:
<script>
function submitForm(action)
{
document.getElementById('summary').action = action;
document.getElementById('summary').submit();
}
</script>
<form action="go-gold.php" method="post" enctype="multipart/form-data">
<input type="image" id="arrow" name="go_back" onclick="submitForm('go-gold.php')" value="go_back" src="images/arrow_back.png" class="submit_button" /><br>
<input type="image" id="arrow" name="submit_form" onclick="submitForm('registration.php')" value="submit_form" src="images/arrow.png" class="submit_button" />
</form>
The first button needs to "go back" within the same browser window (self), and the second button needs to submit the info to a new window (blank). How do I modify the code to achieve this? Putting "target" functions within the input type doesn't work, and putting the target in the Form tag makes both submit buttons submit to the same window.
Thanks!
Easy with jQuery, also you have to identical ids for two separate form elements. You should have these as distinct ids unless you want to use a class name. Php can submit forms to the same page using the $_SERVER superglobal by using $_SERVER['PHP_SELF'] as the forms action name.
<script>
$(document).ready(function() {
$(".submit_button").click(function() {
clickVal = $(".submit_button").val();
if(clickVal == 'go_back') {
//do go back stuff
}
if(clickVal == 'submit_form') {
// do actions for other page
}
});
});
</script>
<form action="go-gold.php" method="post" enctype="multipart/form-data">
<input type="image" value="go_back" src="images/arrow_back.png" class="submit_button" /><br>
<input type="image" value="submit_form" src="images/arrow.png" class="submit_button" />
</form>

Razor - umbraco - get value from form and redirect

I have a form in Razor I am checking for the post in a form in a Razor macro. I am checking for the form being posted with the in built IsPost variable. I need to get the value from the form (the url) and then the page to the value.
form action="" method="POST">
<select>
<option>Please Select</option>
#foreach(var item in #Model.events){
<option value="#item.Url">#item.Name</option>
}
</select>
<button id="SubmitForm" type="submit">Submit Enquiry</button>
<p>#Message</p>
</form>
You're going to want to give your select an id, but you should be able to accomplish what you want by accessing the value of the select using Request collection and then redirecting to the selected url with a Response.Redirect().
Example:
if (IsPost)
{
string url = Request["selectId"] as string;
if (!string.IsNullOrEmpty(url))
{
Response.Redirect(url);
}
}