CodeIgniter repopulate form from both session data & form validation? - forms

I have a form with a couple search options, like a checkbox array and radio button. By using the form validation library I have the form repopulating after a submit, like so:
echo form_checkbox('check_track[]', '1', set_checkbox('check_track[]', '1', TRUE));
echo form_dropdown('select_year', $options, set_value('select_year', '2013'), $attribs);
I also save all the form options (by storing the post) into session userdata. Is it possible to repopulate all the fields from the session data if $_SERVER['REQUEST_METHOD'] !== 'POST' but keep repopulating based on form validation otherwise?

The easier would probably be to separate the form generation from the value generation. In the snippet you provide, the value is read directly from the submitted form.
I would advise you, in you controller or your model to generate a data structure, each field corresponding to one of the form field.
For each, the value would either be the default, either the one stored in the session if it matches you condition ie: valid data and not after a POST if I understood you well.

I ended up just faking that a POST had happened before the form validation stuff ran to get repopulation to work:
if(!isset($_POST['something']) && $this->session->userdata('something'))
{
$_POST = $this->session->all_userdata();
}
$this->form_validation->set_rules('something', 'stuff', 'required');
.
.
.

Related

Suppress errors in Symfony 2

I try to remove some fields from form in event listener. But when I do that I get an error like this form should not contain extra fields. How can I suppress this error?
Here is my listener:
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$form = $event->getForm();
$form->remove('field');
}
});
if you want to ignore data submitted for a field you could unset it's data on "PRE_SET_DATA" or set it to current value in the entity.
Not sure why you would like to first allow the user to submit a form and then cut out part of it instead of just presenting a shorter form in the first place
you could also unset the data AND remove the field from the form on PRE_SUBMIT, but then in case vlaidation goes wrong, user gets back a different form

Symfony 2.x Form Field Name

When I render a form, form Filed Name is given as an array. For example: search[item], search[keyword] etc. where search is name of the form.
I'm not great on working with forms but I think, the name should be rendered as simply, name="item" or name="keyword".
I've looked at all the documentation, customizing form rendering topic etc. but I can't find any way to change the default behaviour of Symfony form to render form filed name from 'search[item]' to 'item'.
This way, when I ask for the POST data, I can ask simply $this->getRequest()->request->get('item'), as I have to deal with lots of individual parameters.
Help would be great i) To figure out how to achieve what I want. ii) to let me know, why the name is rendered this way. is this the good practice?
Rather than accessing parameters from the Request object, you can bind the Request object to the form.
For example, in your controller method that you post your form to:
namespace Acme\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Acme\Form\MyFormClass;
class MyFormController extends Controller
{
receiveFormAction(Request $request)
{
$form = new MyFormClass();
// you can specify that a route only accepts a post
// request in the routing definition
if ($request->isMethod('POST')) {
// this populates the form object with the data
// from the form submission
$form->bind($request);
if ( ! $form->isValid()) {
throw new \Exception('Invalid form');
}
// an array of the data the format you require
$data = $form->getData();
$data['item'];
$data['keyword'];
// etc.
}
}
}
The above is the way you should be handling forms in Symfony 2, and is how you can leverage the power that the forms component gives you, with validation etc.
Symfony supports multiple forms on a page. They might be instances of the same form or have similar field names. Having the fields for each form all together in an array makes this easy to do.

How do i preserve form input - after submiting form with dynamic menu list ?? Zend framework

Im trying to preserve the user inputs from dynamic menu dropdown lists - I have an number of drowpdowns and a user input text field , when the user submits the form after selecting the options from the dropdowns.
I would like to be able to preserve the last choices made so the user does not have to reselect the options again when re posting the form with another value in the text field, i would also like this to work on errors as well ?
Im using ZF to validate the form.
i have tried the follwing code in the value attr of the option:
<option value="<?php if ($_POST && errors) {
echo htmlentities($_POST['CategoryID'], ENT_COMPAT, 'UTF-8');
}?>">Main Category</option>
But does not seem to work ?
I have a static options "Main Category" ect. which is what the form defaults to after submiting
can anyone help me on this one ??
Thanks in advance
I would highly recommend using Zend_Form. If that is not possible, I would next use Zend_View Helpers to build your HTML manually. Then you can use the formSelect in your view like this:
echo $this->formSelect('CategoryId', $selected, $attribs, array(
'main' => 'Main Category'
// ... other options
));
Where $selected variable equals to one of the following: posted value(s), default value(s), or is null and $attribs variable is simply attributes for the select element.

