Form Data Not Being Sent From View To Controller - forms

So I'm trying to send a few pieces of data from a form in cake's form builder but for some reason none of the data being submitted is showing up when I print out $this->data or $this->request->data
I've tried creating the form myself and using cake's Form Builder and I need to send this data via POST. The data shows up if I send it as a GET parameter.
view.ctp
echo $this->Form->create(null, array('action' => 'downloadbgc', 'type' => 'get'));
echo $this->Form->input('userId', ['type' => 'text' , 'id' => 'userId', 'name' => 'userId', 'value' => $user->id]);
echo $this->Form->input('product_id', ['type' => 'hidden' , 'id' => 'product_id', 'name' => 'product_id', 'value' => $user->product_id]);
echo $this->Form->submit('Download PDF', array('class' => 'btn btn-icon btn-primary', 'title' => 'Download'));
echo $this->Form->end();
controller.php
...
public function downloadbgc() {
$this->autoRender = false;
print_r("Data: ");
print_r($this->data); die();
}
}
...
When printing this out I get Data: Array() instead of Array('userId' => X, 'product_id' => Y) And I'm positive that these values aren't null since they print to the console.

Use the FormHelper's create() in a correct way:
echo $this->Form->create(false, ['url' => 'downloadbgc']);
echo $this->Form->input('userId', ['type' => 'text' , 'id' => 'userId', 'name' => 'userId', 'value' => 123]);
echo $this->Form->input('product_id', ['type' => 'hidden' , 'id' => 'product_id', 'name' => 'product_id', 'value' => 4456]);
echo $this->Form->submit('Download PDF', array('class' => 'btn btn-icon btn-primary', 'title' => 'Download'));
echo $this->Form->end();
Like the Docs point out the create() method can take the Model as first parameter or false, if you want to access the data without Model. Also use the url option as action is deprecated
In your Controller you can then use $this->request->data to access your data.

Related

Cakephp 3 Not Recognizing Custom Validation Rule Method and Validation Messages Not Showing

