I am using Yii 1 for my project. I have 5 fields in a form, which must be filled. There's no problem with that - a simple validation rule in model. However, there is one more field, which is not required. But if it is filled, other 5 fields must become not-required. How should I define such validation rules in rules() method in model?
Thank you in advance very much!
Try playing with scenarios. When you validate your data, check if this field is filled and create new model with specific scenario.
Look here
you can create your own custom validation rule so you can skip scenarios, you will need to:
Stating that:
$model->TRIGGERATTR = is the attribute that if informed is going to indicate that the other 5 are required
$model->ATTR1 = one of the five other attributes
$model->ATTR2 = two of the five other attributes
.
.
. and so on...
Declare your rule inside your model like :
array('ATTR1, ATTR2, ATTR3, ATTR4, ATTR5','{NameofRule}Validator'),
Create a custom validation inside your components/validators/general/{NameofRule}Validator
with the following code
class {NameofRule}Validator extends CValidator
{
public function validateAttribute($model, $attribute)
{
if((isset($model->TRIGGERATTR))&&(!is_null($model->TRIGGERATTR))
{
if(!isset$model->$attribute||is_null($model->$attribute))
{
$this->addError($model, $attribute, 'Is not Informed and it should be');
}
}
}
}
DonĀ“t forget to add your comments and mark as solved ;-)
Related
I have a question about enabling the is_unique() rule for form validation in CodeIgniter.
In another explanation (link), they don't include the model query builder for standard usage of is_unique()
I need to use the rule is_unique(table.field) for my id field.
What should I do for making this function work on my model file to initiate table.field from my database? Because at documentation, I didn't see an explanation for enabling the is_unique rule.
My current code is still use matching data manually, but I need to know how to use this rules
$this->form_validation->set_rules('siteid', 'Site ID', 'trim|required|max_length[100]|is_unique[site_tower.site_id_tlp]');
I have just gone through the link you posted, There are 2 ways to use such validation. If you have set in your configuration files.
With that you can use the code as is is_unique[TABLE_NAME.FIELD] and it will work automatically. But at times this logic might not necessarily meet your need and you will need something more complex.
For example lets say you have a members registration that requires you to check if the email already exists, you can run is_unique and it will work perfectly. Now let's say you want to edit the same member, running is_unique on an edit function will render the user unable to save the data if no data is edited. WHY? because is_unique would determine that the email is already registered although it belongs to the current user that is being edited.
How do we fix this? We run our own callback in which we specify the logic.
You do it by specifying a method within the controller (or a model -- slightly different) but you prefix the method name with callback_ so that it is detected.
$this->form_validation->set_rules('username', 'Username', 'callback_username_check');
This will then look for a method in your controller called 'username_check'
public function username_check($str)
{
if ($str == 'test')
{
$this->form_validation->set_message('username_check', 'The {field} field can not be the word "test"');
return FALSE;
}
else
{
return TRUE;
}
}
Of course you can use a query within the callback to check against the db rather than check for just a string as it shows in the example.
more information can be found on Ci3 documentation.
LINK
Use CTRL + F and search for callback or is_unique
You might have missed this?
$this->load->library('database');
works instantly after adding database lib.
I have a view where I used FormHelper methods ($this->Form->input, etc.) to create a form (post), but this form is not tied to any model. It's a dumb form.
For example, some fields are date fields. My controller will do some validation on these fields, but if there is a problem, how would I display the error message right below the field that had a validation error? With forms tied to models, CakePHP will automagically add a div to the relevant field to display the validation error message. Is there something similar for dumb forms?
Thank you for the assistance.
Use a model which isn't associated with a db table. Rest will be same as using a regular db backed model. Eg:
// Model
class Dummy extends Model {
public $useTable = false;
public $validate = array('somefield' => 'notEmpty');
}
// View
echo $this->Form->create('Dummy');
echo $this->Form->input('somefield');
......
// Controller
public some_action() {
//if post request
$this->Dummy->set($this->request->data);
$this->Dummy->validates();
}
What about FormHelper::error() ?
http://api.cakephp.org/1.3/class-FormHelper.html#_error
I use a certain form in several places. In one of them I need to ignore a form element which I set programmatically after the validation.
Because it's just an exception I don't want to create a new form. So I thought, I just remove this element in the controller like:
$myForm->remove('myElement');
The problem is that the form now won't validate. I don't get any errors but the $myForm->isValid() just returns an empty value.
Any ideas what I might be doing wrong?
Ok, finally I found a solution! You can define a ValidationGroup which allows you to set the attributes you'd like to validate. The others are not validated:
$form->setValidationGroup('name', 'email', 'subject', 'message');
$form->setData($data);
if ($form->isValid()) {
...
The first thing I thought about was to remove the validator from your myElement's ValidatorChain. You could get it within the controller with:
$form->getInputFilter()->get( 'myElement' )->getValidatorChain()
It seems like you can't remove from the ValidatorChain, just add. Check this post. Matthew Weier O'Phinney, from Zend, explains why it can't be done and a possible solution for your scenario.
The way I solve this problem, is checking the 'remove condition' when I create the validator in the FormFilter class. If you use annotations I think it doesn't works for you, so Matthew suggestions is the one you should use.
Or you could try the one in this post from #Stoyan Dimov: define two forms, a kind of BasicForm and ExtendedForm. The first one have all the common form elements, the second one is an extended one of the other with the rest of fields. Depending on your condition you could use one or another.
In class ValidatorChain implements Countable, ValidatorInterface, add a new method:
public function remove($name){
foreach ($this->validators as $key => $element) {
$validator = $element['instance'];
if($validator instanceof $name){
unset($this->validators[$key]);
break;
}
}
}
Use like this:
$form->getInputFilter()->get("xxxxx")->getValidatorChain()->remove('xxxxxx');
There must be a validator defined for this particular element that you are trying to remove.
In your controller where you are adding new elements to form, there must be addValidator calling like:
$element->addValidator('alnum');
That is actually causing validation to be failed. So you have removed the element from form but you still have validation defined on that element to be checked.
If you are not able to find this validation adding function in controller, try to see if it has been defined through config file.
You can read further about form validation in zf here: http://framework.zend.com/manual/1.12/en/zend.form.elements.html
I remove the element with:
$form->get('product')->remove('version');
When I post the form I disable the validator on this element with :
$form->getInputFilter()->get('product')->get('version')->setRequired(FALSE);
I am using Symfony with propel to generate a form called BaseMeetingMeetingsForm.
In MeetingMeetingsForm.class.php I have the following configure method:
public function configure() {
$this->useFields(array('name', 'group_id', 'location', 'start', 'length'));
$this->widgetSchema['invited'] = new myWidgetFormTokenAutocompleter(array("url"=>"/user/json"));
}
In MeetingMeetings.php my save method is simply:
public function save(PropelPDO $con = null) {
$this->setOwnerId(Meeting::getUserId());
return parent::save($con);
}
However propel doesn't know about my custom field and as such doesn't do anything with it. Where and how to I put in a special section that can deal with this form field, please be aware it is not just a simple save to database, I need to deal with the input specially before it is input.
Thanks for your time and advice,
You have to define a validator (and/or create your own). The validator clean() method returns the value that needs to be persisted.
In Doctrine (I don't know Propel) the form then calls the doUpdateObject() on the form, which in turns calls the fromArray($arr) function on the model.
So if it's already a property on your model you'll only need to create the validator. If it's a more complex widget, you'll need to add some logic to the form.
I'm building an app for the company I work for in symfony, non the less the app might be pretty useful outside our company so we decided to write it in a more general form so we can make it multi company. I'm facing a problem on how to define a default value for a field that is going to be in every single model (company_id) so we don't need to select which company we belong to every time we want to add data. can anyone help me?
I've tried
class TestForm extends BaseTestForm
{
function configure()
{
$this->setDefault('company_id', '1');
}
}
and when I submit the form I get a missing value for model ....
I did it, in the action of course, before the processForm and after the $this->form = new TestForm();
I used:
public function executeCreate(sfWebRequest $request)
{
...
$this->form->getObject()->setCompanyId('1');
...
}