i have certain fields as required in the model and they are dropdownlist on the form.
if i try to submit the form without selecting anything no validation error occurs on the view the way a textinput would.
model
[['name', 'survey_type','country_id'], 'required',
'isEmpty' => function ($value) {
return empty($value);
}
],
display empty red validation
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
does not display any validation
<?= $form->field($model, 'survey_type')->dropDownList([$surveyTypeList],['prompt'=>'Select Survey Type','id'=>'Survey_Type_dropdown']) ?>
This is because you overrided id for drop-down list:
'id' => 'Survey_Type_dropdown'
You shouldn't do that If you want client validation working for this field.
Ids generated automatically and then used in javascript related with ActiveForm.
Remove it and everything should be fine:
<?= $form->field($model, 'survey_type')->dropDownList([$surveyTypeList],['prompt' => 'Select Survey Type']) ?>
If you want to do something with this element in javascript, use auto generated id or assign custom class.
I think this is because when the value is empty you return the result of empty($value) so the the attribute is set to true or false, meaning it is not empty.
Try removing the isEmpty part.
The accepted answer works, however, it isn't the correct answer. You may need to change the ID of any given input field and just telling people not to do it because they will not retrain client validation isn't true.
As per the Yii2 API docs it states that if you change the ID of an input field you must also update the input property "selector" as well to match the new ID you specified in the "options" property of the input field.
You do this as follows:
<?= $form->field($model, 'survey_type', ['selectors' => ['input' => '#Survey_Type_dropdown']]))->dropDownList([$surveyTypeList],['prompt'=>'Select Survey Type','id'=>'Survey_Type_dropdown']) ?>
Creating the input like above will allow you to change the ID of an input field while retaining client validation.
Related
Today I found a totally weird behaviour and I would like to stop it.
I use CakePhp 2.9 and have a search form, with which I want to search orders. My primary key in the model is the session_id due to relations to other models.
class Order extends AppModel
{
public $primaryKey = 'session_id';
I open my search form with
<?php echo $this->Form->create(
'Order',
array(
'url' => array('controller' => 'orders', 'action' => 'search')
)
); ?>
Which results in the following HTML:
<form id="OrderSearchForm" action="/orders/search" method="post" accept-charset="utf-8">
In the controller I do different things depending on the request being of the type post or not.
For debugging the weird behaviour I added the following debug lines in the controller:
if ($this->request->is('post')) {
debug('post');
} else if ($this->request->is('get')) {
debug('get');
} else {
debug($_REQUEST);
debug($_GET);
debug($_POST);
}
So as long as i search for other values than the session_id of my Order or combine the session_id with other search values everything is fine.
But as soon as I search ONLY for the session_id the generated HTML for the search form is changed to
<form id="OrderSearchForm" action="/orders/search/mysearchvaluesessionidstring" method="post" accept-charset="utf-8">
And when I then submit my form it is suddenly no longer considered as "post". The debug output for $_GET is still empty and the one for $_POST still filled, but the condition if ($this->request->is('post')) is not triggered anymore.
How can I change this behaviour?
It is possible that cake is changing the request type to PUT when the request data only contains the session id. You can get around this by checking if ($this->request->is(array('post', 'put'))) instead of just checking for POST requests.
You can read more about why this might be happening here
The Cookbook introduces for version 2.3 the possibility to deactivate the forced valiadation for forms. Or at least I understood it like that:
Quote: from http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html
" New in version 2.3.
Since 2.3 the HTML5 required attribute will also be added to the input
based on validation rules. You can explicitly set required key in
options array to override it for a field. To skip browser validation
triggering for the whole form you can set option 'formnovalidate' =>
true for the input button you generate using FormHelper::submit() or
set 'novalidate' => true in options for FormHelper::create()."
In my case I have a search from for this model and of course the user does not need to fill in all mandatory fields like for adding a dataset. So I want to deactivate the validation for my search form.
I tried all three variations and see no results: Still the mandatory fields for create are mandatory in my search form.
Those attempts I made:
first try:
echo $this->Form->create('Partner', array('action' => 'search', 'novalidate' => true));
second try:
echo $this->Form->input('name',
array('required' => false, 'value' => $this->Session->read('Searchparameter.name'))
);
third try:
$this->Form->submit('Submit', array('formnovalidate' => true));
echo $this->Form->end();
variation:
echo $this->Form->end(__('Submit'), array('formnovalidate' => true));
What did I understand wrong? btw: I did deactivate caching, so that should not be the problem.
Of course I could still use the old workaround for this validation, but when 2.3 is offering this option, I would gladly use it.
Calamity Jane
So I guess I found the problem and at least got one varation working:
What I am using now is:
echo $this->Form->create('Partner', array('action' => 'search', 'novalidate' => true));
I guess what I expected was that the fields wouldn't be marked with the fat label and the asterisk. Those are still there, but regardless you don't have to fill them in anymore. And the times I tested with really submittig the form I guess I had one of the 99 varations, which was really wrong.
If that makes me happy is mine to decide, but obviously I can switch off the HTML5 validation by that.
If I would want to have the labels not bold & asterisk, is there an option, too?
Calamity Jane
The solution is actually a lot simpler. If you would like to disable validation in specific views you actually only have to refer to a non-existing model when you create the form. You could for example do something like
echo $this->Form->create('PartnerSearch');
In your controller you can access the form fields through:
$this->request->data["PartnerSearch"]["field"]
instead of the usual way:
$this->request->data["Partner"]["field"]
For me, to skip the browser validation, yes, array('novalidate' => true) does work.
<?php echo $this->Form->create('MyModelName', array('novalidate' => true)); ?>
To have the label not bold & asterisk,
<?php echo $this->Form->input('myinput', array('required' => false));
In my case I used button for submitting the form. This allowed me more flexibility. In that case I used then property 'formnovalidate' pass in the array of options for the button. The form would look something like the following:
<?php
echo $this->Form->create('yourCtrllerName',array('action'=>'actionInYourCtrller'));
echo $this->Form->input('your_field_pass',array('label'=>'pass','type'=>'password'));
.... other Form fields .....
echo $this->Form->button('Button Caption',
array('type'=>'submit',
'name'=>'keyInsideTheDataArrayForButtonData',
'formnovalidate' => true,
'value'=>'valueOfTheAboveKeyInTheDataArray',
'style'=>'<style you want to apply to button>',
... other options if needed...
)
);
echo $this->Form->end();
I have the following situation.
Posts hasMany Comments
Comments belongTo Posts
In my /Views/Posts/view, I display the Post with its Comments. Also, with every Post, a Comment Form should be displayed. Therefore, I have to use an Element add_comment.ctp to the View (correct me please if I am wrong, but see this question here).
/Views/Posts/view.ctp:
// add comments
echo $this -> element('add_comment',array('post_id' => $entry['Post']['id']), array('cache' => array('config' => 'long')));
The element:
/**
* Element for adding comments
*
*/
echo $this -> Form -> create('Comment', array('url' => array(
'controller' => 'comments',
'action' => 'add',
$post_id
)));
?>
<fieldset>
<legend><?php echo 'Add Comment'; ?></legend>
<?php
echo $this -> Form -> input('author_name');
echo $this -> Form -> input('author_email', array('type' => 'email required'));
echo $this -> Form -> input('author_website');
//echo $this->Form->input('date_published');
echo $this -> Form -> input('text');
//echo $this->Form->input('is_archived');
?>
</fieldset>
<?php echo $this -> Form -> end(array('label' => 'Post!')); ?>
As you can see, the form is submitted to the add action of CommentsController.
Now, the big question: How can the add action actually pass data such as Validation results back to the form? I mean, form data should also be persisted, so in case somebody entered invalid data, its not lost.
Normally, the add action would render /View/Comments/add, but I neither need this view nor have I even defined one.
So far I have used $this->redirect to go back to the /Views/Posts/view after the Comment was saved -- but redirecting just calls /Views/Posts/view without passing anything. So how can I make use of Elements in Combination with smooth and automagic form handling?
I think if you're redirecting after the submit, it will lose any of the $this->invalidFields() which basically triggers the validation errors and such. There are a couple of ways around this....
1: You could not redirect and render the form once again in your comments/add.ctp view so the form will be displayed with validation errors automatically. Then to make the process smooth again redirect back to your post (you should have the Post ID somehow) once the save is successful and validation has passed.
2: Also You could put the comment saving logic in the Comment model, then check for a comment POST in your Post View action (update form to point to this action) and call the save function you create there with $this->Post->Comment->saveMethodDefinedInModel($this->request->data['Post']);.
3: Or.... You could take option one and combine it with ajax, that'd be rather gnarly.
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.
I think this may be an easy solution, but I've spent an hour now investigating to no avail.
I have a registration form in an element that is being used in views belonging to different controllers. Using the "url" attribute, I've told it to submit to /users/register, but for some reason, the fields aren't submitting to the database.
Instead, there are errors for "undefined index" and a MySQL error for an undefined secondary key that I set (it's empty because it's not being submitted). Strangely, the form works fine if I include the element somewhere in the users views. Does anyone know why this is happening?
UPDATE - Here's the relevant code, sorry:
<?php
echo $form->create(array(
'id' => 'signupform',
'url' => array(
'controller' => 'users',
'action' => 'register')));
?>
The form fields are all correct, since the element works in the user controller's views anywhere. Do I need to include any other information in the creation of the form to point it more directly?
Specify the model 'User' as the first parameter to the $form->create() method.
<?php
echo $form->create('User', array(
'id' => 'signupform',
'url' => array(
'controller' => 'users',
'action' => 'register')
)
);
?>
This will ensure that the form fields are named as data[User][field_name], and prevent you from seeing that undefined index error.
Hope this works for you!
Without seeing the code, it sounds like Cake is magically assuming that the Model is the one for the controller that controls the current view. When that controller is Users, it works correctly. When it is, say, Articles, it will be trying (and failing) to fit the form fields to the Article model.
Without seeing any code, it is impossible to offer any more help.
EDIT:
If the form contains mixed models, e.g. User and Article, you must prefix the fieldnames like this:
$form->input('User.username');
$form->input('Article.title');
etc.
If you don't, the controller will assume they all belong to its own model.