I have three dropdowns for day, month, and year. when I applied required condition yii2 validation show individual error for all three fields. But I want single error message for three fields like "dob is required".
view file :
<?= $form->field($model, "month")->dropDownList([], ['class'=>'form-control day'])->label(false);?>
<?= $form->field($model, "day")->dropDownList([], ['class'=>'form-control day'])->label(false);?>
<?= $form->field($model, "year")->dropDownList([], ['class'=>'form-control year'])->label(false);?>
model :
public $day;
public $month;
public $year;
[['month','day','year'], 'required', 'when' => function ($model) {
return (($model->month == "") || ($model->day == "") || ($model->year == ""));
},
'whenClient' => "function (attribute, value) {
return ($('#user-month').val() == '' || $('#user-day').val() == '' || $('#user-year').val() == '');
}",'on'=>'profile'
]
This code showing me error messages for all three dropdowns individually. But i want single error message for dob: like "dob is required".
Try this :
Write this code in your Model :
public function rules()
{
return [
[['month','day','year',],'required','on'=>['create','update'],'message' => 'Please enter DOB.'],
];
}
Write this code in your Action in Controller where you call your view:
$model = new YourModelName();
$model->scenario = "create";
Example :
$model = new User();
$model->scenario = "create";
Maybe You sholud do something more like:
['month', 'validationFunction', 'skipOnEmpty' => false]
...
public function validationFunction($attribute, $params) {
if( !$this->hasErrors() ) {
if (!$this->month || !$this->day || !$this->year) {
$this->addError($attribute, 'dob is required');
}
}
}
Related
I am trying to add captcha validation based on scenario, for which I am first retrieving number of failed attempts from database. For which I am using checkattempts() function. Based on the result I am displaying captcha in view and adding scenario condition in controller as below.
In LoginForm model:
public function rules()
{
return [
[['username', 'password'], 'required', 'on'=>'loginpage'],
[['username', 'password'], 'required', 'on'=>'withCaptcha'],
[['reference_url'], 'safe'],
[['verifyCode'], 'captcha', 'skipOnEmpty' => true,'on'=>'withCaptcha'],
['username','email', 'on'=>'loginpage', 'message'=> 'Please enter a valid email address'],
['password', 'validatePassword', 'on'=>'loginpage'],
['password', 'validatePassword', 'on'=>'withCaptcha'],
];
}
public function checkattempts($uname)
{
$user = \frontend\models\User::findByEmail($uname);
$ip = $this->get_client_ip();
if($user){
$data = (new Query())->select('*')
->from('login_attempts')
->where(['ip' => $ip])->andWhere(['user_ref_id' => $user->id])
->one();
if($data["attempts"] >=3){
return true;
}else{
return false;
}
}
return false;
}
in SiteController.php controller
public function actionLogin() {
if (!\Yii::$app->user->isGuest) {
return $this->redirect(Yii::$app->getUrlManager()->getBaseUrl() . '/../../');
}
$model = new \common\models\LoginForm();
$model->scenario = 'loginpage';
$captcha = false;
if(Yii::$app->request->post()){
$post_variables =Yii::$app->request->post('LoginForm');
if ($model->checkattempts($post_variables['username'])) {
$model->scenario = 'withCaptcha';
$captcha = true;
}
}
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->login(); print_r($model->getErrors()); exit;
} else {
return $this->render('login', [
'model' => $model, 'captcha' => $captcha,
]);
}
In my login.php view:
<?php if($captcha) { ?>
<?= $form->field($model, 'verifyCode')->widget(Captcha::className(),
['template' => '<div class="captcha_img">{image}</div>'
. '<a class="refreshcaptcha" href="#">'
. Html::img('/images/imageName.png',[]).'</a>'
. 'Verification Code{input}',
])->label(FALSE); ?>
<?php } ?>
In my controller when I am tring to print model errors at $model->login() function it is giving below error everytime even though the verification code is correct.
Array ( [verifycode] => Array ( [0] => The verification code is incorrect. ) )
Why is it failing every time. Is there any mistake in the code written?
Thanks in advance
I have a column named wp_status. If person A, person B, person C, person D approves a work, the value of column wp_status will be changed to Approved, else the value will be as it is in the database - Assigned.
The code to change the value dynamically in the gridview is -
[
'label' => 'Status',
'attribute'=>'wp_status',
'value' => function ($model) {
return $model->Status();
}
],
And the function Status in model Workpermit is -
public function Status()
{
//$data = Workpermit::findOne($this->id);
$total = $this->wp_status;
if($this->wp_type == 'Safe Work Permit' && $this->wp_apoapproval == 'Approved' && $this->wp_spsapproval == 'Approved' && $this->wp_officerapproval == 'Approved'){
$total = 'Approved';
}
return $total;
}
This works fine so far. But I'm not sure how to filter it with Kartik Select2 widget. I tried like following -
[
'label' => 'Status',
'attribute'=>'wp_status',
'filterType'=>GridView::FILTER_SELECT2,
'filter'=>ArrayHelper::map(Workpermit::Status()->asArray()->all(), 'total', 'total'),
'filterWidgetOptions'=>[
'pluginOptions'=>['allowClear'=>true],
],
'filterInputOptions'=>['placeholder'=>'Permit Status'],
'value' => function ($model) {
return $model->Status();
}
],
And here I'm getting error - Using $this when not in object context
could be uisng a getter
public function getStatus()
{
//$data = Workpermit::findOne($this->id);
$total = $this->wp_status;
if($this->wp_type == 'Safe Work Permit' && $this->wp_apoapproval == 'Approved' && $this->wp_spsapproval == 'Approved' && $this->wp_officerapproval == 'Approved'){
$total = 'Approved';
}
return $total;
}
the call $model->status (status lowercase)
[
'label' => 'Status',
'attribute'=>'wp_status',
'value' => function ($model) {
return $model->status;
}
],
i'm still beginner in yii and php.
my problem is:
i want add a value that from db to my textfield.
my db table 'config' have 3 column, id;name;value;
i have tried code like this:
<?= $form->field($model, 'name')->textInput(['value'=>$model->value])->label('name',['class'=>'label-class'])?>
but it didn't show the value.
i want a update form for change value . example: name: title; value: hello world.
Your controller should be something like that:
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
protected function findModel($id)
{
if (($model = Mymodel::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
and in view you simply write
<?= $form->field($model, 'name')->textInput()->label('name',['class'=>'label-class'])?>
Your database values will be in your field.
For simple CRUD you may use GII http://www.yiiframework.com/doc-2.0/guide-start-gii.html
Out of two pairs of input fields I only need one or the other. I can't get the validation right.
listing_image_url and poster_image_url should only be required if $model->listingImage is null.
Also tried using strlen($model->listingImage) == 0.
[['listing_image_url', 'poster_image_url'], 'required',
'when' => function($model){
var_dump($model->listingImage); //result is empty string '0'
return $model->listingImage == NULL && $model->posterImage == NULL;
},'whenClient' => "function(attribute, value) {
return $('#vod-listingimage').val() == '' && $('#vod-posterimage').val() == '';
}", 'message' => 'look'
],
Just as above but the other way around.
[['listingImage', 'posterImage'], 'required',
'when' => function($model) {
return $model->listing_image_url == NULL && $model->poster_image_url == NULL;
},
'whenClient' => "function(attribute, value) {
return $('#vod-listing_image_url').val() == '' && $('#vod-poster_image_url').val() == '';
}", 'message' => 'hi'
],
You could create your own inline validator for the model validation on backend side, like this:
[['listingImage', 'posterImage'], function($attribute, $params) {
if ($this->listingImage === null && empty($this->$attribute)) {
$this->addError($attribute, 'Can not be blank if listingImage is null');
}
}]
In order to also provide the client side validation you can build a custom standalone validator.
I tried myself something similar and the behavior is odd indeed.
But you can create a validator that checks if only one of the two fields is selected.
public function validateListingAgainstPoster($attribute, $params)
{
if (!empty($this->listing_image_url) && !empty($this->poster_image_url)) {
$this->addError($attribute, 'Only one of "Listing" or "Poster" fields can be selected.');
}
if (empty($this->listing_image_url) && empty($this->poster_image_url)) {
$this->addError($attribute, 'Please select one of "Listing" or "Poster Group".');
}
}
And in your rules:
[['listing_image_url', 'poster_image_url'], 'validateListingAgainstPoster', 'skipOnEmpty' => false, 'skipOnError' => false],
I have a registration form with fields that are validated in User entity class. The validation works fine, however I can't return JsonResponse with form error messages in it.
My registration form controller method looks like this:
/**
* #Route("/register", name="register")
*/
public function registerAction(Request $request)
{
$user = new User();
$form = $this->createForm(RegistrationType::class, $user);
$form->handleRequest($request);
$errors = "";
if ($form->isSubmitted())
{
if ($form->isValid())
{
$password = $this->get('security.password_encoder')
->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
$user->setIsActive(1);
$user->setLastname('none');
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return new JsonResponse(
array(
'message' => 'Success! User registered!',
), 200);
}
else
{
$errors = ($this->get('validator')->validate($form));
return new JsonResponse(
array(
'message' => 'Not registered',
'errors' => $errors,
), 400);
}
}
return $this->render(
'ImmoBundle::Security/register.html.twig',
array('form' => $form->createView(), 'errors' => $errors)
);
}
I get the following json response when I submit the registration form with invalid data:
{"message":"Not registered","errors":{}}
Actually I'm expecting that "errors":{} will contain some error fields, but it doesn't. Does anyone know what the problem here is?
UPD:
My RegistrationType looks like this:
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstname', TextType::class)
->add('email', EmailType::class)
->add('plainPassword', RepeatedType::class, array(
'type' => PasswordType::class,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat password'),
'invalid_message' => "Passwords don't match!",
))
->add('register', SubmitType::class, array('label' => 'Register'));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'ImmoBundle\Entity\User',
'csrf_protection' => true,
'csrf_field_name' => '_token',
'csrf_token_id' => 'authenticate',
));
}
}
UPD2: Found the solution. I needed to do this iteration and then call for getMessage():
$allErrors = ($this->get('validator')->validate($form));
foreach ($allErrors as $error)
{
$errors[] = $error->getMessage();
}
Form validated when you call $form->handleRequest($request);
To get form errors use getErrors method
$errors = $form->getErrors(true); // $errors will be Iterator
to convert errors object to messages array you can use code from this response - Handle form errors in controller and pass it to twig
This is exapmle how i'm process errors in one of my projects
$response = $this->get('http.response_formatter');
if (!$form->isValid()) {
$errors = $form->getErrors(true);
foreach ($errors as $error) {
$response->addError($error->getMessage(), Response::HTTP_BAD_REQUEST);
}
return $response->jsonResponse(Response::HTTP_BAD_REQUEST);
}
It's worked for me.
And also this can help you - Symfony2 : How to get form validation errors after binding the request to the form
You must set error_bubbling to true in your form type by explicitly setting the option for each and every field.