Must I re-populate Zend_Form fields after the post back manually?

After a post back, suppose validation fails and I want to show the form again with errors, I find that the form is empty, must I repopulate the form fields manually?
The method isValid populate the form field. You don't have to repopulate manually.
I find the best way to handle form processing is to use something like
$form = new My_Form;
if ($this->getRequest()->isPost()
&& $form->isValid($this->getRequest()->getPost()) {
// process form and redirect (PRG pattern)
}
$this->view->form = $form;
This way, your form is shown on the first request and if not valid, is re-shown with the submitted values and any validation messages.
In case you are using some custom isValid don't forget your form also has a populate() function.
So
$data = $this->getRequest()->getPost();
if(!$myForm->isValid($data)){
$myForm->populate($data);
}
No need to do it by hand thats for sure.
Of course dont forget to assign the same object you did the isValid - populate calls on
$this->view->form = $myForm;
After the checks.

Zend Framework: Post to different action then return to original action if fails validation AND keep form fields

This might sound like an odd scenario, but I've got two forms on one page. One is just posting back to itself. I made the second post to another action to keep the code cleaner. Maybe not the right choice...
The problem I'm having now is that if that second form doesn't validate, I redirect back to the page with the form but I don't know how to keep my form fields filled in with the original information the user entered. Is there a way to do that and keep posting to two separate actions, or do I need to just bite the bullet and have both forms post back to the same action and deal with the messy logic?
I would submit both forms to the same action. There really shouldn't be anything too messy about it. In each form include a hidden field to signify which form is being submitted.
Application_Form_Login:
/* other form elements */
$this->addElement('hidden', 'login', array(
'value' => 1
));
Application_Form_Register:
/* other form elements */
$this->addElement('hidden', 'register', array(
'value' => 1
));
Controller:
$loginForm = new Application_Form_Login();
$registerForm = new Application_Form_Register();
if($this->_request->isPost()) {
if($this->_request->getPost('login')) {
if($loginForm->isValid($this->_request->getPost())) {
// validated, redirect
$this->_helper->redirector('profile', 'user');
}
}
if($this->_request->getPost('register')) {
if($registerForm->isValid($this->_request->getPost())) {
// validated, proceed as needed
}
}
}
$this->view->loginForm = $loginForm;
$this->view->registerForm = $registerForm;
View:
echo $this->loginForm;
echo $this->registerForm;
With this type of a setup, if either of your forms fail validation, isValid() will preserve any data that has been entered and you still redirect on a successful validation of one or both of the forms.
Personally, I think that each form should post to its own controller, as you have. This keeps the code for processing that form in a single place. The issue here is that you want to return to the original page on failed validation. But why? Why not simply redisplay the form in the target controller, just like you would if there were a single form on the page?
For example, consider a login form that appears on every page of a sie (perhaps because it in the site template/layout). It posts to something like AuthController::loginAction(). If the login fails, then you don't typically send him back to the page from which he came. You leave him at the login page, with the form as pre-filled from the $_POST as you want it to be (probably a username, but not his password).
See this answer for a similar discussion.
Update: Had another thought in this. If you really want to handle the processing in two different controllers in order to keep him on the page from which he posted the form, at least extract that form processing out into an action helper. This way, you could at least keep that form-processing DRY.
Update: Rob Allen has just written a great blog post "A form in your layout" in which he describes a method that uses an action-helper with a preDispatch() method that instantiates and processes the form. Very nice.
How do you redirect? I don't see the problem if you just display the form page again. You can prefill you forms using Zend_Form::populate().
Well, I would just keep both forms submitting on the same page.
I don't see why your code should get any less readable. Learn how to use action helpers and your controllers will suddenly look extremely simple and readable:
public function indexAction()
{
$request = $this->getRequest();
// send forms to view, so we can print them
// but also so we can access them in action helpers
$this->view->form = $this->_getForm('Form1', '/');
$this->view->form2 = $this->_getForm('Form2', '/');
if ($request->isPost())
{
// process the first form
if (isset($_POST['form_submit_button']) && $this->view->form->isValid($_POST))
{
$this->_helper->form($this->view->form->getValues());
}
// process the second form
else if (isset($_POST['form2_submit_button']) && $this->view->form2->isValid($_POST))
{
$this->_helper->form2($this->view->form2->getValues());
}
}
Each form's processing would have its own action helper.