First issue is I have the following validators and public function in my table
UsersTable.php
$validator
->scalar('name')
->maxLength('name', 45)
->requirePresence('name', 'create')
->notEmptyString('name', 'You must enter a name for the user.');
$validator
->add('name', 'custom', array('rule' => 'checkExistingUser', 'message' => 'This user already appears to be in the system.', 'on' => 'create'));
public function checkExistingUser($value,$context)
{
return $this->find('all', ['conditions' => ['Users.name' => $context['data']['name'], 'Users.user_type_id' => $context['data']['user_type_id']]])->count() < 1 ;
}
When I save the form below I receive the message "Method checkExistingUser does not exist". Why doesn't it recognize the method when it's clearly defined in the table model? Am I missing something?
add.ctp
<?php echo $this->Form->create($user);?>
<fieldset>
<legend><?php echo __('Add User'); ?></legend>
<?php
echo $this->Form->control('name', ['type' => 'text']);
echo $this->Form->control('user_type_id');
echo $this->Form->control('owner', array('type' => 'text', 'label' => "Owner Name"));
echo $this->Form->control('owner_contact', array('type' => 'text', 'label' => "Owner Contact (phone, email etc)"));
echo $this->Form->control('description', ['type' => 'textarea']);
echo $this->Form->control('ia_exception', array('type' => 'text', 'label' => "IA Exception Number"));
echo $this->Form->control('is_manual', array('type' => 'checkbox', 'label' => "Password Updated Manually"));
echo $this->Form->control('Environment', ['type' => 'select', 'multiple' => 'true', 'label' => 'Environment(s)']);
?>
</fieldset>
<div class="buttons">
<?php
echo $this->Form->button('Save', ['type'=> 'submit', 'name' => 'submit']);
echo $this->Form->button('Cancel', ['type' => 'button', 'name'=>'cancel', 'onClick' => 'history.go(-1);return true;']);
echo $this->Form->end();
?>
</div>
UsersController.php
function add() {
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->set('The user has been saved');
return $this->redirect(array('action' => 'index'));
} else {
$this->Flash->set('The user could not be saved. Please, try again.');
}
}
$userTypes = $this->Users->UserTypes->find('list');
$changeSteps = $this->Users->ChangeSteps->find('list');
$environments = $this->Users->Environments->find('list');
$this->set(compact('user','userTypes', 'changeSteps', 'environments'));
}
Second issue is when I try to submit my form to check that the validator is working correctly for an empty name field I don't receive the message 'You must enter a name for the user'. Instead I receive a message stating 'This field is required'. Why is it not showing my message from notEmptyString? And where is 'This field is required' coming from?
For the first issue, I had to add a provider in my validator.
I changed
$validator
->add('name', 'custom', array('rule' => 'checkExistingUser', 'message' => 'This user already appears to be in the system.', 'on' => 'create'));
To this
$validator
->add('name', 'custom', ['rule' => 'checkExistingUser', 'provider' => 'table', 'message' => 'This user already appears to be in the system.', 'on' => 'create']);
Be careful with custom methods for validation during patching, because Cake expects string to be returned, otherwise it will rendere default meassage.
So for example, if we use a custom validation function during patching
// in a Controller
$this->Users->patchEntity($user, $data, ['validate' => 'custom');
Same applies for closures.
// in UserTable.php
public function validationCustom(Validator $validator) {
$validator = $this->validationDefault($validator);
$validator
->minLength('password',8,'At least 8 digits');
$validator->add('password',
'strength_light',[
'rule' => 'passwordCheck',
'provider' => 'table',
'message' => 'At least a number and a capital letter'
]
);
return $validator;
}
public function passwordCheck ($value = "") {
return preg_match("/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!#$%^&*-]).{8,}/",$value);
}
This will return default message and not the custom one ("At least..") because we set a callable not-cakephp function as rule for custom validation, so the message should be returned by the called function:
public function passwordCheck ($value = "") {
if (!preg_match("/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!#$%^&*-]).{8,}/",$value))
return "At least a number and a capital letter";
}

Create a SelectBox using Form Helper in CakePHP3

I am trying to make a combo box for an edit page.
echo $this->Form->select('status',
['empty' => 'Select Status'],
['class' => 'form-control', 'required']
);
Here I want to add 2 things :
$options = array('0' => 'Inactive',
'1' => 'Active',
);
and selected value. suppose that is $status;
I tried with different options but sometime it do not add classes and sometime it shows options in tag
It will be great if somebody give clue.
Thanks
<?= $this->Form->input('status', [
'type' => 'select',
'options' => ['0' => __('Inactive') , '1' => __('Active')],
'empty' => __('Select Status'),
'class' => 'form-control',
'required' => true, 'label' => __('Type')
])
?>

Cakephp 3.0 form dropdown how to show level

I am trying to add a form field for gender below is my code :
$options = ['m' => 'Male', 'f' => 'Female'];
echo $this->Form->select('gender', $options);
But in my view file I am unable to see lebel gender is there any other code which can help me suggest .
From->select doesn't give a proper label. Just do:
echo $this->Form->input('gender', array(
'options' => $options,
'type' => 'select',
'empty' => 'Select the gender',
'label' => 'Gender'
)
);
<?= $this->Form->select('gender', ['m' => 'Male', 'f' => 'Female'], ['class' => 'form-control', 'required' => true])?>

Display boolean as radio button in CakePHP form

Does anyone know how to display two radio buttons in a form in CakePHP and have them save to a boolean field in the DB?
I can get my boolean value to display as a checkbox (default behaviour) but I need to display two radio buttons, however when I do this the changes don't get saved to the DB.
I feel like it's something very simple. Here's my code:
<h1>Edit Content</h1>
<?php
$thisVal = $this->data['LessonContent']['is_exercise'] ? "1" : "0";
$options = array(
'0' => 'Learning Material',
'1' => 'Exercise'
);
echo $this->Form->create('LessonContent', array('action'=>'edit'));
echo $this->Form->input('name', array('label' => 'Name'));
echo $this->Form->input('description', array('label' => 'Description'));
echo $this->Form->input('is_exercise', array(
'type' => 'radio',
'class' => 'radio',
'legend' => false,
'name' => 'Type',
'options' => $options,
'value' => $thisVal
));
echo $this->Form->input('id', array('type'=>'hidden'));
echo $this->Form->input('lesson_id', array('type'=>'hidden'));
echo $this->Form->end('Save Content');
echo $this->Html->link('Cancel', array('controller'=>'Lessons', 'action'=>'view', $this->data['Lesson']['id']));
?>
Thanks
You're overriding the name of the input, therefore the value for is_excercise will be sent as Type.
Remove the name option;
echo $this->Form->input('is_exercise', array(
'type' => 'radio',
'class' => 'radio',
'legend' => false,
'options' => $options,
'value' => $thisVal
));
note after making this change, you probably don't even have to manually set the value of the radio-button.
debugging
In situations like this, always check/debug the posted form-data, either via FireBug or by debugging it in CakePHP, by putting this in your controller;
debug($this->request);
Even better, install the CakePHP DebugKit Plugin this plugin shows all the information (request data, queries, session variables etc.) without having to add debug-lines

CodeIgniter: Controller structure for forms with many inputs

I'm developing a site using CodeIgniter and am trying to adhere to the "Fat Model / Skinny Controller" paradigm, but am running into some problems when it comes to pages containing forms with a number of inputs. The code below is what I'm using to define the inputs for the address fields
Part of my Controller (where I'm defining the form inputs and their attributes):
$this->data['address1'] = array(
'name' => 'address1',
'id' => 'address1',
'type' => 'text',
'class' => 'field text addr',
'tabindex' => '10',
'value' => $this->form_validation->set_value('address1'),
'placeholder' => 'Street Address'
);
$this->data['address2'] = array(
'name' => 'address2',
'id' => 'address2',
'type' => 'text',
'class' => 'field text addr',
'tabindex' => '11',
'value' => $this->form_validation->set_value('address2'),
'placeholder' => 'Address Line 2',
);
$this->data['city'] = array(
'name' => 'city',
'id' => 'city',
'type' => 'text',
'class' => 'field text addr',
'tabindex' => '12',
'value' => $this->form_validation->set_value('city'),
'placeholder' => 'City'
);
$this->data['state'] = array(
'name' => 'state',
'id' => 'state',
'class' => 'field addr',
'tabindex' => '13',
'value' => $this->form_validation->set_value('state'),
'label' => array('class' => 'desc')
);
$this->data['zip'] = array(
'name' => 'zip',
'id' => 'zip',
'type' => 'text',
'class' => 'field text addr',
'tabindex' => '14',
'maxlength' => '20',
'value' => $this->form_validation->set_value('zip'),
'placeholder' => 'Zip / Postal Code'
);
$this->data['country'] = array(
'name' => 'country',
'id' => 'country',
'class' => 'field addr',
'tabindex' => '15',
'value' => $this->form_validation->set_value('country')
);
Part of my View (minus all the HTML to position the form inputs):
<?php
echo form_open("address/add");
echo form_input($address1);
echo form_input($address2);
echo form_input($city);
$options = array();
$options[''] = 'State / Province / Region';
foreach($province_options AS $prov)
{
$options[$prov->id] = $prov->province;
}
echo form_dropdown('state',$options,'',$state);
echo form_input($zip);
$options = array();
$options[''] = 'Country';
foreach($country_options AS $cnt)
{
$options[$cnt->id] = $cnt->country;
}
echo form_dropdown('country',$options,'',$country);
echo form_submit('submit', 'Submit & Continue');
echo form_close();
?>
I feel like my Controller is overly verbose, but I can't think of what the alternative would be for how to organize the information necessary to represent my form if I'm planning on using the Form Helper to generate the form inputs in my view. Is this the right way to be doing things, or is there a better approach?
Just because Codeigniter provides all of these helpers does not mean you have to use them!
All you need is form_open() because this adds the CRSF token (if used).
Raw HTML is much cleaner and I suspect much faster than waiting for PHP to render markup.
Edit: I would like to add, the reason its cleaner is because you have control over the output, where as CI might adere to certain specifications.
I don't see a problem in your question.
This is just silly
$options = array();
$options[''] = 'State / Province / Region';
There is a little bit of logic that can be moved to the controller or even model layer:
$options = array();
$options[''] = 'Country';
foreach($country_options AS $cnt)
{
$options[$cnt->id] = $cnt->country;
}
echo form_dropdown('country',$options,'',$country);
Could probably look like:
echo form_dropdown('country', $countries, '', $country);
...if you move the options to the controller or view.
This is a problem I run into all the time trying to keep things DRY as possible, where to define the form data? I think sometimes we forget the power of the "V" in "MVC". You could define all the view logic in the view instead.
Things like id, tabindex and placeholder are only necessary and useful in the view. Things like form validation rules and data checking/prepping belong in the Controller/Model layer.
The form helper functions are useful, but sometimes raw HTML is better. For example:
// Controller
$this->data['address1'] = array(
'name' => 'address1',
'id' => 'address1',
'type' => 'text',
'class' => 'field text addr',
'tabindex' => '10',
'value' => $this->form_validation->set_value('address1'),
'placeholder' => 'Street Address'
);
// View
echo form_input($address1);
Or simply:
<input name="address1" id="address1" tabindex="10" type="text" placeholder="Street Address" value="<?php echo set_value('address1'); ?>" class="field text addr">
I wrote a bunch of applications last year where I defined all this stuff in the Model, and now I'm regretting it as I've been going back to do maintenance on them and all the view logic is obscured away in the Model or Controller. Editing a Controller or Model to change a class attribute is just silly.