Yii2 ActiveForm unique validation not show error message - yii2

This is my model contacts,
public function rules()
{
return [
[['fname', 'status','mobile',], 'required'],
[['user_id', 'contact_type','group_type','passport_no','trip_id','group_id','state',], 'integer'],
[['fname', 'mname', 'lname', 'status', 'street', 'location', 'post', 'city', 'district','email','job_title','company_name','source'], 'string', 'max' => 500],
[['department'], 'string', 'max' => 40],
[['pincode'], 'string', 'max' => 15],
[['mobile'],'unique'],
Here the required validation of mobile works and show error message, but unique rule works but it doesn't show any error message
Help me plz.

1) Unique validation work with database.
2) Once form was submitted then validation was checked and model not saved because of unique validation fails.
3) If you want to unique validation on form then use Ajax.
For this, You need to set 'enableAjaxValidation' => true,
$form = ActiveForm::begin([
'id' => 'contact-form',
'enableAjaxValidation' => true,
]);
Controller:
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post()))
{
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
Reference

Maybe you should also set targetClass:
['email', 'unique', 'targetClass' => '\common\models\User']

I am assuming your view page as register.php. So,
register.php (View)
1) Remove use yii\bootstrap\ActiveForm; (if present)
2) Add use yii\widgets\ActiveForm;
3) Add 'enableAjaxValidation' => true in that field (Where you are validating it. Like below)
<?= $form->field($model, 'mobile',['enableAjaxValidation' => true])->textInput(['class'=>'form-control']) ?>
Controller
See below (Add this line wherever I have written //Add This Line)
.
.
use yii\web\Response; // Add This line
use yii\widgets\ActiveForm; //Add This Line
.
.
Class SomeClass
{
.
.
.
public function actionRegister() {
$model = new Candidate();
//Add This For Ajax Mobile Exist Validation
if(Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())){
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
else if ($model->load(Yii::$app->request->post())) {
.
// Your code
.
.
}
}
}
Model
[['mobile'],'unique','message'=>'Mobile No Already Exist'],
For Reference - Click Validate unique value from database in Yii2

if ($model->validate()) {
//SAVE YOUR DATA
} else {
// HERE YOU CAN PRINT THE ERRORS OF MODEL
$data = $model->getErrors();
Yii::$app->session->setFlash('message', $data['password'][0]);// its dislplays error msg on your form
}

This rule in my model worked for me:
['email', 'required'],
['email', 'email'],
['email', 'unique', 'targetClass' => '\app\models\Student', 'message' => 'This email address has already been taken.'],

Related

autologin from register page should be removed

I have an auth login control. Login form and register form all are working. I somehow kept my register form inside after login credentials. It is working inserting into user but needs to disable auto-login when registered.
Register controller
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller
{
use RegistersUsers;
//protected $redirectTo = '/home';
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255','unique:users'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'user_type' => ['required', 'string'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'user_type' => $data['user_type'],
'password' => Hash::make($data['password']),
]);
$this->guard()->login($data);
return $this->registered($request, $data)
?: redirect($this->redirectPath());
Session::flash('flash_message','successfully saved.');
}
}
I changed few things it worked
in register controller i created new function
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
Then added
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;
then removed
$this->guard()->login($user);
It is working now

Yii2 - Dropdownlist to load other attributes

I have this Model Class
public function attributeLabels()
{
return [
'id' => Yii::t('course', 'ID'),
'course_code' => Yii::t('course', 'Course Code'),
'course_type' => Yii::t('course', 'Course Type'),
'course_title' => Yii::t('course', 'Course Title'),
'course_unit' => Yii::t('course', 'Course Unit'),
];
}
On Dropdownlist change, I want to load and display course_code, course_type, course_title, and course_unit. But should only save course_title. The other should only be displayed and not save, except course_title.
Am ableto display only course_title. This is my view for the dropdown list.
<?= $form->field($modelDetail, "course_id")->widget(Select2::classname(), [
'data' => ArrayHelper::map(app\modules\course\models\CourseMaster::find()->where(['is_status'=>0])->all(),'id','course_title'),
'language' => 'en',
'options' => ['placeholder' => '--- Select Course ---',
],
'pluginOptions' => [
'allowClear' => true
],
]); ?>
This is what I have done.
But I want to achieve this.
How do I display other attributes as textInput() or label without saving in database. Thanks
Controller
public function actionCreate()
{
$modelDetail = new CourseMaster();
if (Yii::$app->request->isAjax && $modelDetail->load(Yii::$app->request->post())) {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return ActiveForm::validate($modelDetail);
}
if ($modelDetail->load(Yii::$app->request->post())) {
$modelDetail->attributes = $_POST['CourseMaster'];
if($modelDetail->save())
return $this->redirect(['index']);
else
return $this->render('create', ['modelDetail' => $modelDetail,]);
} else {
return $this->render('create', [
'modelDetail' => $modelDetail,
]);
}
}
If you want to only display other fields without sending it on form submit, you can mark field as disabled:
<?= $form->field($modelDetail, 'course_code')->textInput([
'disabled' => true,
]) ?>
This will render input which cannot be edited directly and it will not be sent on form submit.
Well You can concat the data in the label of dropdown itself, will be an easier option. Use closure on the third argument in ArrayHelper::map($array, $from, $to, $group = null) as follows.
ArrayHelper::map(
app\modules\course\models\CourseMaster::find()->where(['is_status'=>0])->all(),
'id',
function($model){
return $model['course_title']." - ".$model['course_code'];
}
)

Yii2 client side validation refreshes the page on form submit

I am trying to perform client side check but the page is being refreshed. My rules looks like:
public function rules()
{
return [
[['email'], 'required'],
[['email','cron'], 'string'],
[['email'], 'string', 'max' => 100],
[['cron', 'group', 'type'], 'integer'],
[['email'], 'unique'],
['group', 'required', 'when' => function($model){
return $model->type == 1;
}, 'whenClient' => 'function(attribute, value){
return 1==2;
}']
];
}
The form enableClientValidation is switched to true like this :
<?php $form = ActiveForm::begin([
'enableClientValidation' => true
]) ?>
Where is my mistake ? Thank you in advance!
You need to set enableAjaxValidation property of AcitveForm:
$form = ActiveForm::begin([
'id' => 'form-id',
'enableAjaxValidation' => true,
]);
Controller
if ($model->load(Yii::$app->request->post())) {
if(Yii::$app->request->isAjax) {
return $this->asJson(ActiveForm::validate($model));
}
}
Yii2 Ajax Validation
asJson()
<?php $form = ActiveForm::begin([
'id' => 'form',
'enableAjaxValidation' => true
]) ?>

Trying to get property of non-object while using kartik-v for image uploading in Yii2

I'm using yii2-widget-fileinput for an image uploading in a form.
When I click on upload or the create button I get Trying to get property of non-object error in controller.
Controller
public function actionCreate()
{
Yii::$app->params['uploadPath'] = Yii::$app->basePath . '/uploads/';
$model = new Ads();
$provinces = ArrayHelper::map(Province::find()->all(), 'name', 'name');
if ($model->load(Yii::$app->request->post())){
$image = UploadedFile::getInstances($model, 'image');
$model->filename = $image->name;
$ext = end((explode(".", $image->name)));
$avatar = Yii::$app->security->generateRandomString().".{$ext}";
$path = Yii::$app->params['uploadPath'].$avatar;
if ($model->save()) {
$image->saveAs($path);
$model->image_adr = $path;
return $this->redirect(['view', 'id' => $model->id]);
}else{
echo "error on saving the model";
}
}
return $this->render('create', [
'model' => $model,
'provinces'=>$provinces,
]);
}
model rules
public function rules()
{
return [
[['type', 'explanation', 'cost', 'province_name', 'address'], 'required'],
[['type', 'explanation', 'image_adr', 'address'], 'string'],
[['cost'], 'integer'],
[['province_name'], 'string', 'max' => 20],
[['province_name'], 'exist', 'skipOnError' => true, 'targetClass' => Province::className(), 'targetAttribute' => ['province_name' => 'name']],
[['image'],'safe'],
[['image'], 'file', 'extensions'=>'jpg, gif, png', 'maxFiles'=>3,],
];
and finnally the view
<?= $form->field($model, 'image[]')->widget(FileInput::classname(), [
'options'=>['accept'=>'image/*', 'multiple'=>true],
'pluginOptions'=>['allowedFileExtensions'=>['jpg','gif','png'], 'overwriteInitial'=>false,]
]); ?>
the problem should refer to this part in the controller I think
$image = UploadedFile::getInstances($model, 'image');
An image of the error might be helpful
You should check first is image in post or not.
....
$image = UploadedFile::getInstances($model, 'image'); //getInstanceByName
if (!empty($image))
$model->filename = $image->name;
.....
if ($model->save()) {
if (!empty($image))
$image->saveAs($path);
.........
Make sure in your form ency type is added:
$form = ActiveForm::begin([
'id' => 'form_id',
'options' => [
'class' => 'form_class',
'enctype' => 'multipart/form-data',
],
]);
The problem is when you're using UploadedFile::getInstances($model, 'image'); you should work with foreach or treat it like an array.
Something that made me a problem was that even if you're using UploadedFile::getInstanc (notice the obsoleted s in the end) you should still treat it like an array and in all parts you should use $image[0], not $iamge lonely.

yii2 disable the rules if a checkbox is selected

In the active form, I have 3 textinput and one checkbox.
All the 3 textinputs have rules that says cannot be empty. What I want is if the checkbox is clicked, It will disable the rules and will save the empty record in the database.
here is screen shot of the active form..
You could define the rules that way (using when):
public function rules()
{
return [
['cancelled', 'boolean'],
['checkNumber', 'required'],
['payee', 'required', 'when' => function ($model) {return !$model->cancelled;}],
['particulars', 'required', 'when' => function ($model) {return !$model->cancelled;}],
];
}
You may want to add whenClient as well to let the browser check this before it submits the form.
You can do something like this:
$model = new SomeForm();
if ($model->load(Yii::$app->request->post())){
if ($model->checkbox == true) $model->scenario = 'checked';
}
// your model rules:
[['name', 'email', 'subject', 'body'], 'safe', 'on' => 'checked']
or alternatively You can do this:
if ($model->checkbox == true) $model->save(false); //this will disable any validation so be carefull
edit:
if You need cliend side validation switch, You have to use this:
[['name', 'email', 'subject', 'body'], 'required', 'when' => function ($model) {
return $model->cancelled == '0';
}, 'whenClient' => new JsExpression("function (attribute, value) { return $('#mailform-cancelled').val() == '0';}")]